add room to active thread atom

This commit is contained in:
Ajay Bura 2025-11-03 15:27:02 +05:30
parent 12bcbc2e78
commit 38cc6e6f3a
3 changed files with 139 additions and 3 deletions

View file

@ -8,6 +8,8 @@ import { makeNavToActivePathAtom } from '../../state/navToActivePath';
import { NavToActivePathProvider } from '../../state/hooks/navToActivePath';
import { makeOpenedSidebarFolderAtom } from '../../state/openedSidebarFolder';
import { OpenedSidebarFolderProvider } from '../../state/hooks/openedSidebarFolder';
import { makeRoomToActiveThreadAtom } from '../../state/roomToActiveThread';
import { RoomToActiveThreadProvider } from '../../state/hooks/roomToActiveThread';
type ClientInitStorageAtomProps = {
children: ReactNode;
@ -22,15 +24,19 @@ export function ClientInitStorageAtom({ children }: ClientInitStorageAtomProps)
const navToActivePathAtom = useMemo(() => makeNavToActivePathAtom(userId), [userId]);
const roomToActiveThreadAtom = useMemo(() => makeRoomToActiveThreadAtom(userId), [userId]);
const openedSidebarFolderAtom = useMemo(() => makeOpenedSidebarFolderAtom(userId), [userId]);
return (
<ClosedNavCategoriesProvider value={closedNavCategoriesAtom}>
<ClosedLobbyCategoriesProvider value={closedLobbyCategoriesAtom}>
<NavToActivePathProvider value={navToActivePathAtom}>
<OpenedSidebarFolderProvider value={openedSidebarFolderAtom}>
{children}
</OpenedSidebarFolderProvider>
<RoomToActiveThreadProvider value={roomToActiveThreadAtom}>
<OpenedSidebarFolderProvider value={openedSidebarFolderAtom}>
{children}
</OpenedSidebarFolderProvider>
</RoomToActiveThreadProvider>
</NavToActivePathProvider>
</ClosedLobbyCategoriesProvider>
</ClosedNavCategoriesProvider>

View file

@ -0,0 +1,55 @@
import { createContext, useCallback, useContext } from 'react';
import { useAtomValue, useSetAtom } from 'jotai';
import { RoomToActiveThreadAtom } from '../roomToActiveThread';
const RoomToActiveThreadAtomContext = createContext<RoomToActiveThreadAtom | null>(null);
export const RoomToActiveThreadProvider = RoomToActiveThreadAtomContext.Provider;
export const useRoomToActiveThreadAtom = (): RoomToActiveThreadAtom => {
const anAtom = useContext(RoomToActiveThreadAtomContext);
if (!anAtom) {
throw new Error('RoomToActiveThreadAtom is not provided!');
}
return anAtom;
};
export const useThreadSelector = (roomId: string): ((threadId: string) => void) => {
const roomToActiveThreadAtom = useRoomToActiveThreadAtom();
const setRoomToActiveThread = useSetAtom(roomToActiveThreadAtom);
const onThreadSelect = useCallback(
(threadId: string) => {
setRoomToActiveThread({
type: 'PUT',
roomId,
threadId,
});
},
[roomId, setRoomToActiveThread]
);
return onThreadSelect;
};
export const useActiveThread = (roomId: string): string | undefined => {
const roomToActiveThreadAtom = useRoomToActiveThreadAtom();
const roomToActiveThread = useAtomValue(roomToActiveThreadAtom);
return roomToActiveThread.get(roomId);
};
export const useThreadClose = (roomId: string): (() => void) => {
const roomToActiveThreadAtom = useRoomToActiveThreadAtom();
const setRoomToActiveThread = useSetAtom(roomToActiveThreadAtom);
const closeThread = useCallback(() => {
setRoomToActiveThread({
type: 'DELETE',
roomId,
});
}, [roomId, setRoomToActiveThread]);
return closeThread;
};

View file

@ -0,0 +1,75 @@
import { atom, WritableAtom } from 'jotai';
import produce from 'immer';
import {
atomWithLocalStorage,
getLocalStorageItem,
setLocalStorageItem,
} from './utils/atomWithLocalStorage';
const ROOM_TO_ACTIVE_THREAD = 'roomToActiveThread';
const getStoreKey = (userId: string): string => `${ROOM_TO_ACTIVE_THREAD}${userId}`;
type RoomToActiveThread = Map<string, string>;
type RoomToActiveThreadAction =
| {
type: 'PUT';
roomId: string;
threadId: string;
}
| {
type: 'DELETE';
roomId: string;
};
export type RoomToActiveThreadAtom = WritableAtom<
RoomToActiveThread,
[RoomToActiveThreadAction],
undefined
>;
export const makeRoomToActiveThreadAtom = (userId: string): RoomToActiveThreadAtom => {
const storeKey = getStoreKey(userId);
const baseRoomToActiveThread = atomWithLocalStorage<RoomToActiveThread>(
storeKey,
(key) => {
const obj: Record<string, string> = getLocalStorageItem(key, {});
return new Map(Object.entries(obj));
},
(key, value) => {
const obj: Record<string, string> = Object.fromEntries(value);
setLocalStorageItem(key, obj);
}
);
const navToActivePathAtom = atom<RoomToActiveThread, [RoomToActiveThreadAction], undefined>(
(get) => get(baseRoomToActiveThread),
(get, set, action) => {
if (action.type === 'DELETE') {
set(
baseRoomToActiveThread,
produce(get(baseRoomToActiveThread), (draft) => {
draft.delete(action.roomId);
})
);
return;
}
if (action.type === 'PUT') {
set(
baseRoomToActiveThread,
produce(get(baseRoomToActiveThread), (draft) => {
draft.set(action.roomId, action.threadId);
})
);
}
}
);
return navToActivePathAtom;
};
export const clearRoomToActiveThreadStore = (userId: string) => {
localStorage.removeItem(getStoreKey(userId));
};