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 itemPageContent struct { Item itemPageData IsAdmin bool } type itemPageData struct { ID string Title *string Description *string LinkURL *string ItemType string EmbedHTML *string EmbedVideoURL *string Tags []string CreatedAt string ThumbnailID *int64 MediaID *int64 MediaIsVideo bool } func (c itemPageContent) Render(sw *ssr.Writer) error { return sw.Tmpl(c, `
← BACK
{{if eq .Item.ItemType "quote"}}
{{.Item.Description}}
{{if .Item.Title}}— {{.Item.Title}}{{end}}
{{else if eq .Item.ItemType "video"}}
{{else if eq .Item.ItemType "embed"}} {{if .Item.EmbedVideoURL}}
{{else if .Item.ThumbnailID}}
{{if .Item.Title}}{{.Item.Title}}{{else}}Embed{{end}}
{{else if .Item.MediaID}}
{{if .Item.Title}}{{.Item.Title}}{{else}}Embed{{end}}
{{end}} {{else if .Item.MediaID}}
{{if .Item.Title}}{{.Item.Title}}{{else}}Image{{end}}
{{else if .Item.ThumbnailID}}
{{if .Item.Title}}{{.Item.Title}}{{else}}Image{{end}}
{{end}}
{{if .Item.Title}}

{{.Item.Title}}

{{end}} {{if and .Item.Description (ne .Item.ItemType "quote")}}

{{.Item.Description}}

{{end}} {{if .Item.LinkURL}} {{.Item.LinkURL}} {{end}} {{if .Item.Tags}}
{{range .Item.Tags}} {{.}} {{end}}
{{end}}
{{if .IsAdmin}}
{{if .Item.LinkURL}}{{end}}
{{end}}
{{if .IsAdmin}} {{end}} `) } // HandleItemPage handles GET /item/{id} func HandleItemPage(rc *RequestContext, w http.ResponseWriter, r *http.Request) error { pubID := r.PathValue("id") if pubID == "" { http.NotFound(w, r) return nil } ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) defer cancel() it, err := item.QFindByPubID(ctx, rc.DB, pubID) if err != nil { return err } if it == nil { http.NotFound(w, r) return nil } // Get tags itemTags, err := tag.QTagsForItem(ctx, rc.DB, it.ID) if err != nil { return err } tagNames := make([]string, len(itemTags)) for i, t := range itemTags { tagNames[i] = t.Name } // Get media var thumbnailID, mediaID *int64 var mediaIsVideo bool mediaList, err := media.QFindByItemID(ctx, rc.DB, it.ID) if err != nil { return err } for _, m := range mediaList { if m.MediaType == "thumbnail" { thumbnailID = &m.ID } else if m.MediaType == "original" { mediaID = &m.ID mediaIsVideo = strings.HasPrefix(m.ContentType, "video/") } } data := itemPageData{ 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), EmbedVideoURL: item.Ptr(it.EmbedVideoURL), Tags: tagNames, CreatedAt: it.CreatedAt.Format("Jan 2, 2006"), ThumbnailID: thumbnailID, MediaID: mediaID, MediaIsVideo: mediaIsVideo, } w.Header().Set("Content-Type", "text/html; charset=utf-8") sw := ssr.NewWriter(w, rc.TmplCache) var title string if it.Title.Valid { title = it.Title.V } page := components.Page{ Title: title, IsAdmin: rc.IsAdmin, Content: itemPageContent{Item: data, IsAdmin: rc.IsAdmin}, } return page.Render(sw) }