fix: preserve selections in same-side inactive tabs
clearSelectionsExcept was clearing all tabs including same-side inactive ones, causing users to lose file selections when switching between tabs on the same side. Now only the opposite side's selections are cleared. Also scoped tree selection clearing to only affect opposite-side pane IDs, preventing mounted but hidden SFTP surfaces from losing state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -100,25 +100,25 @@ export const useSftpTabsState = ({
|
||||
|
||||
const clearSelectionsExcept = useCallback(
|
||||
(target: { side: "left" | "right"; tabId: string } | null) => {
|
||||
const clearSideSelections = (
|
||||
prev: SftpSideTabs,
|
||||
side: "left" | "right",
|
||||
): SftpSideTabs => {
|
||||
const clearAllTabs = (prev: SftpSideTabs): SftpSideTabs => {
|
||||
let changed = false;
|
||||
const tabs = prev.tabs.map((tab) => {
|
||||
const shouldKeepSelection =
|
||||
target?.side === side && target.tabId === tab.id;
|
||||
if (shouldKeepSelection || tab.selectedFiles.size === 0) {
|
||||
return tab;
|
||||
}
|
||||
if (tab.selectedFiles.size === 0) return tab;
|
||||
changed = true;
|
||||
return { ...tab, selectedFiles: EMPTY_SELECTION };
|
||||
});
|
||||
return changed ? { ...prev, tabs } : prev;
|
||||
};
|
||||
|
||||
setLeftTabs((prev) => clearSideSelections(prev, "left"));
|
||||
setRightTabs((prev) => clearSideSelections(prev, "right"));
|
||||
// Only clear the opposite side's selections, preserving same-side inactive tabs
|
||||
if (target) {
|
||||
const clearOther = target.side === "left" ? setRightTabs : setLeftTabs;
|
||||
clearOther(clearAllTabs);
|
||||
} else {
|
||||
// No target: clear everything
|
||||
setLeftTabs(clearAllTabs);
|
||||
setRightTabs(clearAllTabs);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
@@ -153,7 +153,9 @@ const SftpSidePanelInner: React.FC<SftpSidePanelProps> = ({
|
||||
const syncFocusedSelection = useCallback((tabId: string | null) => {
|
||||
if (tabId) {
|
||||
sftpRef.current.clearSelectionsExcept({ side: "left", tabId });
|
||||
sftpTreeSelectionStore.clearAllExcept([tabId]);
|
||||
// Keep tree selections for all left-side tabs
|
||||
const keepIds = sftpRef.current.leftTabs.tabs.map(t => t.id);
|
||||
sftpTreeSelectionStore.clearAllExcept(keepIds);
|
||||
return;
|
||||
}
|
||||
sftpRef.current.clearSelectionsExcept(null);
|
||||
|
||||
@@ -146,7 +146,10 @@ const SftpViewInner: React.FC<SftpViewProps> = ({
|
||||
const activeTabId = sftpRef.current.getActiveTabId(side);
|
||||
if (activeTabId) {
|
||||
sftpRef.current.clearSelectionsExcept({ side, tabId: activeTabId });
|
||||
sftpTreeSelectionStore.clearAllExcept([activeTabId]);
|
||||
// Keep tree selections for all same-side tabs, only clear opposite side
|
||||
const sameSideTabs = side === "left" ? sftpRef.current.leftTabs : sftpRef.current.rightTabs;
|
||||
const keepIds = sameSideTabs.tabs.map(t => t.id);
|
||||
sftpTreeSelectionStore.clearAllExcept(keepIds);
|
||||
} else {
|
||||
sftpRef.current.clearSelectionsExcept(null);
|
||||
sftpTreeSelectionStore.clearAllExcept();
|
||||
|
||||
@@ -45,7 +45,11 @@ export const useSftpViewTabs = ({ sftp, sftpRef }: UseSftpViewTabsParams): UseSf
|
||||
const clearOtherPaneSelections = useCallback((target: { side: "left" | "right"; tabId: string } | null) => {
|
||||
sftpRef.current.clearSelectionsExcept(target);
|
||||
if (target) {
|
||||
sftpTreeSelectionStore.clearAllExcept([target.tabId]);
|
||||
// Keep tree selections for all same-side tabs, only clear opposite side
|
||||
const sameSideTabs = target.side === "left"
|
||||
? sftpRef.current.leftTabs : sftpRef.current.rightTabs;
|
||||
const keepIds = sameSideTabs.tabs.map(t => t.id);
|
||||
sftpTreeSelectionStore.clearAllExcept(keepIds);
|
||||
return;
|
||||
}
|
||||
sftpTreeSelectionStore.clearAllExcept();
|
||||
|
||||
Reference in New Issue
Block a user