Files
eranos/src/hooks/useFeedTab.ts
T
lemon f68f257234 Replace Ditto feed tab with World feed
- Add useWorldFeed hook combining infinite-scroll pagination with live
  streaming and 'X new posts' buffer/flush pattern
- World feed queries all country-tagged events globally with a diversity
  cap (max 4 posts per country per page)
- Live streaming via persistent relay subscription with scroll-aware
  buffering and highlight animation on flush
- Rename Ditto tab to World across Feed, ContentSettings, and useFeedTab
- Migrate localStorage key from ditto:showDittoFeed to agora:showWorldFeed
2026-04-23 17:02:31 -07:00

48 lines
1.6 KiB
TypeScript

import { useState, useCallback } from 'react';
import { useCurrentUser } from '@/hooks/useCurrentUser';
const STORAGE_PREFIX = 'ditto:feed-tab:';
/**
* Manages the active feed tab for a specific feed page, persisting
* the selection in sessionStorage so it survives navigation within
* the same browser session.
*
* Each feed page should pass a unique `feedId` (e.g. 'home', 'vines', 'videos').
*
* @param feedId Unique identifier for this feed page.
* @param validTabs Optional list of valid tab values for validation. If omitted, any stored value is accepted.
*/
export function useFeedTab<T extends string = string>(
feedId: string,
validTabs?: readonly T[],
): [T, (tab: T) => void] {
const { user } = useCurrentUser();
const key = STORAGE_PREFIX + feedId;
const [activeTab, setActiveTab] = useState<T>(() => {
const defaultTab = (user ? 'follows' : 'world') as T;
try {
const stored = sessionStorage.getItem(key);
if (stored) {
if (!validTabs || validTabs.includes(stored as T)) {
return stored as T;
}
}
} catch { /* sessionStorage unavailable */ }
// Validate the default tab against validTabs. If it's not in the list,
// fall back to the last valid tab (typically 'global').
if (validTabs && !validTabs.includes(defaultTab)) {
return validTabs[validTabs.length - 1];
}
return defaultTab;
});
const setTab = useCallback((tab: T) => {
setActiveTab(tab);
try { sessionStorage.setItem(key, tab); } catch { /* ignore */ }
}, [key]);
return [activeTab, setTab];
}