From 2678f33157d147ba548793709cd8fbaabb4eaae2 Mon Sep 17 00:00:00 2001
From: r <r@freesoftwareextremist.com>
Date: Sat, 21 Dec 2019 13:26:31 +0000
Subject: Add support for scopes

- Add scope selection for for new post
- Save new post scope in db
- Copy scope on reply
- Show scope icon on posts
---
 service/auth.go      | 25 +++++++------------------
 service/logging.go   |  8 ++++----
 service/service.go   | 38 +++++++++++++++++++++++++++++---------
 service/transport.go |  3 ++-
 4 files changed, 42 insertions(+), 32 deletions(-)

(limited to 'service')

diff --git a/service/auth.go b/service/auth.go
index 0209273..13e9c50 100644
--- a/service/auth.go
+++ b/service/auth.go
@@ -23,17 +23,9 @@ func NewAuthService(sessionRepo model.SessionRepository, appRepo model.AppReposi
 	return &authService{sessionRepo, appRepo, s}
 }
 
-func getSessionID(ctx context.Context) (sessionID string, err error) {
+func (s *authService) getClient(ctx context.Context) (c *model.Client, err error) {
 	sessionID, ok := ctx.Value("session_id").(string)
 	if !ok || len(sessionID) < 1 {
-		return "", ErrInvalidSession
-	}
-	return sessionID, nil
-}
-
-func (s *authService) getClient(ctx context.Context) (c *model.Client, err error) {
-	sessionID, err := getSessionID(ctx)
-	if err != nil {
 		return nil, ErrInvalidSession
 	}
 	session, err := s.sessionRepo.Get(sessionID)
@@ -50,7 +42,7 @@ func (s *authService) getClient(ctx context.Context) (c *model.Client, err error
 		ClientSecret: client.ClientSecret,
 		AccessToken:  session.AccessToken,
 	})
-	c = &model.Client{Client: mc}
+	c = &model.Client{Client: mc, Session: session}
 	return c, nil
 }
 
@@ -61,21 +53,18 @@ func (s *authService) GetAuthUrl(ctx context.Context, instance string) (
 
 func (s *authService) GetUserToken(ctx context.Context, sessionID string, c *model.Client,
 	code string) (token string, err error) {
-	sessionID, err = getSessionID(ctx)
-	if err != nil {
-		return
-	}
 	c, err = s.getClient(ctx)
 	if err != nil {
 		return
 	}
 
-	token, err = s.Service.GetUserToken(ctx, sessionID, c, code)
+	token, err = s.Service.GetUserToken(ctx, c.Session.ID, c, code)
 	if err != nil {
 		return
 	}
 
-	err = s.sessionRepo.Update(sessionID, token)
+	c.Session.AccessToken = token
+	err = s.sessionRepo.Add(c.Session)
 	if err != nil {
 		return
 	}
@@ -168,12 +157,12 @@ func (s *authService) UnRetweet(ctx context.Context, client io.Writer, c *model.
 	return s.Service.UnRetweet(ctx, client, c, id)
 }
 
-func (s *authService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, files []*multipart.FileHeader) (id string, err error) {
+func (s *authService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, files []*multipart.FileHeader) (id string, err error) {
 	c, err = s.getClient(ctx)
 	if err != nil {
 		return
 	}
-	return s.Service.PostTweet(ctx, client, c, content, replyToID, files)
+	return s.Service.PostTweet(ctx, client, c, content, replyToID, visibility, files)
 }
 
 func (s *authService) Follow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) {
diff --git a/service/logging.go b/service/logging.go
index f34bef5..ceba716 100644
--- a/service/logging.go
+++ b/service/logging.go
@@ -133,12 +133,12 @@ func (s *loggingService) UnRetweet(ctx context.Context, client io.Writer, c *mod
 	return s.Service.UnRetweet(ctx, client, c, id)
 }
 
-func (s *loggingService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, files []*multipart.FileHeader) (id string, err error) {
+func (s *loggingService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, files []*multipart.FileHeader) (id string, err error) {
 	defer func(begin time.Time) {
-		s.logger.Printf("method=%v, content=%v, reply_to_id=%v, took=%v, err=%v\n",
-			"PostTweet", content, replyToID, time.Since(begin), err)
+		s.logger.Printf("method=%v, content=%v, reply_to_id=%v, visibility=%v, took=%v, err=%v\n",
+			"PostTweet", content, replyToID, visibility, time.Since(begin), err)
 	}(time.Now())
-	return s.Service.PostTweet(ctx, client, c, content, replyToID, files)
+	return s.Service.PostTweet(ctx, client, c, content, replyToID, visibility, files)
 }
 
 func (s *loggingService) Follow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) {
diff --git a/service/service.go b/service/service.go
index d844a6f..07a026a 100644
--- a/service/service.go
+++ b/service/service.go
@@ -38,7 +38,7 @@ type Service interface {
 	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)
 	UnRetweet(ctx context.Context, client io.Writer, c *model.Client, id string) (err error)
-	PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, files []*multipart.FileHeader) (id string, err error)
+	PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, files []*multipart.FileHeader) (id string, err error)
 	Follow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error)
 	UnFollow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error)
 }
@@ -251,12 +251,16 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer,
 		nextLink = "/timeline?max_id=" + pg.MaxID
 	}
 
+	postContext := model.PostContext{
+		DefaultVisibility: c.Session.Settings.DefaultVisibility,
+	}
+
 	navbarData, err := svc.getNavbarTemplateData(ctx, client, c)
 	if err != nil {
 		return
 	}
 
-	data := renderer.NewTimelinePageTemplateData(statuses, hasNext, nextLink, hasPrev, prevLink, navbarData)
+	data := renderer.NewTimelinePageTemplateData(statuses, hasNext, nextLink, hasPrev, prevLink, postContext, navbarData)
 	err = svc.renderer.RenderTimelinePage(ctx, client, data)
 	if err != nil {
 		return
@@ -276,7 +280,7 @@ func (svc *service) ServeThreadPage(ctx context.Context, client io.Writer, c *mo
 		return
 	}
 
-	var replyContext *model.ReplyContext
+	var postContext model.PostContext
 	if reply {
 		var content string
 		if u.ID != status.Account.ID {
@@ -287,10 +291,19 @@ func (svc *service) ServeThreadPage(ctx context.Context, client io.Writer, c *mo
 				content += "@" + status.Mentions[i].Acct + " "
 			}
 		}
-		replyContext = &model.ReplyContext{
-			InReplyToID:   id,
-			InReplyToName: status.Account.Acct,
-			ReplyContent:  content,
+
+		s, err := c.GetStatus(ctx, id)
+		if err != nil {
+			return err
+		}
+
+		postContext = model.PostContext{
+			DefaultVisibility: s.Visibility,
+			ReplyContext: &model.ReplyContext{
+				InReplyToID:   id,
+				InReplyToName: status.Account.Acct,
+				ReplyContent:  content,
+			},
 		}
 	}
 
@@ -314,7 +327,7 @@ func (svc *service) ServeThreadPage(ctx context.Context, client io.Writer, c *mo
 		return
 	}
 
-	data := renderer.NewThreadPageTemplateData(statuses, replyContext, replyMap, navbarData)
+	data := renderer.NewThreadPageTemplateData(statuses, postContext, replyMap, navbarData)
 	err = svc.renderer.RenderThreadPage(ctx, client, data)
 	if err != nil {
 		return
@@ -469,7 +482,7 @@ func (svc *service) UnRetweet(ctx context.Context, client io.Writer, c *model.Cl
 	return
 }
 
-func (svc *service) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, files []*multipart.FileHeader) (id string, err error) {
+func (svc *service) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, files []*multipart.FileHeader) (id string, err error) {
 	var mediaIds []string
 	for _, f := range files {
 		a, err := c.UploadMediaFromMultipartFileHeader(ctx, f)
@@ -479,10 +492,17 @@ func (svc *service) PostTweet(ctx context.Context, client io.Writer, c *model.Cl
 		mediaIds = append(mediaIds, a.ID)
 	}
 
+	// save visibility if it's a non-reply post
+	if len(replyToID) < 1 && visibility != c.Session.Settings.DefaultVisibility {
+		c.Session.Settings.DefaultVisibility = visibility
+		svc.sessionRepo.Add(c.Session)
+	}
+
 	tweet := &mastodon.Toot{
 		Status:      content,
 		InReplyToID: replyToID,
 		MediaIDs:    mediaIds,
+		Visibility:  visibility,
 	}
 
 	s, err := c.PostStatus(ctx, tweet)
diff --git a/service/transport.go b/service/transport.go
index 2b75662..4e852f2 100644
--- a/service/transport.go
+++ b/service/transport.go
@@ -155,9 +155,10 @@ func NewHandler(s Service, staticDir string) http.Handler {
 
 		content := getMultipartFormValue(req.MultipartForm, "content")
 		replyToID := getMultipartFormValue(req.MultipartForm, "reply_to_id")
+		visibility := getMultipartFormValue(req.MultipartForm, "visibility")
 		files := req.MultipartForm.File["attachments"]
 
-		id, err := s.PostTweet(ctx, w, nil, content, replyToID, files)
+		id, err := s.PostTweet(ctx, w, nil, content, replyToID, visibility, files)
 		if err != nil {
 			s.ServeErrorPage(ctx, w, err)
 			return
-- 
cgit v1.2.3