From 0d8541a9374a847b1993af488f6f01951b21a32a Mon Sep 17 00:00:00 2001 From: Erik Brinkman Date: Wed, 14 Oct 2026 12:20:38 -0400 Subject: [PATCH] feat: bulk toggle whole windows --- components/bulk-options.tsx | 85 ++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/components/bulk-options.tsx b/components/bulk-options.tsx index 6ba2c65..6bf1f5d 100644 --- a/components/bulk-options.tsx +++ b/components/bulk-options.tsx @@ -57,21 +57,53 @@ async function listPages(): Promise { return listable(tabs, chrome.runtime.getURL("")); } -/** which window the rows below it are open in */ -function WindowRow({ heading }: { heading: string }): ReactElement { +/** which window the rows below it are open in, and a switch for all of them */ +function WindowRow({ + windowId, + heading, + selected, + total, + running, + onToggle, +}: { + windowId: number; + heading: string; + // how many of the window's convertible tabs are switched on + selected: number; + // how many of its tabs can be converted at all + total: number; + running: boolean; + onToggle: (windowId: number) => void; +}): ReactElement { + const toggle = useCallback(() => { + onToggle(windowId); + }, [onToggle, windowId]); return ( - - {heading} - + + {heading} + + {total ? ( + + ) : null} + ); } @@ -335,6 +367,25 @@ export default function BulkOptions({ }); }, [convertibles]); + const toggleWindow = useCallback( + (windowId: number) => { + change(() => { + const listed = convertibles.filter( + (page) => page.windowId === windowId, + ); + const every = listed.every((page) => panel.selected.has(page.tabId)); + for (const page of listed) { + if (every) { + panel.selected.delete(page.tabId); + } else { + panel.selected.add(page.tabId); + } + } + }); + }, + [convertibles], + ); + const start = useCallback(() => { change(() => { panel.running = chosen.length; @@ -443,7 +494,21 @@ export default function BulkOptions({ )} {windows.map(({ windowId, heading, pages: listed }) => ( - {windows.length > 1 ? : null} + {windows.length > 1 ? ( + + page.convertible && panel.selected.has(page.tabId), + ).length + } + total={listed.filter((page) => page.convertible).length} + running={!!running} + onToggle={toggleWindow} + /> + ) : null} {listed.map((page) => (