diff --git a/mastodon/accounts.go b/mastodon/accounts.go index 8cee6bb..86581ec 100644 --- a/mastodon/accounts.go +++ b/mastodon/accounts.go @@ -133,9 +133,11 @@ func (c *Client) AccountUpdate(ctx context.Context, profile *Profile) (*Account, } // GetAccountStatuses return statuses by specified accuont. -func (c *Client) GetAccountStatuses(ctx context.Context, id string, pg *Pagination) ([]*Status, error) { +func (c *Client) GetAccountStatuses(ctx context.Context, id string, onlyMedia bool, pg *Pagination) ([]*Status, error) { var statuses []*Status - err := c.doAPI(ctx, http.MethodGet, fmt.Sprintf("/api/v1/accounts/%s/statuses", url.PathEscape(string(id))), nil, &statuses, pg) + params := url.Values{} + params.Set("only_media", strconv.FormatBool(onlyMedia)) + err := c.doAPI(ctx, http.MethodGet, fmt.Sprintf("/api/v1/accounts/%s/statuses", url.PathEscape(string(id))), params, &statuses, pg) if err != nil { return nil, err } diff --git a/renderer/model.go b/renderer/model.go index 77e6704..2aa2f22 100644 --- a/renderer/model.go +++ b/renderer/model.go @@ -69,6 +69,8 @@ type NotificationData struct { type UserData struct { *CommonData User *mastodon.Account + Type string + Users []*mastodon.Account Statuses []*mastodon.Status NextLink string DarkMode bool @@ -103,18 +105,6 @@ type RetweetedByData struct { NextLink string } -type FollowingData struct { - *CommonData - Users []*mastodon.Account - NextLink string -} - -type FollowersData struct { - *CommonData - Users []*mastodon.Account - NextLink string -} - type SearchData struct { *CommonData Q string diff --git a/renderer/renderer.go b/renderer/renderer.go index cbb6c73..5e03158 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -28,8 +28,6 @@ type Renderer interface { RenderEmojiPage(ctx *Context, writer io.Writer, data *EmojiData) (err error) RenderLikedByPage(ctx *Context, writer io.Writer, data *LikedByData) (err error) RenderRetweetedByPage(ctx *Context, writer io.Writer, data *RetweetedByData) (err error) - RenderFollowingPage(ctx *Context, writer io.Writer, data *FollowingData) (err error) - RenderFollowersPage(ctx *Context, writer io.Writer, data *FollowersData) (err error) RenderSearchPage(ctx *Context, writer io.Writer, data *SearchData) (err error) RenderSettingsPage(ctx *Context, writer io.Writer, data *SettingsData) (err error) } @@ -113,16 +111,6 @@ func (r *renderer) RenderRetweetedByPage(ctx *Context, writer io.Writer, return r.template.ExecuteTemplate(writer, "retweetedby.tmpl", WithContext(data, ctx)) } -func (r *renderer) RenderFollowingPage(ctx *Context, writer io.Writer, - data *FollowingData) (err error) { - return r.template.ExecuteTemplate(writer, "following.tmpl", WithContext(data, ctx)) -} - -func (r *renderer) RenderFollowersPage(ctx *Context, writer io.Writer, - data *FollowersData) (err error) { - return r.template.ExecuteTemplate(writer, "followers.tmpl", WithContext(data, ctx)) -} - func (r *renderer) RenderSearchPage(ctx *Context, writer io.Writer, data *SearchData) (err error) { return r.template.ExecuteTemplate(writer, "search.tmpl", WithContext(data, ctx)) diff --git a/service/auth.go b/service/auth.go index f127f5c..bc4ddbf 100644 --- a/service/auth.go +++ b/service/auth.go @@ -101,24 +101,6 @@ func (s *as) ServeRetweetedByPage(ctx context.Context, c *model.Client, id strin return s.Service.ServeRetweetedByPage(ctx, c, id) } -func (s *as) ServeFollowingPage(ctx context.Context, c *model.Client, id string, - maxID string, minID string) (err error) { - err = s.authenticateClient(ctx, c) - if err != nil { - return - } - return s.Service.ServeFollowingPage(ctx, c, id, maxID, minID) -} - -func (s *as) ServeFollowersPage(ctx context.Context, c *model.Client, id string, - maxID string, minID string) (err error) { - err = s.authenticateClient(ctx, c) - if err != nil { - return - } - return s.Service.ServeFollowersPage(ctx, c, id, maxID, minID) -} - func (s *as) ServeNotificationPage(ctx context.Context, c *model.Client, maxID string, minID string) (err error) { err = s.authenticateClient(ctx, c) @@ -128,13 +110,13 @@ func (s *as) ServeNotificationPage(ctx context.Context, c *model.Client, return s.Service.ServeNotificationPage(ctx, c, maxID, minID) } -func (s *as) ServeUserPage(ctx context.Context, c *model.Client, id string, - maxID string, minID string) (err error) { +func (s *as) ServeUserPage(ctx context.Context, c *model.Client, id string, + pageType string, maxID string, minID string) (err error) { err = s.authenticateClient(ctx, c) if err != nil { return } - return s.Service.ServeUserPage(ctx, c, id, maxID, minID) + return s.Service.ServeUserPage(ctx, c, id, pageType, maxID, minID) } func (s *as) ServeAboutPage(ctx context.Context, c *model.Client) (err error) { diff --git a/service/logging.go b/service/logging.go index edd1035..3d2baba 100644 --- a/service/logging.go +++ b/service/logging.go @@ -68,24 +68,6 @@ func (s *ls) ServeRetweetedByPage(ctx context.Context, c *model.Client, id strin return s.Service.ServeRetweetedByPage(ctx, c, id) } -func (s *ls) ServeFollowingPage(ctx context.Context, c *model.Client, id string, - maxID string, minID string) (err error) { - defer func(begin time.Time) { - s.logger.Printf("method=%v, id=%v, took=%v, err=%v\n", - "ServeFollowingPage", id, time.Since(begin), err) - }(time.Now()) - return s.Service.ServeFollowingPage(ctx, c, id, maxID, minID) -} - -func (s *ls) ServeFollowersPage(ctx context.Context, c *model.Client, id string, - maxID string, minID string) (err error) { - defer func(begin time.Time) { - s.logger.Printf("method=%v, id=%v, took=%v, err=%v\n", - "ServeFollowersPage", id, time.Since(begin), err) - }(time.Now()) - return s.Service.ServeFollowersPage(ctx, c, id, maxID, minID) -} - func (s *ls) ServeNotificationPage(ctx context.Context, c *model.Client, maxID string, minID string) (err error) { defer func(begin time.Time) { @@ -95,13 +77,13 @@ func (s *ls) ServeNotificationPage(ctx context.Context, c *model.Client, return s.Service.ServeNotificationPage(ctx, c, maxID, minID) } -func (s *ls) ServeUserPage(ctx context.Context, c *model.Client, id string, - maxID string, minID string) (err error) { +func (s *ls) ServeUserPage(ctx context.Context, c *model.Client, id string, + pageType string, maxID string, minID string) (err error) { defer func(begin time.Time) { - s.logger.Printf("method=%v, id=%v, took=%v, err=%v\n", - "ServeUserPage", id, time.Since(begin), err) + s.logger.Printf("method=%v, id=%v, type=%v, took=%v, err=%v\n", + "ServeUserPage", id, pageType, time.Since(begin), err) }(time.Now()) - return s.Service.ServeUserPage(ctx, c, id, maxID, minID) + return s.Service.ServeUserPage(ctx, c, id, pageType, maxID, minID) } func (s *ls) ServeAboutPage(ctx context.Context, c *model.Client) (err error) { diff --git a/service/service.go b/service/service.go index fe025b8..ae480d1 100644 --- a/service/service.go +++ b/service/service.go @@ -25,10 +25,9 @@ type Service interface { ServeThreadPage(ctx context.Context, c *model.Client, id string, reply bool) (err error) ServeLikedByPage(ctx context.Context, c *model.Client, id string) (err error) ServeRetweetedByPage(ctx context.Context, c *model.Client, id string) (err error) - ServeFollowingPage(ctx context.Context, c *model.Client, id string, maxID string, minID string) (err error) - ServeFollowersPage(ctx context.Context, c *model.Client, id string, maxID string, minID string) (err error) ServeNotificationPage(ctx context.Context, c *model.Client, maxID string, minID string) (err error) - ServeUserPage(ctx context.Context, c *model.Client, id string, maxID string, minID string) (err error) + ServeUserPage(ctx context.Context, c *model.Client, id string, pageType string, + maxID string, minID string) (err error) ServeAboutPage(ctx context.Context, c *model.Client) (err error) ServeEmojiPage(ctx context.Context, c *model.Client) (err error) ServeSearchPage(ctx context.Context, c *model.Client, q string, qType string, offset int) (err error) @@ -407,73 +406,6 @@ func (svc *service) ServeRetweetedByPage(ctx context.Context, c *model.Client, return svc.renderer.RenderRetweetedByPage(rCtx, c.Writer, data) } -func (svc *service) ServeFollowingPage(ctx context.Context, c *model.Client, - id string, maxID string, minID string) (err error) { - - var nextLink string - var pg = mastodon.Pagination{ - MaxID: maxID, - MinID: minID, - Limit: 20, - } - - followings, err := c.GetAccountFollowing(ctx, id, &pg) - if err != nil { - return - } - - if len(followings) == 20 && len(pg.MaxID) > 0 { - nextLink = "/following/" + id + "?max_id=" + pg.MaxID - } - - commonData, err := svc.getCommonData(ctx, c, "following") - if err != nil { - return - } - - data := &renderer.FollowingData{ - CommonData: commonData, - Users: followings, - NextLink: nextLink, - } - - rCtx := getRendererContext(c) - return svc.renderer.RenderFollowingPage(rCtx, c.Writer, data) -} - -func (svc *service) ServeFollowersPage(ctx context.Context, c *model.Client, - id string, maxID string, minID string) (err error) { - - var nextLink string - var pg = mastodon.Pagination{ - MaxID: maxID, - MinID: minID, - Limit: 20, - } - - followers, err := c.GetAccountFollowers(ctx, id, &pg) - if err != nil { - return - } - - if len(followers) == 20 && len(pg.MaxID) > 0 { - nextLink = "/followers/" + id + "?max_id=" + pg.MaxID - } - - commonData, err := svc.getCommonData(ctx, c, "followers") - if err != nil { - return - } - - data := &renderer.FollowersData{ - CommonData: commonData, - Users: followers, - NextLink: nextLink, - } - rCtx := getRendererContext(c) - return svc.renderer.RenderFollowersPage(rCtx, c.Writer, data) -} - func (svc *service) ServeNotificationPage(ctx context.Context, c *model.Client, maxID string, minID string) (err error) { @@ -522,10 +454,11 @@ func (svc *service) ServeNotificationPage(ctx context.Context, c *model.Client, } func (svc *service) ServeUserPage(ctx context.Context, c *model.Client, - id string, maxID string, minID string) (err error) { + id string, pageType string, maxID string, minID string) (err error) { var nextLink string - + var statuses []*mastodon.Status + var users []*mastodon.Account var pg = mastodon.Pagination{ MaxID: maxID, MinID: minID, @@ -537,13 +470,45 @@ func (svc *service) ServeUserPage(ctx context.Context, c *model.Client, return } - statuses, err := c.GetAccountStatuses(ctx, id, &pg) - if err != nil { - return - } - - if len(pg.MaxID) > 0 { - nextLink = "/user/" + id + "?max_id=" + pg.MaxID + switch pageType { + case "": + statuses, err = c.GetAccountStatuses(ctx, id, false, &pg) + if err != nil { + return + } + if len(statuses) == 20 && len(pg.MaxID) > 0 { + nextLink = fmt.Sprintf("/user/%s?max_id=%s", id, + pg.MaxID) + } + case "following": + users, err = c.GetAccountFollowing(ctx, id, &pg) + if err != nil { + return + } + if len(users) == 20 && len(pg.MaxID) > 0 { + nextLink = fmt.Sprintf("/user/%s/following?max_id=%s", + id, pg.MaxID) + } + case "followers": + users, err = c.GetAccountFollowers(ctx, id, &pg) + if err != nil { + return + } + if len(users) == 20 && len(pg.MaxID) > 0 { + nextLink = fmt.Sprintf("/user/%s/followers?max_id=%s", + id, pg.MaxID) + } + case "media": + statuses, err = c.GetAccountStatuses(ctx, id, true, &pg) + if err != nil { + return + } + if len(statuses) == 20 && len(pg.MaxID) > 0 { + nextLink = fmt.Sprintf("/user/%s/media?max_id=%s", + id, pg.MaxID) + } + default: + return errInvalidArgument } commonData, err := svc.getCommonData(ctx, c, user.DisplayName) @@ -553,6 +518,8 @@ func (svc *service) ServeUserPage(ctx context.Context, c *model.Client, data := &renderer.UserData{ User: user, + Type: pageType, + Users: users, Statuses: statuses, NextLink: nextLink, CommonData: commonData, diff --git a/service/transport.go b/service/transport.go index b2fb4a8..d945e18 100644 --- a/service/transport.go +++ b/service/transport.go @@ -146,36 +146,6 @@ func NewHandler(s Service, staticDir string) http.Handler { } } - followingPage := func(w http.ResponseWriter, req *http.Request) { - c := newClient(w) - ctx := newCtxWithSesion(req) - id, _ := mux.Vars(req)["id"] - maxID := req.URL.Query().Get("max_id") - minID := req.URL.Query().Get("min_id") - - err := s.ServeFollowingPage(ctx, c, id, maxID, minID) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - s.ServeErrorPage(ctx, c, err) - return - } - } - - followersPage := func(w http.ResponseWriter, req *http.Request) { - c := newClient(w) - ctx := newCtxWithSesion(req) - id, _ := mux.Vars(req)["id"] - maxID := req.URL.Query().Get("max_id") - minID := req.URL.Query().Get("min_id") - - err := s.ServeFollowersPage(ctx, c, id, maxID, minID) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - s.ServeErrorPage(ctx, c, err) - return - } - } - notificationsPage := func(w http.ResponseWriter, req *http.Request) { c := newClient(w) ctx := newCtxWithSesion(req) @@ -194,10 +164,11 @@ func NewHandler(s Service, staticDir string) http.Handler { c := newClient(w) ctx := newCtxWithSesion(req) id, _ := mux.Vars(req)["id"] + pageType, _ := mux.Vars(req)["type"] maxID := req.URL.Query().Get("max_id") minID := req.URL.Query().Get("min_id") - err := s.ServeUserPage(ctx, c, id, maxID, minID) + err := s.ServeUserPage(ctx, c, id, pageType, maxID, minID) if err != nil { w.WriteHeader(http.StatusInternalServerError) s.ServeErrorPage(ctx, c, err) @@ -600,10 +571,9 @@ func NewHandler(s Service, staticDir string) http.Handler { r.HandleFunc("/thread/{id}", threadPage).Methods(http.MethodGet) r.HandleFunc("/likedby/{id}", likedByPage).Methods(http.MethodGet) r.HandleFunc("/retweetedby/{id}", retweetedByPage).Methods(http.MethodGet) - r.HandleFunc("/following/{id}", followingPage).Methods(http.MethodGet) - r.HandleFunc("/followers/{id}", followersPage).Methods(http.MethodGet) r.HandleFunc("/notifications", notificationsPage).Methods(http.MethodGet) r.HandleFunc("/user/{id}", userPage).Methods(http.MethodGet) + r.HandleFunc("/user/{id}/{type}", userPage).Methods(http.MethodGet) r.HandleFunc("/usersearch/{id}", userSearchPage).Methods(http.MethodGet) r.HandleFunc("/about", aboutPage).Methods(http.MethodGet) r.HandleFunc("/emojis", emojisPage).Methods(http.MethodGet) diff --git a/templates/followers.tmpl b/templates/followers.tmpl deleted file mode 100644 index 44a303b..0000000 --- a/templates/followers.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -{{with .Data}} -{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}} -{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}} -
Followers
- -{{template "userlist.tmpl" (WithContext .Users $.Ctx)}} - - -{{template "footer.tmpl"}} -{{end}} diff --git a/templates/following.tmpl b/templates/following.tmpl deleted file mode 100644 index 50413d5..0000000 --- a/templates/following.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -{{with .Data}} -{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}} -{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}} -
Following
- -{{template "userlist.tmpl" (WithContext .Users $.Ctx)}} - - -{{template "footer.tmpl"}} -{{end}} diff --git a/templates/user.tmpl b/templates/user.tmpl index e3cb7e8..3042672 100644 --- a/templates/user.tmpl +++ b/templates/user.tmpl @@ -40,9 +40,10 @@ {{end}}
- {{.User.StatusesCount}} statuses - - {{.User.FollowingCount}} following - - {{.User.FollowersCount}} followers + statuses ({{.User.StatusesCount}}) - + following ({{.User.FollowingCount}}) - + followers ({{.User.FollowersCount}}) - + media
search statuses @@ -54,10 +55,27 @@
+{{if eq .Type ""}} +
Statuses
{{range .Statuses}} {{template "status.tmpl" (WithContext . $.Ctx)}} {{end}} +{{else if eq .Type "following"}} +
Following
+{{template "userlist.tmpl" (WithContext .Users $.Ctx)}} + +{{else if eq .Type "followers"}} +
Followers
+{{template "userlist.tmpl" (WithContext .Users $.Ctx)}} + +{{else if eq .Type "media"}} +
Statuses with media
+{{range .Statuses}} +{{template "status.tmpl" (WithContext . $.Ctx)}} +{{end}} +{{end}} +