Skip to content

Commit 8bb0d05

Browse files
committed
chore: properly initiate APNs connection
1 parent b1b384b commit 8bb0d05

File tree

3 files changed

+116
-38
lines changed

3 files changed

+116
-38
lines changed

examples/SampleApp/src/components/MenuDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export const MenuDrawer = ({ navigation }: DrawerContentComponentProps) => {
102102
</Pressable>
103103
<View style={styles.menuContainer}>
104104
<View>
105-
<SecretMenu visible={secretMenuVisible} close={closeSecretMenu} />
105+
<SecretMenu visible={secretMenuVisible} close={closeSecretMenu} chatClient={chatClient} />
106106
<TouchableOpacity
107107
onPress={() => navigation.navigate('NewDirectMessagingScreen')}
108108
style={styles.menuItem}
Lines changed: 99 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import React from 'react';
1+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
22
import Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
3-
import { LayoutChangeEvent, Text, TouchableOpacity, View } from 'react-native';
4-
import { Close, Notification, useTheme } from 'stream-chat-react-native';
3+
import { LayoutChangeEvent, Text, TouchableOpacity, View, Platform, StyleSheet } from 'react-native';
4+
import { Close, Notification, Check, useTheme } from 'stream-chat-react-native';
55
import { styles as menuDrawerStyles } from './MenuDrawer.tsx';
6+
import AsyncStore from '../utils/AsyncStore.ts';
7+
import { StreamChat } from 'stream-chat';
68

79
export const SlideInView = ({ visible, children }: { visible: boolean; children: React.ReactNode }) => {
810
const animatedHeight = useSharedValue(0);
@@ -26,42 +28,107 @@ export const SlideInView = ({ visible, children }: { visible: boolean; children:
2628
);
2729
};
2830

29-
export const SecretMenu = ({ close, visible }: { close: () => void, visible: boolean }) => {
31+
const isAndroid = Platform.OS === 'android';
32+
33+
export const SecretMenu = ({ close, visible, chatClient }: { close: () => void, visible: boolean, chatClient: StreamChat }) => {
34+
const [selectedProvider, setSelectedProvider] = useState<string | null>(null);
3035
const {
3136
theme: {
3237
colors: { black, grey },
3338
},
3439
} = useTheme();
3540

36-
return <SlideInView visible={visible} >
37-
<TouchableOpacity style={menuDrawerStyles.menuItem}>
38-
<Notification height={24} pathFill={grey} width={24} />
39-
<Text
40-
style={[
41-
menuDrawerStyles.menuTitle,
42-
{
43-
color: black,
44-
},
45-
]}
46-
>
47-
BRUH
48-
</Text>
49-
</TouchableOpacity>
50-
<TouchableOpacity onPress={close} style={menuDrawerStyles.menuItem}>
51-
<Close height={24} pathFill={grey} width={24} />
52-
<Text
41+
const notificationConfigItems = useMemo(() => [{ label: 'Firebase', name: 'rn-fcm', id: 'firebase' }, { label: 'APNs', name: 'APN', id: 'apn' }], []);
42+
43+
useEffect(() => {
44+
const getSelectedProvider = async () => {
45+
const provider = await AsyncStore.getItem('@stream-rn-sampleapp-push-provider', notificationConfigItems[0]);
46+
setSelectedProvider(provider?.id ?? 'firebase');
47+
};
48+
getSelectedProvider();
49+
}, [notificationConfigItems]);
50+
51+
const storeProvider = useCallback(async (item: { label: string, name: string, id: string }) => {
52+
await AsyncStore.setItem('@stream-rn-sampleapp-push-provider', item);
53+
setSelectedProvider(item.id);
54+
}, []);
55+
56+
const removeAllDevices = useCallback(async () => {
57+
const { devices } = await chatClient.getDevices(chatClient.userID);
58+
for (const device of devices ?? []) {
59+
await chatClient.removeDevice(device.id, chatClient.userID);
60+
}
61+
}, [chatClient]);
62+
63+
return (
64+
<SlideInView visible={visible}>
65+
<View
5366
style={[
54-
menuDrawerStyles.menuTitle,
55-
{
56-
color: black,
57-
},
67+
menuDrawerStyles.menuItem,
68+
{ opacity: isAndroid ? 0.3 : 1, alignItems: 'flex-start' },
5869
]}
5970
>
60-
Close
61-
</Text>
62-
</TouchableOpacity>
63-
<View style={menuDrawerStyles.menuItem}>
64-
<View style={{ backgroundColor: grey, height: 1, width: '100%', opacity: 0.2 }}/>
65-
</View>
66-
</SlideInView>;
71+
<Notification height={24} pathFill={grey} width={24} />
72+
<View>
73+
<Text
74+
style={[
75+
menuDrawerStyles.menuTitle,
76+
{
77+
color: black,
78+
marginTop: 4,
79+
},
80+
]}
81+
>
82+
Notification Provider
83+
</Text>
84+
<View style={{ marginLeft: 16 }}>
85+
{notificationConfigItems.map((item) => (
86+
<TouchableOpacity key={item.id} style={{ paddingTop: 8, flexDirection: 'row' }} onPress={() => storeProvider(item)}>
87+
<Text style={styles.notificationItem}>{item.label}</Text>
88+
{item.id === selectedProvider ? <Check height={16} pathFill={'green'} width={16} style={{ marginLeft: 12 }} /> : null}
89+
</TouchableOpacity>
90+
))}
91+
</View>
92+
</View>
93+
</View>
94+
<TouchableOpacity onPress={removeAllDevices} style={menuDrawerStyles.menuItem}>
95+
<Close height={24} pathFill={grey} width={24} />
96+
<Text
97+
style={[
98+
menuDrawerStyles.menuTitle,
99+
{
100+
color: black,
101+
},
102+
]}
103+
>
104+
Remove all devices
105+
</Text>
106+
</TouchableOpacity>
107+
<TouchableOpacity onPress={close} style={menuDrawerStyles.menuItem}>
108+
<Close height={24} pathFill={grey} width={24} />
109+
<Text
110+
style={[
111+
menuDrawerStyles.menuTitle,
112+
{
113+
color: black,
114+
},
115+
]}
116+
>
117+
Close
118+
</Text>
119+
</TouchableOpacity>
120+
<View style={menuDrawerStyles.menuItem}>
121+
<View style={[styles.separator, { backgroundColor: grey }]} />
122+
</View>
123+
</SlideInView>
124+
);
67125
};
126+
127+
export const styles = StyleSheet.create({
128+
separator: { height: 1, width: '100%', opacity: 0.2 },
129+
notificationContainer: {},
130+
notificationItem: {
131+
fontSize: 13,
132+
fontWeight: '500',
133+
},
134+
});

examples/SampleApp/src/hooks/useChatClient.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect, useRef, useState } from 'react';
2-
import { StreamChat } from 'stream-chat';
2+
import { StreamChat, PushProvider } from 'stream-chat';
33
import messaging from '@react-native-firebase/messaging';
44
import notifee from '@notifee/react-native';
55
import { SqliteClient } from 'stream-chat-react-native';
@@ -104,12 +104,19 @@ export const useChatClient = () => {
104104

105105
if (isEnabled) {
106106
// Register FCM token with stream chat server.
107-
const token = await messaging().getToken();
108-
await client.addDevice(token, 'firebase', client.userID, 'rn-fcm');
107+
const firebaseToken = await messaging().getToken();
108+
const apnsToken = await messaging().getAPNSToken();
109+
const provider = await AsyncStore.getItem('@stream-rn-sampleapp-push-provider', { id: 'firebase', name: 'rn-fcm' });
110+
const id = provider?.id ?? 'firebase';
111+
const name = provider?.name ?? 'rn-fcm';
112+
const token = id === 'firebase' ? firebaseToken : apnsToken ?? firebaseToken;
113+
await client.addDevice(token, id as PushProvider, client.userID, name);
109114

110115
// Listen to new FCM tokens and register them with stream chat server.
111-
const unsubscribeTokenRefresh = messaging().onTokenRefresh(async (newToken) => {
112-
await client.addDevice(newToken, 'firebase', client.userID, 'rn-fcm');
116+
const unsubscribeTokenRefresh = messaging().onTokenRefresh(async (newFirebaseToken) => {
117+
const newApnsToken = await messaging().getAPNSToken();
118+
const newToken = id === 'firebase' ? newFirebaseToken : newApnsToken ?? firebaseToken;
119+
await client.addDevice(newToken, id as PushProvider, client.userID, name);
113120
});
114121
// show notifications when on foreground
115122
const unsubscribeForegroundMessageReceive = messaging().onMessage(async (remoteMessage) => {
@@ -153,6 +160,10 @@ export const useChatClient = () => {
153160
};
154161

155162
const switchUser = async (userId?: string) => {
163+
if (chatClient?.userID) {
164+
return;
165+
}
166+
156167
setIsConnecting(true);
157168

158169
try {

0 commit comments

Comments
 (0)