feat(nav): replace Repositories with Explore; drop /repos page and sidebar repo list
4760bf0
Файлы на момент коммита
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> |