7
7
AppState ,
8
8
AppStateStatus ,
9
9
} from 'react-native' ;
10
-
11
10
import {
12
11
CometChatIncomingCall ,
13
12
CometChatThemeProvider ,
@@ -23,64 +22,87 @@ import RootStackNavigator from './src/navigation/RootStackNavigator';
23
22
import { AppConstants } from './src/utils/AppConstants' ;
24
23
import {
25
24
requestAndroidPermissions ,
25
+ navigateToConversation ,
26
26
} from './src/utils/helper' ;
27
+ import { navigationRef } from './src/navigation/NavigationService' ;
27
28
import AsyncStorage from '@react-native-async-storage/async-storage' ;
28
29
import { useActiveChat } from './src/utils/ActiveChatContext' ;
29
30
31
+ // Listener ID for registering and removing CometChat listeners.
30
32
const listenerId = 'app' ;
31
33
32
34
const App = ( ) : React . ReactElement => {
33
- const { activeChat} = useActiveChat ( ) ;
34
35
const [ callReceived , setCallReceived ] = useState ( false ) ;
35
36
const incomingCall = useRef < CometChat . Call | CometChat . CustomMessage | null > (
36
37
null ,
37
38
) ;
38
39
const [ isInitializing , setIsInitializing ] = useState ( true ) ;
39
40
const [ isLoggedIn , setIsLoggedIn ] = useState ( false ) ;
40
41
const [ userLoggedIn , setUserLoggedIn ] = useState ( false ) ;
42
+ const [ hasValidAppCredentials , setHasValidAppCredentials ] = useState ( false ) ;
41
43
42
44
/**
43
- * 1. Initial CometChat + UIKit Initialization
45
+ * Initialize CometChat UIKit and configure Google Sign-In.
46
+ * Retrieves credentials from AsyncStorage and uses fallback constants if needed.
44
47
*/
45
48
useEffect ( ( ) => {
46
49
async function init ( ) {
47
50
try {
51
+ // Retrieve stored app credentials or default to an empty object.
48
52
const AppData = ( await AsyncStorage . getItem ( 'appCredentials' ) ) || '{}' ;
53
+ const storedCredentials = JSON . parse ( AppData ) ;
54
+
55
+ // Determine the final credentials (from AsyncStorage or AppConstants).
56
+ const finalAppId = storedCredentials . appId || AppConstants . appId ;
57
+ const finalAuthKey = storedCredentials . authKey || AppConstants . authKey ;
58
+ const finalRegion = storedCredentials . region || AppConstants . region ;
59
+
60
+ // Set hasValidAppCredentials based on whether all values are available.
61
+ if ( finalAppId && finalAuthKey && finalRegion ) {
62
+ setHasValidAppCredentials ( true ) ;
63
+ } else {
64
+ setHasValidAppCredentials ( false ) ;
65
+ }
66
+
49
67
await CometChatUIKit . init ( {
50
- appId : JSON . parse ( AppData ) . appId || AppConstants . appId ,
51
- authKey : JSON . parse ( AppData ) . authKey || AppConstants . authKey ,
52
- region : JSON . parse ( AppData ) . region || AppConstants . region ,
68
+ appId : finalAppId ,
69
+ authKey : finalAuthKey ,
70
+ region : finalRegion ,
53
71
subscriptionType : CometChat . AppSettings
54
72
. SUBSCRIPTION_TYPE_ALL_USERS as UIKitSettings [ 'subscriptionType' ] ,
55
73
} ) ;
56
74
75
+ // If a user is already logged in, update the state.
57
76
const loggedInUser = CometChatUIKit . loggedInUser ;
58
77
if ( loggedInUser ) {
59
78
setIsLoggedIn ( true ) ;
60
79
}
80
+
61
81
} catch ( error ) {
62
- console . log ( 'CometChat init or getLoggedinUser failed: ' , error ) ;
82
+ console . log ( 'Error during initialization ' , error ) ;
63
83
} finally {
84
+ // Mark initialization as complete.
64
85
setIsInitializing ( false ) ;
65
86
}
66
87
}
67
88
init ( ) ;
68
89
} , [ ] ) ;
69
90
70
91
/**
71
- * 2. Re-check user & possibly re-init or re-login if app resumes
92
+ * Monitor app state changes to verify the logged-in status and clear notifications.
93
+ * When the app becomes active, it cancels Android notifications and checks the login status.
72
94
*/
73
95
useEffect ( ( ) => {
96
+ if ( Platform . OS === 'android' ) {
97
+ // Request required Android permissions for notifications.
98
+ requestAndroidPermissions ( ) ;
99
+ }
74
100
const handleAppStateChange = async ( nextState : AppStateStatus ) => {
75
101
if ( nextState === 'active' ) {
76
102
try {
77
- // Check if CometChat still has a valid logged in user
103
+ // Verify if there is a valid logged- in user.
78
104
const chatUser = await CometChat . getLoggedinUser ( ) ;
79
- if ( ! chatUser ) {
80
- setIsLoggedIn ( false ) ;
81
- } else {
82
- setIsLoggedIn ( true ) ;
83
- }
105
+ setIsLoggedIn ( ! ! chatUser ) ;
84
106
} catch ( error ) {
85
107
console . log ( 'Error verifying CometChat user on resume:' , error ) ;
86
108
}
@@ -94,19 +116,10 @@ const App = (): React.ReactElement => {
94
116
} , [ ] ) ;
95
117
96
118
/**
97
- * 3. Handle inbound FCM messages in the foreground (Android).
119
+ * Attach CometChat login listener to handle login and logout events.
120
+ * Updates user login status accordingly.
98
121
*/
99
122
useEffect ( ( ) => {
100
- if ( Platform . OS === 'android' ) {
101
- requestAndroidPermissions ( ) ;
102
- }
103
- } , [ activeChat ] ) ;
104
-
105
- /**
106
- * 4. Attach CometChatLogin Listener and Call Listener
107
- */
108
- useEffect ( ( ) => {
109
- // Login Listener
110
123
CometChat . addLoginListener (
111
124
listenerId ,
112
125
new CometChat . LoginListener ( {
@@ -125,55 +138,62 @@ const App = (): React.ReactElement => {
125
138
} ) ,
126
139
) ;
127
140
141
+ // Clean up the login listener on component unmount.
128
142
return ( ) => {
129
- // Clean up CometChat listeners
130
143
CometChat . removeLoginListener ( listenerId ) ;
131
144
} ;
132
145
} , [ ] ) ;
133
146
147
+ /**
148
+ * Attach CometChat call listeners to handle incoming, outgoing, and cancelled call events.
149
+ * Also handles UI events for call end.
150
+ */
134
151
useEffect ( ( ) => {
135
- // Call Listener
152
+ // Listener for call events.
136
153
CometChat . addCallListener (
137
154
listenerId ,
138
155
new CometChat . CallListener ( {
139
156
onIncomingCallReceived : ( call : CometChat . Call ) => {
140
- // Close bottomsheet for incoming call overlay
157
+ // Hide any bottom sheet UI before showing the incoming call screen.
141
158
CometChatUIEventHandler . emitUIEvent (
142
159
CometChatUIEvents . ccToggleBottomSheet ,
143
160
{
144
161
isBottomSheetVisible : false ,
145
162
} ,
146
163
) ;
164
+ // Store the incoming call and update state.
147
165
incomingCall . current = call ;
148
166
setCallReceived ( true ) ;
149
167
} ,
150
168
onOutgoingCallRejected : ( ) => {
169
+ // Clear the call state if outgoing call is rejected.
151
170
incomingCall . current = null ;
152
171
setCallReceived ( false ) ;
153
172
} ,
154
173
onIncomingCallCancelled : ( ) => {
174
+ // Clear the call state if the incoming call is cancelled.
155
175
incomingCall . current = null ;
156
176
setCallReceived ( false ) ;
157
177
} ,
158
178
} ) ,
159
179
) ;
160
180
181
+ // Additional listener to handle call end events.
161
182
CometChatUIEventHandler . addCallListener ( listenerId , {
162
183
ccCallEnded : ( ) => {
163
184
incomingCall . current = null ;
164
185
setCallReceived ( false ) ;
165
186
} ,
166
187
} ) ;
167
188
189
+ // Remove call listeners on cleanup.
168
190
return ( ) => {
169
- // Clean up CometChat listeners
170
191
CometChatUIEventHandler . removeCallListener ( listenerId ) ;
171
192
CometChat . removeCallListener ( listenerId ) ;
172
193
} ;
173
194
} , [ userLoggedIn ] ) ;
174
195
175
-
176
- // Show basic splash or blank screen while initializing
196
+ // Show a blank/splash screen while the app is initializing.
177
197
if ( isInitializing ) {
178
198
return (
179
199
< View
@@ -188,21 +208,26 @@ const App = (): React.ReactElement => {
188
208
) ;
189
209
}
190
210
211
+ // Once initialization is complete, render the main app UI.
191
212
return (
192
213
< SafeAreaProvider >
193
214
< CometChatThemeProvider >
194
- { /* Only show incoming call UI if logged in + we have a call object */ }
215
+ { /* Render the incoming call UI if the user is logged in and a call is received */ }
195
216
{ isLoggedIn && callReceived && incomingCall . current ? (
196
217
< CometChatIncomingCall
197
218
call = { incomingCall . current }
198
219
onDecline = { ( ) => {
220
+ // Handle call decline by clearing the incoming call state.
199
221
incomingCall . current = null ;
200
222
setCallReceived ( false ) ;
201
223
} }
202
224
/>
203
225
) : null }
204
- { /* Pass isLoggedIn to your main stack */ }
205
- < RootStackNavigator isLoggedIn = { isLoggedIn } />
226
+ { /* Render the main navigation stack, passing the login status as a prop */ }
227
+ < RootStackNavigator
228
+ isLoggedIn = { isLoggedIn }
229
+ hasValidAppCredentials = { hasValidAppCredentials }
230
+ />
206
231
</ CometChatThemeProvider >
207
232
</ SafeAreaProvider >
208
233
) ;
0 commit comments