rin
Публичный Open-source lightweight git hosting.

feat(nav): replace Repositories with Explore; drop /repos page and sidebar repo list

R rin · 2026-10-16 17:04 UTC
9 файлов изменено +31 -73
internal/i18n/i18n.go
+0 -2
... ... @@ -324,7 +324,6 @@ var translations = map[Lang]map[string]string{
324 324 "shortcuts.palette": "Командная палитра",
325 325 "shortcuts.search": "Фокус на поиск",
326 326 "shortcuts.home": "На главную",
327 - "shortcuts.repos": "Мои репозитории",
328 327 "shortcuts.files": "Фильтр файлов",
329 328 "shortcuts.sidebar": "Скрыть / показать сайдбар",
330 329 "nav.toggle_sidebar": "Сайдбар (Ctrl+B)",
... ... @@ -818,7 +817,6 @@ var translations = map[Lang]map[string]string{
818 817 "shortcuts.palette": "Command palette",
819 818 "shortcuts.search": "Focus search",
820 819 "shortcuts.home": "Go home",
821 - "shortcuts.repos": "Repositories",
822 820 "shortcuts.files": "Filter files",
823 821 "shortcuts.sidebar": "Toggle sidebar",
824 822 "nav.toggle_sidebar": "Sidebar (Ctrl+B)",
internal/web/handlers/auth.go
+4 -4
... ... @@ -14,7 +14,7 @@ import (
14 14
15 15 func (h *Handler) LoginPage(c *fiber.Ctx) error {
16 16 if middleware.CurrentUser(c) != nil {
17 - return c.Redirect("/repos", fiber.StatusSeeOther)
17 + return c.Redirect("/", fiber.StatusSeeOther)
18 18 }
19 19 lang, _ := c.Locals("lang").(i18n.Lang)
20 20 data := h.baseData(c, i18n.T(lang, "nav.login"))
... ... @@ -54,7 +54,7 @@ func (h *Handler) LoginSubmit(c *fiber.Ctx) error {
54 54 if next := safeNextPath(c.FormValue("next")); next != "" {
55 55 return c.Redirect(next, fiber.StatusSeeOther)
56 56 }
57 - return c.Redirect("/repos", fiber.StatusSeeOther)
57 + return c.Redirect("/", fiber.StatusSeeOther)
58 58 }
59 59
60 60 // safeNextPath returns a same-site path for post-login redirects.
... ... @@ -68,7 +68,7 @@ func safeNextPath(next string) string {
68 68
69 69 func (h *Handler) RegisterPage(c *fiber.Ctx) error {
70 70 if middleware.CurrentUser(c) != nil {
71 - return c.Redirect("/repos", fiber.StatusSeeOther)
71 + return c.Redirect("/", fiber.StatusSeeOther)
72 72 }
73 73 lang, _ := c.Locals("lang").(i18n.Lang)
74 74 data := h.baseData(c, i18n.T(lang, "nav.register"))
... ... @@ -107,7 +107,7 @@ func (h *Handler) RegisterSubmit(c *fiber.Ctx) error {
107 107 })
108 108
109 109 h.setFlashT(c, "flash.welcome", u.Username)
110 - return c.Redirect("/repos", fiber.StatusSeeOther)
110 + return c.Redirect("/", fiber.StatusSeeOther)
111 111 }
112 112
113 113 func (h *Handler) LogoutSubmit(c *fiber.Ctx) error {
internal/web/handlers/handlers.go
+10 -11
... ... @@ -87,7 +87,7 @@ func (h *Handler) RegisterRoutes(app *fiber.App) {
87 87 app.Post("/api/v1/device/token", h.DeviceTokenAPI)
88 88
89 89 // Authenticated user routes
90 - app.Get("/repos", middleware.RequireAuth(), h.MyRepos)
90 + app.Get("/repos", h.LegacyReposRedirect)
91 91 app.Get("/new", middleware.RequireAuth(), h.NewRepoPage)
92 92 app.Post("/new", middleware.RequireAuth(), h.NewRepoSubmit)
93 93 app.Get("/settings", middleware.RequireAuth(), h.SettingsPage)
... ... @@ -312,8 +312,11 @@ func (h *Handler) renderError(c *fiber.Ctx, status int, title, message string) e
312 312
313 313 func (h *Handler) Home(c *fiber.Ctx) error {
314 314 if !h.db.IsLandingEnabled(c.UserContext(), h.cfg.Landing.Enabled) {
315 - if middleware.CurrentUser(c) != nil {
316 - return c.Redirect("/repos", fiber.StatusSeeOther)
315 + if u := middleware.CurrentUser(c); u != nil {
316 + if h.db.IsExploreEnabled(c.UserContext()) {
317 + return c.Redirect("/explore", fiber.StatusSeeOther)
318 + }
319 + return c.Redirect("/"+u.Username, fiber.StatusSeeOther)
317 320 }
318 321 return c.Redirect("/login", fiber.StatusSeeOther)
319 322 }
... ... @@ -340,14 +343,10 @@ func (h *Handler) Explore(c *fiber.Ctx) error {
340 343 return h.render(c, fiber.StatusOK, "repos", data)
341 344 }
342 345
343 -func (h *Handler) MyRepos(c *fiber.Ctx) error {
344 - u := middleware.CurrentUser(c)
345 - lang, _ := c.Locals("lang").(i18n.Lang)
346 - data := h.baseData(c, i18n.T(lang, "nav.repositories"))
347 - repos, _ := h.repoSvc.ListByOwner(c.UserContext(), u.ID, true)
348 - data["PageHeading"] = i18n.T(lang, "nav.repositories")
349 - data["Repos"] = repos
350 - return h.render(c, fiber.StatusOK, "repos", data)
346 +// LegacyReposRedirect keeps old /repos links working: the repository
347 +// catalog is served by Explore.
348 +func (h *Handler) LegacyReposRedirect(c *fiber.Ctx) error {
349 + return c.Redirect("/explore", fiber.StatusSeeOther)
351 350 }
352 351
353 352 func (h *Handler) cloneURL(c *fiber.Ctx, ownerUsername, repoName string) string {
internal/web/handlers/repo.go
+1 -1
... ... @@ -385,7 +385,7 @@ func (h *Handler) RepoDeleteSubmit(c *fiber.Ctx) error {
385 385 }
386 386
387 387 h.setFlashT(c, "flash.repo_deleted", r.Name)
388 - return c.Redirect("/repos", fiber.StatusSeeOther)
388 + return c.Redirect("/"+r.OwnerUsername, fiber.StatusSeeOther)
389 389 }
390 390
391 391 func (h *Handler) UserProfilePage(c *fiber.Ctx) error {
internal/web/static/js/app.js
+1 -1
... ... @@ -370,7 +370,7 @@
370 370 }
371 371 if (e.key.toLowerCase() === 'r') {
372 372 e.preventDefault();
373 - window.location.href = '/repos';
373 + window.location.href = '/explore';
374 374 return;
375 375 }
376 376 }
internal/web/views/layouts/base.html
+5 -48
... ... @@ -62,15 +62,9 @@
62 62
63 63 <!-- Primary Navigation -->
64 64 <nav class="flex flex-col gap-1 mt-1">
65 - {{if .CurrentUser}}
66 - <a href="/repos" class="nav-item">
67 - <span class="flex items-center gap-2">{{icon "git-branch" "size-4"}} {{t .Lang "nav.repositories"}}</span>
68 - </a>
69 - {{else}}
70 - <a href="/" class="nav-item">
71 - <span class="flex items-center gap-2">{{icon "home" "size-4"}} {{t .Lang "nav.home"}}</span>
72 - </a>
73 - {{end}}
65 + <a href="/" class="nav-item">
66 + <span class="flex items-center gap-2">{{icon "home" "size-4"}} {{t .Lang "nav.home"}}</span>
67 + </a>
74 68 {{if .ExploreEnabled}}
75 69 <a href="/explore" class="nav-item">
76 70 <span class="flex items-center gap-2">{{icon "globe" "size-4"}} {{t .Lang "nav.explore"}}</span>
... ... @@ -88,39 +82,6 @@
88 82 {{end}}
89 83 </nav>
90 84
91 - <!-- Quick Repository List in Sidebar -->
92 - <div class="mt-2">
93 - <div class="nav-section-label">
94 - <span>{{t .Lang "nav.repositories"}}</span>
95 - {{if .CurrentUser}}
96 - <a href="/new" class="btn btn-ghost btn-icon" style="width:1.35rem;height:1.35rem;" title="{{t .Lang "repo.new.title"}}">
97 - {{icon "plus" "size-3.5"}}
98 - </a>
99 - {{end}}
100 - </div>
101 - <div class="flex flex-col gap-1">
102 - {{if .PaletteRepos}}
103 - {{range .PaletteRepos}}
104 - <a href="/{{.OwnerUsername}}/{{.Name}}" class="nav-item" style="height:1.8rem;font-size:0.8rem;">
105 - <span class="flex items-center gap-2 min-w-0 truncate">
106 - {{if .IsPrivate}}
107 - {{icon "lock" "size-3.5"}}
108 - {{else}}
109 - {{icon "folder" "size-3.5"}}
110 - {{end}}
111 - <span class="truncate">{{.OwnerUsername}}/<strong>{{.Name}}</strong></span>
112 - </span>
113 - </a>
114 - {{end}}
115 - {{else}}
116 - {{if .CurrentUser}}
117 - <a href="/new" class="nav-item text-xs">
118 - <span class="flex items-center gap-1.5">{{icon "plus" "size-3.5"}} {{t .Lang "repo.new.title"}}</span>
119 - </a>
120 - {{end}}
121 - {{end}}
122 - </div>
123 - </div>
124 85 </div>
125 86
126 87 <!-- Sidebar Bottom: 3-Theme Switcher + Account -->
... ... @@ -223,7 +184,6 @@
223 184 <nav class="flex flex-col gap-1">
224 185 <a href="/" class="nav-item">{{icon "home" "size-4"}} {{t .Lang "nav.home"}}</a>
225 186 {{if .CurrentUser}}
226 - <a href="/repos" class="nav-item">{{icon "git-branch" "size-4"}} {{t .Lang "nav.repositories"}}</a>
227 187 <a href="/new" class="nav-item">{{icon "plus" "size-4"}} {{t .Lang "repo.new.title"}}</a>
228 188 <a href="/settings" class="nav-item">{{icon "settings" "size-4"}} {{t .Lang "nav.settings"}}</a>
229 189 {{if .CurrentUser.IsAdmin}}
... ... @@ -258,13 +218,10 @@
258 218 <span class="flex items-center gap-2">{{icon "home" "size-4"}} {{t .Lang "nav.home"}}</span>
259 219 <span class="flex items-center gap-1"><kbd class="kbd">g</kbd><kbd class="kbd">h</kbd></span>
260 220 </button>
261 - <button type="button" class="palette-item" data-palette-item data-palette-href="/repos" data-palette-keywords="repositories repos репозитории">
262 - <span class="flex items-center gap-2">{{icon "git-branch" "size-4"}} {{t .Lang "nav.repositories"}}</span>
263 - <span class="flex items-center gap-1"><kbd class="kbd">g</kbd><kbd class="kbd">r</kbd></span>
264 - </button>
265 221 {{if .ExploreEnabled}}
266 222 <button type="button" class="palette-item" data-palette-item data-palette-href="/explore" data-palette-keywords="explore обзор публичные">
267 223 <span class="flex items-center gap-2">{{icon "globe" "size-4"}} {{t .Lang "nav.explore"}}</span>
224 + <span class="flex items-center gap-1"><kbd class="kbd">g</kbd><kbd class="kbd">r</kbd></span>
268 225 </button>
269 226 {{end}}
270 227 {{if .CurrentUser}}
... ... @@ -362,7 +319,7 @@
362 319 <span class="flex items-center gap-1"><kbd class="kbd">g</kbd><kbd class="kbd">h</kbd></span>
363 320 </div>
364 321 <div class="flex items-center justify-between py-2" style="border-bottom:1px solid hsl(var(--border));">
365 - <span>{{t .Lang "shortcuts.repos"}}</span>
322 + <span>{{t .Lang "nav.explore"}}</span>
366 323 <span class="flex items-center gap-1"><kbd class="kbd">g</kbd><kbd class="kbd">r</kbd></span>
367 324 </div>
368 325 <div class="flex items-center justify-between py-2">
internal/web/views/pages/error.html
+3 -1
... ... @@ -6,7 +6,9 @@
6 6 <p class="text-sm text-muted mt-1">{{.Message}}</p>
7 7 <div class="mt-4 flex items-center justify-center gap-2">
8 8 <a href="/" class="btn btn-primary btn-sm">{{icon "home" "size-3.5"}} {{t .Lang "nav.home"}}</a>
9 - <a href="/repos" class="btn btn-outline btn-sm">{{icon "git-branch" "size-3.5"}} {{t .Lang "nav.repositories"}}</a>
9 + {{if .ExploreEnabled}}
10 + <a href="/explore" class="btn btn-outline btn-sm">{{icon "globe" "size-3.5"}} {{t .Lang "nav.explore"}}</a>
11 + {{end}}
10 12 </div>
11 13 </div>
12 14 </div>
internal/web/views/pages/landing.html
+6 -4
... ... @@ -18,10 +18,12 @@
18 18 {{icon "plus" "size-4"}}
19 19 <span>{{t .Lang "repo.new.title"}}</span>
20 20 </a>
21 - <a href="/repos" class="btn btn-outline">
22 - {{icon "git-branch" "size-4"}}
23 - <span>{{t .Lang "nav.repositories"}}</span>
24 - </a>
21 + {{if .ExploreEnabled}}
22 + <a href="/explore" class="btn btn-outline">
23 + {{icon "globe" "size-4"}}
24 + <span>{{t .Lang "nav.explore"}}</span>
25 + </a>
26 + {{end}}
25 27 {{else}}
26 28 {{if .RegistrationEnabled}}
27 29 <a href="/register" class="btn btn-primary">
internal/web/views/pages/repo_new.html
+1 -1
... ... @@ -43,7 +43,7 @@
43 43 </div>
44 44
45 45 <div class="flex items-center justify-end gap-2 pt-2">
46 - <a href="/repos" class="btn btn-outline">{{t .Lang "common.cancel"}}</a>
46 + <a href="/" class="btn btn-outline">{{t .Lang "common.cancel"}}</a>
47 47 <button type="submit" class="btn btn-primary">
48 48 {{icon "plus" "size-4"}}
49 49 <span>{{t .Lang "repo.create_btn"}}</span>