diff --git a/mastodon/instance.go b/mastodon/instance.go index 3217450..1dc2c8e 100644 --- a/mastodon/instance.go +++ b/mastodon/instance.go @@ -63,3 +63,13 @@ func (c *Client) GetInstancePeers(ctx context.Context) ([]string, error) { } return peers, nil } + +// GetInstanceEmojis return instance emojis. +func (c *Client) GetInstanceEmojis(ctx context.Context) ([]*Emoji, error) { + var emojis []*Emoji + err := c.doAPI(ctx, http.MethodGet, "/api/v1/custom_emojis", nil, &emojis, nil) + if err != nil { + return nil, err + } + return emojis, nil +} diff --git a/renderer/model.go b/renderer/model.go index 9380b7f..2719dbe 100644 --- a/renderer/model.go +++ b/renderer/model.go @@ -97,3 +97,15 @@ func NewAboutPageTemplateData(navbarData *NavbarTemplateData) *AboutPageTemplate NavbarData: navbarData, } } + +type EmojiPageTemplateData struct { + NavbarData *NavbarTemplateData + Emojis []*mastodon.Emoji +} + +func NewEmojiPageTemplateData(navbarData *NavbarTemplateData, emojis []*mastodon.Emoji) *EmojiPageTemplateData { + return &EmojiPageTemplateData{ + NavbarData: navbarData, + Emojis: emojis, + } +} diff --git a/renderer/renderer.go b/renderer/renderer.go index 8009d99..4415b0b 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -20,6 +20,7 @@ type Renderer interface { RenderNotificationPage(ctx context.Context, writer io.Writer, data *NotificationPageTemplateData) (err error) RenderUserPage(ctx context.Context, writer io.Writer, data *UserPageTemplateData) (err error) RenderAboutPage(ctx context.Context, writer io.Writer, data *AboutPageTemplateData) (err error) + RenderEmojiPage(ctx context.Context, writer io.Writer, data *EmojiPageTemplateData) (err error) } type renderer struct { @@ -76,6 +77,10 @@ func (r *renderer) RenderAboutPage(ctx context.Context, writer io.Writer, data * return r.template.ExecuteTemplate(writer, "about.tmpl", data) } +func (r *renderer) RenderEmojiPage(ctx context.Context, writer io.Writer, data *EmojiPageTemplateData) (err error) { + return r.template.ExecuteTemplate(writer, "emoji.tmpl", data) +} + func EmojiFilter(content string, emojis []mastodon.Emoji) string { var replacements []string for _, e := range emojis { diff --git a/service/auth.go b/service/auth.go index 1b2700c..57ef3d0 100644 --- a/service/auth.go +++ b/service/auth.go @@ -125,6 +125,14 @@ func (s *authService) ServeAboutPage(ctx context.Context, client io.Writer, c *m return s.Service.ServeAboutPage(ctx, client, c) } +func (s *authService) ServeEmojiPage(ctx context.Context, client io.Writer, c *model.Client) (err error) { + c, err = s.getClient(ctx) + if err != nil { + return + } + return s.Service.ServeEmojiPage(ctx, client, c) +} + func (s *authService) Like(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) { c, err = s.getClient(ctx) if err != nil { diff --git a/service/logging.go b/service/logging.go index 444584e..9848e54 100644 --- a/service/logging.go +++ b/service/logging.go @@ -101,6 +101,14 @@ func (s *loggingService) ServeAboutPage(ctx context.Context, client io.Writer, c return s.Service.ServeAboutPage(ctx, client, c) } +func (s *loggingService) ServeEmojiPage(ctx context.Context, client io.Writer, c *model.Client) (err error) { + defer func(begin time.Time) { + s.logger.Printf("method=%v, took=%v, err=%v\n", + "ServeEmojiPage", time.Since(begin), err) + }(time.Now()) + return s.Service.ServeEmojiPage(ctx, client, c) +} + func (s *loggingService) Like(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) { defer func(begin time.Time) { s.logger.Printf("method=%v, id=%v, took=%v, err=%v\n", diff --git a/service/service.go b/service/service.go index ad47408..27ee6bf 100644 --- a/service/service.go +++ b/service/service.go @@ -34,6 +34,7 @@ type Service interface { ServeNotificationPage(ctx context.Context, client io.Writer, c *model.Client, maxID string, minID string) (err error) ServeUserPage(ctx context.Context, client io.Writer, c *model.Client, id string, maxID string, minID string) (err error) ServeAboutPage(ctx context.Context, client io.Writer, c *model.Client) (err error) + ServeEmojiPage(ctx context.Context, client io.Writer, c *model.Client) (err error) Like(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) UnLike(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) Retweet(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) @@ -444,6 +445,26 @@ func (svc *service) ServeAboutPage(ctx context.Context, client io.Writer, c *mod return } +func (svc *service) ServeEmojiPage(ctx context.Context, client io.Writer, c *model.Client) (err error) { + navbarData, err := svc.getNavbarTemplateData(ctx, client, c) + if err != nil { + return + } + + emojis, err := c.GetInstanceEmojis(ctx) + if err != nil { + return + } + + data := renderer.NewEmojiPageTemplateData(navbarData, emojis) + err = svc.renderer.RenderEmojiPage(ctx, client, data) + if err != nil { + return + } + + return +} + func (svc *service) getNavbarTemplateData(ctx context.Context, client io.Writer, c *model.Client) (data *renderer.NavbarTemplateData, err error) { notifications, err := c.GetNotifications(ctx, nil) if err != nil { diff --git a/service/transport.go b/service/transport.go index e3ec113..437d32f 100644 --- a/service/transport.go +++ b/service/transport.go @@ -241,6 +241,16 @@ func NewHandler(s Service, staticDir string) http.Handler { } }).Methods(http.MethodGet) + r.HandleFunc("/emojis", func(w http.ResponseWriter, req *http.Request) { + ctx := getContextWithSession(context.Background(), req) + + err := s.ServeEmojiPage(ctx, w, nil) + if err != nil { + s.ServeErrorPage(ctx, w, err) + return + } + }).Methods(http.MethodGet) + r.HandleFunc("/signout", func(w http.ResponseWriter, req *http.Request) { // TODO remove session from database w.Header().Add("Set-Cookie", fmt.Sprintf("session_id=;max-age=0")) diff --git a/static/main.css b/static/main.css index b4b616b..f09f517 100644 --- a/static/main.css +++ b/static/main.css @@ -316,3 +316,22 @@ .post-form-field>* { vertical-align: middle; } + +.emoji { + min-width: 220px; + display: inline-block; + margin-bottom: 2px; +} + +.emoji-img { + height: 24px; + width: 24px; + object-fit: contain; + vertical-align: middle; + +} + +.emoji-shortcode { + vertical-align: middle; + display: inline-block; +} diff --git a/templates/emoji.tmpl b/templates/emoji.tmpl new file mode 100644 index 0000000..a0cf263 --- /dev/null +++ b/templates/emoji.tmpl @@ -0,0 +1,16 @@ +{{template "header.tmpl"}} +{{template "navigation.tmpl" .NavbarData}} +