1
1
import { useSyncExternalStore } from 'use-sync-external-store/shim' ;
2
- import { useContext , useMemo } from 'react' ;
2
+ import { useCallback , useContext , useMemo } from 'react' ;
3
3
import { SendbirdError , User } from '@sendbird/chat' ;
4
4
5
5
import { SendbirdContext } from '../SendbirdContext' ;
@@ -11,27 +11,20 @@ const NO_CONTEXT_ERROR = 'No sendbird state value available. Make sure you are r
11
11
export const useSendbird = ( ) => {
12
12
const store = useContext ( SendbirdContext ) ;
13
13
if ( ! store ) throw new Error ( NO_CONTEXT_ERROR ) ;
14
-
15
14
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 } ) => {
27
19
store . setState ( ( state ) : SendbirdState => (
28
20
updateAppInfoStore ( state , {
29
21
messageTemplatesInfo : payload ,
30
22
waitingTemplateKeysMap : { } ,
31
23
} )
32
24
) ) ;
33
- } ,
34
- upsertMessageTemplates : ( { payload } ) => {
25
+ } , [ store ] ) ,
26
+
27
+ upsertMessageTemplates : useCallback ( ( { payload } ) => {
35
28
const appInfoStore = state . stores . appInfoStore ;
36
29
const templatesInfo = appInfoStore . messageTemplatesInfo ;
37
30
if ( ! templatesInfo ) return state ; // Not initialized. Ignore.
@@ -48,8 +41,9 @@ export const useSendbird = () => {
48
41
messageTemplatesInfo : templatesInfo ,
49
42
} )
50
43
) ) ;
51
- } ,
52
- upsertWaitingTemplateKeys : ( { payload } ) => {
44
+ } , [ store , state . stores . appInfoStore ] ) ,
45
+
46
+ upsertWaitingTemplateKeys : useCallback ( ( { payload } ) => {
53
47
const appInfoStore = state . stores . appInfoStore ;
54
48
const { keys, requestedAt } = payload ;
55
49
const waitingTemplateKeysMap = { ...appInfoStore . waitingTemplateKeysMap } ;
@@ -64,8 +58,9 @@ export const useSendbird = () => {
64
58
waitingTemplateKeysMap,
65
59
} )
66
60
) ) ;
67
- } ,
68
- markErrorWaitingTemplateKeys : ( { payload } ) => {
61
+ } , [ store , state . stores . appInfoStore ] ) ,
62
+
63
+ markErrorWaitingTemplateKeys : useCallback ( ( { payload } ) => {
69
64
const appInfoStore = state . stores . appInfoStore ;
70
65
const { keys, messageId } = payload ;
71
66
const waitingTemplateKeysMap = { ...appInfoStore . waitingTemplateKeysMap } ;
@@ -80,27 +75,31 @@ export const useSendbird = () => {
80
75
waitingTemplateKeysMap,
81
76
} )
82
77
) ) ;
83
- } ,
78
+ } , [ store , state . stores . appInfoStore ] ) ,
79
+ } ;
84
80
85
- /* SDK */
86
- setSdkLoading : ( payload ) => {
81
+ /* SDK */
82
+ const sdkActions = {
83
+ setSdkLoading : useCallback ( ( payload ) => {
87
84
store . setState ( ( state ) : SendbirdState => (
88
85
updateSdkStore ( state , {
89
86
initialized : false ,
90
87
loading : payload ,
91
88
} )
92
89
) ) ;
93
- } ,
94
- sdkError : ( ) => {
90
+ } , [ store ] ) ,
91
+
92
+ sdkError : useCallback ( ( ) => {
95
93
store . setState ( ( state ) : SendbirdState => (
96
94
updateSdkStore ( state , {
97
95
initialized : false ,
98
96
loading : false ,
99
97
error : true ,
100
98
} )
101
99
) ) ;
102
- } ,
103
- initSdk : ( payload ) => {
100
+ } , [ store ] ) ,
101
+
102
+ initSdk : useCallback ( ( payload ) => {
104
103
store . setState ( ( state ) : SendbirdState => (
105
104
updateSdkStore ( state , {
106
105
sdk : payload ,
@@ -109,8 +108,9 @@ export const useSendbird = () => {
109
108
error : false ,
110
109
} )
111
110
) ) ;
112
- } ,
113
- resetSdk : ( ) => {
111
+ } , [ store ] ) ,
112
+
113
+ resetSdk : useCallback ( ( ) => {
114
114
store . setState ( ( state ) : SendbirdState => (
115
115
updateSdkStore ( state , {
116
116
sdk : { } as SdkStore [ 'sdk' ] ,
@@ -119,113 +119,142 @@ export const useSendbird = () => {
119
119
error : false ,
120
120
} )
121
121
) ) ;
122
- } ,
122
+ } , [ store ] ) ,
123
+ } ;
123
124
124
- /* User */
125
- initUser : ( payload ) => {
125
+ /* User */
126
+ const userActions = {
127
+ initUser : useCallback ( ( payload ) => {
126
128
store . setState ( ( state ) : SendbirdState => (
127
129
updateUserStore ( state , {
128
130
initialized : true ,
129
131
loading : false ,
130
132
user : payload ,
131
133
} )
132
134
) ) ;
133
- } ,
134
- resetUser : ( ) => {
135
+ } , [ store ] ) ,
136
+
137
+ resetUser : useCallback ( ( ) => {
135
138
store . setState ( ( state ) : SendbirdState => (
136
139
updateUserStore ( state , {
137
140
initialized : false ,
138
141
loading : false ,
139
142
user : { } as User ,
140
143
} )
141
144
) ) ;
142
- } ,
143
- updateUserInfo : ( payload : User ) => {
145
+ } , [ store ] ) ,
146
+
147
+ updateUserInfo : useCallback ( ( payload : User ) => {
144
148
store . setState ( ( state ) : SendbirdState => (
145
149
updateUserStore ( state , {
146
150
user : payload ,
147
151
} )
148
152
) ) ;
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
+ } ;
180
155
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 ) ;
187
159
188
- actions . setSdkLoading ( true ) ;
160
+ const sdk = state . stores . sdkStore . sdk ;
189
161
190
- try {
191
- const user = await sdk . connect ( userId , accessToken ) ;
192
- actions . initUser ( user ) ;
162
+ if ( sdk ?. disconnectWebSocket ) {
163
+ await sdk . disconnectWebSocket ( ) ;
164
+ }
193
165
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
+ ] ) ;
200
175
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 ;
203
194
204
- actions . initSdk ( sdk ) ;
195
+ // clean up previous ws connection
196
+ await disconnect ( { logger } ) ;
205
197
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
+ } ) ;
217
211
218
- const sdk = state . stores . sdkStore . sdk ;
212
+ sdkActions . setSdkLoading ( true ) ;
219
213
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
+ } ) ;
222
223
}
223
224
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
+ ] ) ;
229
258
230
259
return { state, actions } ;
231
260
} ;
0 commit comments