Skip to content

Commit 3b9189d

Browse files
authored
Merge pull request #2914 from GetStream/develop
Next Release
2 parents f3b8efe + 6657138 commit 3b9189d

File tree

39 files changed

+1341
-422
lines changed

39 files changed

+1341
-422
lines changed

examples/ExpoMessaging/yarn.lock

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7313,6 +7313,21 @@ [email protected]:
73137313
jsonwebtoken "~9.0.0"
73147314
ws "^7.5.10"
73157315

7316+
stream-chat@^8.50.0:
7317+
version "8.52.0"
7318+
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.52.0.tgz#7cb477433d0eb3d7351852f76b3838f5ce0af000"
7319+
integrity sha512-u5M9z4m8O0tB82XTQMkOvLp5+OJg6al8k8/sXQaDx1tMCTMnRWzCIXtRXKjBCWIftwB/4SuPV72+Zy9r/zJMng==
7320+
dependencies:
7321+
"@babel/runtime" "^7.16.3"
7322+
"@types/jsonwebtoken" "~9.0.0"
7323+
"@types/ws" "^7.4.0"
7324+
axios "^1.6.0"
7325+
base64-js "^1.5.1"
7326+
form-data "^4.0.0"
7327+
isomorphic-ws "^4.0.1"
7328+
jsonwebtoken "~9.0.0"
7329+
ws "^7.5.10"
7330+
73167331
stream-slice@^0.1.2:
73177332
version "0.1.2"
73187333
resolved "https://registry.yarnpkg.com/stream-slice/-/stream-slice-0.1.2.tgz#2dc4f4e1b936fb13f3eb39a2def1932798d07a4b"
@@ -7765,6 +7780,11 @@ use-sync-external-store@^1.2.2:
77657780
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz#c3b6390f3a30eba13200d2302dcdf1e7b57b2ef9"
77667781
integrity sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==
77677782

7783+
use-sync-external-store@^1.4.0:
7784+
version "1.4.0"
7785+
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc"
7786+
integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==
7787+
77687788
util-deprecate@~1.0.1:
77697789
version "1.0.2"
77707790
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"

examples/SampleApp/src/components/ChannelInfoOverlay.tsx

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import {
3333
import { useAppOverlayContext } from '../context/AppOverlayContext';
3434
import { useBottomSheetOverlayContext } from '../context/BottomSheetOverlayContext';
3535
import { useChannelInfoOverlayContext } from '../context/ChannelInfoOverlayContext';
36+
import { Archive } from '../icons/Archive';
37+
import { Pin } from '../icons/Pin';
3638

3739
dayjs.extend(relativeTime);
3840

@@ -111,7 +113,7 @@ export const ChannelInfoOverlay = (props: ChannelInfoOverlayProps) => {
111113
const halfScreenHeight = vh(50);
112114
const width = vw(100) - 60;
113115

114-
const { channel, clientId, navigation } = data || {};
116+
const { channel, clientId, membership, navigation } = data || {};
115117

116118
const {
117119
theme: {
@@ -361,6 +363,73 @@ export const ChannelInfoOverlay = (props: ChannelInfoOverlayProps) => {
361363
<Text style={[styles.rowText, { color: black }]}>View info</Text>
362364
</View>
363365
</TapGestureHandler>
366+
<TapGestureHandler
367+
onHandlerStateChange={async ({ nativeEvent: { state } }) => {
368+
if (state === State.END) {
369+
try {
370+
if (membership?.pinned_at) {
371+
await channel.unpin();
372+
} else {
373+
await channel.pin();
374+
}
375+
} catch (error) {
376+
console.log('Error pinning/unpinning channel', error);
377+
}
378+
379+
setOverlay('none');
380+
}
381+
}}
382+
>
383+
<View
384+
style={[
385+
styles.row,
386+
{
387+
borderTopColor: border,
388+
},
389+
]}
390+
>
391+
<View style={styles.rowInner}>
392+
<Pin height={24} width={24} />
393+
</View>
394+
<Text style={[styles.rowText, { color: black }]}>
395+
{membership?.pinned_at ? 'Unpin' : 'Pin'}
396+
</Text>
397+
</View>
398+
</TapGestureHandler>
399+
<TapGestureHandler
400+
onHandlerStateChange={async ({ nativeEvent: { state } }) => {
401+
if (state === State.END) {
402+
try {
403+
if (membership?.archived_at) {
404+
await channel.unarchive();
405+
} else {
406+
await channel.archive();
407+
}
408+
} catch (error) {
409+
console.log('Error archiving/unarchiving channel', error);
410+
}
411+
412+
setOverlay('none');
413+
}
414+
}}
415+
>
416+
<View
417+
style={[
418+
styles.row,
419+
{
420+
borderTopColor: border,
421+
},
422+
]}
423+
>
424+
<View style={styles.rowInner}>
425+
<Archive height={24} width={24} />
426+
</View>
427+
<Text style={[styles.rowText, { color: black }]}>
428+
{membership?.archived_at ? 'Unarchive' : 'Archive'}
429+
</Text>
430+
</View>
431+
</TapGestureHandler>
432+
364433
{otherMembers.length > 1 && (
365434
<TapGestureHandler
366435
onHandlerStateChange={({ nativeEvent: { state } }) => {

examples/SampleApp/src/components/ChannelPreview.tsx

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ import Swipeable from 'react-native-gesture-handler/Swipeable';
66
import {
77
ChannelPreviewMessenger,
88
ChannelPreviewMessengerProps,
9+
ChannelPreviewStatus,
10+
ChannelPreviewStatusProps,
911
Delete,
1012
MenuPointHorizontal,
13+
Pin,
14+
useChannelMembershipState,
1115
useChatContext,
1216
useTheme,
1317
} from 'stream-chat-react-native';
@@ -19,6 +23,7 @@ import { useChannelInfoOverlayContext } from '../context/ChannelInfoOverlayConte
1923
import type { StackNavigationProp } from '@react-navigation/stack';
2024

2125
import type { StackNavigatorParamList, StreamChatGenerics } from '../types';
26+
import { ChannelState } from 'stream-chat';
2227

2328
const styles = StyleSheet.create({
2429
leftSwipeableButton: {
@@ -35,13 +40,37 @@ const styles = StyleSheet.create({
3540
alignItems: 'center',
3641
flexDirection: 'row',
3742
},
43+
statusContainer: {
44+
display: 'flex',
45+
flexDirection: 'row',
46+
},
47+
pinIconContainer: {
48+
marginLeft: 8,
49+
},
3850
});
3951

4052
type ChannelListScreenNavigationProp = StackNavigationProp<
4153
StackNavigatorParamList,
4254
'ChannelListScreen'
4355
>;
4456

57+
const CustomChannelPreviewStatus = (
58+
props: ChannelPreviewStatusProps & { membership: ChannelState['membership'] },
59+
) => {
60+
const { membership } = props;
61+
62+
return (
63+
<View style={styles.statusContainer}>
64+
<ChannelPreviewStatus {...props} />
65+
{membership.pinned_at && (
66+
<View style={styles.pinIconContainer}>
67+
<Pin size={24} />
68+
</View>
69+
)}
70+
</View>
71+
);
72+
};
73+
4574
export const ChannelPreview: React.FC<ChannelPreviewMessengerProps<StreamChatGenerics>> = (
4675
props,
4776
) => {
@@ -57,6 +86,8 @@ export const ChannelPreview: React.FC<ChannelPreviewMessengerProps<StreamChatGen
5786

5887
const navigation = useNavigation<ChannelListScreenNavigationProp>();
5988

89+
const membership = useChannelMembershipState(channel);
90+
6091
const {
6192
theme: {
6293
colors: { accent_red, white_smoke },
@@ -75,7 +106,7 @@ export const ChannelPreview: React.FC<ChannelPreviewMessengerProps<StreamChatGen
75106
<View style={[styles.swipeableContainer, { backgroundColor: white_smoke }]}>
76107
<RectButton
77108
onPress={() => {
78-
setData({ channel, clientId: client.userID, navigation });
109+
setData({ channel, clientId: client.userID, membership, navigation });
79110
setOverlay('channelInfo');
80111
}}
81112
style={[styles.leftSwipeableButton]}
@@ -104,7 +135,13 @@ export const ChannelPreview: React.FC<ChannelPreviewMessengerProps<StreamChatGen
104135
</View>
105136
)}
106137
>
107-
<ChannelPreviewMessenger {...props} />
138+
<ChannelPreviewMessenger
139+
{...props}
140+
// eslint-disable-next-line react/no-unstable-nested-components
141+
PreviewStatus={(statusProps) => (
142+
<CustomChannelPreviewStatus {...statusProps} membership={membership} />
143+
)}
144+
/>
108145
</Swipeable>
109146
);
110147
};

examples/SampleApp/src/components/MessageSearch/MessageSearchList.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import React from 'react';
22
import { FlatList, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3-
import { useNavigation } from '@react-navigation/native';
3+
import { NavigationProp, useNavigation } from '@react-navigation/native';
44
import dayjs from 'dayjs';
55
import calendar from 'dayjs/plugin/calendar';
66
import { Avatar, Spinner, useTheme, useViewport } from 'stream-chat-react-native';
7-
8-
import { MESSAGE_SEARCH_LIMIT } from '../../hooks/usePaginatedSearchedMessages';
7+
import { DEFAULT_PAGINATION_LIMIT } from '../../utils/constants';
98

109
import type { MessageResponse } from 'stream-chat';
1110

12-
import type { StreamChatGenerics } from '../../types';
11+
import type { StackNavigatorParamList, StreamChatGenerics } from '../../types';
1312

1413
dayjs.extend(calendar);
1514

@@ -46,6 +45,7 @@ const styles = StyleSheet.create({
4645
paddingLeft: 8,
4746
},
4847
title: { fontSize: 14, fontWeight: '700' },
48+
titleContainer: {},
4949
});
5050

5151
export type MessageSearchListProps = {
@@ -74,7 +74,8 @@ export const MessageSearchList: React.FC<MessageSearchListProps> = React.forward
7474
},
7575
} = useTheme();
7676
const { vw } = useViewport();
77-
const navigation = useNavigation();
77+
const navigation =
78+
useNavigation<NavigationProp<StackNavigatorParamList, 'ChannelListScreen'>>();
7879

7980
if (!messages && !refreshing) {
8081
return null;
@@ -92,8 +93,10 @@ export const MessageSearchList: React.FC<MessageSearchListProps> = React.forward
9293
>
9394
<Text style={{ color: grey }}>
9495
{`${
95-
messages.length >= MESSAGE_SEARCH_LIMIT ? MESSAGE_SEARCH_LIMIT : messages.length
96-
}${messages.length >= MESSAGE_SEARCH_LIMIT ? '+ ' : ' '} result${
96+
messages.length >= DEFAULT_PAGINATION_LIMIT
97+
? DEFAULT_PAGINATION_LIMIT
98+
: messages.length
99+
}${messages.length >= DEFAULT_PAGINATION_LIMIT ? '+ ' : ' '} result${
97100
messages.length === 1 ? '' : 's'
98101
}`}
99102
</Text>
@@ -129,8 +132,6 @@ export const MessageSearchList: React.FC<MessageSearchListProps> = React.forward
129132
testID='channel-preview-button'
130133
>
131134
<Avatar
132-
channelId={item.channel?.id}
133-
id={item.user?.id}
134135
image={item.user?.image}
135136
name={item.user?.name}
136137
online={item?.user?.online}

examples/SampleApp/src/context/ChannelInfoOverlayContext.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useContext, useState } from 'react';
22

3+
import { ChannelState } from 'stream-chat';
34
import type { StackNavigationProp } from '@react-navigation/stack';
45
import type { ChannelContextValue } from 'stream-chat-react-native';
56

@@ -14,6 +15,7 @@ export type ChannelInfoOverlayData = Partial<
1415
Pick<ChannelContextValue<StreamChatGenerics>, 'channel'>
1516
> & {
1617
clientId?: string;
18+
membership?: ChannelState<StreamChatGenerics>['membership'];
1719
navigation?: ChannelListScreenNavigationProp;
1820
};
1921

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
import Svg, { Path } from 'react-native-svg';
3+
import { useTheme } from 'stream-chat-react-native';
4+
5+
import { IconProps } from '../utils/base';
6+
7+
export const Archive: React.FC<IconProps> = ({ height = 512, width = 512 }) => {
8+
const {
9+
theme: {
10+
colors: { grey },
11+
},
12+
} = useTheme();
13+
14+
return (
15+
<Svg height={height} viewBox={'0 0 512 512'} width={width}>
16+
<Path
17+
d='M32 32l448 0c17.7 0 32 14.3 32 32l0 32c0 17.7-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96L0 64C0 46.3 14.3 32 32 32zm0 128l448 0 0 256c0 35.3-28.7 64-64 64L96 480c-35.3 0-64-28.7-64-64l0-256zm128 80c0 8.8 7.2 16 16 16l160 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-160 0c-8.8 0-16 7.2-16 16z'
18+
fill={grey}
19+
/>
20+
</Svg>
21+
);
22+
};

examples/SampleApp/src/screens/ChannelListScreen.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,22 @@ const styles = StyleSheet.create({
4949
});
5050

5151
const baseFilters = {
52+
archived: false,
5253
type: 'messaging',
5354
};
54-
const sort: ChannelSort<StreamChatGenerics> = { last_updated: -1 };
55+
56+
const sort: ChannelSort<StreamChatGenerics> = [
57+
{ pinned_at: -1 },
58+
{ last_message_at: -1 },
59+
{ updated_at: -1 },
60+
];
61+
5562
const options = {
5663
presence: true,
5764
state: true,
5865
watch: true,
5966
};
67+
6068
export const ChannelListScreen: React.FC = () => {
6169
const { chatClient } = useAppContext();
6270
const navigation = useNavigation();
@@ -75,7 +83,7 @@ export const ChannelListScreen: React.FC = () => {
7583
const { loading, loadMore, messages, refreshing, refreshList, reset } =
7684
usePaginatedSearchedMessages(searchQuery);
7785

78-
const chatClientUserId = chatClient?.user?.id;
86+
const chatClientUserId = chatClient?.user?.id || '';
7987
const filters = useMemo(
8088
() => ({
8189
...baseFilters,
@@ -98,7 +106,7 @@ export const ChannelListScreen: React.FC = () => {
98106
</View>
99107
);
100108

101-
const setScrollRef = (ref: React.RefObject<FlatList<Channel<StreamChatGenerics>> | null>) => {
109+
const setScrollRef = (ref: FlatList<Channel<StreamChatGenerics>> | null) => {
102110
scrollRef.current = ref;
103111
};
104112

examples/SampleApp/yarn.lock

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7993,6 +7993,21 @@ [email protected]:
79937993
jsonwebtoken "~9.0.0"
79947994
ws "^7.5.10"
79957995

7996+
stream-chat@^8.50.0:
7997+
version "8.52.0"
7998+
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.52.0.tgz#7cb477433d0eb3d7351852f76b3838f5ce0af000"
7999+
integrity sha512-u5M9z4m8O0tB82XTQMkOvLp5+OJg6al8k8/sXQaDx1tMCTMnRWzCIXtRXKjBCWIftwB/4SuPV72+Zy9r/zJMng==
8000+
dependencies:
8001+
"@babel/runtime" "^7.16.3"
8002+
"@types/jsonwebtoken" "~9.0.0"
8003+
"@types/ws" "^7.4.0"
8004+
axios "^1.6.0"
8005+
base64-js "^1.5.1"
8006+
form-data "^4.0.0"
8007+
isomorphic-ws "^4.0.1"
8008+
jsonwebtoken "~9.0.0"
8009+
ws "^7.5.10"
8010+
79968011
strict-uri-encode@^2.0.0:
79978012
version "2.0.0"
79988013
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
@@ -8443,6 +8458,11 @@ use-latest-callback@^0.2.1:
84438458
resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.2.3.tgz#2d644d3063040b9bc2d4c55bb525a13ae3de9e16"
84448459
integrity sha512-7vI3fBuyRcP91pazVboc4qu+6ZqM8izPWX9k7cRnT8hbD5svslcknsh3S9BUhaK11OmgTV4oWZZVSeQAiV53SQ==
84458460

8461+
use-sync-external-store@^1.4.0:
8462+
version "1.4.0"
8463+
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc"
8464+
integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==
8465+
84468466
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
84478467
version "1.0.2"
84488468
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"

0 commit comments

Comments
 (0)