Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions examples/SampleApp/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import { Toast } from './src/components/ToastComponent/Toast';
import { useClientNotificationsToastHandler } from './src/hooks/useClientNotificationsToastHandler';
import AsyncStore from './src/utils/AsyncStore.ts';
import {
MessageInputFloatingConfigItem,
MessageListImplementationConfigItem,
MessageListModeConfigItem,
MessageListPruningConfigItem,
Expand Down Expand Up @@ -106,6 +107,9 @@ const App = () => {
const [messageListPruning, setMessageListPruning] = useState<
MessageListPruningConfigItem['value'] | undefined
>(undefined);
const [messageInputFloating, setMessageInputFloating] = useState<
MessageInputFloatingConfigItem['value'] | undefined
>(undefined);
const colorScheme = useColorScheme();
const streamChatTheme = useStreamChatTheme();
const streami18n = new Streami18n();
Expand Down Expand Up @@ -161,13 +165,20 @@ const App = () => {
'@stream-rn-sampleapp-messagelist-pruning',
{ value: undefined },
);
const messageInputFloatingStoredValue = await AsyncStore.getItem(
'@stream-rn-sampleapp-messageinput-floating',
{ value: false },
);
setMessageListImplementation(
messageListImplementationStoredValue?.id as MessageListImplementationConfigItem['id'],
);
setMessageListMode(messageListModeStoredValue?.mode as MessageListModeConfigItem['mode']);
setMessageListPruning(
messageListPruningStoredValue?.value as MessageListPruningConfigItem['value'],
);
setMessageInputFloating(
messageInputFloatingStoredValue?.value as MessageInputFloatingConfigItem['value'],
);
};
getMessageListConfig();
return () => {
Expand Down Expand Up @@ -232,6 +243,7 @@ const App = () => {
logout,
switchUser,
messageListImplementation,
messageInputFloating: messageInputFloating ?? false,
messageListMode,
messageListPruning,
}}
Expand Down
53 changes: 53 additions & 0 deletions examples/SampleApp/src/components/SecretMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type NotificationConfigItem = { label: string; name: string; id: string }
export type MessageListImplementationConfigItem = { label: string; id: 'flatlist' | 'flashlist' };
export type MessageListModeConfigItem = { label: string; mode: 'default' | 'livestream' };
export type MessageListPruningConfigItem = { label: string; value: 100 | 500 | 1000 | undefined };
export type MessageInputFloatingConfigItem = { label: string; value: boolean };

const messageListImplementationConfigItems: MessageListImplementationConfigItem[] = [
{ label: 'FlatList', id: 'flatlist' },
Expand All @@ -44,6 +45,11 @@ const messageListPruningConfigItems: MessageListPruningConfigItem[] = [
{ label: '1000 Messages', value: 1000 },
];

const messageInputFloatingConfigItems: MessageInputFloatingConfigItem[] = [
{ label: 'Normal', value: false },
{ label: 'Floating', value: true },
];

export const SlideInView = ({
visible,
children,
Expand Down Expand Up @@ -161,6 +167,23 @@ const SecretMenuMessageListImplementationConfigItem = ({
</TouchableOpacity>
);

const SecretMenuMessageInputFloatingConfigItem = ({
messageInputFloatingConfigItem,
storeMessageInputFloating,
isSelected,
}: {
messageInputFloatingConfigItem: MessageInputFloatingConfigItem;
storeMessageInputFloating: (item: MessageInputFloatingConfigItem) => void;
isSelected: boolean;
}) => (
<TouchableOpacity
style={[styles.notificationItemContainer, { borderColor: isSelected ? 'green' : 'gray' }]}
onPress={() => storeMessageInputFloating(messageInputFloatingConfigItem)}
>
<Text style={styles.notificationItem}>{messageInputFloatingConfigItem.label}</Text>
</TouchableOpacity>
);

const SecretMenuMessageListModeConfigItem = ({
messageListModeConfigItem,
storeMessageListMode,
Expand Down Expand Up @@ -218,6 +241,8 @@ export const SecretMenu = ({
const [selectedMessageListPruning, setSelectedMessageListPruning] = useState<
MessageListPruningConfigItem['value'] | null
>(null);
const [selectedMessageInputFloating, setSelectedMessageInputFloating] =
useState<MessageInputFloatingConfigItem['value']>(false);
const {
theme: {
colors: { black, grey },
Expand Down Expand Up @@ -250,12 +275,19 @@ export const SecretMenu = ({
'@stream-rn-sampleapp-messagelist-pruning',
messageListPruningConfigItems[0],
);
const messageInputFloating = await AsyncStore.getItem(
'@stream-rn-sampleapp-messageinput-floating',
messageInputFloatingConfigItems[0],
);
setSelectedProvider(notificationProvider?.id ?? notificationConfigItems[0].id);
setSelectedMessageListImplementation(
messageListImplementation?.id ?? messageListImplementationConfigItems[0].id,
);
setSelectedMessageListMode(messageListMode?.mode ?? messageListModeConfigItems[0].mode);
setSelectedMessageListPruning(messageListPruning?.value);
setSelectedMessageInputFloating(
messageInputFloating?.value ?? messageInputFloatingConfigItems[0].value,
);
};
getSelectedConfig();
}, [notificationConfigItems]);
Expand Down Expand Up @@ -283,6 +315,11 @@ export const SecretMenu = ({
setSelectedMessageListPruning(item.value);
}, []);

const storeMessageInputFloating = useCallback(async (item: MessageInputFloatingConfigItem) => {
await AsyncStore.setItem('@stream-rn-sampleapp-messageinput-floating', item);
setSelectedMessageInputFloating(item.value);
}, []);

const removeAllDevices = useCallback(async () => {
const { devices } = await chatClient.getDevices(chatClient.userID);
for (const device of devices ?? []) {
Expand Down Expand Up @@ -335,6 +372,22 @@ export const SecretMenu = ({
</View>
</View>
</View>
<View style={[menuDrawerStyles.menuItem, { alignItems: 'flex-start' }]}>
<Folder height={20} pathFill={grey} width={20} />
<View>
<Text style={[menuDrawerStyles.menuTitle]}>Message Input Floating</Text>
<View style={{ marginLeft: 16 }}>
{messageInputFloatingConfigItems.map((item) => (
<SecretMenuMessageInputFloatingConfigItem
key={item.value.toString()}
messageInputFloatingConfigItem={item}
storeMessageInputFloating={storeMessageInputFloating}
isSelected={item.value === selectedMessageInputFloating}
/>
))}
</View>
</View>
</View>
<View style={[menuDrawerStyles.menuItem, { alignItems: 'flex-start' }]}>
<Edit height={20} pathFill={grey} width={20} />
<View>
Expand Down
2 changes: 2 additions & 0 deletions examples/SampleApp/src/context/AppContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { StreamChat } from 'stream-chat';

import type { LoginConfig } from '../types';
import {
MessageInputFloatingConfigItem,
MessageListImplementationConfigItem,
MessageListModeConfigItem,
MessageListPruningConfigItem,
Expand All @@ -15,6 +16,7 @@ type AppContextType = {
logout: () => void;
switchUser: (userId?: string) => void;
messageListImplementation: MessageListImplementationConfigItem['id'];
messageInputFloating: MessageInputFloatingConfigItem['value'];
messageListMode: MessageListModeConfigItem['mode'];
messageListPruning: MessageListPruningConfigItem['value'];
};
Expand Down
3 changes: 2 additions & 1 deletion examples/SampleApp/src/screens/ChannelListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
View,
} from 'react-native';
import { useNavigation, useScrollToTop } from '@react-navigation/native';
import { ChannelList, CircleClose, Search, useTheme } from 'stream-chat-react-native';
import { ChannelList, CircleClose, useTheme } from 'stream-chat-react-native';
import { Channel } from 'stream-chat';
import { ChannelPreview } from '../components/ChannelPreview';
import { ChatScreenHeader } from '../components/ChatScreenHeader';
Expand All @@ -19,6 +19,7 @@ import { usePaginatedSearchedMessages } from '../hooks/usePaginatedSearchedMessa

import type { ChannelSort } from 'stream-chat';
import { useStreamChatContext } from '../context/StreamChatContext';
import { Search } from '../icons/Search';

const styles = StyleSheet.create({
channelListContainer: {
Expand Down
16 changes: 10 additions & 6 deletions examples/SampleApp/src/screens/ChannelScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
} from 'stream-chat-react-native';
import { Pressable, StyleSheet, View } from 'react-native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { useAppContext } from '../context/AppContext';
import { ScreenHeader } from '../components/ScreenHeader';
Expand Down Expand Up @@ -122,9 +121,13 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
params: { channel: channelFromProp, channelId, messageId },
},
}) => {
const { chatClient, messageListImplementation, messageListMode, messageListPruning } =
useAppContext();
const { bottom } = useSafeAreaInsets();
const {
chatClient,
messageListImplementation,
messageListMode,
messageListPruning,
messageInputFloating,
} = useAppContext();
const {
theme: { colors },
} = useTheme();
Expand Down Expand Up @@ -218,11 +221,12 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
}

return (
<View style={[styles.flex, { backgroundColor: colors.white_snow, paddingBottom: bottom }]}>
<View style={[styles.flex, { backgroundColor: 'transparent' }]}>
<Channel
audioRecordingEnabled={true}
audioRecordingEnabled={false}
AttachmentPickerSelectionBar={CustomAttachmentPickerSelectionBar}
channel={channel}
messageInputFloating={messageInputFloating}
onPressMessage={onPressMessage}
disableTypingIndicator
enforceUniqueReaction
Expand Down
17 changes: 11 additions & 6 deletions examples/SampleApp/src/screens/ThreadScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useCallback } from 'react';
import { Platform, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { StyleSheet, View } from 'react-native';
import { useHeaderHeight } from '@react-navigation/elements';

import {
Channel,
MessageActionsParams,
Expand All @@ -26,6 +27,7 @@ import { useStreamChatContext } from '../context/StreamChatContext.tsx';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { CustomAttachmentPickerSelectionBar } from '../components/AttachmentPickerSelectionBar.tsx';
import { MessageLocation } from '../components/LocationSharing/MessageLocation.tsx';
import { useAppContext } from '../context/AppContext.ts';

const selector = (nextValue: ThreadState) => ({ parentMessage: nextValue.parentMessage }) as const;

Expand Down Expand Up @@ -84,6 +86,8 @@ export const ThreadScreen: React.FC<ThreadScreenProps> = ({
const { client: chatClient } = useChatContext();
const { t } = useTranslationContext();
const { setThread } = useStreamChatContext();
const { messageInputFloating } = useAppContext();
const headerHeight = useHeaderHeight();

const onPressMessage: NonNullable<React.ComponentProps<typeof Channel>['onPressMessage']> = (
payload,
Expand Down Expand Up @@ -115,14 +119,15 @@ export const ThreadScreen: React.FC<ThreadScreenProps> = ({
}, [setThread]);

return (
<SafeAreaView edges={['bottom']} style={[styles.container, { backgroundColor: white }]}>
<View style={[styles.container, { backgroundColor: white }]}>
<Channel
audioRecordingEnabled={true}
audioRecordingEnabled={false}
AttachmentPickerSelectionBar={CustomAttachmentPickerSelectionBar}
channel={channel}
enforceUniqueReaction
keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : -300}
keyboardVerticalOffset={headerHeight}
messageActions={messageActions}
messageInputFloating={messageInputFloating}
MessageHeader={MessageReminderHeader}
MessageLocation={MessageLocation}
onPressMessage={onPressMessage}
Expand All @@ -132,6 +137,6 @@ export const ThreadScreen: React.FC<ThreadScreenProps> = ({
<ThreadHeader thread={thread} />
<Thread onThreadDismount={onThreadDismount} />
</Channel>
</SafeAreaView>
</View>
);
};
Loading
Loading