diff --git a/src/templates/svg/chevron-left.svg b/src/templates/svg/chevron-left.svg
new file mode 100755
index 00000000..50d25e90
--- /dev/null
+++ b/src/templates/svg/chevron-left.svg
@@ -0,0 +1,56 @@
+
+
+
+
diff --git a/src/templates/svg/chevron-right.svg b/src/templates/svg/chevron-right.svg
new file mode 100755
index 00000000..dd79d6af
--- /dev/null
+++ b/src/templates/svg/chevron-right.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/src/templates/svg/close.svg b/src/templates/svg/close.svg
new file mode 100755
index 00000000..a1a36cf9
--- /dev/null
+++ b/src/templates/svg/close.svg
@@ -0,0 +1,11 @@
+
+
+
diff --git a/src/templates/templates.go b/src/templates/templates.go
index bd167a40..e713c3c7 100644
--- a/src/templates/templates.go
+++ b/src/templates/templates.go
@@ -71,6 +71,21 @@ func names(ts []*template.Template) []string {
return result
}
+//go:embed svg/close.svg
+var SVGClose string
+
+//go:embed svg/chevron-left.svg
+var SVGChevronLeft string
+
+//go:embed svg/chevron-right.svg
+var SVGChevronRight string
+
+var SVGMap = map[string]string{
+ "close": SVGClose,
+ "chevron-left": SVGChevronLeft,
+ "chevron-right": SVGChevronRight,
+}
+
var HMNTemplateFuncs = template.FuncMap{
"add": func(a int, b ...int) int {
for _, num := range b {
@@ -148,6 +163,13 @@ var HMNTemplateFuncs = template.FuncMap{
return str(int(delta/Yearish), "year", int((delta%Yearish)/Monthish), "month")
}
},
+ "svg": func(name string) template.HTML {
+ contents, found := SVGMap[name]
+ if !found {
+ panic("SVG not found: " + name)
+ }
+ return template.HTML(contents)
+ },
"static": func(filepath string) string {
return hmnurl.BuildPublic(filepath, true)
},
diff --git a/src/website/landing.go b/src/website/landing.go
index 1c6f08b3..81a066f9 100644
--- a/src/website/landing.go
+++ b/src/website/landing.go
@@ -278,6 +278,42 @@ func Index(c *RequestContext) ResponseData {
newsPostResult := newsPostRow.(*newsPostQuery)
c.Perf.EndBlock()
+ c.Perf.StartBlock("SQL", "Fetch showcase snippets")
+ type snippetQuery struct {
+ Owner models.User `db:"owner"`
+ Snippet models.Snippet `db:"snippet"`
+ Asset *models.Asset `db:"asset"`
+ DiscordMessage *models.DiscordMessage `db:"discord_message"`
+ }
+ snippetQueryResult, err := db.Query(c.Context(), c.Conn, snippetQuery{},
+ `
+ SELECT $columns
+ FROM
+ handmade_snippet AS snippet
+ INNER JOIN auth_user AS owner ON owner.id = snippet.owner_id
+ LEFT JOIN handmade_asset AS asset ON asset.id = snippet.asset_id
+ LEFT JOIN handmade_discordmessage AS discord_message ON discord_message.id = snippet.discord_message_id
+ ORDER BY snippet.when DESC
+ `,
+ )
+ if err != nil {
+ return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets"))
+ }
+ snippetQuerySlice := snippetQueryResult.ToSlice()
+ showcaseItems := make([]templates.TimelineItem, 0, len(snippetQuerySlice))
+ for _, s := range snippetQuerySlice {
+ row := s.(*snippetQuery)
+ timelineItem := SnippetToTimelineItem(&row.Snippet, row.Asset, row.DiscordMessage, &row.Owner, c.Theme)
+ if timelineItem.Type != templates.TimelineTypeSnippetYoutube {
+ showcaseItems = append(showcaseItems, timelineItem)
+ }
+ }
+ c.Perf.EndBlock()
+
+ c.Perf.StartBlock("SHOWCASE", "Convert to json")
+ showcaseJson := templates.TimelineItemsToJSON(showcaseItems)
+ c.Perf.EndBlock()
+
baseData := getBaseData(c)
baseData.BodyClasses = append(baseData.BodyClasses, "hmdev", "landing") // TODO: Is "hmdev" necessary any more?
@@ -299,10 +335,11 @@ func Index(c *RequestContext) ResponseData {
Unread: true, // TODO
Content: template.HTML(newsPostResult.PostVersion.TextParsed),
},
- PostColumns: cols,
+ PostColumns: cols,
+ ShowcaseTimelineJson: showcaseJson,
}, c.Perf)
if err != nil {
- panic(err)
+ return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render landing page template"))
}
return res