mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
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.
This commit is contained in:
@@ -8,7 +8,7 @@ import styles from './topbar-edit-modal.module.css';
|
|||||||
|
|
||||||
const TopbarEditModal = () => {
|
const TopbarEditModal = () => {
|
||||||
const { showModal, closeTopbarEditModal } = useTopbarEditModalStore();
|
const { showModal, closeTopbarEditModal } = useTopbarEditModalStore();
|
||||||
const { visibleDirectories, visibleSubscriptions, setDirectoryVisibility, setSubscriptionVisibility } = useTopbarVisibilityStore();
|
const { visibleDirectories, showSubscriptionsInTopbar, setDirectoryVisibility, setShowSubscriptionsInTopbar } = useTopbarVisibilityStore();
|
||||||
const account = useAccount();
|
const account = useAccount();
|
||||||
const subscriptions = useMemo(() => account?.subscriptions || [], [account?.subscriptions]);
|
const subscriptions = useMemo(() => account?.subscriptions || [], [account?.subscriptions]);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -37,17 +37,16 @@ const TopbarEditModal = () => {
|
|||||||
// Local state for text input (will be saved on Save click)
|
// Local state for text input (will be saved on Save click)
|
||||||
// Empty string means all directories visible (default), otherwise show only the specified codes
|
// Empty string means all directories visible (default), otherwise show only the specified codes
|
||||||
const [localDirectoryInput, setLocalDirectoryInput] = useState<string>(allDirectoriesVisible ? '' : directoriesToString(visibleDirectories));
|
const [localDirectoryInput, setLocalDirectoryInput] = useState<string>(allDirectoriesVisible ? '' : directoriesToString(visibleDirectories));
|
||||||
// Check if all subscriptions are visible (if any subscription is visible, show subscriptions is checked)
|
const [showSubscriptions, setShowSubscriptions] = useState<boolean>(showSubscriptionsInTopbar);
|
||||||
const [showSubscriptions, setShowSubscriptions] = useState<boolean>(subscriptions.length > 0 && subscriptions.some((addr: string) => visibleSubscriptions.has(addr)));
|
|
||||||
|
|
||||||
// Update local state when modal opens or store changes
|
// Sync local state when modal opens or store changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showModal) {
|
if (showModal) {
|
||||||
const allVisible = allBoardCodes.every((code) => visibleDirectories.has(code));
|
const allVisible = allBoardCodes.every((code) => visibleDirectories.has(code));
|
||||||
setLocalDirectoryInput(allVisible ? '' : directoriesToString(visibleDirectories));
|
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) {
|
if (!showModal) {
|
||||||
return null;
|
return null;
|
||||||
@@ -75,13 +74,7 @@ const TopbarEditModal = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply subscription visibility changes
|
setShowSubscriptionsInTopbar(showSubscriptions);
|
||||||
// If showSubscriptions is checked, make all subscriptions visible
|
|
||||||
// Otherwise, hide all subscriptions
|
|
||||||
subscriptions.forEach((address: string) => {
|
|
||||||
setSubscriptionVisibility(address, showSubscriptions);
|
|
||||||
});
|
|
||||||
|
|
||||||
closeTopbarEditModal();
|
closeTopbarEditModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ const TopBarDesktop = () => {
|
|||||||
const { openCreateBoardModal } = useCreateBoardModalStore();
|
const { openCreateBoardModal } = useCreateBoardModalStore();
|
||||||
const { openTopbarEditModal } = useTopbarEditModalStore();
|
const { openTopbarEditModal } = useTopbarEditModalStore();
|
||||||
const { openDirectoryModal } = useDirectoryModalStore();
|
const { openDirectoryModal } = useDirectoryModalStore();
|
||||||
const { visibleDirectories, visibleSubscriptions } = useTopbarVisibilityStore();
|
const { visibleDirectories, showSubscriptionsInTopbar } = useTopbarVisibilityStore();
|
||||||
const directories = useDirectories();
|
const directories = useDirectories();
|
||||||
|
|
||||||
// Memoize allBoardCodes since it's derived from a constant
|
// Memoize allBoardCodes since it's derived from a constant
|
||||||
@@ -127,8 +127,8 @@ const TopBarDesktop = () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Filter subscriptions to only show visible ones
|
// Show all subscriptions when enabled; no separate per-address tracking (avoids drift when subscribing from board-buttons)
|
||||||
const visibleSubscriptionAddresses = subscriptions.filter((address: string) => visibleSubscriptions.has(address));
|
const visibleSubscriptionAddresses = showSubscriptionsInTopbar ? subscriptions : [];
|
||||||
|
|
||||||
// Check if any directories are hidden
|
// Check if any directories are hidden
|
||||||
const hasHiddenDirectories = useMemo(() => {
|
const hasHiddenDirectories = useMemo(() => {
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ const LOCALSTORAGE_KEY_SUBSCRIPTIONS = '5chan-topbar-subscriptions-visible';
|
|||||||
interface TopbarVisibilityState {
|
interface TopbarVisibilityState {
|
||||||
// Directory codes that are visible (all visible by default)
|
// Directory codes that are visible (all visible by default)
|
||||||
visibleDirectories: Set<string>;
|
visibleDirectories: Set<string>;
|
||||||
// Subscription addresses that are visible in topbar (all hidden by default)
|
// If true, show all account subscriptions in topbar (default: false)
|
||||||
visibleSubscriptions: Set<string>;
|
showSubscriptionsInTopbar: boolean;
|
||||||
// Actions
|
// Actions
|
||||||
toggleDirectory: (code: string) => void;
|
toggleDirectory: (code: string) => void;
|
||||||
toggleSubscription: (address: string) => void;
|
|
||||||
setDirectoryVisibility: (code: string, visible: boolean) => void;
|
setDirectoryVisibility: (code: string, visible: boolean) => void;
|
||||||
setSubscriptionVisibility: (address: string, visible: boolean) => void;
|
setShowSubscriptionsInTopbar: (show: boolean) => void;
|
||||||
// Initialize from localStorage
|
// Initialize from localStorage
|
||||||
initialize: () => void;
|
initialize: () => void;
|
||||||
}
|
}
|
||||||
@@ -40,15 +39,36 @@ const saveToLocalStorage = (key: string, set: Set<string>) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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<TopbarVisibilityState>((set, _get) => {
|
const useTopbarVisibilityStore = create<TopbarVisibilityState>((set, _get) => {
|
||||||
// Initialize with all directories visible by default
|
// Initialize with all directories visible by default
|
||||||
const allBoardCodes = getAllBoardCodes();
|
const allBoardCodes = getAllBoardCodes();
|
||||||
const defaultVisibleDirectories = new Set(allBoardCodes);
|
const defaultVisibleDirectories = new Set(allBoardCodes);
|
||||||
const defaultVisibleSubscriptions = new Set<string>();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visibleDirectories: loadFromLocalStorage(LOCALSTORAGE_KEY_DIRECTORIES, defaultVisibleDirectories),
|
visibleDirectories: loadFromLocalStorage(LOCALSTORAGE_KEY_DIRECTORIES, defaultVisibleDirectories),
|
||||||
visibleSubscriptions: loadFromLocalStorage(LOCALSTORAGE_KEY_SUBSCRIPTIONS, defaultVisibleSubscriptions),
|
showSubscriptionsInTopbar: loadShowSubscriptionsFromStorage(),
|
||||||
|
|
||||||
toggleDirectory: (code: string) => {
|
toggleDirectory: (code: string) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
@@ -63,19 +83,6 @@ const useTopbarVisibilityStore = create<TopbarVisibilityState>((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) => {
|
setDirectoryVisibility: (code: string, visible: boolean) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const newSet = new Set(state.visibleDirectories);
|
const newSet = new Set(state.visibleDirectories);
|
||||||
@@ -89,26 +96,17 @@ const useTopbarVisibilityStore = create<TopbarVisibilityState>((set, _get) => {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setSubscriptionVisibility: (address: string, visible: boolean) => {
|
setShowSubscriptionsInTopbar: (show: boolean) => {
|
||||||
set((state) => {
|
saveShowSubscriptionsToStorage(show);
|
||||||
const newSet = new Set(state.visibleSubscriptions);
|
set({ showSubscriptionsInTopbar: show });
|
||||||
if (visible) {
|
|
||||||
newSet.add(address);
|
|
||||||
} else {
|
|
||||||
newSet.delete(address);
|
|
||||||
}
|
|
||||||
saveToLocalStorage(LOCALSTORAGE_KEY_SUBSCRIPTIONS, newSet);
|
|
||||||
return { visibleSubscriptions: newSet };
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: () => {
|
initialize: () => {
|
||||||
// Load from localStorage on initialization
|
|
||||||
const directories = loadFromLocalStorage(LOCALSTORAGE_KEY_DIRECTORIES, defaultVisibleDirectories);
|
const directories = loadFromLocalStorage(LOCALSTORAGE_KEY_DIRECTORIES, defaultVisibleDirectories);
|
||||||
const subscriptions = loadFromLocalStorage(LOCALSTORAGE_KEY_SUBSCRIPTIONS, defaultVisibleSubscriptions);
|
const showSubscriptions = loadShowSubscriptionsFromStorage();
|
||||||
set({
|
set({
|
||||||
visibleDirectories: directories,
|
visibleDirectories: directories,
|
||||||
visibleSubscriptions: subscriptions,
|
showSubscriptionsInTopbar: showSubscriptions,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user