Skip to content

Commit 8e34d4f

Browse files
authored
Merge pull request #3294 from GetStream/develop
Next Release
2 parents 5fe309e + 53739b8 commit 8e34d4f

File tree

21 files changed

+639
-450
lines changed

21 files changed

+639
-450
lines changed

examples/ExpoMessaging/app.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
"updates": {
1616
"fallbackToCacheTimeout": 0
1717
},
18+
"experiments": {
19+
"reactCompiler": true
20+
},
1821
"assetBundlePatterns": ["**/*"],
1922
"ios": {
2023
"supportsTablet": true,

examples/ExpoMessaging/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,26 @@
1818
"@react-native-firebase/messaging": "^23.4.0",
1919
"@react-navigation/elements": "^2.6.4",
2020
"@react-navigation/native": "^7.1.8",
21-
"@shopify/flash-list": "^2.1.0",
22-
"expo": "54.0.13",
23-
"expo-audio": "~1.0.13",
21+
"@shopify/flash-list": "2.0.2",
22+
"expo": "54.0.22",
23+
"expo-audio": "~1.0.14",
2424
"expo-build-properties": "~1.0.9",
2525
"expo-clipboard": "~8.0.7",
26-
"expo-constants": "~18.0.9",
26+
"expo-constants": "~18.0.10",
2727
"expo-document-picker": "~14.0.7",
2828
"expo-file-system": "~19.0.17",
2929
"expo-haptics": "~15.0.7",
3030
"expo-image-manipulator": "~14.0.7",
3131
"expo-image-picker": "~17.0.8",
3232
"expo-linking": "~8.0.8",
3333
"expo-location": "~19.0.7",
34-
"expo-router": "~6.0.12",
34+
"expo-router": "~6.0.14",
3535
"expo-sharing": "~14.0.7",
3636
"expo-splash-screen": "~31.0.10",
3737
"expo-status-bar": "~3.0.8",
38-
"expo-video": "~3.0.11",
38+
"expo-video": "~3.0.14",
3939
"react": "19.1.0",
40-
"react-native": "0.81.4",
40+
"react-native": "0.81.5",
4141
"react-native-gesture-handler": "~2.28.0",
4242
"react-native-maps": "1.20.1",
4343
"react-native-reanimated": "~4.1.1",

examples/ExpoMessaging/yarn.lock

Lines changed: 263 additions & 321 deletions
Large diffs are not rendered by default.

examples/SampleApp/babel.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
module.exports = {
22
presets: ['module:@react-native/babel-preset'],
3-
plugins: ['react-native-worklets/plugin'],
3+
plugins: ['babel-plugin-react-compiler', 'react-native-worklets/plugin'],
44
};

examples/SampleApp/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"@types/lodash.mergewith": "^4.6.9",
7676
"@types/react": "^19.1.0",
7777
"@types/react-test-renderer": "^19.1.0",
78+
"babel-plugin-react-compiler": "^1.0.0",
7879
"eslint": "^9.28.0",
7980
"eslint-plugin-eslint-comments": "^3.2.0",
8081
"eslint-plugin-jest": "^28.13.3",
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, { useMemo } from 'react';
2+
import BottomSheet, { BottomSheetFlatList } from '@gorhom/bottom-sheet';
3+
import { BottomSheetView } from '@gorhom/bottom-sheet';
4+
import {
5+
Avatar,
6+
useChatContext,
7+
useMessageDeliveredData,
8+
useMessageReadData,
9+
useTheme,
10+
} from 'stream-chat-react-native';
11+
import { LocalMessage, UserResponse } from 'stream-chat';
12+
import { StyleSheet, Text, View } from 'react-native';
13+
14+
const renderUserItem = ({ item }: { item: UserResponse }) => (
15+
<View style={styles.userItem}>
16+
<Avatar image={item.image} name={item.name ?? item.id} size={32} />
17+
<Text style={styles.userName}>{item.name ?? item.id}</Text>
18+
</View>
19+
);
20+
21+
const renderEmptyText = ({ text }: { text: string }) => (
22+
<Text style={styles.emptyText}>{text}</Text>
23+
);
24+
25+
export const MessageInfoBottomSheet = ({
26+
message,
27+
ref,
28+
}: {
29+
message?: LocalMessage;
30+
ref: React.RefObject<BottomSheet | null>;
31+
}) => {
32+
const {
33+
theme: { colors },
34+
} = useTheme();
35+
const { client } = useChatContext();
36+
const deliveredStatus = useMessageDeliveredData({ message });
37+
const readStatus = useMessageReadData({ message });
38+
39+
const otherDeliveredToUsers = useMemo(() => {
40+
return deliveredStatus.filter((user: UserResponse) => user.id !== client?.user?.id);
41+
}, [deliveredStatus, client?.user?.id]);
42+
43+
const otherReadUsers = useMemo(() => {
44+
return readStatus.filter((user: UserResponse) => user.id !== client?.user?.id);
45+
}, [readStatus, client?.user?.id]);
46+
47+
return (
48+
<BottomSheet enablePanDownToClose ref={ref} index={-1} snapPoints={['50%']}>
49+
<BottomSheetView style={[styles.container, { backgroundColor: colors.white_smoke }]}>
50+
<Text style={styles.title}>Read</Text>
51+
<BottomSheetFlatList
52+
data={otherReadUsers}
53+
renderItem={renderUserItem}
54+
keyExtractor={(item) => item.id}
55+
style={styles.flatList}
56+
ListEmptyComponent={renderEmptyText({ text: 'No one has read this message.' })}
57+
/>
58+
<Text style={styles.title}>Delivered</Text>
59+
<BottomSheetFlatList
60+
data={otherDeliveredToUsers}
61+
renderItem={renderUserItem}
62+
keyExtractor={(item) => item.id}
63+
style={styles.flatList}
64+
ListEmptyComponent={renderEmptyText({ text: 'The message was not delivered to anyone.' })}
65+
/>
66+
</BottomSheetView>
67+
</BottomSheet>
68+
);
69+
};
70+
71+
const styles = StyleSheet.create({
72+
container: {
73+
flex: 1,
74+
padding: 24,
75+
justifyContent: 'center',
76+
height: '100%',
77+
},
78+
title: {
79+
fontSize: 16,
80+
fontWeight: 'bold',
81+
marginVertical: 8,
82+
},
83+
flatList: {
84+
borderRadius: 16,
85+
},
86+
userItem: {
87+
flexDirection: 'row',
88+
alignItems: 'center',
89+
padding: 8,
90+
backgroundColor: 'white',
91+
},
92+
userName: {
93+
fontSize: 16,
94+
fontWeight: 'bold',
95+
marginLeft: 16,
96+
},
97+
emptyText: {
98+
fontSize: 16,
99+
marginVertical: 16,
100+
textAlign: 'center',
101+
},
102+
});

examples/SampleApp/src/screens/ChannelScreen.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useEffect, useState } from 'react';
1+
import React, { useCallback, useEffect, useRef, useState } from 'react';
22
import type { LocalMessage, Channel as StreamChatChannel } from 'stream-chat';
33
import { RouteProp, useFocusEffect, useNavigation } from '@react-navigation/native';
44
import {
@@ -33,6 +33,8 @@ import { channelMessageActions } from '../utils/messageActions.tsx';
3333
import { MessageLocation } from '../components/LocationSharing/MessageLocation.tsx';
3434
import { useStreamChatContext } from '../context/StreamChatContext.tsx';
3535
import { CustomAttachmentPickerSelectionBar } from '../components/AttachmentPickerSelectionBar.tsx';
36+
import BottomSheet from '@gorhom/bottom-sheet';
37+
import { MessageInfoBottomSheet } from '../components/MessageInfoBottomSheet.tsx';
3638

3739
export type ChannelScreenNavigationProp = NativeStackNavigationProp<
3840
StackNavigatorParamList,
@@ -115,19 +117,20 @@ const ChannelHeader: React.FC<ChannelHeaderProps> = ({ channel }) => {
115117

116118
// Either provide channel or channelId.
117119
export const ChannelScreen: React.FC<ChannelScreenProps> = ({
120+
navigation,
118121
route: {
119122
params: { channel: channelFromProp, channelId, messageId },
120123
},
121124
}) => {
122125
const { chatClient, messageListImplementation, messageListMode, messageListPruning } =
123126
useAppContext();
124-
const navigation = useNavigation();
125127
const { bottom } = useSafeAreaInsets();
126128
const {
127129
theme: { colors },
128130
} = useTheme();
129131
const { t } = useTranslationContext();
130132
const { setThread } = useStreamChatContext();
133+
const [selectedMessage, setSelectedMessage] = useState<LocalMessage | undefined>(undefined);
131134

132135
const [channel, setChannel] = useState<StreamChatChannel | undefined>(channelFromProp);
133136

@@ -170,6 +173,9 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
170173

171174
const onThreadSelect = useCallback(
172175
(thread: LocalMessage | null) => {
176+
if (!thread || !channel) {
177+
return;
178+
}
173179
setSelectedThread(thread);
174180
setThread(thread);
175181
navigation.navigate('ThreadScreen', {
@@ -180,6 +186,16 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
180186
[channel, navigation, setThread],
181187
);
182188

189+
const messageInfoBottomSheetRef = useRef<BottomSheet>(null);
190+
191+
const handleMessageInfo = useCallback(
192+
(message: LocalMessage) => {
193+
setSelectedMessage(message);
194+
messageInfoBottomSheetRef.current?.snapToIndex(1);
195+
},
196+
[messageInfoBottomSheetRef],
197+
);
198+
183199
const messageActions = useCallback(
184200
(params: MessageActionsParams) => {
185201
if (!chatClient) {
@@ -190,9 +206,10 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
190206
chatClient,
191207
t,
192208
colors,
209+
handleMessageInfo,
193210
});
194211
},
195-
[chatClient, colors, t],
212+
[chatClient, colors, t, handleMessageInfo],
196213
);
197214

198215
if (!channel || !chatClient) {
@@ -232,6 +249,7 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
232249
)}
233250
<AITypingIndicatorView channel={channel} />
234251
<MessageInput />
252+
<MessageInfoBottomSheet message={selectedMessage} ref={messageInfoBottomSheetRef} />
235253
</Channel>
236254
</View>
237255
);

examples/SampleApp/src/utils/messageActions.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import React from 'react';
12
import { Alert } from 'react-native';
2-
import { StreamChat } from 'stream-chat';
3+
import { LocalMessage, StreamChat } from 'stream-chat';
34
import {
45
Colors,
56
Delete,
7+
Eye,
68
messageActions,
79
MessageActionsParams,
810
Time,
@@ -15,11 +17,13 @@ export function channelMessageActions({
1517
chatClient,
1618
colors,
1719
t,
20+
handleMessageInfo,
1821
}: {
1922
params: MessageActionsParams;
2023
chatClient: StreamChat;
2124
t: TranslationContextValue['t'];
2225
colors?: typeof Colors;
26+
handleMessageInfo: (message: LocalMessage) => void;
2327
}) {
2428
const { dismissOverlay, deleteForMeMessage } = params;
2529
const actions = messageActions(params);
@@ -111,5 +115,15 @@ export function channelMessageActions({
111115
title: t('Delete for me'),
112116
});
113117

118+
actions.push({
119+
action: () => {
120+
dismissOverlay();
121+
handleMessageInfo(params.message);
122+
},
123+
actionType: 'messageInfo',
124+
icon: <Eye height={24} width={24} pathFill={colors?.grey} />,
125+
title: 'Message Info',
126+
});
127+
114128
return actions;
115129
}

examples/SampleApp/yarn.lock

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@
355355
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
356356
integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
357357

358+
"@babel/helper-validator-identifier@^7.28.5":
359+
version "7.28.5"
360+
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4"
361+
integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==
362+
358363
"@babel/helper-validator-option@^7.25.9":
359364
version "7.25.9"
360365
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72"
@@ -1033,6 +1038,14 @@
10331038
"@babel/helper-string-parser" "^7.25.9"
10341039
"@babel/helper-validator-identifier" "^7.25.9"
10351040

1041+
"@babel/types@^7.26.0":
1042+
version "7.28.5"
1043+
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b"
1044+
integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==
1045+
dependencies:
1046+
"@babel/helper-string-parser" "^7.27.1"
1047+
"@babel/helper-validator-identifier" "^7.28.5"
1048+
10361049
"@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.27.6":
10371050
version "7.27.6"
10381051
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.6.tgz#a434ca7add514d4e646c80f7375c0aa2befc5535"
@@ -3662,6 +3675,13 @@ babel-plugin-polyfill-regenerator@^0.6.1:
36623675
dependencies:
36633676
"@babel/helper-define-polyfill-provider" "^0.6.3"
36643677

3678+
babel-plugin-react-compiler@^1.0.0:
3679+
version "1.0.0"
3680+
resolved "https://registry.yarnpkg.com/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz#bdf7360a23a4d5ebfca090255da3893efd07425f"
3681+
integrity sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==
3682+
dependencies:
3683+
"@babel/types" "^7.26.0"
3684+
36653685
36663686
version "0.28.1"
36673687
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.28.1.tgz#9e80a774ddb8038307a62316486669c668fb3568"

examples/TypeScriptMessaging/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"devDependencies": {
3939
"@babel/core": "^7.27.4",
4040
"@babel/runtime": "^7.27.6",
41-
"@react-native-community/cli": "19.1.1",
41+
"@react-native-community/cli": "19.1.2",
4242
"@react-native-community/cli-platform-android": "19.1.1",
4343
"@react-native-community/cli-platform-ios": "19.1.1",
4444
"@react-native/babel-preset": "0.80.2",

0 commit comments

Comments
 (0)