From b5c700edee717dcaa8f94a0432e4743fe08faf1f Mon Sep 17 00:00:00 2001 From: the-nelsonator Date: Thu, 28 May 2026 19:20:58 -0700 Subject: [PATCH 1/3] 2129: add 'Unload other tabs' tab menu option --- src/_locales/dict.common.ts | 11 +++++++++ src/page.setup/components/menu-editor.vue | 1 + src/services/menu.fg.options.tabs.ts | 27 +++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/_locales/dict.common.ts b/src/_locales/dict.common.ts index f61e5b34c..9c663e29c 100644 --- a/src/_locales/dict.common.ts +++ b/src/_locales/dict.common.ts @@ -1955,6 +1955,17 @@ export const commonTranslations: Translations = { zh_TW: '卸載分頁', ja: 'アンロード', }, + 'menu.tab.discard_other': { + en: 'Unload other tabs', + de: 'Andere Tabs entladen', + fr: 'Décharger les autres onglets', + hu: 'A többi lap kisöprése', + pl: 'Uśpij inne karty', + ru: 'Выгрузить другие вкладки', + zh_CN: '卸载其他标签页', + zh_TW: '卸載其他分頁', + ja: '他のタブをアンロード', + }, 'menu.tab.edit_title': { en: 'Edit title', de: 'Titel bearbeiten', diff --git a/src/page.setup/components/menu-editor.vue b/src/page.setup/components/menu-editor.vue index f6c858879..8a1525c66 100644 --- a/src/page.setup/components/menu-editor.vue +++ b/src/page.setup/components/menu-editor.vue @@ -174,6 +174,7 @@ const TABS_MENU_OPTS: Record = { mute: 'menu.tab.mute', duplicate: 'menu.tab.duplicate', discard: 'menu.tab.discard', + discardOtherTabs: 'menu.tab.discard_other', dedupeTabs: 'menu.dedupe', copyTabsUrls: 'menu.copy_urls', copyTabsTitles: 'menu.copy_titles', diff --git a/src/services/menu.fg.options.tabs.ts b/src/services/menu.fg.options.tabs.ts index fad4e7e14..a103704a2 100644 --- a/src/services/menu.fg.options.tabs.ts +++ b/src/services/menu.fg.options.tabs.ts @@ -309,6 +309,33 @@ export const tabsMenuOptions: Record MenuOption | MenuOption[] | u return option }, + discardOtherTabs: () => { + const option: MenuOption = { + label: translate('menu.tab.discard_other'), + icon: 'icon_discard', + onClick: () => { + const ids = Selection.ids() + const firstTab = Tabs.byId[ids[0]] + if (!firstTab) return + const panel = Sidebar.panelsById[firstTab.panelId] + if (!Utils.isTabsPanel(panel)) return + const tabIds: ID[] = [] + panel.tabs.forEach(t => !ids.includes(t.id) && tabIds.push(t.id)) + if (tabIds.length) Tabs.discardTabs(tabIds) + }, + } + + const tabId = Selection.getFirst() + const tab = Tabs.byId[tabId] + if (!tab || tab.pinned) option.inactive = true + if (tab) { + const panel = Sidebar.panelsById[tab.panelId] + if (!panel || panel.reactive.len === 1) option.inactive = true + } + if (!Settings.state.ctxMenuRenderInact && option.inactive) return + return option + }, + group: () => { const option: MenuOption = { label: translate('menu.tab.group'), From 33732316206f2bbf8ad966a5b09fa56a55697dcc Mon Sep 17 00:00:00 2001 From: the-nelsonator Date: Thu, 28 May 2026 19:45:50 -0700 Subject: [PATCH 2/3] 2129: cleanup, fix pinned tabs, inactivating when none eligible --- src/services/menu.fg.options.tabs.ts | 32 ++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/services/menu.fg.options.tabs.ts b/src/services/menu.fg.options.tabs.ts index a103704a2..b97270b8d 100644 --- a/src/services/menu.fg.options.tabs.ts +++ b/src/services/menu.fg.options.tabs.ts @@ -310,27 +310,37 @@ export const tabsMenuOptions: Record MenuOption | MenuOption[] | u }, discardOtherTabs: () => { + const getEligibleTabIds = (): ID[] => { + const tabIds: ID[] = [] + const ids = Selection.ids() + const firstTab = Tabs.byId[ids[0]] + if (firstTab) { + const panel = Sidebar.panelsById[firstTab.panelId] + if (Utils.isTabsPanel(panel)) { + panel.tabs.forEach(t => !ids.includes(t.id) && tabIds.push(t.id)) + if (!Settings.state.pinnedNoUnload || !Settings.state.pinnedNoUnloadExplicit) { + panel.pinnedTabs.forEach(t => !ids.includes(t.id) && tabIds.push(t.id)) + } + } + } + return tabIds + } + const option: MenuOption = { label: translate('menu.tab.discard_other'), icon: 'icon_discard', onClick: () => { - const ids = Selection.ids() - const firstTab = Tabs.byId[ids[0]] - if (!firstTab) return - const panel = Sidebar.panelsById[firstTab.panelId] - if (!Utils.isTabsPanel(panel)) return - const tabIds: ID[] = [] - panel.tabs.forEach(t => !ids.includes(t.id) && tabIds.push(t.id)) - if (tabIds.length) Tabs.discardTabs(tabIds) + const tabIds: ID[] = getEligibleTabIds() + if (tabIds.length) Tabs.discardTabs(tabIds, true) }, } const tabId = Selection.getFirst() const tab = Tabs.byId[tabId] - if (!tab || tab.pinned) option.inactive = true - if (tab) { + if (!tab) option.inactive = true + else { const panel = Sidebar.panelsById[tab.panelId] - if (!panel || panel.reactive.len === 1) option.inactive = true + if (!panel || getEligibleTabIds().length === 0) option.inactive = true } if (!Settings.state.ctxMenuRenderInact && option.inactive) return return option From c929bb50207b6c294c9aea5b32f5db328a2219e4 Mon Sep 17 00:00:00 2001 From: the-nelsonator Date: Thu, 28 May 2026 20:32:19 -0700 Subject: [PATCH 3/3] 1633: fix lint fail by removing mock attr --- src/defaults/mocks.tabs.fg.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/defaults/mocks.tabs.fg.ts b/src/defaults/mocks.tabs.fg.ts index fdcd4c31f..9a0854eac 100644 --- a/src/defaults/mocks.tabs.fg.ts +++ b/src/defaults/mocks.tabs.fg.ts @@ -64,7 +64,6 @@ export class MTab implements Tab { branchColor: null, customColor: null, isGroup: false, - preview: false, } sessionData?: TabSessionData | undefined titleEl?: HTMLElement | undefined