diff options
author | r <r@freesoftwareextremist.com> | 2021-01-30 16:51:09 +0000 |
---|---|---|
committer | r <r@freesoftwareextremist.com> | 2021-01-30 16:53:57 +0000 |
commit | 4f1425febf6efb45eaf91aff19b215b8c7e77bec (patch) | |
tree | b6b72093906cac8c98ef9d593eed62214c3b5ceb | |
parent | 3ac95ab3b117ee8867a30c8e4b30ab37411e5ccf (diff) | |
download | bloat-4f1425febf6efb45eaf91aff19b215b8c7e77bec.tar.gz bloat-4f1425febf6efb45eaf91aff19b215b8c7e77bec.zip |
Add filters
-rw-r--r-- | mastodon/filter.go | 50 | ||||
-rw-r--r-- | renderer/model.go | 5 | ||||
-rw-r--r-- | renderer/renderer.go | 1 | ||||
-rw-r--r-- | service/service.go | 25 | ||||
-rw-r--r-- | service/transport.go | 28 | ||||
-rw-r--r-- | static/style.css | 8 | ||||
-rw-r--r-- | templates/filters.tmpl | 40 | ||||
-rw-r--r-- | templates/user.tmpl | 1 |
8 files changed, 158 insertions, 0 deletions
diff --git a/mastodon/filter.go b/mastodon/filter.go new file mode 100644 index 0000000..55beac1 --- /dev/null +++ b/mastodon/filter.go @@ -0,0 +1,50 @@ +package mastodon + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strconv" + "time" +) + +type Filter struct { + ID string `json:"id"` + Phrase string `json:"phrase"` + Context []string `json:"context"` + WholeWord bool `json:"whole_word"` + ExpiresAt *time.Time `json:"expires_at"` + Irreversible bool `json:"irreversible"` +} + +func (c *Client) GetFilters(ctx context.Context) ([]*Filter, error) { + var filters []*Filter + err := c.doAPI(ctx, http.MethodGet, "/api/v1/filters", nil, &filters, nil) + if err != nil { + return nil, err + } + return filters, nil +} + +func (c *Client) AddFilter(ctx context.Context, phrase string, context []string, irreversible bool, wholeWord bool, expiresIn *time.Time) error { + params := url.Values{} + params.Set("phrase", phrase) + for i := range context { + params.Add("context[]", context[i]) + } + params.Set("irreversible", strconv.FormatBool(irreversible)) + params.Set("whole_word", strconv.FormatBool(wholeWord)) + if expiresIn != nil { + params.Set("expires_in", expiresIn.Format(time.RFC3339)) + } + err := c.doAPI(ctx, http.MethodPost, "/api/v1/filters", params, nil, nil) + if err != nil { + return err + } + return nil +} + +func (c *Client) RemoveFilter(ctx context.Context, id string) error { + return c.doAPI(ctx, http.MethodDelete, fmt.Sprintf("/api/v1/filters/%s", id), nil, nil, nil) +} diff --git a/renderer/model.go b/renderer/model.go index 6c3ba90..aed444a 100644 --- a/renderer/model.go +++ b/renderer/model.go @@ -127,3 +127,8 @@ type SettingsData struct { Settings *model.Settings PostFormats []model.PostFormat } + +type FiltersData struct { + *CommonData + Filters []*mastodon.Filter +} diff --git a/renderer/renderer.go b/renderer/renderer.go index 3d4685f..067632f 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -29,6 +29,7 @@ const ( RetweetedByPage = "retweetedby.tmpl" SearchPage = "search.tmpl" SettingsPage = "settings.tmpl" + FiltersPage = "filters.tmpl" ) type TemplateData struct { diff --git a/service/service.go b/service/service.go index ce689fd..8149f33 100644 --- a/service/service.go +++ b/service/service.go @@ -641,6 +641,22 @@ func (s *service) SettingsPage(c *client) (err error) { return s.renderer.Render(rCtx, c, renderer.SettingsPage, data) } +func (svc *service) FiltersPage(c *client) (err error) { + filters, err := c.GetFilters(ctx) + if err != nil { + return + } + + commonData := svc.getCommonData(c, "filters") + data := &renderer.FiltersData{ + CommonData: commonData, + Filters: filters, + } + + rCtx := getRendererContext(c) + return svc.renderer.Render(rCtx, c, renderer.FiltersPage, data) +} + func (s *service) SingleInstance() (instance string, ok bool) { if len(s.singleInstance) > 0 { instance = s.singleInstance @@ -908,3 +924,12 @@ func (s *service) UnBookmark(c *client, id string) (err error) { _, err = c.Unbookmark(ctx, id) return } + +func (svc *service) Filter(c *client, phrase string, wholeWord bool) (err error) { + fctx := []string{"home", "notifications", "public", "thread"} + return c.AddFilter(ctx, phrase, fctx, true, wholeWord, nil) +} + +func (svc *service) UnFilter(c *client, id string) (err error) { + return c.RemoveFilter(ctx, id) +} diff --git a/service/transport.go b/service/transport.go index 096b44e..1180f6c 100644 --- a/service/transport.go +++ b/service/transport.go @@ -262,6 +262,10 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler { return s.SettingsPage(c) }, SESSION, HTML) + filtersPage := handle(func(c *client) error { + return s.FiltersPage(c) + }, SESSION, HTML) + signin := handle(func(c *client) error { instance := c.Req.FormValue("instance") url, sid, err := s.NewSession(instance) @@ -589,6 +593,27 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler { return nil }, CSRF, HTML) + filter := handle(func(c *client) error { + phrase := c.Req.FormValue("phrase") + wholeWord := c.Req.FormValue("whole_word") == "true" + err := s.Filter(c, phrase, wholeWord) + if err != nil { + return err + } + redirect(c, c.Req.FormValue("referrer")) + return nil + }, CSRF, HTML) + + unFilter := handle(func(c *client) error { + id, _ := mux.Vars(c.Req)["id"] + err := s.UnFilter(c, id) + if err != nil { + return err + } + redirect(c, c.Req.FormValue("referrer")) + return nil + }, CSRF, HTML) + signout := handle(func(c *client) error { s.Signout(c) setSessionCookie(c, "", 0) @@ -648,6 +673,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler { r.HandleFunc("/emojis", emojisPage).Methods(http.MethodGet) r.HandleFunc("/search", searchPage).Methods(http.MethodGet) r.HandleFunc("/settings", settingsPage).Methods(http.MethodGet) + r.HandleFunc("/filters", filtersPage).Methods(http.MethodGet) r.HandleFunc("/signin", signin).Methods(http.MethodPost) r.HandleFunc("/oauth_callback", oauthCallback).Methods(http.MethodGet) r.HandleFunc("/post", post).Methods(http.MethodPost) @@ -673,6 +699,8 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler { r.HandleFunc("/notifications/read", readNotifications).Methods(http.MethodPost) r.HandleFunc("/bookmark/{id}", bookmark).Methods(http.MethodPost) r.HandleFunc("/unbookmark/{id}", unBookmark).Methods(http.MethodPost) + r.HandleFunc("/filter", filter).Methods(http.MethodPost) + r.HandleFunc("/unfilter/{id}", unFilter).Methods(http.MethodPost) r.HandleFunc("/signout", signout).Methods(http.MethodPost) r.HandleFunc("/fluoride/like/{id}", fLike).Methods(http.MethodPost) r.HandleFunc("/fluoride/unlike/{id}", fUnlike).Methods(http.MethodPost) diff --git a/static/style.css b/static/style.css index 1921f5e..b51b439 100644 --- a/static/style.css +++ b/static/style.css @@ -552,6 +552,14 @@ kbd { font-size: 10pt; } +.filters { + margin: 10px 0; +} + +.filters td { + padding: 2px 4px; +} + .dark { background-color: #222222; background-image: none; diff --git a/templates/filters.tmpl b/templates/filters.tmpl new file mode 100644 index 0000000..ef7c024 --- /dev/null +++ b/templates/filters.tmpl @@ -0,0 +1,40 @@ +{{with .Data}} +{{template "header.tmpl" (WithContext .CommonData $.Ctx)}} +<div class="page-title"> Filters </div> + +{{if .Filters}} +<table class="filters"> + {{range .Filters}} + <tr> + <td> {{.Phrase}}{{if not .WholeWord}}*{{end}} </td> + <td> + <form action="/unfilter/{{.ID}}" method="POST"> + <input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}"> + <input type="hidden" name="referrer" value="{{$.Ctx.Referrer}}"> + <button type="submit"> Delete </button> + </form> + </td> + </tr> + {{end}} +</table> +{{else}} + <div class="filters"> No filters added </div> +{{end}} + +<div class="page-title"> Add filter </div> +<form action="/filter" method="POST"> + <input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}"> + <input type="hidden" name="referrer" value="{{$.Ctx.Referrer}}"> + <span class="settings-form-field"> + <label for="phrase"> Phrase </label> + <input id="phrase" name="phrase" required> + </span> + <span class="settings-form-field"> + <input id="whole-word" name="whole_word" type="checkbox" value="true" checked> + <label for="whole-word"> Whole word </label> + </span> + <button type="submit"> Add </button> +</form> + +{{template "footer.tmpl"}} +{{end}} diff --git a/templates/user.tmpl b/templates/user.tmpl index af6a8d1..7aaefa7 100644 --- a/templates/user.tmpl +++ b/templates/user.tmpl @@ -119,6 +119,7 @@ {{end}} <div> <a href="/usersearch/{{.User.ID}}"> search statuses </a> + {{if .IsCurrent}} - <a href="/filters"> filters </a> {{end}} </div> </div> <div class="user-profile-decription"> |