Allow access to trending page without loginUnverified
c5ad568 parent: 076805f modified
internal/server/server.go +0 -1 | @@ -177,7 +177,6 @@ func (s *Server) setupRoutes() { | ||
| 177 | 177 | }) |
| 178 | 178 | |
| 179 | 179 | s.router.Route("/trending", func(r chi.Router) { |
| 180 | - r.Use(s.requireAuth) | |
| 181 | 180 | r.Get("/", s.handleTrending) |
| 182 | 181 | }) |
| 183 | 182 | |
| @@ -177,7 +177,6 @@ func (s *Server) setupRoutes() { | |||
| 177 | }) | 177 | }) |
| 178 | 178 | ||
| 179 | s.router.Route("/trending", func(r chi.Router) { | 179 | s.router.Route("/trending", func(r chi.Router) { |
| 180 | - r.Use(s.requireAuth) | ||
| 181 | r.Get("/", s.handleTrending) | 180 | r.Get("/", s.handleTrending) |
| 182 | }) | 181 | }) |
| 183 | 182 | ||
modified
internal/server/trending_handler.go +11 -2 | @@ -11,6 +11,10 @@ func (s *Server) handleTrending(w http.ResponseWriter, r *http.Request) { | ||
| 11 | 11 | user := currentUser(r) |
| 12 | 12 | |
| 13 | 13 | scope := r.URL.Query().Get("scope") |
| 14 | + if scope == "for-me" && user == nil { | |
| 15 | + http.Redirect(w, r, "/auth/login", http.StatusSeeOther) | |
| 16 | + return | |
| 17 | + } | |
| 14 | 18 | if scope != "for-me" { |
| 15 | 19 | scope = "all" |
| 16 | 20 | } |
| @@ -18,11 +22,16 @@ func (s *Server) handleTrending(w http.ResponseWriter, r *http.Request) { | ||
| 18 | 22 | page := pageFromRequest(r, 25) |
| 19 | 23 | since := time.Now().AddDate(0, 0, -7).Format(time.RFC3339) |
| 20 | 24 | |
| 25 | + var userDID string | |
| 26 | + if user != nil { | |
| 27 | + userDID = user.DID | |
| 28 | + } | |
| 29 | + | |
| 21 | 30 | var trending []*db.TrendingItem |
| 22 | 31 | if scope == "for-me" { |
| 23 | - trending, _ = s.db.ListTrendingArticlesForUser(r.Context(), user.DID, since, page.Limit()+1, page.Offset()) | |
| 32 | + trending, _ = s.db.ListTrendingArticlesForUser(r.Context(), userDID, since, page.Limit()+1, page.Offset()) | |
| 24 | 33 | } else { |
| 25 | - trending, _ = s.db.ListTrendingArticles(r.Context(), user.DID, since, page.Limit()+1, page.Offset()) | |
| 34 | + trending, _ = s.db.ListTrendingArticles(r.Context(), userDID, since, page.Limit()+1, page.Offset()) | |
| 26 | 35 | } |
| 27 | 36 | |
| 28 | 37 | totalFetched := len(trending) |
| @@ -11,6 +11,10 @@ func (s *Server) handleTrending(w http.ResponseWriter, r *http.Request) { | |||
| 11 | user := currentUser(r) | 11 | user := currentUser(r) |
| 12 | 12 | ||
| 13 | scope := r.URL.Query().Get("scope") | 13 | scope := r.URL.Query().Get("scope") |
| 14 | + if scope == "for-me" && user == nil { | ||
| 15 | + http.Redirect(w, r, "/auth/login", http.StatusSeeOther) | ||
| 16 | + return | ||
| 17 | + } | ||
| 14 | if scope != "for-me" { | 18 | if scope != "for-me" { |
| 15 | scope = "all" | 19 | scope = "all" |
| 16 | } | 20 | } |
| @@ -18,11 +22,16 @@ func (s *Server) handleTrending(w http.ResponseWriter, r *http.Request) { | |||
| 18 | page := pageFromRequest(r, 25) | 22 | page := pageFromRequest(r, 25) |
| 19 | since := time.Now().AddDate(0, 0, -7).Format(time.RFC3339) | 23 | since := time.Now().AddDate(0, 0, -7).Format(time.RFC3339) |
| 20 | 24 | ||
| 25 | + var userDID string | ||
| 26 | + if user != nil { | ||
| 27 | + userDID = user.DID | ||
| 28 | + } | ||
| 29 | + | ||
| 21 | var trending []*db.TrendingItem | 30 | var trending []*db.TrendingItem |
| 22 | if scope == "for-me" { | 31 | if scope == "for-me" { |
| 23 | - trending, _ = s.db.ListTrendingArticlesForUser(r.Context(), user.DID, since, page.Limit()+1, page.Offset()) | 32 | + trending, _ = s.db.ListTrendingArticlesForUser(r.Context(), userDID, since, page.Limit()+1, page.Offset()) |
| 24 | } else { | 33 | } else { |
| 25 | - trending, _ = s.db.ListTrendingArticles(r.Context(), user.DID, since, page.Limit()+1, page.Offset()) | 34 | + trending, _ = s.db.ListTrendingArticles(r.Context(), userDID, since, page.Limit()+1, page.Offset()) |
| 26 | } | 35 | } |
| 27 | 36 | ||
| 28 | totalFetched := len(trending) | 37 | totalFetched := len(trending) |
modified
internal/tmpl/base.html +26 -14 | @@ -65,7 +65,7 @@ | ||
| 65 | 65 | </div> |
| 66 | 66 | <button onclick="document.getElementById('shortcuts-dialog').close()" class="mt-4 w-full text-sm text-spot-secondary hover:text-spot-text px-4 py-2 rounded-pill border border-spot-outline transition">Close</button> |
| 67 | 67 | </dialog> |
| 68 | - {{if .User}} | |
| 68 | + {{if or .User (eq .ActivePath "/trending")}} | |
| 69 | 69 | <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20"> |
| 70 | 70 | <div class="mb-8 px-3"> |
| 71 | 71 | {{template "logo-link"}} |
| @@ -92,17 +92,25 @@ | ||
| 92 | 92 | Library |
| 93 | 93 | </a> |
| 94 | 94 | </nav> |
| 95 | - <div class="mt-auto pt-4 border-t border-spot-divider-30 flex items-center gap-2 px-1"> | |
| 96 | - <a href="/profile/{{.User.DID}}" class="flex items-center gap-2 flex-1 min-w-0 px-2 py-1.5 rounded-md hover:bg-spot-hover-50 transition"> | |
| 97 | - {{if .User.AvatarURL.Valid}}<img src="{{.User.AvatarURL.String}}" class="w-7 h-7 rounded-full shrink-0">{{end}} | |
| 98 | - <span class="text-sm font-medium truncate text-spot-text">@{{.User.Handle}}</span> | |
| 95 | + <div class="mt-auto pt-4 border-t border-spot-divider-30 px-1"> | |
| 96 | + {{if .User}} | |
| 97 | + <div class="flex items-center gap-2"> | |
| 98 | + <a href="/profile/{{.User.DID}}" class="flex items-center gap-2 flex-1 min-w-0 px-2 py-1.5 rounded-md hover:bg-spot-hover-50 transition"> | |
| 99 | + {{if .User.AvatarURL.Valid}}<img src="{{.User.AvatarURL.String}}" class="w-7 h-7 rounded-full shrink-0">{{end}} | |
| 100 | + <span class="text-sm font-medium truncate text-spot-text">@{{.User.Handle}}</span> | |
| 101 | + </a> | |
| 102 | + <form method="POST" action="/auth/logout" class="shrink-0"> | |
| 103 | + {{csrfInput .CSRFToken}} | |
| 104 | + <button type="submit" class="text-spot-secondary hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout"> | |
| 105 | + <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg> | |
| 106 | + </button> | |
| 107 | + </form> | |
| 108 | + </div> | |
| 109 | + {{else}} | |
| 110 | + <a href="/auth/login" class="flex items-center justify-center gap-2 w-full bg-spot-green text-white rounded-pill px-4 py-2 text-xs font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 111 | + Sign in | |
| 99 | 112 | </a> |
| 100 | - <form method="POST" action="/auth/logout" class="shrink-0"> | |
| 101 | - {{csrfInput .CSRFToken}} | |
| 102 | - <button type="submit" class="text-spot-secondary hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout"> | |
| 103 | - <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg> | |
| 104 | - </button> | |
| 105 | - </form> | |
| 113 | + {{end}} | |
| 106 | 114 | </div> |
| 107 | 115 | </aside> |
| 108 | 116 | |
| @@ -128,17 +136,21 @@ | ||
| 128 | 136 | </nav> |
| 129 | 137 | {{end}} |
| 130 | 138 | |
| 131 | - <main id="main-content" class="{{if .User}}lg:ml-60 pb-20 lg:pb-0{{end}} flex-1 min-h-screen flex flex-col"> | |
| 132 | - {{if .User}} | |
| 139 | + <main id="main-content" class="{{if or .User (eq .ActivePath "/trending")}}lg:ml-60 pb-20 lg:pb-0{{end}} flex-1 min-h-screen flex flex-col"> | |
| 140 | + {{if or .User (eq .ActivePath "/trending")}} | |
| 133 | 141 | <div class="lg:hidden bg-spot-surface border-b border-spot-divider px-4 py-3 flex items-center justify-between sticky top-0 z-20"> |
| 134 | 142 | {{template "logo-text"}} |
| 143 | + {{if .User}} | |
| 135 | 144 | <a href="/profile/{{.User.DID}}" class="flex items-center gap-2"> |
| 136 | 145 | {{if .User.AvatarURL.Valid}}<img src="{{.User.AvatarURL.String}}" class="w-7 h-7 rounded-full">{{end}} |
| 137 | 146 | <span class="text-xs text-spot-secondary">@{{.User.Handle}}</span> |
| 138 | 147 | </a> |
| 148 | + {{else}} | |
| 149 | + <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-4 py-1.5 text-xs font-bold uppercase tracking-button hover:brightness-110 transition">Sign in</a> | |
| 150 | + {{end}} | |
| 139 | 151 | </div> |
| 140 | 152 | {{end}} |
| 141 | - <div class="{{if not .User}}w-full{{else}}max-w-6xl mx-auto px-4 lg:px-8 py-6{{end}} flex-1"> | |
| 153 | + <div class="{{if not (or .User (eq .ActivePath "/trending"))}}w-full{{else}}max-w-6xl mx-auto px-4 lg:px-8 py-6{{end}} flex-1"> | |
| 142 | 154 | {{.Content}} |
| 143 | 155 | </div> |
| 144 | 156 | <footer class="mt-auto"> |
| @@ -65,7 +65,7 @@ | |||
| 65 | </div> | 65 | </div> |
| 66 | <button onclick="document.getElementById('shortcuts-dialog').close()" class="mt-4 w-full text-sm text-spot-secondary hover:text-spot-text px-4 py-2 rounded-pill border border-spot-outline transition">Close</button> | 66 | <button onclick="document.getElementById('shortcuts-dialog').close()" class="mt-4 w-full text-sm text-spot-secondary hover:text-spot-text px-4 py-2 rounded-pill border border-spot-outline transition">Close</button> |
| 67 | </dialog> | 67 | </dialog> |
| 68 | - {{if .User}} | 68 | + {{if or .User (eq .ActivePath "/trending")}} |
| 69 | <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20"> | 69 | <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20"> |
| 70 | <div class="mb-8 px-3"> | 70 | <div class="mb-8 px-3"> |
| 71 | {{template "logo-link"}} | 71 | {{template "logo-link"}} |
| @@ -92,17 +92,25 @@ | |||
| 92 | Library | 92 | Library |
| 93 | </a> | 93 | </a> |
| 94 | </nav> | 94 | </nav> |
| 95 | - <div class="mt-auto pt-4 border-t border-spot-divider-30 flex items-center gap-2 px-1"> | 95 | + <div class="mt-auto pt-4 border-t border-spot-divider-30 px-1"> |
| 96 | - <a href="/profile/{{.User.DID}}" class="flex items-center gap-2 flex-1 min-w-0 px-2 py-1.5 rounded-md hover:bg-spot-hover-50 transition"> | 96 | + {{if .User}} |
| 97 | - {{if .User.AvatarURL.Valid}}<img src="{{.User.AvatarURL.String}}" class="w-7 h-7 rounded-full shrink-0">{{end}} | 97 | + <div class="flex items-center gap-2"> |
| 98 | - <span class="text-sm font-medium truncate text-spot-text">@{{.User.Handle}}</span> | 98 | + <a href="/profile/{{.User.DID}}" class="flex items-center gap-2 flex-1 min-w-0 px-2 py-1.5 rounded-md hover:bg-spot-hover-50 transition"> |
| 99 | + {{if .User.AvatarURL.Valid}}<img src="{{.User.AvatarURL.String}}" class="w-7 h-7 rounded-full shrink-0">{{end}} | ||
| 100 | + <span class="text-sm font-medium truncate text-spot-text">@{{.User.Handle}}</span> | ||
| 101 | + </a> | ||
| 102 | + <form method="POST" action="/auth/logout" class="shrink-0"> | ||
| 103 | + {{csrfInput .CSRFToken}} | ||
| 104 | + <button type="submit" class="text-spot-secondary hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout"> | ||
| 105 | + <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg> | ||
| 106 | + </button> | ||
| 107 | + </form> | ||
| 108 | + </div> | ||
| 109 | + {{else}} | ||
| 110 | + <a href="/auth/login" class="flex items-center justify-center gap-2 w-full bg-spot-green text-white rounded-pill px-4 py-2 text-xs font-bold uppercase tracking-button hover:brightness-110 transition"> | ||
| 111 | + Sign in | ||
| 99 | </a> | 112 | </a> |
| 100 | - <form method="POST" action="/auth/logout" class="shrink-0"> | 113 | + {{end}} |
| 101 | - {{csrfInput .CSRFToken}} | ||
| 102 | - <button type="submit" class="text-spot-secondary hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout"> | ||
| 103 | - <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg> | ||
| 104 | - </button> | ||
| 105 | - </form> | ||
| 106 | </div> | 114 | </div> |
| 107 | </aside> | 115 | </aside> |
| 108 | 116 | ||
| @@ -128,17 +136,21 @@ | |||
| 128 | </nav> | 136 | </nav> |
| 129 | {{end}} | 137 | {{end}} |
| 130 | 138 | ||
| 131 | - <main id="main-content" class="{{if .User}}lg:ml-60 pb-20 lg:pb-0{{end}} flex-1 min-h-screen flex flex-col"> | 139 | + <main id="main-content" class="{{if or .User (eq .ActivePath "/trending")}}lg:ml-60 pb-20 lg:pb-0{{end}} flex-1 min-h-screen flex flex-col"> |
| 132 | - {{if .User}} | 140 | + {{if or .User (eq .ActivePath "/trending")}} |
| 133 | <div class="lg:hidden bg-spot-surface border-b border-spot-divider px-4 py-3 flex items-center justify-between sticky top-0 z-20"> | 141 | <div class="lg:hidden bg-spot-surface border-b border-spot-divider px-4 py-3 flex items-center justify-between sticky top-0 z-20"> |
| 134 | {{template "logo-text"}} | 142 | {{template "logo-text"}} |
| 143 | + {{if .User}} | ||
| 135 | <a href="/profile/{{.User.DID}}" class="flex items-center gap-2"> | 144 | <a href="/profile/{{.User.DID}}" class="flex items-center gap-2"> |
| 136 | {{if .User.AvatarURL.Valid}}<img src="{{.User.AvatarURL.String}}" class="w-7 h-7 rounded-full">{{end}} | 145 | {{if .User.AvatarURL.Valid}}<img src="{{.User.AvatarURL.String}}" class="w-7 h-7 rounded-full">{{end}} |
| 137 | <span class="text-xs text-spot-secondary">@{{.User.Handle}}</span> | 146 | <span class="text-xs text-spot-secondary">@{{.User.Handle}}</span> |
| 138 | </a> | 147 | </a> |
| 148 | + {{else}} | ||
| 149 | + <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-4 py-1.5 text-xs font-bold uppercase tracking-button hover:brightness-110 transition">Sign in</a> | ||
| 150 | + {{end}} | ||
| 139 | </div> | 151 | </div> |
| 140 | {{end}} | 152 | {{end}} |
| 141 | - <div class="{{if not .User}}w-full{{else}}max-w-6xl mx-auto px-4 lg:px-8 py-6{{end}} flex-1"> | 153 | + <div class="{{if not (or .User (eq .ActivePath "/trending"))}}w-full{{else}}max-w-6xl mx-auto px-4 lg:px-8 py-6{{end}} flex-1"> |
| 142 | {{.Content}} | 154 | {{.Content}} |
| 143 | </div> | 155 | </div> |
| 144 | <footer class="mt-auto"> | 156 | <footer class="mt-auto"> |
modified
internal/tmpl/trending.html +9 -0 | @@ -1,4 +1,13 @@ | ||
| 1 | 1 | {{define "trending.html"}} |
| 2 | +{{if not .User}} | |
| 3 | +<div class="bg-spot-surface rounded-xl shadow-spot-heavy p-6 mb-6 flex items-center justify-between gap-4"> | |
| 4 | + <div> | |
| 5 | + <p class="text-sm text-spot-text font-bold">Sign in to like, annotate, and get personalized recommendations.</p> | |
| 6 | + </div> | |
| 7 | + <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-5 py-2 text-xs font-bold uppercase tracking-button hover:brightness-110 transition shrink-0">Sign in</a> | |
| 8 | +</div> | |
| 9 | +{{end}} | |
| 10 | + | |
| 2 | 11 | <div class="flex items-center justify-between mb-2"> |
| 3 | 12 | <h1 class="text-2xl font-bold text-spot-text">Trending</h1> |
| 4 | 13 | <div class="flex gap-2"> |
| @@ -1,4 +1,13 @@ | |||
| 1 | {{define "trending.html"}} | 1 | {{define "trending.html"}} |
| 2 | +{{if not .User}} | ||
| 3 | +<div class="bg-spot-surface rounded-xl shadow-spot-heavy p-6 mb-6 flex items-center justify-between gap-4"> | ||
| 4 | + <div> | ||
| 5 | + <p class="text-sm text-spot-text font-bold">Sign in to like, annotate, and get personalized recommendations.</p> | ||
| 6 | + </div> | ||
| 7 | + <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-5 py-2 text-xs font-bold uppercase tracking-button hover:brightness-110 transition shrink-0">Sign in</a> | ||
| 8 | +</div> | ||
| 9 | +{{end}} | ||
| 10 | + | ||
| 2 | <div class="flex items-center justify-between mb-2"> | 11 | <div class="flex items-center justify-between mb-2"> |
| 3 | <h1 class="text-2xl font-bold text-spot-text">Trending</h1> | 12 | <h1 class="text-2xl font-bold text-spot-text">Trending</h1> |
| 4 | <div class="flex gap-2"> | 13 | <div class="flex gap-2"> |