Skip to content

Commit 244425a

Browse files
authored
1 parent 5f34d86 commit 244425a

File tree

13 files changed

+431
-306
lines changed

13 files changed

+431
-306
lines changed

src/hooks/useUnmount.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { DependencyList, useLayoutEffect } from 'react';
1+
import { useLayoutEffect, useRef } from 'react';
22

33
// this hook accepts a callback to run component is unmounted
4-
export function useUnmount(callback: () => void, deps: DependencyList = []) {
4+
export function useUnmount(callback: () => void) {
5+
const callbackRef = useRef(callback);
6+
7+
callbackRef.current = callback;
8+
59
useLayoutEffect(() => {
610
return () => {
7-
callback();
11+
callbackRef.current();
812
};
9-
}, deps);
13+
}, []);
1014
}

src/lib/Sendbird/context/SendbirdProvider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ const SendbirdContextManager = ({
125125
// Disconnect on unmount
126126
useUnmount(() => {
127127
actions.disconnect({ logger });
128-
}, [sdkStore]);
128+
});
129129

130130
// should move to reducer
131131
const [currentTheme, setCurrentTheme] = useState(theme);

src/lib/Sendbird/context/hooks/useSendbird.tsx

Lines changed: 133 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useSyncExternalStore } from 'use-sync-external-store/shim';
2-
import { useContext, useMemo } from 'react';
2+
import { useCallback, useContext, useMemo } from 'react';
33
import { SendbirdError, User } from '@sendbird/chat';
44

55
import { SendbirdContext } from '../SendbirdContext';
@@ -11,27 +11,20 @@ const NO_CONTEXT_ERROR = 'No sendbird state value available. Make sure you are r
1111
export const useSendbird = () => {
1212
const store = useContext(SendbirdContext);
1313
if (!store) throw new Error(NO_CONTEXT_ERROR);
14-
1514
const state: SendbirdState = useSyncExternalStore(store.subscribe, store.getState);
16-
const actions = useMemo(() => ({
17-
/* Example: How to set the state basically */
18-
// exampleAction: () => {
19-
// store.setState((state): SendbirdState => ({
20-
// ...state,
21-
// example: true,
22-
// })),
23-
// },
24-
25-
/* AppInfo */
26-
initMessageTemplateInfo: ({ payload }: { payload: MessageTemplatesInfo }) => {
15+
16+
/* AppInfo */
17+
const appInfoActions = {
18+
initMessageTemplateInfo: useCallback(({ payload }: { payload: MessageTemplatesInfo }) => {
2719
store.setState((state): SendbirdState => (
2820
updateAppInfoStore(state, {
2921
messageTemplatesInfo: payload,
3022
waitingTemplateKeysMap: {},
3123
})
3224
));
33-
},
34-
upsertMessageTemplates: ({ payload }) => {
25+
}, [store]),
26+
27+
upsertMessageTemplates: useCallback(({ payload }) => {
3528
const appInfoStore = state.stores.appInfoStore;
3629
const templatesInfo = appInfoStore.messageTemplatesInfo;
3730
if (!templatesInfo) return state; // Not initialized. Ignore.
@@ -48,8 +41,9 @@ export const useSendbird = () => {
4841
messageTemplatesInfo: templatesInfo,
4942
})
5043
));
51-
},
52-
upsertWaitingTemplateKeys: ({ payload }) => {
44+
}, [store, state.stores.appInfoStore]),
45+
46+
upsertWaitingTemplateKeys: useCallback(({ payload }) => {
5347
const appInfoStore = state.stores.appInfoStore;
5448
const { keys, requestedAt } = payload;
5549
const waitingTemplateKeysMap = { ...appInfoStore.waitingTemplateKeysMap };
@@ -64,8 +58,9 @@ export const useSendbird = () => {
6458
waitingTemplateKeysMap,
6559
})
6660
));
67-
},
68-
markErrorWaitingTemplateKeys: ({ payload }) => {
61+
}, [store, state.stores.appInfoStore]),
62+
63+
markErrorWaitingTemplateKeys: useCallback(({ payload }) => {
6964
const appInfoStore = state.stores.appInfoStore;
7065
const { keys, messageId } = payload;
7166
const waitingTemplateKeysMap = { ...appInfoStore.waitingTemplateKeysMap };
@@ -80,27 +75,31 @@ export const useSendbird = () => {
8075
waitingTemplateKeysMap,
8176
})
8277
));
83-
},
78+
}, [store, state.stores.appInfoStore]),
79+
};
8480

85-
/* SDK */
86-
setSdkLoading: (payload) => {
81+
/* SDK */
82+
const sdkActions = {
83+
setSdkLoading: useCallback((payload) => {
8784
store.setState((state): SendbirdState => (
8885
updateSdkStore(state, {
8986
initialized: false,
9087
loading: payload,
9188
})
9289
));
93-
},
94-
sdkError: () => {
90+
}, [store]),
91+
92+
sdkError: useCallback(() => {
9593
store.setState((state): SendbirdState => (
9694
updateSdkStore(state, {
9795
initialized: false,
9896
loading: false,
9997
error: true,
10098
})
10199
));
102-
},
103-
initSdk: (payload) => {
100+
}, [store]),
101+
102+
initSdk: useCallback((payload) => {
104103
store.setState((state): SendbirdState => (
105104
updateSdkStore(state, {
106105
sdk: payload,
@@ -109,8 +108,9 @@ export const useSendbird = () => {
109108
error: false,
110109
})
111110
));
112-
},
113-
resetSdk: () => {
111+
}, [store]),
112+
113+
resetSdk: useCallback(() => {
114114
store.setState((state): SendbirdState => (
115115
updateSdkStore(state, {
116116
sdk: {} as SdkStore['sdk'],
@@ -119,113 +119,142 @@ export const useSendbird = () => {
119119
error: false,
120120
})
121121
));
122-
},
122+
}, [store]),
123+
};
123124

124-
/* User */
125-
initUser: (payload) => {
125+
/* User */
126+
const userActions = {
127+
initUser: useCallback((payload) => {
126128
store.setState((state): SendbirdState => (
127129
updateUserStore(state, {
128130
initialized: true,
129131
loading: false,
130132
user: payload,
131133
})
132134
));
133-
},
134-
resetUser: () => {
135+
}, [store]),
136+
137+
resetUser: useCallback(() => {
135138
store.setState((state): SendbirdState => (
136139
updateUserStore(state, {
137140
initialized: false,
138141
loading: false,
139142
user: {} as User,
140143
})
141144
));
142-
},
143-
updateUserInfo: (payload: User) => {
145+
}, [store]),
146+
147+
updateUserInfo: useCallback((payload: User) => {
144148
store.setState((state): SendbirdState => (
145149
updateUserStore(state, {
146150
user: payload,
147151
})
148152
));
149-
},
150-
151-
/* Connection */
152-
connect: async (params) => {
153-
const {
154-
logger,
155-
userId,
156-
appId,
157-
accessToken,
158-
nickname,
159-
profileUrl,
160-
isMobile,
161-
sdkInitParams,
162-
customApiHost,
163-
customWebSocketHost,
164-
customExtensionParams,
165-
eventHandlers,
166-
initializeMessageTemplatesInfo,
167-
configureSession,
168-
initDashboardConfigs,
169-
} = params;
170-
171-
// clean up previous ws connection
172-
await actions.disconnect({ logger });
173-
174-
const sdk = initSDK({
175-
appId,
176-
customApiHost,
177-
customWebSocketHost,
178-
sdkInitParams,
179-
});
153+
}, [store]),
154+
};
180155

181-
setupSDK(sdk, {
182-
logger,
183-
isMobile,
184-
customExtensionParams,
185-
sessionHandler: configureSession ? configureSession(sdk) : undefined,
186-
});
156+
/* Connection */
157+
const disconnect = useCallback(async ({ logger }: { logger: LoggerInterface }) => {
158+
sdkActions.setSdkLoading(true);
187159

188-
actions.setSdkLoading(true);
160+
const sdk = state.stores.sdkStore.sdk;
189161

190-
try {
191-
const user = await sdk.connect(userId, accessToken);
192-
actions.initUser(user);
162+
if (sdk?.disconnectWebSocket) {
163+
await sdk.disconnectWebSocket();
164+
}
193165

194-
if (nickname || profileUrl) {
195-
await sdk.updateCurrentUserInfo({
196-
nickname: nickname || user.nickname || '',
197-
profileUrl: profileUrl || user.profileUrl,
198-
});
199-
}
166+
sdkActions.resetSdk();
167+
userActions.resetUser();
168+
logger.info?.('SendbirdProvider | useSendbird/disconnect completed');
169+
}, [
170+
store,
171+
state.stores.sdkStore?.sdk,
172+
sdkActions,
173+
userActions,
174+
]);
200175

201-
await initializeMessageTemplatesInfo?.(sdk);
202-
await initDashboardConfigs?.(sdk);
176+
const connect = useCallback(async (params) => {
177+
const {
178+
logger,
179+
userId,
180+
appId,
181+
accessToken,
182+
nickname,
183+
profileUrl,
184+
isMobile,
185+
sdkInitParams,
186+
customApiHost,
187+
customWebSocketHost,
188+
customExtensionParams,
189+
eventHandlers,
190+
initializeMessageTemplatesInfo,
191+
configureSession,
192+
initDashboardConfigs,
193+
} = params;
203194

204-
actions.initSdk(sdk);
195+
// clean up previous ws connection
196+
await disconnect({ logger });
205197

206-
eventHandlers?.connection?.onConnected?.(user);
207-
} catch (error) {
208-
const sendbirdError = error as SendbirdError;
209-
actions.resetSdk();
210-
actions.resetUser();
211-
logger.error?.('SendbirdProvider | useSendbird/connect failed', sendbirdError);
212-
eventHandlers?.connection?.onFailed?.(sendbirdError);
213-
}
214-
},
215-
disconnect: async ({ logger }: { logger: LoggerInterface }) => {
216-
actions.setSdkLoading(true);
198+
const sdk = initSDK({
199+
appId,
200+
customApiHost,
201+
customWebSocketHost,
202+
sdkInitParams,
203+
});
204+
205+
setupSDK(sdk, {
206+
logger,
207+
isMobile,
208+
customExtensionParams,
209+
sessionHandler: configureSession ? configureSession(sdk) : undefined,
210+
});
217211

218-
const sdk = state.stores.sdkStore.sdk;
212+
sdkActions.setSdkLoading(true);
219213

220-
if (sdk?.disconnectWebSocket) {
221-
await sdk.disconnectWebSocket();
214+
try {
215+
const user = await sdk.connect(userId, accessToken);
216+
userActions.initUser(user);
217+
218+
if (nickname || profileUrl) {
219+
await sdk.updateCurrentUserInfo({
220+
nickname: nickname || user.nickname || '',
221+
profileUrl: profileUrl || user.profileUrl,
222+
});
222223
}
223224

224-
actions.resetSdk();
225-
actions.resetUser();
226-
logger.info?.('SendbirdProvider | useSendbird/disconnect completed');
227-
},
228-
}), [store, state.stores.sdkStore?.sdk, state.stores.appInfoStore]);
225+
await initializeMessageTemplatesInfo?.(sdk);
226+
await initDashboardConfigs?.(sdk);
227+
228+
sdkActions.initSdk(sdk);
229+
230+
eventHandlers?.connection?.onConnected?.(user);
231+
} catch (error) {
232+
const sendbirdError = error as SendbirdError;
233+
sdkActions.resetSdk();
234+
userActions.resetUser();
235+
logger.error?.('SendbirdProvider | useSendbird/connect failed', sendbirdError);
236+
eventHandlers?.connection?.onFailed?.(sendbirdError);
237+
}
238+
}, [
239+
store,
240+
sdkActions,
241+
userActions,
242+
disconnect,
243+
]);
244+
245+
const actions = useMemo(() => ({
246+
...appInfoActions,
247+
...sdkActions,
248+
...userActions,
249+
disconnect,
250+
connect,
251+
}), [
252+
appInfoActions,
253+
sdkActions,
254+
userActions,
255+
disconnect,
256+
connect,
257+
]);
229258

230259
return { state, actions };
231260
};

0 commit comments

Comments
 (0)