From f6f7b27e40f97ffe88323be01bea1d04ca39d6b0 Mon Sep 17 00:00:00 2001
From: r <r@freesoftwareextremist.com>
Date: Wed, 25 Dec 2019 04:30:21 +0000
Subject: Add local and twkn timelines

---
 mastodon/status.go        |  2 +-
 renderer/model.go         |  4 +++-
 service/auth.go           |  4 ++--
 service/logging.go        |  8 ++++----
 service/service.go        | 23 +++++++++++++++++++----
 service/transport.go      | 14 ++++++++++----
 templates/error.tmpl      |  2 +-
 templates/navigation.tmpl |  6 ++++--
 templates/timeline.tmpl   |  2 +-
 9 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/mastodon/status.go b/mastodon/status.go
index 9f029d1..c36b6cb 100644
--- a/mastodon/status.go
+++ b/mastodon/status.go
@@ -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) {
 	params := url.Values{}
 	if isLocal {
-		params.Set("local", "t")
+		params.Set("local", "true")
 	}
 
 	var statuses []*Status
diff --git a/renderer/model.go b/renderer/model.go
index 9ec4a9a..be777f6 100644
--- a/renderer/model.go
+++ b/renderer/model.go
@@ -18,6 +18,7 @@ func NewNavbarTemplateData(notificationCount int, user *mastodon.Account) *Navba
 }
 
 type TimelinePageTemplateData struct {
+	Title       string
 	Statuses    []*mastodon.Status
 	HasNext     bool
 	NextLink    string
@@ -27,9 +28,10 @@ type TimelinePageTemplateData struct {
 	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 {
 	return &TimelinePageTemplateData{
+		Title:       title,
 		Statuses:    statuses,
 		HasNext:     hasNext,
 		NextLink:    nextLink,
diff --git a/service/auth.go b/service/auth.go
index 57ef3d0..cadb050 100644
--- a/service/auth.go
+++ b/service/auth.go
@@ -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,
-	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)
 	if err != nil {
 		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) {
diff --git a/service/logging.go b/service/logging.go
index 9848e54..87433a4 100644
--- a/service/logging.go
+++ b/service/logging.go
@@ -61,12 +61,12 @@ func (s *loggingService) ServeSigninPage(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) {
-		s.logger.Printf("method=%v, max_id=%v, since_id=%v, min_id=%v, took=%v, err=%v\n",
-			"ServeTimelinePage", maxID, sinceID, minID, time.Since(begin), err)
+		s.logger.Printf("method=%v, timeline_type=%v, max_id=%v, since_id=%v, min_id=%v, took=%v, err=%v\n",
+			"ServeTimelinePage", timelineType, maxID, sinceID, minID, time.Since(begin), err)
 	}(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) {
diff --git a/service/service.go b/service/service.go
index 8a262b6..7fc27fc 100644
--- a/service/service.go
+++ b/service/service.go
@@ -21,6 +21,7 @@ var (
 	ErrInvalidArgument = errors.New("invalid argument")
 	ErrInvalidToken    = errors.New("invalid token")
 	ErrInvalidClient   = errors.New("invalid client")
+	ErrInvalidTimeline = errors.New("invalid timeline")
 )
 
 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)
 	ServeErrorPage(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)
 	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)
@@ -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,
-	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 nextLink, prevLink string
@@ -221,7 +222,21 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer,
 		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 {
 		return err
 	}
@@ -261,7 +276,7 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer,
 		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)
 	if err != nil {
 		return
diff --git a/service/transport.go b/service/transport.go
index 437d32f..438b39d 100644
--- a/service/transport.go
+++ b/service/transport.go
@@ -26,7 +26,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
 
 		sessionID, _ := req.Cookie("session_id")
 		if sessionID != nil && len(sessionID.Value) > 0 {
-			location = "/timeline"
+			location = "/timeline/home"
 		}
 
 		w.Header().Add("Location", location)
@@ -63,18 +63,24 @@ func NewHandler(s Service, staticDir string) http.Handler {
 			return
 		}
 
-		w.Header().Add("Location", "/timeline")
+		w.Header().Add("Location", "/timeline/home")
 		w.WriteHeader(http.StatusFound)
 	}).Methods(http.MethodGet)
 
 	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)
 
+		timelineType, _ := mux.Vars(req)["type"]
 		maxID := req.URL.Query().Get("max_id")
 		sinceID := req.URL.Query().Get("since_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 {
 			s.ServeErrorPage(ctx, w, err)
 			return
@@ -166,7 +172,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
 			return
 		}
 
-		location := "/timeline" + "#status-" + id
+		location := "/timeline/home" + "#status-" + id
 		if len(replyToID) > 0 {
 			location = "/thread/" + replyToID + "#status-" + id
 		}
diff --git a/templates/error.tmpl b/templates/error.tmpl
index 890b5a7..d4bd817 100644
--- a/templates/error.tmpl
+++ b/templates/error.tmpl
@@ -2,7 +2,7 @@
 <div class="page-title"> Error </div>
 <div class="error-text"> {{.}} </div>
 <div>
-<a href="/timeline">Home</a>
+<a href="/timeline/home">Home</a>
 <a href="/signin">Sign In</a>
 </div>
 {{template "footer.tmpl"}}
diff --git a/templates/navigation.tmpl b/templates/navigation.tmpl
index 0e745a2..bd97d2d 100644
--- a/templates/navigation.tmpl
+++ b/templates/navigation.tmpl
@@ -1,6 +1,6 @@
 <div class="user-info">
 	<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" />
 		</a>
 	</div>
@@ -12,8 +12,10 @@
 			</a>
 		</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="/timeline/local">local</a>
+			<a class="nav-link" href="/timeline/twkn">twkn</a>
 			<a class="nav-link" href="/about">about</a>
 		</div>
 		<div>
diff --git a/templates/timeline.tmpl b/templates/timeline.tmpl
index 6280e65..5bff2d0 100644
--- a/templates/timeline.tmpl
+++ b/templates/timeline.tmpl
@@ -1,6 +1,6 @@
 {{template "header.tmpl"}}
 {{template "navigation.tmpl" .NavbarData}}
-<div class="page-title"> Timeline </div>
+<div class="page-title"> {{.Title}} </div>
 
 
 {{template "postform.tmpl" .PostContext}}
-- 
cgit v1.2.3