From 61eb1e80f5514382c2a2ebf403710ab116b9d679 Mon Sep 17 00:00:00 2001 From: plebeius Date: Fri, 13 Feb 2026 14:01:49 +0800 Subject: [PATCH] fix(topbar): sync subscription visibility with account subscriptions Replace per-address visibility tracking with a boolean flag so newly subscribed boards appear immediately in the topbar without requiring a modal reopen. --- .../topbar-edit-modal/topbar-edit-modal.tsx | 19 ++---- src/components/topbar/topbar.tsx | 6 +- src/stores/use-topbar-visibility-store.ts | 64 +++++++++---------- 3 files changed, 40 insertions(+), 49 deletions(-) diff --git a/src/components/topbar-edit-modal/topbar-edit-modal.tsx b/src/components/topbar-edit-modal/topbar-edit-modal.tsx index 2d014da3..b46940d3 100644 --- a/src/components/topbar-edit-modal/topbar-edit-modal.tsx +++ b/src/components/topbar-edit-modal/topbar-edit-modal.tsx @@ -8,7 +8,7 @@ import styles from './topbar-edit-modal.module.css'; const TopbarEditModal = () => { const { showModal, closeTopbarEditModal } = useTopbarEditModalStore(); - const { visibleDirectories, visibleSubscriptions, setDirectoryVisibility, setSubscriptionVisibility } = useTopbarVisibilityStore(); + const { visibleDirectories, showSubscriptionsInTopbar, setDirectoryVisibility, setShowSubscriptionsInTopbar } = useTopbarVisibilityStore(); const account = useAccount(); const subscriptions = useMemo(() => account?.subscriptions || [], [account?.subscriptions]); const location = useLocation(); @@ -37,17 +37,16 @@ const TopbarEditModal = () => { // Local state for text input (will be saved on Save click) // Empty string means all directories visible (default), otherwise show only the specified codes const [localDirectoryInput, setLocalDirectoryInput] = useState(allDirectoriesVisible ? '' : directoriesToString(visibleDirectories)); - // Check if all subscriptions are visible (if any subscription is visible, show subscriptions is checked) - const [showSubscriptions, setShowSubscriptions] = useState(subscriptions.length > 0 && subscriptions.some((addr: string) => visibleSubscriptions.has(addr))); + const [showSubscriptions, setShowSubscriptions] = useState(showSubscriptionsInTopbar); - // Update local state when modal opens or store changes + // Sync local state when modal opens or store changes useEffect(() => { if (showModal) { const allVisible = allBoardCodes.every((code) => visibleDirectories.has(code)); setLocalDirectoryInput(allVisible ? '' : directoriesToString(visibleDirectories)); - setShowSubscriptions(subscriptions.length > 0 && subscriptions.some((addr: string) => visibleSubscriptions.has(addr))); + setShowSubscriptions(showSubscriptionsInTopbar); } - }, [showModal, visibleDirectories, visibleSubscriptions, allBoardCodes, subscriptions]); + }, [showModal, visibleDirectories, showSubscriptionsInTopbar, allBoardCodes]); if (!showModal) { return null; @@ -75,13 +74,7 @@ const TopbarEditModal = () => { }); } - // Apply subscription visibility changes - // If showSubscriptions is checked, make all subscriptions visible - // Otherwise, hide all subscriptions - subscriptions.forEach((address: string) => { - setSubscriptionVisibility(address, showSubscriptions); - }); - + setShowSubscriptionsInTopbar(showSubscriptions); closeTopbarEditModal(); }; diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx index 7527096d..05a7fa4f 100644 --- a/src/components/topbar/topbar.tsx +++ b/src/components/topbar/topbar.tsx @@ -96,7 +96,7 @@ const TopBarDesktop = () => { const { openCreateBoardModal } = useCreateBoardModalStore(); const { openTopbarEditModal } = useTopbarEditModalStore(); const { openDirectoryModal } = useDirectoryModalStore(); - const { visibleDirectories, visibleSubscriptions } = useTopbarVisibilityStore(); + const { visibleDirectories, showSubscriptionsInTopbar } = useTopbarVisibilityStore(); const directories = useDirectories(); // Memoize allBoardCodes since it's derived from a constant @@ -127,8 +127,8 @@ const TopBarDesktop = () => { }, ); - // Filter subscriptions to only show visible ones - const visibleSubscriptionAddresses = subscriptions.filter((address: string) => visibleSubscriptions.has(address)); + // Show all subscriptions when enabled; no separate per-address tracking (avoids drift when subscribing from board-buttons) + const visibleSubscriptionAddresses = showSubscriptionsInTopbar ? subscriptions : []; // Check if any directories are hidden const hasHiddenDirectories = useMemo(() => { diff --git a/src/stores/use-topbar-visibility-store.ts b/src/stores/use-topbar-visibility-store.ts index 3f2acbab..7d05b8fe 100644 --- a/src/stores/use-topbar-visibility-store.ts +++ b/src/stores/use-topbar-visibility-store.ts @@ -7,13 +7,12 @@ const LOCALSTORAGE_KEY_SUBSCRIPTIONS = '5chan-topbar-subscriptions-visible'; interface TopbarVisibilityState { // Directory codes that are visible (all visible by default) visibleDirectories: Set; - // Subscription addresses that are visible in topbar (all hidden by default) - visibleSubscriptions: Set; + // If true, show all account subscriptions in topbar (default: false) + showSubscriptionsInTopbar: boolean; // Actions toggleDirectory: (code: string) => void; - toggleSubscription: (address: string) => void; setDirectoryVisibility: (code: string, visible: boolean) => void; - setSubscriptionVisibility: (address: string, visible: boolean) => void; + setShowSubscriptionsInTopbar: (show: boolean) => void; // Initialize from localStorage initialize: () => void; } @@ -40,15 +39,36 @@ const saveToLocalStorage = (key: string, set: Set) => { } }; +const loadShowSubscriptionsFromStorage = (): boolean => { + try { + const stored = localStorage.getItem(LOCALSTORAGE_KEY_SUBSCRIPTIONS); + if (!stored) return false; + const parsed = JSON.parse(stored); + // Migrate from old format (array of addresses) + if (Array.isArray(parsed)) return parsed.length > 0; + if (typeof parsed === 'boolean') return parsed; + } catch (e) { + console.warn('Failed to load subscriptions visibility from localStorage:', e); + } + return false; +}; + +const saveShowSubscriptionsToStorage = (show: boolean) => { + try { + localStorage.setItem(LOCALSTORAGE_KEY_SUBSCRIPTIONS, JSON.stringify(show)); + } catch (e) { + console.warn('Failed to save subscriptions visibility to localStorage:', e); + } +}; + const useTopbarVisibilityStore = create((set, _get) => { // Initialize with all directories visible by default const allBoardCodes = getAllBoardCodes(); const defaultVisibleDirectories = new Set(allBoardCodes); - const defaultVisibleSubscriptions = new Set(); return { visibleDirectories: loadFromLocalStorage(LOCALSTORAGE_KEY_DIRECTORIES, defaultVisibleDirectories), - visibleSubscriptions: loadFromLocalStorage(LOCALSTORAGE_KEY_SUBSCRIPTIONS, defaultVisibleSubscriptions), + showSubscriptionsInTopbar: loadShowSubscriptionsFromStorage(), toggleDirectory: (code: string) => { set((state) => { @@ -63,19 +83,6 @@ const useTopbarVisibilityStore = create((set, _get) => { }); }, - toggleSubscription: (address: string) => { - set((state) => { - const newSet = new Set(state.visibleSubscriptions); - if (newSet.has(address)) { - newSet.delete(address); - } else { - newSet.add(address); - } - saveToLocalStorage(LOCALSTORAGE_KEY_SUBSCRIPTIONS, newSet); - return { visibleSubscriptions: newSet }; - }); - }, - setDirectoryVisibility: (code: string, visible: boolean) => { set((state) => { const newSet = new Set(state.visibleDirectories); @@ -89,26 +96,17 @@ const useTopbarVisibilityStore = create((set, _get) => { }); }, - setSubscriptionVisibility: (address: string, visible: boolean) => { - set((state) => { - const newSet = new Set(state.visibleSubscriptions); - if (visible) { - newSet.add(address); - } else { - newSet.delete(address); - } - saveToLocalStorage(LOCALSTORAGE_KEY_SUBSCRIPTIONS, newSet); - return { visibleSubscriptions: newSet }; - }); + setShowSubscriptionsInTopbar: (show: boolean) => { + saveShowSubscriptionsToStorage(show); + set({ showSubscriptionsInTopbar: show }); }, initialize: () => { - // Load from localStorage on initialization const directories = loadFromLocalStorage(LOCALSTORAGE_KEY_DIRECTORIES, defaultVisibleDirectories); - const subscriptions = loadFromLocalStorage(LOCALSTORAGE_KEY_SUBSCRIPTIONS, defaultVisibleSubscriptions); + const showSubscriptions = loadShowSubscriptionsFromStorage(); set({ visibleDirectories: directories, - visibleSubscriptions: subscriptions, + showSubscriptionsInTopbar: showSubscriptions, }); }, };