htmgo/examples/hackernews/partials/story.go

92 lines
2 KiB
Go
Raw Normal View History

2024-10-10 22:00:20 +00:00
package partials
import (
"fmt"
"github.com/maddalax/htmgo/framework/h"
"hackernews/internal/news"
"hackernews/internal/timeformat"
2024-10-10 22:59:08 +00:00
"time"
2024-10-10 22:00:20 +00:00
)
func Story(ctx *h.RequestContext) *h.Partial {
2024-10-10 22:59:08 +00:00
storyId := news.MustItemId(ctx)
if storyId == 0 {
2024-10-10 22:17:05 +00:00
return h.NewPartial(
2024-10-10 22:00:20 +00:00
h.Div(
2024-10-10 22:17:05 +00:00
h.Class("flex justify-center bg-neutral-300"),
h.Id("story-body"),
2024-10-10 22:00:20 +00:00
),
)
}
if ctx.IsHxRequest() {
return h.SwapManyPartialWithHeaders(
ctx,
h.PushUrlHeader(fmt.Sprintf("/?item=%d", storyId)),
2024-10-10 22:59:08 +00:00
h.Div(
h.Id("story-body"),
CachedStoryBody(storyId),
),
2024-10-10 22:00:20 +00:00
)
}
return h.NewPartial(
2024-10-10 22:59:08 +00:00
CachedStoryBody(storyId),
2024-10-10 22:00:20 +00:00
)
}
2024-10-10 22:59:08 +00:00
var CachedStoryBody = h.CachedPerKeyT[string, int](time.Minute*3, func(itemId int) (string, h.GetElementFunc) {
return fmt.Sprintf("story-%d", itemId), func() *h.Element {
story, err := news.GetStory(itemId)
if err != nil {
return h.Div(
h.Id("story-body"),
h.Text("Failed to load story"),
)
}
return StoryBody(story)
}
})
2024-10-10 22:00:20 +00:00
func StoryBody(story *news.Story) *h.Element {
return h.Div(
h.Id("story-body"),
h.Div(
2024-10-10 22:17:05 +00:00
h.Class("prose prose-2xl bg-white border-b border-gray-200 pb-3 min-w-3xl max-w-3xl"),
2024-10-10 22:00:20 +00:00
h.H5(
2024-10-10 22:59:08 +00:00
h.Class("flex gap-2 items-left font-bold"),
2024-10-10 22:00:20 +00:00
h.UnsafeRaw(story.Title),
),
h.A(
h.Href(story.Url),
h.Class("text-sm text-rose-400 no-underline"),
h.Text(story.Url),
),
h.Div(
h.Class("text-sm text-gray-600"),
h.UnsafeRaw(story.Text),
),
h.Div(
h.Class("text-sm text-gray-600 mt-2"),
h.TextF("%d upvotes ", story.Score),
h.UnsafeRaw("•"),
h.TextF(" %s ", story.By),
h.UnsafeRaw("•"),
h.TextF(" %s", timeformat.RelativeTime(story.Time)),
),
),
2024-10-10 22:59:08 +00:00
h.TriggerChildren(),
h.Div(
h.Id("comments-loader"),
h.Class("flex justify-center items-center h-24"),
h.Div(
h.Class("animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-rose-500"),
),
),
2024-10-10 22:00:20 +00:00
h.Div(
2024-10-10 22:17:05 +00:00
h.Class("mt-2 min-w-3xl max-w-3xl"),
2024-10-10 22:00:20 +00:00
h.GetPartial(StoryComments, "load"),
),
)
}