diff options
author | r <r@freesoftwareextremist.com> | 2019-12-13 18:08:26 +0000 |
---|---|---|
committer | r <r@freesoftwareextremist.com> | 2019-12-13 18:26:24 +0000 |
commit | 5e4da01c3ae3ae2e870faba9085d9d9213c01c29 (patch) | |
tree | 39d6f1e76b901549f194ddbac3c6cb82e0abd019 /renderer | |
download | bloat-5e4da01c3ae3ae2e870faba9085d9d9213c01c29.tar.gz bloat-5e4da01c3ae3ae2e870faba9085d9d9213c01c29.zip |
Initial commit
Diffstat (limited to 'renderer')
-rw-r--r-- | renderer/model.go | 40 | ||||
-rw-r--r-- | renderer/renderer.go | 112 |
2 files changed, 152 insertions, 0 deletions
diff --git a/renderer/model.go b/renderer/model.go new file mode 100644 index 0000000..ddc9e2d --- /dev/null +++ b/renderer/model.go @@ -0,0 +1,40 @@ +package renderer + +import ( + "mastodon" +) + +type TimelinePageTemplateData struct { + Statuses []*mastodon.Status + HasNext bool + NextLink string + HasPrev bool + PrevLink string +} + +func NewTimelinePageTemplateData(statuses []*mastodon.Status, hasNext bool, nextLink string, hasPrev bool, + prevLink string) *TimelinePageTemplateData { + return &TimelinePageTemplateData{ + Statuses: statuses, + HasNext: hasNext, + NextLink: nextLink, + HasPrev: hasPrev, + PrevLink: prevLink, + } +} + +type ThreadPageTemplateData struct { + Status *mastodon.Status + Context *mastodon.Context + PostReply bool + ReplyToID string +} + +func NewThreadPageTemplateData(status *mastodon.Status, context *mastodon.Context, postReply bool, replyToID string) *ThreadPageTemplateData { + return &ThreadPageTemplateData{ + Status: status, + Context: context, + PostReply: postReply, + ReplyToID: replyToID, + } +} diff --git a/renderer/renderer.go b/renderer/renderer.go new file mode 100644 index 0000000..c3d3526 --- /dev/null +++ b/renderer/renderer.go @@ -0,0 +1,112 @@ +package renderer + +import ( + "context" + "io" + "strconv" + "strings" + "text/template" + "time" + + "mastodon" +) + +type Renderer interface { + RenderErrorPage(ctx context.Context, writer io.Writer, err error) + RenderHomePage(ctx context.Context, writer io.Writer) (err error) + RenderSigninPage(ctx context.Context, writer io.Writer) (err error) + RenderTimelinePage(ctx context.Context, writer io.Writer, data *TimelinePageTemplateData) (err error) + RenderThreadPage(ctx context.Context, writer io.Writer, data *ThreadPageTemplateData) (err error) +} + +type renderer struct { + template *template.Template +} + +func NewRenderer(templateGlobPattern string) (r *renderer, err error) { + t := template.New("default") + t, err = t.Funcs(template.FuncMap{ + "WithEmojis": WithEmojis, + "DisplayInteractionCount": DisplayInteractionCount, + "TimeSince": TimeSince, + "FormatTimeRFC3339": FormatTimeRFC3339, + }).ParseGlob(templateGlobPattern) + if err != nil { + return + } + return &renderer{ + template: t, + }, nil +} + +func (r *renderer) RenderErrorPage(ctx context.Context, writer io.Writer, err error) { + r.template.ExecuteTemplate(writer, "error.tmpl", err) + return +} + +func (r *renderer) RenderHomePage(ctx context.Context, writer io.Writer) (err error) { + return r.template.ExecuteTemplate(writer, "homepage.tmpl", nil) +} + +func (r *renderer) RenderSigninPage(ctx context.Context, writer io.Writer) (err error) { + return r.template.ExecuteTemplate(writer, "signin.tmpl", nil) +} + +func (r *renderer) RenderTimelinePage(ctx context.Context, writer io.Writer, data *TimelinePageTemplateData) (err error) { + return r.template.ExecuteTemplate(writer, "timeline.tmpl", data) +} + +func (r *renderer) RenderThreadPage(ctx context.Context, writer io.Writer, data *ThreadPageTemplateData) (err error) { + return r.template.ExecuteTemplate(writer, "thread.tmpl", data) +} + +func WithEmojis(content string, emojis []mastodon.Emoji) string { + var emojiNameContentPair []string + for _, e := range emojis { + emojiNameContentPair = append(emojiNameContentPair, ":"+e.ShortCode+":", "<img class=\"status-emoji\" src=\""+e.URL+"\" alt=\""+e.ShortCode+"\" />") + } + return strings.NewReplacer(emojiNameContentPair...).Replace(content) +} + +func DisplayInteractionCount(c int64) string { + if c > 0 { + return strconv.Itoa(int(c)) + } + return "" +} + +func TimeSince(t time.Time) string { + dur := time.Since(t) + + s := dur.Seconds() + if s < 60 { + return strconv.Itoa(int(s)) + "s" + } + + m := dur.Minutes() + if m < 60 { + return strconv.Itoa(int(m)) + "m" + } + + h := dur.Hours() + if h < 24 { + return strconv.Itoa(int(h)) + "h" + } + + d := h / 24 + if d < 30 { + return strconv.Itoa(int(d)) + "d" + } + + mo := d / 30 + if mo < 12 { + return strconv.Itoa(int(mo)) + "mo" + } + + y := m / 12 + return strconv.Itoa(int(y)) + "y" +} + +func FormatTimeRFC3339(t time.Time) string { + return t.Format(time.RFC3339) +} |