From f68d72ae0eb2eb6c15cd225c1a3b9185aaa20e3f Mon Sep 17 00:00:00 2001 From: r Date: Sun, 15 Dec 2019 17:37:58 +0000 Subject: Add notification support --- service/auth.go | 8 +++++ service/logging.go | 8 +++++ service/service.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++++---- service/transport.go | 13 +++++++ 4 files changed, 118 insertions(+), 7 deletions(-) (limited to 'service') diff --git a/service/auth.go b/service/auth.go index 98012af..e9bec38 100644 --- a/service/auth.go +++ b/service/auth.go @@ -111,6 +111,14 @@ func (s *authService) ServeThreadPage(ctx context.Context, client io.Writer, c * return s.Service.ServeThreadPage(ctx, client, c, id, reply) } +func (s *authService) ServeNotificationPage(ctx context.Context, client io.Writer, c *mastodon.Client, maxID string, minID string) (err error) { + c, err = s.getClient(ctx) + if err != nil { + return + } + return s.Service.ServeNotificationPage(ctx, client, c, maxID, minID) +} + func (s *authService) Like(ctx context.Context, client io.Writer, c *mastodon.Client, id string) (err error) { c, err = s.getClient(ctx) if err != nil { diff --git a/service/logging.go b/service/logging.go index 3a95a94..aa1da68 100644 --- a/service/logging.go +++ b/service/logging.go @@ -77,6 +77,14 @@ func (s *loggingService) ServeThreadPage(ctx context.Context, client io.Writer, return s.Service.ServeThreadPage(ctx, client, c, id, reply) } +func (s *loggingService) ServeNotificationPage(ctx context.Context, client io.Writer, c *mastodon.Client, maxID string, minID string) (err error) { + defer func(begin time.Time) { + s.logger.Printf("method=%v, max_id=%v, min_id=%v, took=%v, err=%v\n", + "ServeNotificationPage", maxID, minID, time.Since(begin), err) + }(time.Now()) + return s.Service.ServeNotificationPage(ctx, client, c, maxID, minID) +} + func (s *loggingService) Like(ctx context.Context, client io.Writer, c *mastodon.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 e502b65..93f22fa 100644 --- a/service/service.go +++ b/service/service.go @@ -5,7 +5,6 @@ import ( "context" "encoding/json" "errors" - "fmt" "io" "mime/multipart" "net/http" @@ -33,6 +32,7 @@ type Service interface { ServeSigninPage(ctx context.Context, client io.Writer) (err error) ServeTimelinePage(ctx context.Context, client io.Writer, c *mastodon.Client, maxID string, sinceID string, minID string) (err error) ServeThreadPage(ctx context.Context, client io.Writer, c *mastodon.Client, id string, reply bool) (err error) + ServeNotificationPage(ctx context.Context, client io.Writer, c *mastodon.Client, maxID string, minID string) (err error) Like(ctx context.Context, client io.Writer, c *mastodon.Client, id string) (err error) UnLike(ctx context.Context, client io.Writer, c *mastodon.Client, id string) (err error) Retweet(ctx context.Context, client io.Writer, c *mastodon.Client, id string) (err error) @@ -219,7 +219,7 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer, if len(maxID) > 0 && len(statuses) > 0 { hasPrev = true - prevLink = fmt.Sprintf("/timeline?min_id=%s", statuses[0].ID) + prevLink = "/timeline?min_id=" + statuses[0].ID } if len(minID) > 0 && len(pg.MinID) > 0 { newStatuses, err := c.GetTimelineHome(ctx, &mastodon.Pagination{MinID: pg.MinID, Limit: 20}) @@ -229,21 +229,26 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer, newStatusesLen := len(newStatuses) if newStatusesLen == 20 { hasPrev = true - prevLink = fmt.Sprintf("/timeline?min_id=%s", pg.MinID) + prevLink = "/timeline?min_id=" + pg.MinID } else { i := 20 - newStatusesLen - 1 if len(statuses) > i { hasPrev = true - prevLink = fmt.Sprintf("/timeline?min_id=%s", statuses[i].ID) + prevLink = "/timeline?min_id=" + statuses[i].ID } } } if len(pg.MaxID) > 0 { hasNext = true - nextLink = fmt.Sprintf("/timeline?max_id=%s", pg.MaxID) + nextLink = "/timeline?max_id=" + pg.MaxID } - data := renderer.NewTimelinePageTemplateData(statuses, hasNext, nextLink, hasPrev, prevLink) + navbarData, err := svc.getNavbarTemplateData(ctx, client, c) + if err != nil { + return + } + + data := renderer.NewTimelinePageTemplateData(statuses, hasNext, nextLink, hasPrev, prevLink, navbarData) err = svc.renderer.RenderTimelinePage(ctx, client, data) if err != nil { return @@ -280,7 +285,12 @@ func (svc *service) ServeThreadPage(ctx context.Context, client io.Writer, c *ma } } - data := renderer.NewThreadPageTemplateData(status, context, reply, id, content) + navbarData, err := svc.getNavbarTemplateData(ctx, client, c) + if err != nil { + return + } + + data := renderer.NewThreadPageTemplateData(status, context, reply, id, content, navbarData) err = svc.renderer.RenderThreadPage(ctx, client, data) if err != nil { return @@ -289,6 +299,78 @@ func (svc *service) ServeThreadPage(ctx context.Context, client io.Writer, c *ma return } +func (svc *service) ServeNotificationPage(ctx context.Context, client io.Writer, c *mastodon.Client, maxID string, minID string) (err error) { + var hasNext bool + var nextLink string + + var pg = mastodon.Pagination{ + MaxID: maxID, + MinID: minID, + Limit: 20, + } + + notifications, err := c.GetNotifications(ctx, &pg) + if err != nil { + return + } + + var unreadCount int + for i := range notifications { + switch notifications[i].Type { + case "reblog", "favourite": + if notifications[i].Status != nil { + notifications[i].Status.Account.ID = "" + } + } + if notifications[i].Pleroma != nil && notifications[i].Pleroma.IsSeen { + unreadCount++ + } + } + + if unreadCount > 0 { + err := c.ReadNotifications(ctx, notifications[0].ID) + if err != nil { + return err + } + } + + if len(pg.MaxID) > 0 { + hasNext = true + nextLink = "/notifications?max_id=" + pg.MaxID + } + + navbarData, err := svc.getNavbarTemplateData(ctx, client, c) + if err != nil { + return + } + + data := renderer.NewNotificationPageTemplateData(notifications, hasNext, nextLink, navbarData) + err = svc.renderer.RenderNotificationPage(ctx, client, data) + if err != nil { + return + } + + return +} + +func (svc *service) getNavbarTemplateData(ctx context.Context, client io.Writer, c *mastodon.Client) (data *renderer.NavbarTemplateData, err error) { + notifications, err := c.GetNotifications(ctx, nil) + if err != nil { + return + } + + var notificationCount int + for i := range notifications { + if notifications[i].Pleroma != nil && !notifications[i].Pleroma.IsSeen { + notificationCount++ + } + } + + data = renderer.NewNavbarTemplateData(notificationCount) + + return +} + func (svc *service) Like(ctx context.Context, client io.Writer, c *mastodon.Client, id string) (err error) { _, err = c.Favourite(ctx, id) return diff --git a/service/transport.go b/service/transport.go index d5a6ee8..377ab23 100644 --- a/service/transport.go +++ b/service/transport.go @@ -179,6 +179,19 @@ func NewHandler(s Service, staticDir string) http.Handler { w.WriteHeader(http.StatusSeeOther) }).Methods(http.MethodPost) + r.HandleFunc("/notifications", func(w http.ResponseWriter, req *http.Request) { + ctx := getContextWithSession(context.Background(), req) + + maxID := req.URL.Query().Get("max_id") + minID := req.URL.Query().Get("min_id") + + err := s.ServeNotificationPage(ctx, w, nil, maxID, minID) + 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")) -- cgit v1.2.3