package handlers import ( "context" "net/http" "strings" "time" "git.soup.land/soup/sxgo/ssr" "lookbook/internal/components" "lookbook/internal/data/item" "lookbook/internal/data/media" "lookbook/internal/data/tag" ) type homeContent struct { Items []homeItem Tags []string ActiveTag string IsAdmin bool } type homeItem struct { ID string Title *string Description *string LinkURL *string ItemType string EmbedHTML *string Tags []string MediaID *int64 HasVideo bool ImageIDs []int64 // Fetched images (from URLs/embeds) } func (h homeContent) Render(sw *ssr.Writer) error { return sw.Tmpl(h, `
{{if .IsAdmin}}
{{end}}
ALL {{range .Tags}} {{.}} {{end}}
{{range .Items}} {{if eq .ItemType "quote"}}
{{.Description}}
{{if .Title}}— {{.Title}}{{end}}
{{else if .ImageIDs}}
{{range $i, $id := .ImageIDs}}Image{{end}}
{{if gt (len .ImageIDs) 1}}{{end}} {{if .HasVideo}}
{{end}} {{else if .MediaID}} Image {{if or .HasVideo (eq .ItemType "video")}}
{{end}} {{else if eq .ItemType "embed"}}
{{else}} {{end}} {{if or .Title .Tags}}
{{if and .Title (ne .ItemType "link") (ne .ItemType "quote")}}
{{.Title}}
{{end}} {{if .Tags}}
{{range .Tags}}{{.}}{{end}}
{{end}}
{{end}}
{{end}}
{{if .IsAdmin}} {{end}} `) } // HandleHome handles GET / func HandleHome(rc *RequestContext, w http.ResponseWriter, r *http.Request) error { ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) defer cancel() tagFilter := r.URL.Query().Get("tag") var items []item.Row var err error if tagFilter != "" { items, err = item.QListByTag(ctx, rc.DB, tagFilter) } else { items, err = item.QList(ctx, rc.DB) } if err != nil { return err } // Get all tags allTags, err := tag.QList(ctx, rc.DB) if err != nil { return err } tagNames := make([]string, len(allTags)) for i, t := range allTags { tagNames[i] = t.Name } // Build home items homeItems := make([]homeItem, 0, len(items)) for _, it := range items { hi := homeItem{ ID: it.PubID, Title: item.Ptr(it.Title), Description: item.Ptr(it.Description), LinkURL: item.Ptr(it.LinkURL), ItemType: it.ItemType, EmbedHTML: item.Ptr(it.EmbedHTML), } // Get tags itemTags, err := tag.QTagsForItem(ctx, rc.DB, it.ID) if err != nil { return err } hi.Tags = make([]string, len(itemTags)) for i, t := range itemTags { hi.Tags[i] = t.Name } // Get media mediaList, err := media.QFindByItemID(ctx, rc.DB, it.ID) if err != nil { return err } for _, m := range mediaList { if m.MediaType == "original" { hi.MediaID = &m.ID if strings.HasPrefix(m.ContentType, "video/") { hi.HasVideo = true } } else if m.MediaType == "image" { hi.ImageIDs = append(hi.ImageIDs, m.ID) } } // Also check for embed video URL if it.EmbedVideoURL.Valid && it.EmbedVideoURL.V != "" { hi.HasVideo = true } homeItems = append(homeItems, hi) } content := homeContent{ Items: homeItems, Tags: tagNames, ActiveTag: tagFilter, IsAdmin: rc.IsAdmin, } w.Header().Set("Content-Type", "text/html; charset=utf-8") sw := ssr.NewWriter(w, rc.TmplCache) page := components.Page{ Title: "", IsAdmin: rc.IsAdmin, Content: content, } return page.Render(sw) }