Skip to content

Commit 70b11e3

Browse files
feat!: message composer attachment manager integration and improve send flow (#3093)
* chore: modify gh workflows * feat: removal of StreamChatGenerics (#2993) * feat: remove StreamChatGenerics and introduce interface merging * fix: some of the outstanding todos * chore: add default interfaces * chore: remove SCG from sample app * fix: remove redundant types * fix: remove type module * fix: change the way interface declaration is consumed * fix: ignore ts complaints for interface declaration * chore: migrate TypescriptMessagingApp away from SCG * chore: migrate the Expo sample app away from SCG * fix: commit missing files * fix: revert mistaken change * fix: add resolutions for symlinked libs * chore: remove support for react-native-document-picker (#3000) * BREAKING CHANGE: V7 release candidate * chore: add rc channel * fix: typo in branch name * feat: trigger breaking change for v7 (#3005) BREAKING CHANGE: Release V7 * chore: remove dryRun * chore: bump stream-chat version to latest rc * chore: bump stream-chat to latest * feat: introduce expo-video support (#3010) * feat: introduce support for expo-video * fix: remove redundant test * fix: add check for audio component * fix: lint issues * fix: different types inference with latest stream-chat changes * chore(deps): update sample apps too * fix: remove generics from new hook * fix: remove remnants from SCG and fix missing types * fix: lint issues * fix: replace TouchableOpacity with Pressable * fix: move to RN TouchableOpacity instead * chore(deps): update peer deps * chore: remove unused hooks * chore: remove deps scope * fix: all instances of FormatMessageResponse in respect to the new llc changes * chore: ref branch specifically * fix: try clearing cache * fix: remove cache clean * fix: remove console.log * fix: use latest commit * fix: use latest rc of llc * chore: use specific commit again * fix: SCG remnants from merge * fix: lint issues * fix: lint issues * fix: unify file and image types (#3050) * fix: unify file and image types * fix: refine types * fix: remove props from auto complete input * chore: update deps * fix: failing tests and AutoCompleteInput type * chore: update custom data module interfaces * fix: change RNFile to FileReference as per latest client changes (#3061) * fix: merge conflicts * fix: remove MessageType type from the SDK * fix: resolve conflicts from V7 branch * fix: broken tests * fix: useMessageActions remove reserved fields logic * revert: useMessageActions change * fix: confine readBy data to Message Status component * fix: change date separator and group styles to ref * fix: add app changes * feat: use new text composer for RN SDK * fix: bump stream-chat to latest rc * chore: bump stream-chat version to latest rc again * fix: thread messages state not updating properly * chore: change type to inferred one * fix: set correct core lib versions * chore: bump stream-chat to latest rc again * chore: update sample app yarn.locks as well * fix: refine the implementation * fix: add useCallback * fix: keyboard taking full screen issue when the prefer cross-fade transition setting is enabled (#3073) * fix: respect the hasCommand channel prop as well * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled (#3072) * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled * chore: bump stream-chat-js rc again * chore: full reinstall after merge from develop * fix: add back mistakenly removed mime dep * feat: add poll composer * feat: add emoji middleware and make text input better * fix: add channel command middleware * fix: add channel command middleware * fix: remove unused values from message input context * fix: remove unused values from message input context * fix: code clean up * fix: point out a bug with the ban user command * fix: added option reordering fix * fix: improve the emoji and command middleware and cleanup * fix: quoted message state using the message composer * fix: improve poll composer integration * fix: reduce prop surface area from auto complete input * fix: tests * feat: add integration for attachment manager * fix: yarn.lock update * fix: poll composer crash bug * fix: change emoji middleware name * chore: remove workflow changes * feat: move attachment picker context to Channel wrapper and handle only bottom sheet stuff in it * fix: add app refactor * fix: add app refactor * fix: auto complete input changes * refactor: add improvements * refactor: add poll changes * fix: add back react memo * fix: input buttons hasText optimization * fix: improve upload preview components * fix: improve upload preview components * fix: audio attachment issues * chore: resolve conflicts * fix: sync up changes * fix: sync up changes * fix: commands button hastext optimization * fix: create poll options useEffect * fix: comment * fix: default values * fix: try out picker in channel * fix: attachment picker component usage * fix: cleanup for the attachment manager * fix: input button hasText bug * fix: file unsupported types * fix: style for upload unsupported indicator * fix: improve upload new file * fix: send button and audiorecordingbutton re-renders * fix: send button and audiorecordingbutton re-renders * revert: the memo change * fix: remove profiler code * fix: optimize send button performance * fix: type export from audio recording button * fix: iLocalUri utility * fix: update yarn lock * fix: attachment send while offline support is enabled * fix: make sending flow faster and bug free and fix bug with cooldown * fix: edited message usage * fix: attachments draft middleware * fix: make command control middleware better * fix: use text composer for command handling * tests: add tests * tests: add tests * fix: remove thread from MessageInput * perf: messages rerendering on every composer change * perf: remove editing state from channel ctx and add composer ctx * fix: double editing issue * fix: introduce hasText * fix: quoted message edited update bug * fix: quoted message edited update bug * fix: close poll modal before send to avoid reset on the UI * fix: selected picker bug * fix: memoize the photos * fix: performance issue with quoted message checks * fix: further optimize memo checks * perf: separate composer ctxs and optimize usage (#3112) * perf: abstract away composer api and usage * fix: remove props inport and remove comments --------- Co-authored-by: Khushal Agarwal <[email protected]> * fix: change how message composer config is set * perf: make attachbutton better * fix: poll option animation breaking (#3115) * fix: poll option animation breaking * fix: add container animation * chore: remove console.log * fix: revert not needed prop drilling * fix: use draft attachments middlware * fix: image upload preview loading indicator * tests: add tests setup * tests: add tests setup * tests: add more tests * perf: improve the input buttons and command input perf * fix: sample app channel header component perf * fix: remove isCommandUIEnabled from channel context * chore: temporarily comment out commands feature * chore: bump stream-chat to latest * chore: comment out setting up middleware again * fix: send button visibility when async audio off and fixed few tests --------- Co-authored-by: Ivan Sekovanikj <[email protected]> Co-authored-by: Ivan Sekovanikj <[email protected]>
1 parent 5ef5da3 commit 70b11e3

File tree

115 files changed

+4966
-5687
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+4966
-5687
lines changed

examples/SampleApp/App.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DevSettings, LogBox, Platform, useColorScheme } from 'react-native';
33
import { createDrawerNavigator } from '@react-navigation/drawer';
44
import { DarkTheme, DefaultTheme, NavigationContainer } from '@react-navigation/native';
55
import { createStackNavigator } from '@react-navigation/stack';
6-
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
6+
import { SafeAreaProvider } from 'react-native-safe-area-context';
77
import {
88
Chat,
99
OverlayProvider,
@@ -169,12 +169,11 @@ const isMessageAIGenerated = (message: LocalMessage) => !!message.ai_generated;
169169
const DrawerNavigatorWrapper: React.FC<{
170170
chatClient: StreamChat;
171171
}> = ({ chatClient }) => {
172-
const { bottom } = useSafeAreaInsets();
173172
const streamChatTheme = useStreamChatTheme();
174173

175174
return (
176175
<GestureHandlerRootView style={{ flex: 1 }}>
177-
<OverlayProvider bottomInset={bottom} value={{ style: streamChatTheme }}>
176+
<OverlayProvider value={{ style: streamChatTheme }}>
178177
<Chat
179178
client={chatClient}
180179
enableOfflineSupport

examples/SampleApp/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,7 @@ PODS:
14751475
- ReactCommon/turbomodule/bridging
14761476
- ReactCommon/turbomodule/core
14771477
- Yoga
1478-
- react-native-image-picker (8.2.0):
1478+
- react-native-image-picker (8.2.1):
14791479
- DoubleConversion
14801480
- glog
14811481
- hermes-engine
@@ -2581,7 +2581,7 @@ SPEC CHECKSUMS:
25812581
op-sqlite: c33561ea312a2ae38aae032fd3a42635dc6b57e8
25822582
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
25832583
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
2584-
RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809
2584+
RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82
25852585
RCTDeprecation: b2eecf2d60216df56bc5e6be5f063826d3c1ee35
25862586
RCTRequired: 78522de7dc73b81f3ed7890d145fa341f5bb32ea
25872587
RCTTypeSafety: c135dd2bf50402d87fd12884cbad5d5e64850edd
@@ -2615,7 +2615,7 @@ SPEC CHECKSUMS:
26152615
react-native-blob-util: 875bbeee07e4ada135e4edf9fc7b22acf8d9721d
26162616
react-native-cameraroll: cdc91c4c953d1a18aa3ce88b5a25698025c8c4d2
26172617
react-native-document-picker: 19be73c0423e4bc886cef74ec282eff750698013
2618-
react-native-image-picker: 1c620a65f900a47d6d12ec94874c6a1820ebea7d
2618+
react-native-image-picker: 3a03f96b11ef2b727d3d58a7ed009900b0a56a52
26192619
react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac
26202620
react-native-safe-area-context: 0b43456abcaaa3c8323bbfafe9c5f0f9511219d2
26212621
react-native-video: a225b4d4d3286f3253dc7b00a62e7c8e59d04d51

examples/SampleApp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"react-native-fast-image": "^8.6.3",
4646
"react-native-gesture-handler": "^2.24.0",
4747
"react-native-haptic-feedback": "^2.3.3",
48-
"react-native-image-picker": "^8.2.0",
48+
"react-native-image-picker": "^8.2.1",
4949
"react-native-reanimated": "^3.17.1",
5050
"react-native-safe-area-context": "^5.2.0",
5151
"react-native-screens": "^4.9.1",

examples/SampleApp/src/components/ScreenHeader.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import React, { useEffect } from 'react';
1+
import React from 'react';
22
import { StyleProp, StyleSheet, Text, TouchableOpacity, View, ViewStyle } from 'react-native';
33
import { CompositeNavigationProp, useNavigation } from '@react-navigation/native';
44
import { useSafeAreaInsets } from 'react-native-safe-area-context';
5-
import { useAttachmentPickerContext, useTheme } from 'stream-chat-react-native';
5+
import { useTheme } from 'stream-chat-react-native';
66

77
import { ChannelsUnreadCountBadge } from './UnreadCountBadge';
88

@@ -122,13 +122,6 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = (props) => {
122122
},
123123
} = useTheme();
124124
const insets = useSafeAreaInsets();
125-
const { setTopInset } = useAttachmentPickerContext();
126-
127-
useEffect(() => {
128-
if (setTopInset) {
129-
setTopInset(HEADER_CONTENT_HEIGHT + insets.top);
130-
}
131-
}, [insets.top, setTopInset]);
132125

133126
return (
134127
<View

examples/SampleApp/src/screens/ChannelScreen.tsx

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ import {
1919
AITypingIndicatorView,
2020
createTextComposerEmojiMiddleware,
2121
} from 'stream-chat-react-native';
22-
import { Platform, StyleSheet, View } from 'react-native';
22+
import { Platform, Pressable, StyleSheet, View } from 'react-native';
2323
import type { StackNavigationProp } from '@react-navigation/stack';
2424
import { useSafeAreaInsets } from 'react-native-safe-area-context';
2525

2626
import { useAppContext } from '../context/AppContext';
2727
import { ScreenHeader } from '../components/ScreenHeader';
28-
import { TouchableOpacity } from 'react-native-gesture-handler';
2928
import { useChannelMembersStatus } from '../hooks/useChannelMembersStatus';
3029

3130
import type { StackNavigatorParamList } from '../types';
@@ -58,44 +57,51 @@ const ChannelHeader: React.FC<ChannelHeaderProps> = ({ channel }) => {
5857
const navigation = useNavigation<ChannelScreenNavigationProp>();
5958
const typing = useTypingString();
6059

61-
if (!channel || !chatClient) {
62-
return null;
63-
}
64-
6560
const isOneOnOneConversation =
6661
channel &&
6762
Object.values(channel.state.members).length === 2 &&
6863
channel.id?.indexOf('!members-') === 0;
6964

65+
const onBackPress = useCallback(() => {
66+
if (!navigation.canGoBack()) {
67+
// if no previous screen was present in history, go to the list screen
68+
// this can happen when opened through push notification
69+
navigation.reset({ index: 0, routes: [{ name: 'MessagingScreen' }] });
70+
} else {
71+
navigation.goBack();
72+
}
73+
}, [navigation]);
74+
75+
const onRightContentPress = useCallback(() => {
76+
closePicker();
77+
if (isOneOnOneConversation) {
78+
navigation.navigate('OneOnOneChannelDetailScreen', {
79+
channel,
80+
});
81+
} else {
82+
navigation.navigate('GroupChannelDetailsScreen', {
83+
channel,
84+
});
85+
}
86+
}, [channel, closePicker, isOneOnOneConversation, navigation]);
87+
88+
if (!channel || !chatClient) {
89+
return null;
90+
}
91+
7092
return (
7193
<ScreenHeader
72-
onBack={() => {
73-
if (!navigation.canGoBack()) {
74-
// if no previous screen was present in history, go to the list screen
75-
// this can happen when opened through push notification
76-
navigation.reset({ index: 0, routes: [{ name: 'MessagingScreen' }] });
77-
} else {
78-
navigation.goBack();
79-
}
80-
}}
94+
onBack={onBackPress}
8195
// eslint-disable-next-line react/no-unstable-nested-components
8296
RightContent={() => (
83-
<TouchableOpacity
84-
onPress={() => {
85-
closePicker();
86-
if (isOneOnOneConversation) {
87-
navigation.navigate('OneOnOneChannelDetailScreen', {
88-
channel,
89-
});
90-
} else {
91-
navigation.navigate('GroupChannelDetailsScreen', {
92-
channel,
93-
});
94-
}
95-
}}
97+
<Pressable
98+
onPress={onRightContentPress}
99+
style={({ pressed }) => ({
100+
opacity: pressed ? 0.5 : 1,
101+
})}
96102
>
97103
<ChannelAvatar channel={channel} />
98-
</TouchableOpacity>
104+
</Pressable>
99105
)}
100106
showUnreadCountBadge
101107
Subtitle={isOnline ? undefined : NetworkDownIndicator}
@@ -135,7 +141,7 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
135141
if (!newChannel?.initialized) {
136142
await newChannel?.watch();
137143
}
138-
} catch(error) {
144+
} catch (error) {
139145
console.log('An error has occurred while watching the channel: ', error);
140146
}
141147
setChannel(newChannel);

examples/SampleApp/src/screens/ThreadScreen.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
import React, { useEffect } from 'react';
1+
import React from 'react';
22
import { StyleSheet, View } from 'react-native';
33
import { SafeAreaView } from 'react-native-safe-area-context';
4-
import {
5-
Channel,
6-
Thread,
7-
ThreadType,
8-
useAttachmentPickerContext,
9-
useTheme,
10-
useTypingString,
11-
} from 'stream-chat-react-native';
4+
import { Channel, Thread, ThreadType, useTheme, useTypingString } from 'stream-chat-react-native';
125
import { useStateStore } from 'stream-chat-react-native';
136

147
import { ScreenHeader } from '../components/ScreenHeader';
@@ -65,13 +58,6 @@ export const ThreadScreen: React.FC<ThreadScreenProps> = ({
6558
colors: { white },
6659
},
6760
} = useTheme();
68-
const { setSelectedImages } = useAttachmentPickerContext();
69-
70-
useEffect(() => {
71-
setSelectedImages([]);
72-
return () => setSelectedImages([]);
73-
// eslint-disable-next-line react-hooks/exhaustive-deps
74-
}, []);
7561

7662
return (
7763
<SafeAreaView style={[styles.container, { backgroundColor: white }]}>

examples/SampleApp/yarn.lock

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,6 +2862,11 @@
28622862
"@typescript-eslint/types" "8.24.1"
28632863
eslint-visitor-keys "^4.2.0"
28642864

2865+
"@ungap/structured-clone@^1.3.0":
2866+
version "1.3.0"
2867+
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8"
2868+
integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==
2869+
28652870
abort-controller@^3.0.0:
28662871
version "3.0.0"
28672872
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
@@ -3894,7 +3899,7 @@ emoji-mart@^5.6.0:
38943899
resolved "https://registry.yarnpkg.com/emoji-mart/-/emoji-mart-5.6.0.tgz#71b3ed0091d3e8c68487b240d9d6d9a73c27f023"
38953900
integrity sha512-eJp3QRe79pjwa+duv+n7+5YsNhRcMl812EcFVwrnRvYKoNPoQb5qxU8DG6Bgwji0akHdp6D4Ln6tYLG58MFSow==
38963901

3897-
emoji-regex@^10.4.0:
3902+
emoji-regex@^10.3.0, emoji-regex@^10.4.0:
38983903
version "10.4.0"
38993904
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4"
39003905
integrity sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==
@@ -6922,10 +6927,10 @@ react-native-haptic-feedback@^2.3.3:
69226927
resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-2.3.3.tgz#88b6876e91399a69bd1b551fe1681b2f3dc1214e"
69236928
integrity sha512-svS4D5PxfNv8o68m9ahWfwje5NqukM3qLS48+WTdhbDkNUkOhP9rDfDSRHzlhk4zq+ISjyw95EhLeh8NkKX5vQ==
69246929

6925-
react-native-image-picker@^8.2.0:
6926-
version "8.2.0"
6927-
resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-8.2.0.tgz#d8656fdd1a0f1ad262c9c129d4f75900b685e56e"
6928-
integrity sha512-jIGllQJuJIn0YKss/JEeb0Kos1HSsnIpU+i3bYxR27sOxSyDZQyP9dKR22olssQPlfH+rGNR/Jc6xKRkhm48vw==
6930+
react-native-image-picker@^8.2.1:
6931+
version "8.2.1"
6932+
resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-8.2.1.tgz#1ac7826563cbaa5d5298d9f2acc53c69805e5393"
6933+
integrity sha512-FBeGYJGFDjMdGCcyubDJgBAPCQ4L1D3hwLXyUU91jY9ahOZMTbluceVvRmrEKqnDPFJ0gF1NVhJ0nr1nROFLdg==
69296934

69306935
69316936
version "1.1.6"
@@ -7595,9 +7600,9 @@ [email protected]:
75957600
uid ""
75967601

75977602
stream-chat@^9.2.0:
7598-
version "9.2.0"
7599-
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.2.0.tgz#f3109891ca27f17b6fd0aa6ebcf66be12df1f88c"
7600-
integrity sha512-inz3CA5tuqqSrla7qjRTCKs+coRKOYROWf0wEWYgbCu0tAUuiBTRtu1PJL1isEXIaPLiWi00BuRrBEIFon9Kng==
7603+
version "9.3.0"
7604+
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.3.0.tgz#35ca4db9e841eb92d07413ae156de0500ad77b23"
7605+
integrity sha512-S73B3HrvmQvJjq58Zjo50vh74juhsWsVRpT+OBjGAxSGxlA+ITkZ3vKs8Y/r2eDK7mBTMmX5QCruFaDJH5dRuw==
76017606
dependencies:
76027607
"@types/jsonwebtoken" "^9.0.8"
76037608
"@types/ws" "^8.5.14"
@@ -7609,10 +7614,9 @@ stream-chat@^9.2.0:
76097614
linkifyjs "^4.2.0"
76107615
ws "^8.18.1"
76117616

7612-
stream-chat@^9.3.0:
7613-
version "9.3.0"
7614-
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.3.0.tgz#35ca4db9e841eb92d07413ae156de0500ad77b23"
7615-
integrity sha512-S73B3HrvmQvJjq58Zjo50vh74juhsWsVRpT+OBjGAxSGxlA+ITkZ3vKs8Y/r2eDK7mBTMmX5QCruFaDJH5dRuw==
7617+
stream-chat@getstream/stream-chat-js#handle-command-injection:
7618+
version "0.0.0-development"
7619+
resolved "https://codeload.github.com/getstream/stream-chat-js/tar.gz/780c52cfc3cd7379273a9b8db34461fb935f568d"
76167620
dependencies:
76177621
"@types/jsonwebtoken" "^9.0.8"
76187622
"@types/ws" "^8.5.14"
@@ -7624,21 +7628,6 @@ stream-chat@^9.3.0:
76247628
linkifyjs "^4.2.0"
76257629
ws "^8.18.1"
76267630

7627-
stream-chat@^8.57.6:
7628-
version "8.60.0"
7629-
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3"
7630-
integrity sha512-7FpO7Wno++r+n+x9aFuXtGYtNO06CIMd2Bxe3doYZLhMfS0nuaXloeFlGcMT0r4U/6bnguz1qQdDJUPNQAS8bQ==
7631-
dependencies:
7632-
"@babel/runtime" "^7.27.0"
7633-
"@types/jsonwebtoken" "~9.0.0"
7634-
"@types/ws" "^7.4.0"
7635-
axios "^1.6.0"
7636-
base64-js "^1.5.1"
7637-
form-data "^4.0.0"
7638-
isomorphic-ws "^4.0.1"
7639-
jsonwebtoken "~9.0.0"
7640-
ws "^7.5.10"
7641-
76427631
strict-uri-encode@^2.0.0:
76437632
version "2.0.0"
76447633
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"

0 commit comments

Comments
 (0)