mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
fix: conversation tab state sync across browser tabs (#11680)
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
This commit is contained in:
parent
1d9cf72e39
commit
e1b283886f
@ -19,8 +19,10 @@ import {
|
|||||||
} from "#/state/conversation-store";
|
} from "#/state/conversation-store";
|
||||||
import { ConversationTabsContextMenu } from "./conversation-tabs-context-menu";
|
import { ConversationTabsContextMenu } from "./conversation-tabs-context-menu";
|
||||||
import { USE_PLANNING_AGENT } from "#/utils/feature-flags";
|
import { USE_PLANNING_AGENT } from "#/utils/feature-flags";
|
||||||
|
import { useConversationId } from "#/hooks/use-conversation-id";
|
||||||
|
|
||||||
export function ConversationTabs() {
|
export function ConversationTabs() {
|
||||||
|
const { conversationId } = useConversationId();
|
||||||
const {
|
const {
|
||||||
selectedTab,
|
selectedTab,
|
||||||
isRightPanelShown,
|
isRightPanelShown,
|
||||||
@ -30,18 +32,21 @@ export function ConversationTabs() {
|
|||||||
|
|
||||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||||
|
|
||||||
// Persist selectedTab and isRightPanelShown in localStorage
|
// Persist selectedTab and isRightPanelShown in localStorage per conversation
|
||||||
const [persistedSelectedTab, setPersistedSelectedTab] =
|
const [persistedSelectedTab, setPersistedSelectedTab] =
|
||||||
useLocalStorage<ConversationTab | null>(
|
useLocalStorage<ConversationTab | null>(
|
||||||
"conversation-selected-tab",
|
`conversation-selected-tab-${conversationId}`,
|
||||||
"editor",
|
"editor",
|
||||||
);
|
);
|
||||||
|
|
||||||
const [persistedIsRightPanelShown, setPersistedIsRightPanelShown] =
|
const [persistedIsRightPanelShown, setPersistedIsRightPanelShown] =
|
||||||
useLocalStorage<boolean>("conversation-right-panel-shown", true);
|
useLocalStorage<boolean>(
|
||||||
|
`conversation-right-panel-shown-${conversationId}`,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
const [persistedUnpinnedTabs] = useLocalStorage<string[]>(
|
const [persistedUnpinnedTabs] = useLocalStorage<string[]>(
|
||||||
"conversation-unpinned-tabs",
|
`conversation-unpinned-tabs-${conversationId}`,
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -61,10 +61,48 @@ interface ConversationActions {
|
|||||||
|
|
||||||
type ConversationStore = ConversationState & ConversationActions;
|
type ConversationStore = ConversationState & ConversationActions;
|
||||||
|
|
||||||
// Helper function to get initial right panel state from localStorage
|
const getConversationIdFromLocation = (): string | null => {
|
||||||
|
if (typeof window === "undefined") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const match = window.location.pathname.match(/\/conversations\/([^/]+)/);
|
||||||
|
return match ? match[1] : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const parseStoredBoolean = (value: string | null): boolean | null => {
|
||||||
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return JSON.parse(value);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const getInitialRightPanelState = (): boolean => {
|
const getInitialRightPanelState = (): boolean => {
|
||||||
const stored = localStorage.getItem("conversation-right-panel-shown");
|
if (typeof window === "undefined") {
|
||||||
return stored !== null ? JSON.parse(stored) : true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const conversationId = getConversationIdFromLocation();
|
||||||
|
const keysToCheck = conversationId
|
||||||
|
? [`conversation-right-panel-shown-${conversationId}`]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
// Fallback to legacy global key for users who haven't switched tabs yet
|
||||||
|
keysToCheck.push("conversation-right-panel-shown");
|
||||||
|
|
||||||
|
for (const key of keysToCheck) {
|
||||||
|
const parsed = parseStoredBoolean(localStorage.getItem(key));
|
||||||
|
if (parsed !== null) {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useConversationStore = create<ConversationStore>()(
|
export const useConversationStore = create<ConversationStore>()(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user