11import { useSyncExternalStore } from 'use-sync-external-store/shim' ;
2- import { useContext , useMemo } from 'react' ;
2+ import { useCallback , useContext , useMemo } from 'react' ;
33import { SendbirdError , User } from '@sendbird/chat' ;
44
55import { SendbirdContext } from '../SendbirdContext' ;
@@ -11,27 +11,20 @@ const NO_CONTEXT_ERROR = 'No sendbird state value available. Make sure you are r
1111export 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