Add local and twkn timelines

This commit is contained in:
r 2019-12-25 04:30:21 +00:00
parent 51bdb20402
commit f6f7b27e40
9 changed files with 45 additions and 20 deletions

View File

@ -192,7 +192,7 @@ func (c *Client) GetTimelineHome(ctx context.Context, pg *Pagination) ([]*Status
func (c *Client) GetTimelinePublic(ctx context.Context, isLocal bool, pg *Pagination) ([]*Status, error) { func (c *Client) GetTimelinePublic(ctx context.Context, isLocal bool, pg *Pagination) ([]*Status, error) {
params := url.Values{} params := url.Values{}
if isLocal { if isLocal {
params.Set("local", "t") params.Set("local", "true")
} }
var statuses []*Status var statuses []*Status

View File

@ -18,6 +18,7 @@ func NewNavbarTemplateData(notificationCount int, user *mastodon.Account) *Navba
} }
type TimelinePageTemplateData struct { type TimelinePageTemplateData struct {
Title string
Statuses []*mastodon.Status Statuses []*mastodon.Status
HasNext bool HasNext bool
NextLink string NextLink string
@ -27,9 +28,10 @@ type TimelinePageTemplateData struct {
NavbarData *NavbarTemplateData NavbarData *NavbarTemplateData
} }
func NewTimelinePageTemplateData(statuses []*mastodon.Status, hasNext bool, nextLink string, hasPrev bool, func NewTimelinePageTemplateData(title string, statuses []*mastodon.Status, hasNext bool, nextLink string, hasPrev bool,
prevLink string, postContext model.PostContext, navbarData *NavbarTemplateData) *TimelinePageTemplateData { prevLink string, postContext model.PostContext, navbarData *NavbarTemplateData) *TimelinePageTemplateData {
return &TimelinePageTemplateData{ return &TimelinePageTemplateData{
Title: title,
Statuses: statuses, Statuses: statuses,
HasNext: hasNext, HasNext: hasNext,
NextLink: nextLink, NextLink: nextLink,

View File

@ -85,12 +85,12 @@ func (s *authService) ServeSigninPage(ctx context.Context, client io.Writer) (er
} }
func (s *authService) ServeTimelinePage(ctx context.Context, client io.Writer, func (s *authService) ServeTimelinePage(ctx context.Context, client io.Writer,
c *model.Client, maxID string, sinceID string, minID string) (err error) { c *model.Client, timelineType string, maxID string, sinceID string, minID string) (err error) {
c, err = s.getClient(ctx) c, err = s.getClient(ctx)
if err != nil { if err != nil {
return return
} }
return s.Service.ServeTimelinePage(ctx, client, c, maxID, sinceID, minID) return s.Service.ServeTimelinePage(ctx, client, c, timelineType, maxID, sinceID, minID)
} }
func (s *authService) ServeThreadPage(ctx context.Context, client io.Writer, c *model.Client, id string, reply bool) (err error) { func (s *authService) ServeThreadPage(ctx context.Context, client io.Writer, c *model.Client, id string, reply bool) (err error) {

View File

@ -61,12 +61,12 @@ func (s *loggingService) ServeSigninPage(ctx context.Context, client io.Writer)
} }
func (s *loggingService) ServeTimelinePage(ctx context.Context, client io.Writer, func (s *loggingService) ServeTimelinePage(ctx context.Context, client io.Writer,
c *model.Client, maxID string, sinceID string, minID string) (err error) { c *model.Client, timelineType string, maxID string, sinceID string, minID string) (err error) {
defer func(begin time.Time) { defer func(begin time.Time) {
s.logger.Printf("method=%v, max_id=%v, since_id=%v, min_id=%v, took=%v, err=%v\n", s.logger.Printf("method=%v, timeline_type=%v, max_id=%v, since_id=%v, min_id=%v, took=%v, err=%v\n",
"ServeTimelinePage", maxID, sinceID, minID, time.Since(begin), err) "ServeTimelinePage", timelineType, maxID, sinceID, minID, time.Since(begin), err)
}(time.Now()) }(time.Now())
return s.Service.ServeTimelinePage(ctx, client, c, maxID, sinceID, minID) return s.Service.ServeTimelinePage(ctx, client, c, timelineType, maxID, sinceID, minID)
} }
func (s *loggingService) ServeThreadPage(ctx context.Context, client io.Writer, c *model.Client, id string, reply bool) (err error) { func (s *loggingService) ServeThreadPage(ctx context.Context, client io.Writer, c *model.Client, id string, reply bool) (err error) {

View File

@ -21,6 +21,7 @@ var (
ErrInvalidArgument = errors.New("invalid argument") ErrInvalidArgument = errors.New("invalid argument")
ErrInvalidToken = errors.New("invalid token") ErrInvalidToken = errors.New("invalid token")
ErrInvalidClient = errors.New("invalid client") ErrInvalidClient = errors.New("invalid client")
ErrInvalidTimeline = errors.New("invalid timeline")
) )
type Service interface { type Service interface {
@ -29,7 +30,7 @@ type Service interface {
GetUserToken(ctx context.Context, sessionID string, c *model.Client, token string) (accessToken string, err error) GetUserToken(ctx context.Context, sessionID string, c *model.Client, token string) (accessToken string, err error)
ServeErrorPage(ctx context.Context, client io.Writer, err error) ServeErrorPage(ctx context.Context, client io.Writer, err error)
ServeSigninPage(ctx context.Context, client io.Writer) (err error) ServeSigninPage(ctx context.Context, client io.Writer) (err error)
ServeTimelinePage(ctx context.Context, client io.Writer, c *model.Client, maxID string, sinceID string, minID string) (err error) ServeTimelinePage(ctx context.Context, client io.Writer, c *model.Client, timelineType string, maxID string, sinceID string, minID string) (err error)
ServeThreadPage(ctx context.Context, client io.Writer, c *model.Client, id string, reply bool) (err error) ServeThreadPage(ctx context.Context, client io.Writer, c *model.Client, id string, reply bool) (err error)
ServeNotificationPage(ctx context.Context, client io.Writer, c *model.Client, maxID string, minID string) (err error) ServeNotificationPage(ctx context.Context, client io.Writer, c *model.Client, maxID string, minID string) (err error)
ServeUserPage(ctx context.Context, client io.Writer, c *model.Client, id string, maxID string, minID string) (err error) ServeUserPage(ctx context.Context, client io.Writer, c *model.Client, id string, maxID string, minID string) (err error)
@ -210,7 +211,7 @@ func (svc *service) ServeSigninPage(ctx context.Context, client io.Writer) (err
} }
func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer, func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer,
c *model.Client, maxID string, sinceID string, minID string) (err error) { c *model.Client, timelineType string, maxID string, sinceID string, minID string) (err error) {
var hasNext, hasPrev bool var hasNext, hasPrev bool
var nextLink, prevLink string var nextLink, prevLink string
@ -221,7 +222,21 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer,
Limit: 20, Limit: 20,
} }
statuses, err := c.GetTimelineHome(ctx, &pg) var statuses []*mastodon.Status
var title string
switch timelineType {
default:
return ErrInvalidTimeline
case "home":
statuses, err = c.GetTimelineHome(ctx, &pg)
title = "Timeline"
case "local":
statuses, err = c.GetTimelinePublic(ctx, true, &pg)
title = "Local Timeline"
case "twkn":
statuses, err = c.GetTimelinePublic(ctx, false, &pg)
title = "The Whole Known Network"
}
if err != nil { if err != nil {
return err return err
} }
@ -261,7 +276,7 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer,
return return
} }
data := renderer.NewTimelinePageTemplateData(statuses, hasNext, nextLink, hasPrev, prevLink, postContext, navbarData) data := renderer.NewTimelinePageTemplateData(title, statuses, hasNext, nextLink, hasPrev, prevLink, postContext, navbarData)
err = svc.renderer.RenderTimelinePage(ctx, client, data) err = svc.renderer.RenderTimelinePage(ctx, client, data)
if err != nil { if err != nil {
return return

View File

@ -26,7 +26,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
sessionID, _ := req.Cookie("session_id") sessionID, _ := req.Cookie("session_id")
if sessionID != nil && len(sessionID.Value) > 0 { if sessionID != nil && len(sessionID.Value) > 0 {
location = "/timeline" location = "/timeline/home"
} }
w.Header().Add("Location", location) w.Header().Add("Location", location)
@ -63,18 +63,24 @@ func NewHandler(s Service, staticDir string) http.Handler {
return return
} }
w.Header().Add("Location", "/timeline") w.Header().Add("Location", "/timeline/home")
w.WriteHeader(http.StatusFound) w.WriteHeader(http.StatusFound)
}).Methods(http.MethodGet) }).Methods(http.MethodGet)
r.HandleFunc("/timeline", func(w http.ResponseWriter, req *http.Request) { r.HandleFunc("/timeline", func(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Location", "/timeline/home")
w.WriteHeader(http.StatusFound)
}).Methods(http.MethodGet)
r.HandleFunc("/timeline/{type}", func(w http.ResponseWriter, req *http.Request) {
ctx := getContextWithSession(context.Background(), req) ctx := getContextWithSession(context.Background(), req)
timelineType, _ := mux.Vars(req)["type"]
maxID := req.URL.Query().Get("max_id") maxID := req.URL.Query().Get("max_id")
sinceID := req.URL.Query().Get("since_id") sinceID := req.URL.Query().Get("since_id")
minID := req.URL.Query().Get("min_id") minID := req.URL.Query().Get("min_id")
err := s.ServeTimelinePage(ctx, w, nil, maxID, sinceID, minID) err := s.ServeTimelinePage(ctx, w, nil, timelineType, maxID, sinceID, minID)
if err != nil { if err != nil {
s.ServeErrorPage(ctx, w, err) s.ServeErrorPage(ctx, w, err)
return return
@ -166,7 +172,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
return return
} }
location := "/timeline" + "#status-" + id location := "/timeline/home" + "#status-" + id
if len(replyToID) > 0 { if len(replyToID) > 0 {
location = "/thread/" + replyToID + "#status-" + id location = "/thread/" + replyToID + "#status-" + id
} }

View File

@ -2,7 +2,7 @@
<div class="page-title"> Error </div> <div class="page-title"> Error </div>
<div class="error-text"> {{.}} </div> <div class="error-text"> {{.}} </div>
<div> <div>
<a href="/timeline">Home</a> <a href="/timeline/home">Home</a>
<a href="/signin">Sign In</a> <a href="/signin">Sign In</a>
</div> </div>
{{template "footer.tmpl"}} {{template "footer.tmpl"}}

View File

@ -1,6 +1,6 @@
<div class="user-info"> <div class="user-info">
<div class="user-info-img-container"> <div class="user-info-img-container">
<a class="img-link" href="/timeline" title="home"> <a class="img-link" href="/timeline/home" title="home">
<img class="user-info-img" src="{{.User.AvatarStatic}}" alt="profile-avatar" /> <img class="user-info-img" src="{{.User.AvatarStatic}}" alt="profile-avatar" />
</a> </a>
</div> </div>
@ -12,8 +12,10 @@
</a> </a>
</div> </div>
<div> <div>
<a class="nav-link" href="/timeline">home</a> <a class="nav-link" href="/timeline/home">home</a>
<a class="nav-link" href="/notifications">notifications{{if gt .NotificationCount 0}}({{.NotificationCount}}){{end}}</a> <a class="nav-link" href="/notifications">notifications{{if gt .NotificationCount 0}}({{.NotificationCount}}){{end}}</a>
<a class="nav-link" href="/timeline/local">local</a>
<a class="nav-link" href="/timeline/twkn">twkn</a>
<a class="nav-link" href="/about">about</a> <a class="nav-link" href="/about">about</a>
</div> </div>
<div> <div>

View File

@ -1,6 +1,6 @@
{{template "header.tmpl"}} {{template "header.tmpl"}}
{{template "navigation.tmpl" .NavbarData}} {{template "navigation.tmpl" .NavbarData}}
<div class="page-title"> Timeline </div> <div class="page-title"> {{.Title}} </div>
{{template "postform.tmpl" .PostContext}} {{template "postform.tmpl" .PostContext}}