refactor(ui): simplify custom context menu
7e469ac
Browse files
R
rin
·
2026-10-18 23:51 UTC
5 files changed
+4
-182
assets/input.css
+1
-26
| ... | ... | @@ -1176,9 +1176,6 @@ kbd, .kbd { |
| 1176 | 1176 | transform: translateY(0) scale(1); |
| 1177 | 1177 | animation: contextMenuIn 130ms cubic-bezier(0.16, 1, 0.3, 1); |
| 1178 | 1178 | } |
| 1179 | -body[data-repo-path] .context-menu { | |
| 1180 | - max-height: min(80vh, 52rem); | |
| 1181 | -} | |
| 1182 | 1179 | .context-menu-section[hidden], |
| 1183 | 1180 | .context-menu-item[hidden] { |
| 1184 | 1181 | display: none; |
| ... | ... | @@ -1199,18 +1196,6 @@ body[data-repo-path] .context-menu { |
| 1199 | 1196 | text-transform: uppercase; |
| 1200 | 1197 | color: hsl(var(--muted-foreground)); |
| 1201 | 1198 | } |
| 1202 | -.context-menu-meta { | |
| 1203 | - margin-left: auto; | |
| 1204 | - max-width: 9.5rem; | |
| 1205 | - overflow: hidden; | |
| 1206 | - text-overflow: ellipsis; | |
| 1207 | - white-space: nowrap; | |
| 1208 | - font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; | |
| 1209 | - font-size: 0.6rem; | |
| 1210 | - letter-spacing: 0; | |
| 1211 | - text-transform: none; | |
| 1212 | - opacity: 0.85; | |
| 1213 | -} | |
| 1214 | 1199 | .context-menu-item { |
| 1215 | 1200 | display: flex; |
| 1216 | 1201 | width: 100%; |
| ... | ... | @@ -1236,7 +1221,7 @@ body[data-repo-path] .context-menu { |
| 1236 | 1221 | color: hsl(var(--muted-foreground)); |
| 1237 | 1222 | transition: color 90ms ease; |
| 1238 | 1223 | } |
| 1239 | -.context-menu-item > span:not(.context-menu-check):not(.context-menu-kbd) { | |
| 1224 | +.context-menu-item > span:not(.context-menu-kbd) { | |
| 1240 | 1225 | min-width: 0; |
| 1241 | 1226 | overflow: hidden; |
| 1242 | 1227 | text-overflow: ellipsis; |
| ... | ... | @@ -1266,16 +1251,6 @@ body[data-repo-path] .context-menu { |
| 1266 | 1251 | border: 1px solid hsl(var(--border)); |
| 1267 | 1252 | border-radius: 0.22rem; |
| 1268 | 1253 | } |
| 1269 | -.context-menu-check { | |
| 1270 | - display: inline-flex; | |
| 1271 | - margin-left: auto; | |
| 1272 | - flex: none; | |
| 1273 | - opacity: 0; | |
| 1274 | - color: hsl(var(--foreground)); | |
| 1275 | -} | |
| 1276 | -.context-menu-item.is-current .context-menu-check { | |
| 1277 | - opacity: 1; | |
| 1278 | -} | |
| 1279 | 1254 | |
| 1280 | 1255 | /* Shortcuts dialog */ |
| 1281 | 1256 | .shortcuts-list { |
internal/i18n/i18n.go
+0
-8
| ... | ... | @@ -364,15 +364,11 @@ var translations = map[Lang]map[string]string{ |
| 364 | 364 | "contextmenu.open_image": "Открыть изображение", |
| 365 | 365 | "contextmenu.copy_image": "Копировать адрес изображения", |
| 366 | 366 | "contextmenu.save_image": "Сохранить изображение", |
| 367 | - "contextmenu.repository": "Репозиторий", | |
| 368 | - "contextmenu.repo_actions": "Действия", | |
| 369 | 367 | "contextmenu.page": "Страница", |
| 370 | 368 | "contextmenu.back": "Назад", |
| 371 | 369 | "contextmenu.forward": "Вперёд", |
| 372 | 370 | "contextmenu.reload": "Обновить", |
| 373 | 371 | "contextmenu.copy_url": "Копировать адрес страницы", |
| 374 | - "contextmenu.appearance": "Оформление", | |
| 375 | - "contextmenu.app": "Приложение", | |
| 376 | 372 | |
| 377 | 373 | // Флеш-сообщения |
| 378 | 374 | "flash.welcome": "Добро пожаловать в Polar, @%s!", |
| ... | ... | @@ -982,15 +978,11 @@ var translations = map[Lang]map[string]string{ |
| 982 | 978 | "contextmenu.open_image": "Open image in new tab", |
| 983 | 979 | "contextmenu.copy_image": "Copy image address", |
| 984 | 980 | "contextmenu.save_image": "Save image", |
| 985 | - "contextmenu.repository": "Repository", | |
| 986 | - "contextmenu.repo_actions": "Actions", | |
| 987 | 981 | "contextmenu.page": "Page", |
| 988 | 982 | "contextmenu.back": "Back", |
| 989 | 983 | "contextmenu.forward": "Forward", |
| 990 | 984 | "contextmenu.reload": "Reload", |
| 991 | 985 | "contextmenu.copy_url": "Copy page URL", |
| 992 | - "contextmenu.appearance": "Appearance", | |
| 993 | - "contextmenu.app": "Application", | |
| 994 | 986 | |
| 995 | 987 | // Flash messages |
| 996 | 988 | "flash.welcome": "Welcome to Polar, @%s!", |
internal/web/static/css/app.css
+1
-26
| ... | ... | @@ -1176,9 +1176,6 @@ kbd, .kbd { |
| 1176 | 1176 | transform: translateY(0) scale(1); |
| 1177 | 1177 | animation: contextMenuIn 130ms cubic-bezier(0.16, 1, 0.3, 1); |
| 1178 | 1178 | } |
| 1179 | -body[data-repo-path] .context-menu { | |
| 1180 | - max-height: min(80vh, 52rem); | |
| 1181 | -} | |
| 1182 | 1179 | .context-menu-section[hidden], |
| 1183 | 1180 | .context-menu-item[hidden] { |
| 1184 | 1181 | display: none; |
| ... | ... | @@ -1199,18 +1196,6 @@ body[data-repo-path] .context-menu { |
| 1199 | 1196 | text-transform: uppercase; |
| 1200 | 1197 | color: hsl(var(--muted-foreground)); |
| 1201 | 1198 | } |
| 1202 | -.context-menu-meta { | |
| 1203 | - margin-left: auto; | |
| 1204 | - max-width: 9.5rem; | |
| 1205 | - overflow: hidden; | |
| 1206 | - text-overflow: ellipsis; | |
| 1207 | - white-space: nowrap; | |
| 1208 | - font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; | |
| 1209 | - font-size: 0.6rem; | |
| 1210 | - letter-spacing: 0; | |
| 1211 | - text-transform: none; | |
| 1212 | - opacity: 0.85; | |
| 1213 | -} | |
| 1214 | 1199 | .context-menu-item { |
| 1215 | 1200 | display: flex; |
| 1216 | 1201 | width: 100%; |
| ... | ... | @@ -1236,7 +1221,7 @@ body[data-repo-path] .context-menu { |
| 1236 | 1221 | color: hsl(var(--muted-foreground)); |
| 1237 | 1222 | transition: color 90ms ease; |
| 1238 | 1223 | } |
| 1239 | -.context-menu-item > span:not(.context-menu-check):not(.context-menu-kbd) { | |
| 1224 | +.context-menu-item > span:not(.context-menu-kbd) { | |
| 1240 | 1225 | min-width: 0; |
| 1241 | 1226 | overflow: hidden; |
| 1242 | 1227 | text-overflow: ellipsis; |
| ... | ... | @@ -1266,16 +1251,6 @@ body[data-repo-path] .context-menu { |
| 1266 | 1251 | border: 1px solid hsl(var(--border)); |
| 1267 | 1252 | border-radius: 0.22rem; |
| 1268 | 1253 | } |
| 1269 | -.context-menu-check { | |
| 1270 | - display: inline-flex; | |
| 1271 | - margin-left: auto; | |
| 1272 | - flex: none; | |
| 1273 | - opacity: 0; | |
| 1274 | - color: hsl(var(--foreground)); | |
| 1275 | -} | |
| 1276 | -.context-menu-item.is-current .context-menu-check { | |
| 1277 | - opacity: 1; | |
| 1278 | -} | |
| 1279 | 1254 | |
| 1280 | 1255 | /* Shortcuts dialog */ |
| 1281 | 1256 | .shortcuts-list { |
internal/web/static/js/app.js
+2
-26
| ... | ... | @@ -69,7 +69,6 @@ |
| 69 | 69 | el.classList.toggle('active', isCurrent); |
| 70 | 70 | el.setAttribute('aria-checked', isCurrent ? 'true' : 'false'); |
| 71 | 71 | }); |
| 72 | - updateContextMenuThemeState(); | |
| 73 | 72 | } |
| 74 | 73 | window.PolarSetTheme = setTheme; |
| 75 | 74 | |
| ... | ... | @@ -146,17 +145,6 @@ |
| 146 | 145 | } |
| 147 | 146 | } |
| 148 | 147 | |
| 149 | - function updateContextMenuThemeState() { | |
| 150 | - var menu = document.getElementById('context-menu'); | |
| 151 | - if (!menu) return; | |
| 152 | - var theme = document.documentElement.getAttribute('data-theme') || 'system'; | |
| 153 | - menu.querySelectorAll('[data-theme-value]').forEach(function (item) { | |
| 154 | - var isCurrent = item.getAttribute('data-theme-value') === theme; | |
| 155 | - item.classList.toggle('is-current', isCurrent); | |
| 156 | - item.setAttribute('aria-checked', isCurrent ? 'true' : 'false'); | |
| 157 | - }); | |
| 158 | - } | |
| 159 | - | |
| 160 | 148 | function closeContextMenu() { |
| 161 | 149 | var menu = document.getElementById('context-menu'); |
| 162 | 150 | if (!menu || !menu.classList.contains('open')) return; |
| ... | ... | @@ -229,7 +217,6 @@ |
| 229 | 217 | var imageCopyItem = menu.querySelector('[data-context-action="image-copy"]'); |
| 230 | 218 | if (imageCopyItem) imageCopyItem.hidden = !imageURL || imageIsTemporary; |
| 231 | 219 | |
| 232 | - updateContextMenuThemeState(); | |
| 233 | 220 | menu.classList.add('open'); |
| 234 | 221 | menu.setAttribute('aria-hidden', 'false'); |
| 235 | 222 | menu.scrollTop = 0; |
| ... | ... | @@ -271,12 +258,6 @@ |
| 271 | 258 | var action = item.getAttribute('data-context-action'); |
| 272 | 259 | var state = contextMenuState || {}; |
| 273 | 260 | |
| 274 | - if (action === 'theme') { | |
| 275 | - setTheme(item.getAttribute('data-theme-value'), false); | |
| 276 | - closeContextMenu(); | |
| 277 | - return; | |
| 278 | - } | |
| 279 | - | |
| 280 | 261 | closeContextMenu(); |
| 281 | 262 | |
| 282 | 263 | if (action === 'copy-selection') { |
| ... | ... | @@ -320,10 +301,6 @@ |
| 320 | 301 | window.history.back(); |
| 321 | 302 | } else if (action === 'page-forward') { |
| 322 | 303 | window.history.forward(); |
| 323 | - } else if (action === 'palette') { | |
| 324 | - openPalette(''); | |
| 325 | - } else if (action === 'shortcuts') { | |
| 326 | - openDialog('shortcuts-dialog'); | |
| 327 | 304 | } |
| 328 | 305 | } |
| 329 | 306 | |
| ... | ... | @@ -332,9 +309,8 @@ |
| 332 | 309 | var order = ['light', 'dark', 'system']; |
| 333 | 310 | var next = order[(order.indexOf(current) + 1) % order.length]; |
| 334 | 311 | setTheme(next, false); |
| 335 | - var item = document.querySelector('#context-menu [data-theme-value="' + next + '"]'); | |
| 336 | - var label = item ? item.querySelector('span:not(.context-menu-check)') : null; | |
| 337 | - showToast(label ? label.textContent.trim() : next); | |
| 312 | + var item = document.querySelector('#command-palette [data-palette-theme="' + next + '"]'); | |
| 313 | + showToast(item ? item.textContent.trim() : next); | |
| 338 | 314 | } |
| 339 | 315 | |
| 340 | 316 | function shortcutUnavailable() { |
internal/web/views/layouts/base.html
+0
-96
| ... | ... | @@ -401,73 +401,6 @@ |
| 401 | 401 | </button> |
| 402 | 402 | </div> |
| 403 | 403 | |
| 404 | - {{if .Repo}} | |
| 405 | - <div class="context-menu-section" data-context-section="repo"> | |
| 406 | - <div class="context-menu-label"> | |
| 407 | - <span>{{t .Lang "contextmenu.repository"}}</span> | |
| 408 | - <span class="context-menu-meta">{{.Repo.OwnerUsername}}/{{.Repo.Name}}</span> | |
| 409 | - </div> | |
| 410 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}" role="menuitem"> | |
| 411 | - {{icon "code" "size-3.5"}}<span>{{t .Lang "repo.tab.code"}}</span> | |
| 412 | - </a> | |
| 413 | - {{if .Repo.EnableIssues}} | |
| 414 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/issues" role="menuitem"> | |
| 415 | - {{icon "issue" "size-3.5"}}<span>{{t .Lang "repo.tab.issues"}}</span> | |
| 416 | - </a> | |
| 417 | - {{end}} | |
| 418 | - {{if .Repo.EnablePulls}} | |
| 419 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/pulls" role="menuitem"> | |
| 420 | - {{icon "git-pull-request" "size-3.5"}}<span>{{t .Lang "repo.tab.pulls"}}</span> | |
| 421 | - </a> | |
| 422 | - {{end}} | |
| 423 | - {{if .Repo.EnableReleases}} | |
| 424 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/releases" role="menuitem"> | |
| 425 | - {{icon "tag" "size-3.5"}}<span>{{t .Lang "repo.tab.releases"}}</span> | |
| 426 | - </a> | |
| 427 | - {{end}} | |
| 428 | - {{if .Repo.EnableActivity}} | |
| 429 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/activity" role="menuitem"> | |
| 430 | - {{icon "activity" "size-3.5"}}<span>{{t .Lang "repo.tab.activity"}}</span> | |
| 431 | - </a> | |
| 432 | - {{end}} | |
| 433 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/branches" role="menuitem"> | |
| 434 | - {{icon "git-branch" "size-3.5"}}<span>{{t .Lang "repo.tab.branches"}}</span> | |
| 435 | - </a> | |
| 436 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/commits/{{.Repo.DefaultBranch}}" role="menuitem"> | |
| 437 | - {{icon "history" "size-3.5"}}<span>{{t .Lang "repo.tab.commits"}}</span> | |
| 438 | - </a> | |
| 439 | - </div> | |
| 440 | - | |
| 441 | - {{if or .CanWrite (and .CurrentUser (or .Repo.EnableIssues .Repo.EnablePulls))}} | |
| 442 | - <div class="context-menu-section" data-context-section="repo-actions"> | |
| 443 | - <div class="context-menu-label">{{t .Lang "contextmenu.repo_actions"}}</div> | |
| 444 | - {{if .CurrentUser}}{{if .Repo.EnableIssues}} | |
| 445 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/issues/new" role="menuitem"> | |
| 446 | - {{icon "issue" "size-3.5"}}<span>{{t .Lang "issues.new"}}</span> | |
| 447 | - </a> | |
| 448 | - {{end}}{{if .Repo.EnablePulls}} | |
| 449 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/pulls/new" role="menuitem"> | |
| 450 | - {{icon "git-pull-request" "size-3.5"}}<span>{{t .Lang "pulls.new"}}</span> | |
| 451 | - </a> | |
| 452 | - {{end}}{{end}} | |
| 453 | - {{if .CanWrite}} | |
| 454 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/new-file" role="menuitem"> | |
| 455 | - {{icon "plus" "size-3.5"}}<span>{{t .Lang "file.new_file"}}</span> | |
| 456 | - </a> | |
| 457 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/new-folder" role="menuitem"> | |
| 458 | - {{icon "folder" "size-3.5"}}<span>{{t .Lang "file.new_folder"}}</span> | |
| 459 | - </a> | |
| 460 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/upload" role="menuitem"> | |
| 461 | - {{icon "upload" "size-3.5"}}<span>{{t .Lang "file.upload_file"}}</span> | |
| 462 | - </a> | |
| 463 | - <a class="context-menu-item" href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/settings" role="menuitem"> | |
| 464 | - {{icon "settings" "size-3.5"}}<span>{{t .Lang "repo.tab.settings"}}</span> | |
| 465 | - </a> | |
| 466 | - {{end}} | |
| 467 | - </div> | |
| 468 | - {{end}} | |
| 469 | - {{end}} | |
| 470 | - | |
| 471 | 404 | <div class="context-menu-section" data-context-section="page"> |
| 472 | 405 | <div class="context-menu-label">{{t .Lang "contextmenu.page"}}</div> |
| 473 | 406 | <button type="button" class="context-menu-item" data-context-action="page-back" role="menuitem"> |
| ... | ... | @@ -484,36 +417,7 @@ |
| 484 | 417 | </button> |
| 485 | 418 | </div> |
| 486 | 419 | |
| 487 | - <div class="context-menu-section" data-context-section="appearance"> | |
| 488 | - <div class="context-menu-label">{{t .Lang "contextmenu.appearance"}}</div> | |
| 489 | - <button type="button" class="context-menu-item" data-context-action="theme" data-theme-value="light" role="menuitemradio" aria-checked="false"> | |
| 490 | - {{icon "sun" "size-3.5"}}<span>{{t .Lang "theme.light"}}</span><span class="context-menu-check">{{icon "check" "size-3.5"}}</span> | |
| 491 | - </button> | |
| 492 | - <button type="button" class="context-menu-item" data-context-action="theme" data-theme-value="dark" role="menuitemradio" aria-checked="false"> | |
| 493 | - {{icon "moon" "size-3.5"}}<span>{{t .Lang "theme.dark"}}</span><span class="context-menu-check">{{icon "check" "size-3.5"}}</span> | |
| 494 | - </button> | |
| 495 | - <button type="button" class="context-menu-item" data-context-action="theme" data-theme-value="system" role="menuitemradio" aria-checked="false"> | |
| 496 | - {{icon "laptop" "size-3.5"}}<span>{{t .Lang "theme.system"}}</span><span class="context-menu-check">{{icon "check" "size-3.5"}}</span> | |
| 497 | - </button> | |
| 498 | - </div> | |
| 499 | 420 | |
| 500 | - <div class="context-menu-section" data-context-section="app"> | |
| 501 | - <div class="context-menu-label">{{t .Lang "contextmenu.app"}}</div> | |
| 502 | - <button type="button" class="context-menu-item" data-context-action="palette" role="menuitem"> | |
| 503 | - {{icon "command" "size-3.5"}}<span>{{t .Lang "shortcuts.palette"}}</span><kbd class="context-menu-kbd">Ctrl K</kbd> | |
| 504 | - </button> | |
| 505 | - <button type="button" class="context-menu-item" data-context-action="shortcuts" role="menuitem"> | |
| 506 | - {{icon "keyboard" "size-3.5"}}<span>{{t .Lang "shortcuts.title"}}</span><kbd class="context-menu-kbd">?</kbd> | |
| 507 | - </button> | |
| 508 | - {{if .CurrentUser}} | |
| 509 | - <a class="context-menu-item" href="/new" role="menuitem"> | |
| 510 | - {{icon "plus" "size-3.5"}}<span>{{t .Lang "repo.new.title"}}</span> | |
| 511 | - </a> | |
| 512 | - <a class="context-menu-item" href="/settings" role="menuitem"> | |
| 513 | - {{icon "settings" "size-3.5"}}<span>{{t .Lang "nav.settings"}}</span> | |
| 514 | - </a> | |
| 515 | - {{end}} | |
| 516 | - </div> | |
| 517 | 421 | </div> |
| 518 | 422 | |
| 519 | 423 | <div id="toast-container" class="toast-container" aria-live="polite"></div> |