Skip to content

Commit eb2ecaa

Browse files
authored
Merge pull request #3206 from GetStream/develop
Next Release
2 parents d39c3de + 1f7e056 commit eb2ecaa

File tree

26 files changed

+470
-102
lines changed

26 files changed

+470
-102
lines changed

examples/ExpoMessaging/yarn.lock

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2963,6 +2963,14 @@ [email protected]:
29632963
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
29642964
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
29652965

2966+
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
2967+
version "1.0.2"
2968+
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
2969+
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
2970+
dependencies:
2971+
es-errors "^1.3.0"
2972+
function-bind "^1.1.2"
2973+
29662974
caller-callsite@^2.0.0:
29672975
version "2.0.0"
29682976
resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
@@ -3418,6 +3426,15 @@ dotenv@^16.4.4, dotenv@~16.4.5:
34183426
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
34193427
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
34203428

3429+
dunder-proto@^1.0.1:
3430+
version "1.0.1"
3431+
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
3432+
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
3433+
dependencies:
3434+
call-bind-apply-helpers "^1.0.1"
3435+
es-errors "^1.3.0"
3436+
gopd "^1.2.0"
3437+
34213438
eastasianwidth@^0.2.0:
34223439
version "0.2.0"
34233440
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
@@ -3507,6 +3524,33 @@ error-stack-parser@^2.0.6:
35073524
dependencies:
35083525
stackframe "^1.3.4"
35093526

3527+
es-define-property@^1.0.1:
3528+
version "1.0.1"
3529+
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
3530+
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
3531+
3532+
es-errors@^1.3.0:
3533+
version "1.3.0"
3534+
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
3535+
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
3536+
3537+
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
3538+
version "1.1.1"
3539+
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
3540+
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
3541+
dependencies:
3542+
es-errors "^1.3.0"
3543+
3544+
es-set-tostringtag@^2.1.0:
3545+
version "2.1.0"
3546+
resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d"
3547+
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
3548+
dependencies:
3549+
es-errors "^1.3.0"
3550+
get-intrinsic "^1.2.6"
3551+
has-tostringtag "^1.0.2"
3552+
hasown "^2.0.2"
3553+
35103554
escalade@^3.1.1:
35113555
version "3.1.1"
35123556
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -3868,6 +3912,17 @@ form-data@^4.0.0:
38683912
combined-stream "^1.0.8"
38693913
mime-types "^2.1.12"
38703914

3915+
form-data@^4.0.4:
3916+
version "4.0.4"
3917+
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
3918+
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
3919+
dependencies:
3920+
asynckit "^0.4.0"
3921+
combined-stream "^1.0.8"
3922+
es-set-tostringtag "^2.1.0"
3923+
hasown "^2.0.2"
3924+
mime-types "^2.1.12"
3925+
38713926
freeport-async@^2.0.0:
38723927
version "2.0.0"
38733928
resolved "https://registry.yarnpkg.com/freeport-async/-/freeport-async-2.0.0.tgz#6adf2ec0c629d11abff92836acd04b399135bab4"
@@ -3908,6 +3963,22 @@ get-caller-file@^2.0.5:
39083963
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
39093964
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
39103965

3966+
get-intrinsic@^1.2.6:
3967+
version "1.3.0"
3968+
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
3969+
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
3970+
dependencies:
3971+
call-bind-apply-helpers "^1.0.2"
3972+
es-define-property "^1.0.1"
3973+
es-errors "^1.3.0"
3974+
es-object-atoms "^1.1.1"
3975+
function-bind "^1.1.2"
3976+
get-proto "^1.0.1"
3977+
gopd "^1.2.0"
3978+
has-symbols "^1.1.0"
3979+
hasown "^2.0.2"
3980+
math-intrinsics "^1.1.0"
3981+
39113982
get-package-type@^0.1.0:
39123983
version "0.1.0"
39133984
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
@@ -3918,6 +3989,14 @@ get-port@^3.2.0:
39183989
resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc"
39193990
integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==
39203991

3992+
get-proto@^1.0.1:
3993+
version "1.0.1"
3994+
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
3995+
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
3996+
dependencies:
3997+
dunder-proto "^1.0.1"
3998+
es-object-atoms "^1.0.0"
3999+
39214000
getenv@^2.0.0:
39224001
version "2.0.0"
39234002
resolved "https://registry.yarnpkg.com/getenv/-/getenv-2.0.0.tgz#b1698c7b0f29588f4577d06c42c73a5b475c69e0"
@@ -3959,6 +4038,11 @@ globals@^11.1.0:
39594038
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
39604039
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
39614040

4041+
gopd@^1.2.0:
4042+
version "1.2.0"
4043+
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
4044+
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
4045+
39624046
graceful-fs@^4.2.4, graceful-fs@^4.2.9:
39634047
version "4.2.11"
39644048
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
@@ -3974,14 +4058,26 @@ has-flag@^4.0.0:
39744058
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
39754059
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
39764060

4061+
has-symbols@^1.0.3, has-symbols@^1.1.0:
4062+
version "1.1.0"
4063+
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
4064+
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
4065+
4066+
has-tostringtag@^1.0.2:
4067+
version "1.0.2"
4068+
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
4069+
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
4070+
dependencies:
4071+
has-symbols "^1.0.3"
4072+
39774073
has@^1.0.3:
39784074
version "1.0.3"
39794075
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
39804076
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
39814077
dependencies:
39824078
function-bind "^1.1.1"
39834079

3984-
hasown@^2.0.0:
4080+
hasown@^2.0.0, hasown@^2.0.2:
39854081
version "2.0.2"
39864082
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
39874083
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
@@ -4520,6 +4616,11 @@ linkifyjs@^4.3.1:
45204616
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.3.1.tgz#1f246ebf4be040002accd1f4535b6af7c7e37898"
45214617
integrity sha512-DRSlB9DKVW04c4SUdGvKK5FR6be45lTU9M76JnngqPeeGDqPwYc0zdUErtsNVMtxPXgUWV4HbXbnC4sNyBxkYg==
45224618

4619+
linkifyjs@^4.3.2:
4620+
version "4.3.2"
4621+
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.3.2.tgz#d97eb45419aabf97ceb4b05a7adeb7b8c8ade2b1"
4622+
integrity sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==
4623+
45234624
locate-path@^5.0.0:
45244625
version "5.0.0"
45254626
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
@@ -4634,6 +4735,11 @@ marky@^1.2.2:
46344735
resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0"
46354736
integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==
46364737

4738+
math-intrinsics@^1.1.0:
4739+
version "1.1.0"
4740+
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
4741+
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
4742+
46374743
46384744
version "2.0.14"
46394745
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
@@ -6078,19 +6184,19 @@ [email protected]:
60786184
version "0.0.0"
60796185
uid ""
60806186

6081-
stream-chat@^9.13.0:
6082-
version "9.13.0"
6083-
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.13.0.tgz#f303921bf5300a4d48f29cc54902579f91e9ee21"
6084-
integrity sha512-sI81k1lNQwBUXx+wuX0jSLrKh5kOZYA/eg8A+VNgC40tF+QWtY0rUsgnprsAPlIwPuYyKxAiZAzGTFWWkZ2qsA==
6187+
stream-chat@^9.17.0:
6188+
version "9.17.0"
6189+
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.17.0.tgz#540cf1ea03b08a394d6140696aae8528e9ba9ce2"
6190+
integrity sha512-ys6K73wIVWs5+qsfPJ9wumEUtgbMXYVbH1dhmAZ1oYtQ01dY/avsvt25PYDakVjKeyrnT+y8T/xEzfeF/WDJsg==
60856191
dependencies:
60866192
"@types/jsonwebtoken" "^9.0.8"
60876193
"@types/ws" "^8.5.14"
60886194
axios "^1.6.0"
60896195
base64-js "^1.5.1"
6090-
form-data "^4.0.0"
6196+
form-data "^4.0.4"
60916197
isomorphic-ws "^5.0.0"
60926198
jsonwebtoken "^9.0.2"
6093-
linkifyjs "^4.2.0"
6199+
linkifyjs "^4.3.2"
60946200
ws "^8.18.1"
60956201

60966202
stream-chat@^9.9.0:

examples/SampleApp/App.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ Geolocation.setRNConfiguration({
5656
});
5757

5858
import type { LocalMessage, StreamChat, TextComposerMiddleware } from 'stream-chat';
59+
import { Toast } from './src/components/ToastComponent/Toast';
60+
import { useClientNotificationsToastHandler } from './src/hooks/useClientNotificationsToastHandler';
5961

6062
init({ data });
6163

@@ -231,6 +233,7 @@ const DrawerNavigatorWrapper: React.FC<{
231233
<AppOverlayProvider>
232234
<UserSearchProvider>
233235
<DrawerNavigator />
236+
<Toast />
234237
</UserSearchProvider>
235238
</AppOverlayProvider>
236239
</StreamChatProvider>
@@ -258,6 +261,7 @@ const UserSelector = () => (
258261
// TODO: Split the stack into multiple stacks - ChannelStack, CreateChannelStack etc.
259262
const HomeScreen = () => {
260263
const { overlay } = useOverlayContext();
264+
useClientNotificationsToastHandler();
261265

262266
return (
263267
<Stack.Navigator
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { Dimensions, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
2+
import Animated, { Easing, SlideInDown, SlideOutDown } from 'react-native-reanimated';
3+
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
4+
import { useInAppNotificationsState, useTheme } from 'stream-chat-react-native';
5+
import type { Notification } from 'stream-chat';
6+
7+
const { width } = Dimensions.get('window');
8+
9+
const severityIconMap: Record<Notification['severity'], string> = {
10+
error: '❌',
11+
success: '✅',
12+
warning: '⚠️',
13+
info: 'ℹ️',
14+
};
15+
16+
export const Toast = () => {
17+
const { closeInAppNotification, notifications } = useInAppNotificationsState();
18+
const { top } = useSafeAreaInsets();
19+
const {
20+
theme: {
21+
colors: { overlay, white_smoke },
22+
},
23+
} = useTheme();
24+
25+
return (
26+
<SafeAreaView style={[styles.container, { top }]} pointerEvents='box-none'>
27+
{notifications.map((notification) => (
28+
<Animated.View
29+
key={notification.id}
30+
entering={SlideInDown.easing(Easing.bezierFn(0.25, 0.1, 0.25, 1.0))}
31+
exiting={SlideOutDown}
32+
style={[styles.toast, { backgroundColor: overlay }]}
33+
>
34+
<View style={[styles.icon, { backgroundColor: overlay }]}>
35+
<Text style={[styles.iconText, { color: white_smoke }]}>
36+
{severityIconMap[notification.severity]}
37+
</Text>
38+
</View>
39+
<View style={styles.content}>
40+
<Text style={[styles.message, { color: white_smoke }]}>{notification.message}</Text>
41+
</View>
42+
<TouchableOpacity onPress={() => closeInAppNotification(notification.id)}>
43+
<Text style={[styles.close, { color: white_smoke }]}></Text>
44+
</TouchableOpacity>
45+
</Animated.View>
46+
))}
47+
</SafeAreaView>
48+
);
49+
};
50+
51+
const styles = StyleSheet.create({
52+
container: {
53+
position: 'absolute',
54+
right: 16,
55+
left: 16,
56+
alignItems: 'flex-end',
57+
},
58+
toast: {
59+
width: width * 0.9,
60+
borderRadius: 12,
61+
padding: 12,
62+
marginBottom: 8,
63+
flexDirection: 'row',
64+
justifyContent: 'space-between',
65+
alignItems: 'center',
66+
shadowColor: '#000',
67+
shadowOpacity: 0.2,
68+
shadowRadius: 4,
69+
elevation: 5,
70+
},
71+
content: {
72+
flex: 1,
73+
marginHorizontal: 8,
74+
},
75+
message: {
76+
fontSize: 14,
77+
fontWeight: '600',
78+
},
79+
close: {
80+
fontSize: 16,
81+
},
82+
icon: {
83+
width: 20,
84+
height: 20,
85+
borderRadius: 12,
86+
justifyContent: 'center',
87+
alignItems: 'center',
88+
},
89+
iconText: {
90+
fontWeight: 'bold',
91+
includeFontPadding: false,
92+
},
93+
warning: {
94+
backgroundColor: 'yellow',
95+
},
96+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { Notification } from 'stream-chat';
2+
import { useClientNotifications, useInAppNotificationsState } from 'stream-chat-react-native';
3+
4+
import { useEffect, useMemo, useRef } from 'react';
5+
6+
export const usePreviousNotifications = (notifications: Notification[]) => {
7+
const prevNotifications = useRef<Notification[]>(notifications);
8+
9+
const difference = useMemo(() => {
10+
const prevIds = new Set(prevNotifications.current.map((notification) => notification.id));
11+
const newIds = new Set(notifications.map((notification) => notification.id));
12+
return {
13+
added: notifications.filter((notification) => !prevIds.has(notification.id)),
14+
removed: prevNotifications.current.filter((notification) => !newIds.has(notification.id)),
15+
};
16+
}, [notifications]);
17+
18+
prevNotifications.current = notifications;
19+
20+
return difference;
21+
};
22+
23+
/**
24+
* This hook is used to open and close the toast notifications when the notifications are added or removed.
25+
* @returns {void}
26+
*/
27+
export const useClientNotificationsToastHandler = () => {
28+
const { notifications } = useClientNotifications();
29+
const { openInAppNotification, closeInAppNotification } = useInAppNotificationsState();
30+
const { added, removed } = usePreviousNotifications(notifications);
31+
32+
useEffect(() => {
33+
added.forEach(openInAppNotification);
34+
removed.forEach((notification) => closeInAppNotification(notification.id));
35+
}, [added, closeInAppNotification, openInAppNotification, removed]);
36+
};

0 commit comments

Comments
 (0)