package view import ( _ "embed" "fmt" "goreader/gallery" "goreader/state" "strconv" "strings" "github.com/silva-guimaraes/gtag" ) //go:embed static/styles.css var styles string //go:embed static/reader.js var readerJavascript string //go:embed static/index.js var indexJavascript string //go:embed static/hotkeys.min.js var hotkeys string //go:embed static/htmx.min.js var htmx string func tag(t gallery.Tag, state *state.State) *gtag.Tag { gender := "X" backgroundClass := "any" if t.Sex == gallery.Male { gender = "M" backgroundClass = "male" } if t.Sex == gallery.Female { gender = "F" backgroundClass = "female" } d := gtag.New("a"). Href(fmt.Sprintf("javascript:filter_tags('%s')", strings.TrimSpace(t.Name) /* FIXME */)). Class("tag") { d.Tag("span").Text(gender).Class("name", backgroundClass) d.Tag("span").Text(t.Name).Class("name") d.Tag("span").Text(strconv.Itoa(state.UniqueTags[t.Name])).Class("name", backgroundClass) } return d } func artistTag(artistName string) *gtag.Tag { d := gtag.New("a"). Href(fmt.Sprintf("javascript:filter_artist('%s')", artistName /* FIXME */)). Class("tag") { d.Tag("span").Text(artistName).Class("name") } return d } func thumbnail(src string) *gtag.Tag { return gtag.NewVoid("img").SetAttr("src", src).SetAttr("loading", "lazy") } func fullThumbnail(g gallery.Gallery) *gtag.Tag { thumb := thumbnail(fmt.Sprintf("/page/%s/1", g.Uuid())) return gtag.Div().Id("image-wrapper").Append(thumb) } func smallThumbnail(g gallery.Gallery) *gtag.Tag { return thumbnail(fmt.Sprintf("/thumb/%s", g.Uuid())).Class("thumbnail") } func InspectorInfo(g gallery.Gallery, state *state.State) *gtag.Tag { d := gtag.Div().Class("float") { // d.Append(smallThumbnail(g)) d.Append(fullThumbnail(g)) // d.Tag("div").Id("inspector-image-placeholder") d.Tag("a"). SetAttr("href", fmt.Sprintf("/read/%s", g.Uuid())). SetAttr("hx-boost", "false"). Tag("h1"). SetAttr("style", "color: white; margin: 10px 0 10px 0;"). Text(g.Name()) d.Tag("h2").Style("margin: 0").Text(g.JpName()) d.Tag("h3"). Text(fmt.Sprintf("Pages: %d", len(g.Images()))). Style("font-size: 14px; ; margin: 0;") d.Tag("h2").Text("Artists") artists := d.Div() { for _, a := range g.Artists() { artists.Append(artistTag(a)) } } d.Tag("h2").Text("Tags") tags := d.Div() { for _, t := range g.Tags() { tags.Append(tag(t, state)) } } } return d } func cover(g gallery.Gallery) *gtag.Tag { var s []string for _, tag := range g.Tags() { s = append(s, fmt.Sprintf("'%s'", strings.TrimSpace(tag.Name)) /* FIXME */) } dataset := fmt.Sprintf("[%s]", strings.Join(s, ", ")) a := gtag.New("a"). Class("cover"). Id(fmt.Sprintf("cover-%s", g.Uuid())). SetAttr("href", fmt.Sprintf("/read/%s", g.Uuid())). SetAttr("data-tags", dataset). SetAttr("hx-get", fmt.Sprintf("/details/%s", g.Uuid())). SetAttr("onmouseenter", "inspectSetTimeout(event)"). SetAttr("onmouseleave", "inspectClearTimeout(event)"). SetAttr("hx-trigger", "inspect"). SetAttr("hx-target", "#inspector"). SetAttr("hx-boost", "false") a.Append(smallThumbnail(g)) return a } const galleriesPerPage = 70 func SearchResults(galleries []gallery.Gallery) *gtag.Tag { s := gtag.New("section") results := s.Tag("section").Id("results") { results.Tag("header").Tag("h1").Text(fmt.Sprintf("Listing %d Galleries", len(galleries))) covers := results.Tag("main") for _, g := range galleries { covers.Append(cover(g)) } } return s } func Stats(state *state.State) *gtag.Tag { s := gtag.New("div").Id("stats") { s.Tag("p").Text(fmt.Sprintf("Galleries loaded: %d", len(state.Galleries))) s.Tag("p").Text(fmt.Sprintf("Unique tags: %d", len(state.UniqueTags))) s.Tag("p").Text(fmt.Sprintf("Unique artists: %d", len(state.UniqueArtists))) s.Tag("p").Text(fmt.Sprintf("Unique groups: %d", len(state.UniqueGroups))) s.Tag("p").Text(fmt.Sprintf("Unique parodies: %d", len(state.UniqueParodies))) } if !state.Done { s.SetAttr("hx-get", "/stats").SetAttr("hx-trigger", "every 0.01s").SetAttr("hx-swap", "outerHTML") } return s } func Index(state *state.State, page int) *gtag.Tag { html := gtag.Doc() { head := html.Head() { head.Tag("title").Text("index") head.Tag("style").Asis(styles) head.Asis( ``, ) head.Asis("") head.Tag("script").Asis(hotkeys) head.Asis("") head.Tag("script").Asis(htmx) } body := html.Body().Id("index").SetAttr("hx-boost", "true") { nav := body.Tag("nav").Class("container") { nav.Tag("a"). Href("javascript:clear_filters()"). Text("clear filters") nav.Div().Text("omakase v1") } center := body.Div().Id("center") { d := center.Div() // HTMX faz com que isso receba [InspectorInfo] quando usuário paira o // mouse sobre algum cover d.Tag("section").Id("inspector") d.Append(SearchResults(state.Galleries)) } body.Tag("footer").P().Text(randomQuote()) body.Tag("script").Asis(indexJavascript) } } return html } // content := body.Div().Id("content").Class("container"); { // details := content.Tag("details"); { // details.Tag("summary").Text("filter tags...") // tags := details.Div().Id("tags"); { // tags.Tag("a").Href("javascript:void(0)").Text("clear tags"). // Class("name", "tag").Style("display: block;"). // SetAttr("hx-post", "/filter/clear/all"). // SetAttr("hx-target", "#listing"). // SetAttr("hx-swap", "outerHTML") // tags.Text("Tags:") // tagsSpan := tags.Tag("span").SetAttr("hx-boost", "true"); { // for k, v := range uniqueTags { // tagsSpan.Append(tag(k, v)) // } // } // } // } // content.Append(galleriesListing(galleries)) // }