Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions src/modules/GroupChannel/context/GroupChannelProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,7 @@ const GroupChannelManager :React.FC<React.PropsWithChildren<GroupChannelProvider
onBackClick?.();
},
onChannelUpdated: (channel) => {
// Note: this shouldn't happen ideally, but it happens on re-rendering GroupChannelManager
// even though the next channel and the current channel are the same.
// So added this condition to check if they are the same to prevent unnecessary calling setCurrentChannel action
if (!state.currentChannel?.isEqual(channel)) {
actions.setCurrentChannel(channel);
}
actions.setCurrentChannel(channel);
},
logger: logger as any,
});
Expand Down
2 changes: 1 addition & 1 deletion src/modules/GroupChannel/context/hooks/useGroupChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export const useGroupChannel = () => {
nicknamesMap: new Map(
channel.members.map(({ userId, nickname }) => [userId, nickname]),
),
}));
}), true);
}, []);

const handleChannelError = useCallback((error: SendbirdError) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const GroupChannelListManager: React.FC<GroupChannelListProviderProps> =
}: GroupChannelListProviderProps) => {
const { state: sendbirdState } = useSendbird();
const { config, stores } = sendbirdState;
const { state } = useGroupChannelList();
const { state, actions } = useGroupChannelList();
const { updateState } = useGroupChannelListStore();
const { sdkStore } = stores;

Expand All @@ -126,6 +126,9 @@ export const GroupChannelListManager: React.FC<GroupChannelListProviderProps> =
if (url === selectedChannelUrl) onChannelSelect(null);
});
},
onChannelsUpdated: () => {
actions.setGroupChannels(groupChannels);
},
});

const { refreshing, initialized, groupChannels, refresh, loadMore } = channelListDataSource;
Expand Down
12 changes: 10 additions & 2 deletions src/modules/GroupChannelList/context/useGroupChannelList.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { useSyncExternalStore } from 'use-sync-external-store/shim';
import { useMemo, useContext } from 'react';
import { useMemo, useContext, useCallback } from 'react';
import { GroupChannelListState, GroupChannelListContext } from './GroupChannelListProvider';

export const useGroupChannelList = () => {
const store = useContext(GroupChannelListContext);
if (!store) throw new Error('useGroupChannelList must be used within a GroupChannelListProvider');

const setGroupChannels = useCallback((channels) => {
store.setState(state => ({
...state,
groupChannels: channels,
}), true);
}, []);

const state: GroupChannelListState = useSyncExternalStore(store.subscribe, store.getState);
const actions = useMemo(() => ({
}), [store]);
setGroupChannels,
}), [setGroupChannels]);

return { state, actions };
};
Expand Down
6 changes: 3 additions & 3 deletions src/utils/storeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import isEqual from 'lodash/isEqual';
// Referrence: https://github.com/pmndrs/zustand
export type Store<T> = {
getState: () => T;
setState: (partial: Partial<T> | ((state: T) => Partial<T>)) => void;
setState: (partial: Partial<T> | ((state: T) => Partial<T>), force?: boolean) => void;
subscribe: (listener: () => void) => () => void;
};

Expand All @@ -30,7 +30,7 @@ export function createStore<T extends object>(initialState: T): Store<T> {
const listeners = new Set<() => void>();
let isUpdating = false;

const setState = (partial: Partial<T> | ((state: T) => Partial<T>)) => {
const setState = (partial: Partial<T> | ((state: T) => Partial<T>), force?: boolean) => {
// Prevent nested updates
if (isUpdating) return;

Expand All @@ -39,7 +39,7 @@ export function createStore<T extends object>(initialState: T): Store<T> {
const nextState = typeof partial === 'function' ? partial(state) : partial;
const hasChanged = hasStateChanged(state, nextState);

if (hasChanged) {
if (force || hasChanged) {
state = { ...state, ...nextState };
listeners.forEach((listener) => listener());
}
Expand Down