Skip to content

Commit

Permalink
feat: sort tabs by title, url, access time
Browse files Browse the repository at this point in the history
- tab context menu options
- tab panel context menu options
- keybindings

(#170, #643)
  • Loading branch information
mbnuqw committed Mar 3, 2024
1 parent 3f01362 commit 4d30d92
Show file tree
Hide file tree
Showing 11 changed files with 766 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/_locales/dict.browser.json
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,42 @@
"zh_CN": "将选定(或活动)标签页移动到第十个面板",
"zh_TW": "將選定(或當前)分頁移動到第十個面板"
},
"KbSortTabsByTitleAsc": {
"en": "Sort selected tabs or siblings of the active tab by title (A-z)"
},
"KbSortTabsByTitleDes": {
"en": "Sort selected tabs or siblings of the active tab by title (z-A)"
},
"KbSortTabsByTrlAsc": {
"en": "Sort selected tabs or siblings of the active tab by URL (A-z)"
},
"KbSortTabsByTrlDes": {
"en": "Sort selected tabs or siblings of the active tab by URL (z-A)"
},
"KbSortTabsByTimeAsc": {
"en": "Sort selected tabs or siblings of the active tab by access time (Old-Recent)"
},
"KbSortTabsByTimeDes": {
"en": "Sort selected tabs or siblings of the active tab by access time (Recent-Old)"
},
"KbSortPanelTabsByTitleAsc": {
"en": "Sort tabs of the active panel by title (A-z)"
},
"KbSortPanelTabsByTitleDes": {
"en": "Sort tabs of the active panel by title (z-A)"
},
"KbSortPanelTabsByTrlAsc": {
"en": "Sort tabs of the active panel by URL (A-z)"
},
"KbSortPanelTabsByTrlDes": {
"en": "Sort tabs of the active panel by URL (z-A)"
},
"KbSortPanelTabsByTimeAsc": {
"en": "Sort tabs of the active panel by access time (Old-Recent)"
},
"KbSortPanelTabsByTimeDes": {
"en": "Sort tabs of the active panel by access time (Recent-Old)"
},

"proxy_popup_title_prefix": {
"en": "Proxy for \"",
Expand Down
111 changes: 111 additions & 0 deletions src/_locales/dict.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,96 @@ export const commonTranslations: Translations = {
zh_CN: '关闭其他标签页',
zh_TW: '關閉其他分頁',
},
'menu.tab.sort_sub_menu_name': {
en: 'Sort',
ru: 'Сортировать',
de: 'Sortieren',
zh: '排序',
},
'menu.tab.sort_by_title_asc': {
en: 'Sort by title (A-z)',
ru: 'Сортировать по названию (А-я)',
de: 'Sortieren nach Titel (A-z)',
zh_CN: '按名称排序 (A-z)',
zh_TW: '依名稱排序 (A-z)',
},
'menu.tab.sort_by_title_des': {
en: 'Sort by title (z-A)',
ru: 'Сортировать по названию (я-А)',
de: 'Sortieren nach Titel (z-A)',
zh_CN: '按名称排序 (z-A)',
zh_TW: '依名稱排序 (z-A)',
},
'menu.tab.sort_by_url_asc': {
en: 'Sort by URL (A-z)',
ru: 'Сортировать по адресу (А-я)',
de: 'Sortieren nach URL (A-z)',
zh_CN: '按网址排序 (A-z)',
zh_TW: '依網址排序 (A-z)',
},
'menu.tab.sort_by_url_des': {
en: 'Sort by URL (z-A)',
ru: 'Сортировать по адресу (я-А)',
de: 'Sortieren nach URL (z-A)',
zh_CN: '按网址排序 (z-A)',
zh_TW: '依網址排序 (z-A)',
},
'menu.tab.sort_by_time_asc': {
en: 'Sort by access time (Old-Recent)',
ru: 'Сортировать по времени доступа (Старые-Новые)',
de: 'Sortieren nach Zugriffszeit (Alt-Neu)',
zh_CN: '按存取时间排序(旧-新)',
zh_TW: '按訪問時間排序(舊-新)',
},
'menu.tab.sort_by_time_des': {
en: 'Sort by access time (Recent-Old)',
ru: 'Сортировать по времени доступа (Новые-Старые)',
de: 'Sortieren nach Zugriffszeit (Neu-Alt)',
zh_CN: '按存取时间排序(新-旧)',
zh_TW: '按訪問時間排序(新-舊)',
},
'menu.tab.sort_tree_by_title_asc': {
en: 'Sort tree by title (A-z)',
ru: 'Сортировать дерево по названию (А-я)',
de: 'Baum nach Titel sortieren (A-z)',
zh_CN: '按标题对树进行排序 (A-z)',
zh_TW: '按標題對樹進行排序 (A-z)',
},
'menu.tab.sort_tree_by_title_des': {
en: 'Sort tree by title (z-A)',
ru: 'Сортировать дерево по названию (я-А)',
de: 'Baum nach Titel sortieren (z-A)',
zh_CN: '按标题对树进行排序 (z-A)',
zh_TW: '按標題對樹進行排序 (z-A)',
},
'menu.tab.sort_tree_by_url_asc': {
en: 'Sort tree by URL (A-z)',
ru: 'Сортировать дерево по адресу (А-я)',
de: 'Baum nach URL sortieren (A-z)',
zh_CN: '按 URL 对树排序 (A-z)',
zh_TW: '按 URL 對樹排序 (A-z)',
},
'menu.tab.sort_tree_by_url_des': {
en: 'Sort tree by URL (z-A)',
ru: 'Сортировать дерево по адресу (я-А)',
de: 'Baum nach URL sortieren (z-A)',
zh_CN: '按 URL 对树排序 (z-A)',
zh_TW: '按 URL 對樹排序 (z-A)',
},
'menu.tab.sort_tree_by_time_asc': {
en: 'Sort tree by access time (Old-Recent)',
ru: 'Сортировать дерево по времени доступа (Старые-Новые)',
de: 'Baum nach Zugriffszeit sortieren (Alt-Neu)',
zh_CN: '按访问时间排序树(旧-新)',
zh_TW: '按訪問時間對樹進行排序(舊-新)',
},
'menu.tab.sort_tree_by_time_des': {
en: 'Sort tree by access time (Recent-Old)',
ru: 'Сортировать дерево по времени доступа (Новые-Старые)',
de: 'Baum nach Zugriffszeit sortieren (Neu-Alt)',
zh_CN: '按访问时间排序树(新-旧)',
zh_TW: '按訪問時間對樹進行排序(新-舊)',
},
// - Tabs panel
'menu.tabs_panel.mute_all_audible': {
en: 'Mute all audible tabs',
Expand Down Expand Up @@ -1191,6 +1281,27 @@ export const commonTranslations: Translations = {
de: 'Panel entfernen',
zh: '移除面板',
},
'menu.tabs_panel.sort_all_sub_menu_name': {
en: 'Sort all tabs',
},
'menu.tabs_panel.sort_all_by_title_asc': {
en: 'Sort all tabs by title (A-z)',
},
'menu.tabs_panel.sort_all_by_title_des': {
en: 'Sort all tabs by title (z-A)',
},
'menu.tabs_panel.sort_all_by_url_asc': {
en: 'Sort all tabs by URL (A-z)',
},
'menu.tabs_panel.sort_all_by_url_des': {
en: 'Sort all tabs by URL (z-A)',
},
'menu.tabs_panel.sort_all_by_time_asc': {
en: 'Sort all tabs by access time (Old-Recent)',
},
'menu.tabs_panel.sort_all_by_time_des': {
en: 'Sort all tabs by access time (Recent-Old)',
},
// - History
'menu.history.open': {
en: 'Open',
Expand Down
3 changes: 3 additions & 0 deletions src/_locales/dict.setup-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4025,6 +4025,9 @@ Beispiele: "*", "ctrl+$", "ctrl+alt+g"`,
zh_CN: '移动标签',
zh_TW: '移動分頁',
},
'settings.kb_sort_tabs': {
en: 'Sorting tabs',
},
'settings.reset_kb': {
en: 'Reset Keybindings',
ru: 'Сбросить клав. настройки',
Expand Down
7 changes: 7 additions & 0 deletions src/_locales/dict.sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,13 @@ export const sidebarTranslations: Translations = {
zh_CN: '书签排序',
zh_TW: '書籤排序',
},
'notif.tabs_sort': {
en: 'Sorting tabs...',
ru: 'Сортировка вкладок...',
de: 'Sortiere Tabs...',
zh_CN: '排序选项卡...',
zh_TW: '排序選項卡...',
},
'notif.snapshot_created': {
en: 'Snapshot created',
ru: 'Снепшот создан',
Expand Down
30 changes: 30 additions & 0 deletions src/defaults/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,24 @@ export const TABS_MENU: MenuConf = [
name: '%menu.tab.colorize_',
opts: ['colorizeTab'],
},
{
name: '%menu.tab.sort_sub_menu_name',
opts: [
'sortTabsByTitleAscending',
'sortTabsByTitleDescending',
'sortTabsByUrlAscending',
'sortTabsByUrlDescending',
'sortTabsByAccessTimeAscending',
'sortTabsByAccessTimeDescending',
'separator-45654',
'sortTabsTreeByTitleAscending',
'sortTabsTreeByTitleDescending',
'sortTabsTreeByUrlAscending',
'sortTabsTreeByUrlDescending',
'sortTabsTreeByAccessTimeAscending',
'sortTabsTreeByAccessTimeDescending',
],
},
'separator-2',
'pin',
'duplicate',
Expand All @@ -33,6 +51,18 @@ export const TABS_MENU: MenuConf = [

export const TABS_PANEL_MENU: MenuConf = [
{ opts: ['undoRmTab', 'muteAllAudibleTabs', 'reloadTabs', 'discardTabs'] },
'separator-1224',
{
name: '%menu.tabs_panel.sort_all_sub_menu_name',
opts: [
'sortAllTabsByTitleAscending',
'sortAllTabsByTitleDescending',
'sortAllTabsByUrlAscending',
'sortAllTabsByUrlDescending',
'sortAllTabsByAccessTimeAscending',
'sortAllTabsByAccessTimeDescending',
],
},
'separator-7',
'selectAllTabs',
'collapseInactiveBranches',
Expand Down
36 changes: 36 additions & 0 deletions src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,42 @@
},
"sel_child_tabs": {
"description": "__MSG_KbSelChildTabs__"
},
"sort_tabs_by_title_asc": {
"description": "__MSG_KbSortTabsByTitleAsc__"
},
"sort_tabs_by_title_des": {
"description": "__MSG_KbSortTabsByTitleDes__"
},
"sort_tabs_by_url_asc": {
"description": "__MSG_KbSortTabsByTrlAsc__"
},
"sort_tabs_by_url_des": {
"description": "__MSG_KbSortTabsByTrlDes__"
},
"sort_tabs_by_time_asc": {
"description": "__MSG_KbSortTabsByTimeAsc__"
},
"sort_tabs_by_time_des": {
"description": "__MSG_KbSortTabsByTimeDes__"
},
"sort_panel_tabs_by_title_asc": {
"description": "__MSG_KbSortPanelTabsByTitleAsc__"
},
"sort_panel_tabs_by_title_des": {
"description": "__MSG_KbSortPanelTabsByTitleDes__"
},
"sort_panel_tabs_by_url_asc": {
"description": "__MSG_KbSortPanelTabsByTrlAsc__"
},
"sort_panel_tabs_by_url_des": {
"description": "__MSG_KbSortPanelTabsByTrlDes__"
},
"sort_panel_tabs_by_time_asc": {
"description": "__MSG_KbSortPanelTabsByTimeAsc__"
},
"sort_panel_tabs_by_time_des": {
"description": "__MSG_KbSortPanelTabsByTimeDes__"
}
},
"browser_action": {
Expand Down
16 changes: 16 additions & 0 deletions src/page.setup/components/keybindings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@
KeybindingField(:keybinding="Keybindings.reactive.byName.move_tabs_to_panel_8")
KeybindingField(:keybinding="Keybindings.reactive.byName.move_tabs_to_panel_9")

section
h2 {{translate('settings.kb_sort_tabs')}}
span.header-shadow
KeybindingField.-no-separator(:keybinding="Keybindings.reactive.byName.sort_tabs_by_title_asc")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_tabs_by_title_des")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_tabs_by_url_asc")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_tabs_by_url_des")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_tabs_by_time_asc")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_tabs_by_time_des")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_panel_tabs_by_title_asc")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_panel_tabs_by_title_des")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_panel_tabs_by_url_asc")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_panel_tabs_by_url_des")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_panel_tabs_by_time_asc")
KeybindingField(:keybinding="Keybindings.reactive.byName.sort_panel_tabs_by_time_des")

section
.ctrls
.btn(@click="Keybindings.resetKeybindings") {{translate('settings.reset_kb')}}
Expand Down
18 changes: 18 additions & 0 deletions src/page.setup/components/menu-editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ const TABS_MENU_OPTS: Record<string, string> = {
group: 'menu.tab.group',
flatten: 'menu.tab.flatten',
urlConf: 'menu.tab.url_conf',
sortTabsByTitleAscending: 'menu.tab.sort_by_title_asc',
sortTabsByTitleDescending: 'menu.tab.sort_by_title_des',
sortTabsByUrlAscending: 'menu.tab.sort_by_url_asc',
sortTabsByUrlDescending: 'menu.tab.sort_by_url_des',
sortTabsByAccessTimeAscending: 'menu.tab.sort_by_time_asc',
sortTabsByAccessTimeDescending: 'menu.tab.sort_by_time_des',
sortTabsTreeByTitleAscending: 'menu.tab.sort_tree_by_title_asc',
sortTabsTreeByTitleDescending: 'menu.tab.sort_tree_by_title_des',
sortTabsTreeByUrlAscending: 'menu.tab.sort_tree_by_url_asc',
sortTabsTreeByUrlDescending: 'menu.tab.sort_tree_by_url_des',
sortTabsTreeByAccessTimeAscending: 'menu.tab.sort_tree_by_time_asc',
sortTabsTreeByAccessTimeDescending: 'menu.tab.sort_tree_by_time_des',
clearCookies: 'menu.tab.clear_cookies',
closeDescendants: 'menu.tab.close_descendants',
close: 'menu.tab.close',
Expand All @@ -206,6 +218,12 @@ const TABS_PANEL_MENU_OPTS: Record<string, string> = {
bookmarkTabsPanel: 'menu.tabs_panel.bookmark',
restoreFromBookmarks: 'menu.tabs_panel.restore_from_bookmarks',
convertToBookmarksPanel: 'menu.tabs_panel.convert_to_bookmarks_panel',
sortAllTabsByTitleAscending: 'menu.tabs_panel.sort_all_by_title_asc',
sortAllTabsByTitleDescending: 'menu.tabs_panel.sort_all_by_title_des',
sortAllTabsByUrlAscending: 'menu.tabs_panel.sort_all_by_url_asc',
sortAllTabsByUrlDescending: 'menu.tabs_panel.sort_all_by_url_des',
sortAllTabsByAccessTimeAscending: 'menu.tabs_panel.sort_all_by_time_asc',
sortAllTabsByAccessTimeDescending: 'menu.tabs_panel.sort_all_by_time_des',
}
const BOOKMARKS_MENU_OPTS: Record<string, string> = {
Expand Down
29 changes: 29 additions & 0 deletions src/services/keybindings.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Store } from 'src/services/storage'
import { SwitchingTabScope } from './tabs.fg.actions'
import * as IPC from 'src/services/ipc'
import * as Logs from 'src/services/logs'
import { By as SortBy, sort as sortTabs } from 'src/services/tabs.fg.sorting'
import { SetupPage } from './setup-page'

const VALID_SHORTCUT =
Expand Down Expand Up @@ -196,6 +197,34 @@ function onCmd(name: string): void {
else if (name === 'group_tabs_act') onKeyGroupTabs(true)
else if (name === 'flatten_tabs') onKeyFlattenTabs()
else if (name === 'sel_child_tabs') onKeySelChildTabs()
else if (name === 'sort_tabs_by_title_asc') onKeySortTabs(SortBy.Title, 1)
else if (name === 'sort_tabs_by_title_des') onKeySortTabs(SortBy.Title, -1)
else if (name === 'sort_tabs_by_url_asc') onKeySortTabs(SortBy.Url, 1)
else if (name === 'sort_tabs_by_url_des') onKeySortTabs(SortBy.Url, -1)
else if (name === 'sort_tabs_by_time_asc') onKeySortTabs(SortBy.ATime, 1)
else if (name === 'sort_tabs_by_time_des') onKeySortTabs(SortBy.ATime, -1)
else if (name === 'sort_panel_tabs_by_title_asc') onKeySortTabs(SortBy.Title, 1, true, true)
else if (name === 'sort_panel_tabs_by_title_des') onKeySortTabs(SortBy.Title, -1, true, true)
else if (name === 'sort_panel_tabs_by_url_asc') onKeySortTabs(SortBy.Url, 1, true, true)
else if (name === 'sort_panel_tabs_by_url_des') onKeySortTabs(SortBy.Url, -1, true, true)
else if (name === 'sort_panel_tabs_by_time_asc') onKeySortTabs(SortBy.ATime, 1, true, true)
else if (name === 'sort_panel_tabs_by_time_des') onKeySortTabs(SortBy.ATime, -1, true, true)
}

function onKeySortTabs(type: SortBy, dir = 0, tree?: boolean, panel?: boolean) {
if (Tabs.sorting) return
let ids

if (panel) {
const activePanel = Sidebar.panelsById[Sidebar.activePanelId]
if (!Utils.isTabsPanel(activePanel)) return
ids = activePanel.tabs.map(t => t.id)
} else {
ids = Selection.isTabs() ? Selection.get() : [Tabs.activeId]
}
if (!ids.length) return

sortTabs(type, ids, dir, tree)
}

function onKeyScrollToTopBottom(dir: 1 | -1) {
Expand Down
Loading

0 comments on commit 4d30d92

Please sign in to comment.