Skip to content

Commit dbee91c

Browse files
committed
feat: in app notifications store
1 parent bbc26b5 commit dbee91c

File tree

8 files changed

+54
-44
lines changed

8 files changed

+54
-44
lines changed

examples/SampleApp/src/components/ToastComponent/Toast.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { Dimensions, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
2-
import { useToastState } from '../../hooks/useToastState';
32
import Animated, { Easing, SlideInDown, SlideOutDown } from 'react-native-reanimated';
43
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
5-
import { useTheme } from 'stream-chat-react-native';
4+
import { useInAppNotificationsState, useTheme } from 'stream-chat-react-native';
65
import type { Notification } from 'stream-chat';
76

87
const { width } = Dimensions.get('window');
@@ -15,7 +14,7 @@ const severityIconMap: Record<Notification['severity'], string> = {
1514
};
1615

1716
export const Toast = () => {
18-
const { closeToast, notifications } = useToastState();
17+
const { closeInAppNotification, notifications } = useInAppNotificationsState();
1918
const { top } = useSafeAreaInsets();
2019
const {
2120
theme: {
@@ -40,7 +39,7 @@ export const Toast = () => {
4039
<View style={styles.content}>
4140
<Text style={[styles.message, { color: white_smoke }]}>{notification.message}</Text>
4241
</View>
43-
<TouchableOpacity onPress={() => closeToast(notification.id)}>
42+
<TouchableOpacity onPress={() => closeInAppNotification(notification.id)}>
4443
<Text style={[styles.close, { color: white_smoke }]}></Text>
4544
</TouchableOpacity>
4645
</Animated.View>
Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import type { Notification } from 'stream-chat';
2-
import { useClientNotifications } from 'stream-chat-react-native';
2+
import { useClientNotifications, useInAppNotificationsState } from 'stream-chat-react-native';
33

44
import { useEffect, useMemo, useRef } from 'react';
5-
import { useToastState } from './useToastState';
65

76
export const usePreviousNotifications = (notifications: Notification[]) => {
87
const prevNotifications = useRef<Notification[]>(notifications);
@@ -16,9 +15,7 @@ export const usePreviousNotifications = (notifications: Notification[]) => {
1615
};
1716
}, [notifications]);
1817

19-
useEffect(() => {
20-
prevNotifications.current = notifications;
21-
}, [notifications]);
18+
prevNotifications.current = notifications;
2219

2320
return difference;
2421
};
@@ -29,11 +26,11 @@ export const usePreviousNotifications = (notifications: Notification[]) => {
2926
*/
3027
export const useClientNotificationsToastHandler = () => {
3128
const { notifications } = useClientNotifications();
32-
const { openToast, closeToast } = useToastState();
29+
const { openInAppNotification, closeInAppNotification } = useInAppNotificationsState();
3330
const { added, removed } = usePreviousNotifications(notifications);
3431

3532
useEffect(() => {
36-
added.forEach(openToast);
37-
removed.forEach((notification) => closeToast(notification.id));
38-
}, [added, closeToast, openToast, removed]);
33+
added.forEach(openInAppNotification);
34+
removed.forEach((notification) => closeInAppNotification(notification.id));
35+
}, [added, closeInAppNotification, openInAppNotification, removed]);
3936
};

examples/SampleApp/src/hooks/useToastState.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

package/src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from './useLoadingImage';
88
export * from './useMessageReminder';
99
export * from './useQueryReminders';
1010
export * from './useClientNotifications';
11+
export * from './useInAppNotificationsState';
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Notification } from 'stream-chat';
2+
3+
import { useStableCallback } from './useStableCallback';
4+
import { useStateStore } from './useStateStore';
5+
6+
import type { InAppNotificationsState } from '../store/in-app-notifications-store';
7+
import {
8+
closeInAppNotification,
9+
inAppNotificationsStore,
10+
openInAppNotification,
11+
} from '../store/in-app-notifications-store';
12+
13+
const selector = ({ notifications }: InAppNotificationsState) => ({
14+
notifications,
15+
});
16+
17+
export const useInAppNotificationsState = () => {
18+
const { notifications } = useStateStore(inAppNotificationsStore, selector);
19+
20+
const openInAppNotificationInternal = useStableCallback((notificationData: Notification) => {
21+
openInAppNotification(notificationData);
22+
});
23+
24+
const closeInAppNotificationInternal = useStableCallback((id: string) => {
25+
closeInAppNotification(id);
26+
});
27+
28+
return {
29+
closeInAppNotification: closeInAppNotificationInternal,
30+
notifications,
31+
openInAppNotification: openInAppNotificationInternal,
32+
};
33+
};

package/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export { default as ptBRTranslations } from './i18n/pt-br.json';
3131
export { default as ruTranslations } from './i18n/ru.json';
3232
export { default as trTranslations } from './i18n/tr.json';
3333

34+
export * from './store';
3435
export { SqliteClient } from './store/SqliteClient';
3536
export { OfflineDB } from './store/OfflineDB';
3637
export { version } from './version.json';
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
import { Notification, StateStore } from 'stream-chat';
22

3-
export type ToastState = {
3+
export type InAppNotificationsState = {
44
notifications: Notification[];
55
};
66

7-
const INITIAL_STATE: ToastState = {
7+
const INITIAL_STATE: InAppNotificationsState = {
88
notifications: [],
99
};
1010

11-
export const toastStore = new StateStore<ToastState>(INITIAL_STATE);
11+
export const inAppNotificationsStore = new StateStore<InAppNotificationsState>(INITIAL_STATE);
1212

13-
export const openToast = (notification: Notification) => {
13+
export const openInAppNotification = (notification: Notification) => {
1414
if (!notification.id) {
1515
console.warn('Notification must have an id to be opened!');
1616
return;
1717
}
18-
const { notifications } = toastStore.getLatestValue();
18+
const { notifications } = inAppNotificationsStore.getLatestValue();
1919

2020
// Prevent duplicate notifications
2121
if (notifications.some((n) => n.id === notification.id)) {
2222
console.warn('Notification with the same id already exists!');
2323
return;
2424
}
2525

26-
toastStore.partialNext({
26+
inAppNotificationsStore.partialNext({
2727
notifications: [...notifications, notification],
2828
});
2929
};
3030

31-
export const closeToast = (id: string) => {
31+
export const closeInAppNotification = (id: string) => {
3232
if (!id) {
3333
console.warn('Notification id is required to be closed!');
3434
return;
3535
}
36-
const { notifications } = toastStore.getLatestValue();
37-
toastStore.partialNext({
36+
const { notifications } = inAppNotificationsStore.getLatestValue();
37+
inAppNotificationsStore.partialNext({
3838
notifications: notifications.filter((notification) => notification.id !== id),
3939
});
4040
};

package/src/store/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './in-app-notifications-store';

0 commit comments

Comments
 (0)