diff options
| author | r <r@freesoftwareextremist.com> | 2019-12-27 08:06:43 +0000 | 
|---|---|---|
| committer | r <r@freesoftwareextremist.com> | 2019-12-27 08:09:40 +0000 | 
| commit | b9d7eb05beb57926181f91685a75b3069d1f8cf8 (patch) | |
| tree | 1aa0b5a28fd8cc0c3fc425c227eb747d8528c910 | |
| parent | 14bb18fbc7e6cdea57f27a44093d645d97bacb64 (diff) | |
| download | bloat-b9d7eb05beb57926181f91685a75b3069d1f8cf8.tar.gz bloat-b9d7eb05beb57926181f91685a75b3069d1f8cf8.zip | |
Add settings page
| -rw-r--r-- | model/settings.go | 1 | ||||
| -rw-r--r-- | renderer/model.go | 15 | ||||
| -rw-r--r-- | renderer/renderer.go | 5 | ||||
| -rw-r--r-- | service/auth.go | 16 | ||||
| -rw-r--r-- | service/logging.go | 16 | ||||
| -rw-r--r-- | service/service.go | 56 | ||||
| -rw-r--r-- | service/transport.go | 31 | ||||
| -rw-r--r-- | static/main.css | 16 | ||||
| -rw-r--r-- | templates/navigation.tmpl | 1 | ||||
| -rw-r--r-- | templates/postform.tmpl | 2 | ||||
| -rw-r--r-- | templates/settings.tmpl | 22 | 
11 files changed, 165 insertions, 16 deletions
| diff --git a/model/settings.go b/model/settings.go index 7afe936..bc8f09f 100644 --- a/model/settings.go +++ b/model/settings.go @@ -2,4 +2,5 @@ package model  type Settings struct {  	DefaultVisibility string `json:"default_visibility"` +	CopyScope         bool   `json:"copy_scope"`  } diff --git a/renderer/model.go b/renderer/model.go index ffeb2d1..12fa90f 100644 --- a/renderer/model.go +++ b/renderer/model.go @@ -92,10 +92,15 @@ type RetweetedByData struct {  type SearchData struct {  	*CommonData -	Q         string -	Type      string -	Users     []*mastodon.Account -	Statuses  []*mastodon.Status -	HasNext bool +	Q        string +	Type     string +	Users    []*mastodon.Account +	Statuses []*mastodon.Status +	HasNext  bool  	NextLink string  } + +type SettingsData struct { +	*CommonData +	Settings *model.Settings +} diff --git a/renderer/renderer.go b/renderer/renderer.go index 5e5f005..a46cfd2 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -24,6 +24,7 @@ type Renderer interface {  	RenderLikedByPage(ctx context.Context, writer io.Writer, data *LikedByData) (err error)  	RenderRetweetedByPage(ctx context.Context, writer io.Writer, data *RetweetedByData) (err error)  	RenderSearchPage(ctx context.Context, writer io.Writer, data *SearchData) (err error) +	RenderSettingsPage(ctx context.Context, writer io.Writer, data *SettingsData) (err error)  }  type renderer struct { @@ -96,6 +97,10 @@ func (r *renderer) RenderSearchPage(ctx context.Context, writer io.Writer, data  	return r.template.ExecuteTemplate(writer, "search.tmpl", data)  } +func (r *renderer) RenderSettingsPage(ctx context.Context, writer io.Writer, data *SettingsData) (err error) { +	return r.template.ExecuteTemplate(writer, "settings.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 431e093..4d1b5af 100644 --- a/service/auth.go +++ b/service/auth.go @@ -157,6 +157,22 @@ func (s *authService) ServeSearchPage(ctx context.Context, client io.Writer, c *  	return s.Service.ServeSearchPage(ctx, client, c, q, qType, offset)  } +func (s *authService) ServeSettingsPage(ctx context.Context, client io.Writer, c *model.Client) (err error) { +	c, err = s.getClient(ctx) +	if err != nil { +		return +	} +	return s.Service.ServeSettingsPage(ctx, client, c) +} + +func (s *authService) SaveSettings(ctx context.Context, client io.Writer, c *model.Client, settings *model.Settings) (err error) { +	c, err = s.getClient(ctx) +	if err != nil { +		return +	} +	return s.Service.SaveSettings(ctx, client, c, settings) +} +  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 a5ffd57..cfd3654 100644 --- a/service/logging.go +++ b/service/logging.go @@ -133,6 +133,22 @@ func (s *loggingService) ServeSearchPage(ctx context.Context, client io.Writer,  	return s.Service.ServeSearchPage(ctx, client, c, q, qType, offset)  } +func (s *loggingService) ServeSettingsPage(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", +			"ServeSettingsPage", time.Since(begin), err) +	}(time.Now()) +	return s.Service.ServeSettingsPage(ctx, client, c) +} + +func (s *loggingService) SaveSettings(ctx context.Context, client io.Writer, c *model.Client, settings *model.Settings) (err error) { +	defer func(begin time.Time) { +		s.logger.Printf("method=%v, took=%v, err=%v\n", +			"SaveSettings", time.Since(begin), err) +	}(time.Now()) +	return s.Service.SaveSettings(ctx, client, c, settings) +} +  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 157ddf8..bf7967d 100644 --- a/service/service.go +++ b/service/service.go @@ -40,6 +40,8 @@ type Service interface {  	ServeLikedByPage(ctx context.Context, client io.Writer, c *model.Client, id string) (err error)  	ServeRetweetedByPage(ctx context.Context, client io.Writer, c *model.Client, id string) (err error)  	ServeSearchPage(ctx context.Context, client io.Writer, c *model.Client, q string, qType string, offset int) (err error) +	ServeSettingsPage(ctx context.Context, client io.Writer, c *model.Client) (err error) +	SaveSettings(ctx context.Context, client io.Writer, c *model.Client, settings *model.Settings) (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) @@ -350,13 +352,19 @@ func (svc *service) ServeThreadPage(ctx context.Context, client io.Writer, c *mo  			}  		} -		s, err := c.GetStatus(ctx, id) -		if err != nil { -			return err +		var visibility string +		if c.Session.Settings.CopyScope { +			s, err := c.GetStatus(ctx, id) +			if err != nil { +				return err +			} +			visibility = s.Visibility +		} else { +			visibility = c.Session.Settings.DefaultVisibility  		}  		postContext = model.PostContext{ -			DefaultVisibility: s.Visibility, +			DefaultVisibility: visibility,  			Formats:           svc.postFormats,  			ReplyContext: &model.ReplyContext{  				InReplyToID:   id, @@ -639,6 +647,40 @@ func (svc *service) ServeSearchPage(ctx context.Context, client io.Writer, c *mo  	return  } +func (svc *service) ServeSettingsPage(ctx context.Context, client io.Writer, c *model.Client) (err error) { +	commonData, err := svc.getCommonData(ctx, client, c) +	if err != nil { +		return +	} + +	data := &renderer.SettingsData{ +		CommonData: commonData, +		Settings:   &c.Session.Settings, +	} + +	err = svc.renderer.RenderSettingsPage(ctx, client, data) +	if err != nil { +		return +	} + +	return +} + +func (svc *service) SaveSettings(ctx context.Context, client io.Writer, c *model.Client, settings *model.Settings) (err error) { +	session, err := svc.sessionRepo.Get(c.Session.ID) +	if err != nil { +		return +	} + +	session.Settings = *settings +	err = svc.sessionRepo.Add(session) +	if err != nil { +		return +	} + +	return +} +  func (svc *service) getCommonData(ctx context.Context, client io.Writer, c *model.Client) (data *renderer.CommonData, err error) {  	data = new(renderer.CommonData) @@ -707,12 +749,6 @@ 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, diff --git a/service/transport.go b/service/transport.go index c42462f..3ab2546 100644 --- a/service/transport.go +++ b/service/transport.go @@ -7,6 +7,7 @@ import (  	"net/http"  	"path"  	"strconv" +	"web/model"  	"github.com/gorilla/mux"  ) @@ -305,6 +306,36 @@ func NewHandler(s Service, staticDir string) http.Handler {  		}  	}).Methods(http.MethodGet) +	r.HandleFunc("/settings", func(w http.ResponseWriter, req *http.Request) { +		ctx := getContextWithSession(context.Background(), req) + +		err := s.ServeSettingsPage(ctx, w, nil) +		if err != nil { +			s.ServeErrorPage(ctx, w, err) +			return +		} +	}).Methods(http.MethodGet) + +	r.HandleFunc("/settings", func(w http.ResponseWriter, req *http.Request) { +		ctx := getContextWithSession(context.Background(), req) + +		visibility := req.FormValue("visibility") +		copyScope := req.FormValue("copy_scope") == "true" +		settings := &model.Settings{ +			DefaultVisibility: visibility, +			CopyScope: copyScope, +		} + +		err := s.SaveSettings(ctx, w, nil, settings) +		if err != nil { +			s.ServeErrorPage(ctx, w, err) +			return +		} + +		w.Header().Add("Location", req.Header.Get("Referer")) +		w.WriteHeader(http.StatusFound) +	}).Methods(http.MethodPost) +  	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 87e2cfa..f17a171 100644 --- a/static/main.css +++ b/static/main.css @@ -386,3 +386,19 @@  	vertical-align: top;  	margin: 0 4px 8px 0;  } + +#settings-form { +	margin: 8px 0; +} + +.settings-form-field { +	margin: 4px 0; +} + +.settings-form-field * { +	vertical-align: middle; +} + +#settings-form button[type=submit] { +	margin-top: 8px; +} diff --git a/templates/navigation.tmpl b/templates/navigation.tmpl index b82c7f5..fe83476 100644 --- a/templates/navigation.tmpl +++ b/templates/navigation.tmpl @@ -20,6 +20,7 @@  			<a class="nav-link" href="/about">about</a>  		</div>  		<div> +			<a class="nav-link" href="/settings">settings</a>  			<a class="nav-link" href="/signout">sign out</a>  		</div>  	</div> diff --git a/templates/postform.tmpl b/templates/postform.tmpl index 0e104b4..a79f86b 100644 --- a/templates/postform.tmpl +++ b/templates/postform.tmpl @@ -21,7 +21,7 @@  		</span>  		{{end}}  		<span class="post-form-field"> -			<label for="post-visilibity"> Visibility </label> +			<label for="post-visilibity"> Scope </label>  			<select id="post-visilibity" name="visibility">  				<option value="public" {{if eq .DefaultVisibility "public"}}selected{{end}}>Public</option>  				<option value="unlisted" {{if eq .DefaultVisibility "unlisted"}}selected{{end}}>Unlisted</option> diff --git a/templates/settings.tmpl b/templates/settings.tmpl new file mode 100644 index 0000000..e2fd778 --- /dev/null +++ b/templates/settings.tmpl @@ -0,0 +1,22 @@ +{{template "header.tmpl" .HeaderData}} +{{template "navigation.tmpl" .NavbarData}} +<div class="page-title"> Settings </div> + +<form id="settings-form" action="/settings" method="POST"> +	<div class="settings-form-field"> +		<label for="visibility"> Default scope </label> +		<select id="visibility" name="visibility"> +			<option value="public" {{if eq .Settings.DefaultVisibility "public"}}selected{{end}}>Public</option> +			<option value="unlisted" {{if eq .Settings.DefaultVisibility "unlisted"}}selected{{end}}>Unlisted</option> +			<option value="private" {{if eq .Settings.DefaultVisibility "private"}}selected{{end}}>Private</option> +			<option value="direct" {{if eq .Settings.DefaultVisibility "direct"}}selected{{end}}>Direct</option> +		</select> +	</div> +	<div class="settings-form-field"> +		<input id="copy-scope" name="copy_scope" type="checkbox" value="true" {{if .Settings.CopyScope}}checked{{end}}> +		<label for="copy-scope"> Copy scope when replying </label> +	</div> +	<button type="submit"> Save </button> +</form> + +{{template "footer.tmpl"}} | 
