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
35 changes: 15 additions & 20 deletions examples/ExpoMessaging/app/channel/[cid]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@ import {
useChatContext,
ThreadContextValue,
MessageList,
WithComponents,
} from 'stream-chat-expo';
import { Stack, useLocalSearchParams, useRouter } from 'expo-router';
import { AuthProgressLoader } from '../../../components/AuthProgressLoader';
import { AppContext } from '../../../context/AppContext';
import { useHeaderHeight } from '@react-navigation/elements';
import InputButtons from '../../../components/InputButtons';
import { MessageLocation } from '../../../components/LocationSharing/MessageLocation';
import { StyleSheet, View } from 'react-native';

export default function ChannelScreen() {
Expand Down Expand Up @@ -71,23 +68,21 @@ export default function ChannelScreen() {
<Stack.Screen
options={{ title: 'Channel Screen', contentStyle: { backgroundColor: 'white' } }}
/>
<WithComponents overrides={{ MessageLocation, InputButtons }}>
<Channel
audioRecordingEnabled={true}
channel={channel}
onPressMessage={onPressMessage}
keyboardVerticalOffset={headerHeight}
thread={thread}
>
<MessageList
onThreadSelect={(thread: ThreadContextValue['thread']) => {
setThread(thread);
router.push(`/channel/${channel.cid}/thread/${thread?.cid ?? ''}`);
}}
/>
<MessageComposer />
</Channel>
</WithComponents>
<Channel
audioRecordingEnabled={true}
channel={channel}
onPressMessage={onPressMessage}
keyboardVerticalOffset={headerHeight}
thread={thread}
>
<MessageList
onThreadSelect={(thread: ThreadContextValue['thread']) => {
setThread(thread);
router.push(`/channel/${channel.cid}/thread/${thread?.cid ?? ''}`);
}}
/>
<MessageComposer />
</Channel>
</View>
);
}
Expand Down
15 changes: 10 additions & 5 deletions examples/ExpoMessaging/components/ChatWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import {
SqliteClient,
Streami18n,
useCreateChatClient,
WithComponents,
} from 'stream-chat-expo';
import { UserResponse } from 'stream-chat';
import { AuthProgressLoader } from './AuthProgressLoader';
import { useStreamChatTheme } from '../hooks/useStreamChatTheme';
import { useUserContext } from '@/context/UserContext';
import { STREAM_API_KEY, USER_TOKENS } from '@/constants/ChatUsers';
import { usePushNotifications } from '@/hooks/usePushNotifications';
import { useExpoMessagingComponentOverrides } from './ExpoMessagingComponentOverrides';
import '../utils/backgroundMessageHandler';

const streami18n = new Streami18n({
Expand All @@ -39,16 +41,19 @@ export const ChatWrapper = ({ children }: PropsWithChildren<{}>) => {
});

const theme = useStreamChatTheme();
const componentOverrides = useExpoMessagingComponentOverrides();

if (!chatClient) {
return <AuthProgressLoader />;
}

return (
<OverlayProvider i18nInstance={streami18n} value={{ style: theme }}>
<Chat client={chatClient} i18nInstance={streami18n} enableOfflineSupport>
{children}
</Chat>
</OverlayProvider>
<WithComponents overrides={componentOverrides}>
<OverlayProvider i18nInstance={streami18n} value={{ style: theme }}>
<Chat client={chatClient} i18nInstance={streami18n} enableOfflineSupport>
{children}
</Chat>
</OverlayProvider>
</WithComponents>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useMemo } from 'react';
import type { ComponentOverrides } from 'stream-chat-expo';

import InputButtons from './InputButtons';
import { MessageLocation } from './LocationSharing/MessageLocation';

export const useExpoMessagingComponentOverrides = () => {
return useMemo<ComponentOverrides>(
() => ({ InputButtons, MessageLocation }),
[],
);
};
114 changes: 41 additions & 73 deletions examples/SampleApp/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ import {
I18nManager,
LogBox,
Platform,
StyleSheet,
useColorScheme,
View,
} from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { DarkTheme, DefaultTheme, NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { BlurView } from '@react-native-community/blur';
import {
Chat,
createTextComposerEmojiMiddleware,
Expand All @@ -23,7 +20,7 @@ import {
Streami18n,
ThemeProvider,
useOverlayContext,
useTheme,
WithComponents,
} from 'stream-chat-react-native';

import { getMessaging } from '@react-native-firebase/messaging';
Expand Down Expand Up @@ -55,10 +52,10 @@ import Geolocation from '@react-native-community/geolocation';
import type { StackNavigatorParamList, UserSelectorParamList } from './src/types';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { navigateToChannel, RootNavigationRef } from './src/utils/RootNavigation';
import FastImage from 'react-native-fast-image';
import { StreamChatProvider } from './src/context/StreamChatContext';
import { MapScreen } from './src/screens/MapScreen';
import { watchLocation } from './src/utils/watchLocation';
import { useSampleAppComponentOverrides } from './src/components/SampleAppComponentOverrides';

Geolocation.setRNConfiguration({
skipPermissionRequests: false,
Expand Down Expand Up @@ -107,30 +104,6 @@ const Stack = createNativeStackNavigator<StackNavigatorParamList>();
const UserSelectorStack = createNativeStackNavigator<UserSelectorParamList>();
const RTL_STORAGE_KEY = '@stream-rn-sampleapp-rtl-enabled';

const MessageOverlayBlurBackground = () => {
const {
theme: { semantics },
} = useTheme();
const scheme = useColorScheme();
const isDark = scheme === 'dark';
const isIOS = Platform.OS === 'ios';

return (
<>
<BlurView
blurAmount={isIOS ? 10 : 6}
blurType={isDark ? 'dark' : 'light'}
blurRadius={isIOS ? undefined : 6}
downsampleFactor={isIOS ? undefined : 12}
pointerEvents='none'
reducedTransparencyFallbackColor='rgba(0, 0, 0, 0.8)'
style={StyleSheet.absoluteFill}
/>
<View style={[StyleSheet.absoluteFill, { backgroundColor: semantics.backgroundCoreScrim }]} />
</>
);
};

const App = () => {
const { chatClient, isConnecting, loginUser, logout, switchUser } = useChatClient();
const [rtlEnabled, setRtlEnabled] = useState<boolean | undefined>(undefined);
Expand All @@ -152,6 +125,7 @@ const App = () => {
const colorScheme = useColorScheme();
const streamChatTheme = useStreamChatTheme();
const streami18n = new Streami18n();
const componentOverrides = useSampleAppComponentOverrides(messageOverlayBackdrop);

const setRTLEnabled = React.useCallback(async (enabled: boolean) => {
await AsyncStore.setItem(RTL_STORAGE_KEY, enabled);
Expand Down Expand Up @@ -295,50 +269,46 @@ const App = () => {
}}
>
<GestureHandlerRootView style={{ flex: 1 }}>
<OverlayProvider
MessageOverlayBackground={
messageOverlayBackdrop === 'blurview' ? MessageOverlayBlurBackground : undefined
}
value={{ style: streamChatTheme }}
i18nInstance={streami18n}
>
<ThemeProvider style={streamChatTheme}>
<NavigationContainer
ref={RootNavigationRef}
theme={{
colors: {
...(colorScheme === 'dark' ? DarkTheme : DefaultTheme).colors,
background: streamChatTheme.colors?.white_snow || '#FCFCFC',
},
fonts: (colorScheme === 'dark' ? DarkTheme : DefaultTheme).fonts,
dark: colorScheme === 'dark',
}}
>
<AppContext.Provider
value={{
chatClient,
loginUser,
logout,
switchUser,
rtlEnabled,
setRTLEnabled,
messageListImplementation,
messageInputFloating: messageInputFloating ?? false,
messageListMode,
messageListPruning,
<WithComponents overrides={componentOverrides}>
<OverlayProvider value={{ style: streamChatTheme }} i18nInstance={streami18n}>
<ThemeProvider style={streamChatTheme}>
<NavigationContainer
ref={RootNavigationRef}
theme={{
colors: {
...(colorScheme === 'dark' ? DarkTheme : DefaultTheme).colors,
background: streamChatTheme.colors?.white_snow || '#FCFCFC',
},
fonts: (colorScheme === 'dark' ? DarkTheme : DefaultTheme).fonts,
dark: colorScheme === 'dark',
}}
>
{isConnecting && !chatClient ? (
<LoadingScreen />
) : chatClient ? (
<DrawerNavigatorWrapper chatClient={chatClient} i18nInstance={streami18n} />
) : (
<UserSelector />
)}
</AppContext.Provider>
</NavigationContainer>
</ThemeProvider>
</OverlayProvider>
<AppContext.Provider
value={{
chatClient,
loginUser,
logout,
switchUser,
rtlEnabled,
setRTLEnabled,
messageListImplementation,
messageInputFloating: messageInputFloating ?? false,
messageListMode,
messageListPruning,
}}
>
{isConnecting && !chatClient ? (
<LoadingScreen />
) : chatClient ? (
<DrawerNavigatorWrapper chatClient={chatClient} i18nInstance={streami18n} />
) : (
<UserSelector />
)}
</AppContext.Provider>
</NavigationContainer>
</ThemeProvider>
</OverlayProvider>
</WithComponents>
</GestureHandlerRootView>
</SafeAreaProvider>
);
Expand Down Expand Up @@ -369,8 +339,6 @@ const DrawerNavigatorWrapper: React.FC<{
<Chat
client={chatClient}
enableOfflineSupport
// @ts-expect-error - the `ImageComponent` prop is generic, meaning we can expect an error
ImageComponent={FastImage}
isMessageAIGenerated={isMessageAIGenerated}
i18nInstance={i18nInstance}
>
Expand Down
8 changes: 1 addition & 7 deletions examples/SampleApp/src/components/ChannelPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
import {
ChannelPreviewView,
ChannelPreviewViewProps,
ChannelPreviewStatus,
ChannelPreviewStatusProps,
Pin,
Expand Down Expand Up @@ -34,7 +32,7 @@ const styles = StyleSheet.create({
},
});

const CustomChannelPreviewStatus = (props: ChannelPreviewStatusProps) => {
export const CustomChannelPreviewStatus = (props: ChannelPreviewStatusProps) => {
const { channel } = props;

const membership = useChannelMembershipState(channel);
Expand All @@ -53,7 +51,3 @@ const CustomChannelPreviewStatus = (props: ChannelPreviewStatusProps) => {
</View>
);
};

export const ChannelPreview: React.FC<ChannelPreviewViewProps> = (props) => {
return <ChannelPreviewView {...props} PreviewStatus={CustomChannelPreviewStatus} />;
};
60 changes: 60 additions & 0 deletions examples/SampleApp/src/components/SampleAppComponentOverrides.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useMemo } from 'react';
import { Platform, StyleSheet, useColorScheme, View } from 'react-native';
import type { ComponentOverrides } from 'stream-chat-react-native';
import { BlurView } from '@react-native-community/blur';
import FastImage from 'react-native-fast-image';
import {
useTheme,
} from 'stream-chat-react-native';

import { CustomAttachmentPickerContent } from './AttachmentPickerContent';
import { CustomChannelPreviewStatus } from './ChannelPreview';
import { MessageLocation } from './LocationSharing/MessageLocation';
import type { MessageOverlayBackdropConfigItem } from './SecretMenu';

const MessageOverlayBlurBackground: NonNullable<ComponentOverrides['MessageOverlayBackground']> =
() => {
const {
theme: { semantics },
} = useTheme();
const scheme = useColorScheme();
const isDark = scheme === 'dark';
const isIOS = Platform.OS === 'ios';

return (
<>
<BlurView
blurAmount={isIOS ? 10 : 6}
blurRadius={isIOS ? undefined : 6}
blurType={isDark ? 'dark' : 'light'}
downsampleFactor={isIOS ? undefined : 12}
pointerEvents='none'
reducedTransparencyFallbackColor='rgba(0, 0, 0, 0.8)'
style={StyleSheet.absoluteFill}
/>
<View
style={[StyleSheet.absoluteFill, { backgroundColor: semantics.backgroundCoreScrim }]}
/>
</>
);
};

const RenderNull = () => null;

export const useSampleAppComponentOverrides = (
messageOverlayBackdrop?: MessageOverlayBackdropConfigItem['value'],
) =>
useMemo<ComponentOverrides>(
() => ({
AttachmentPickerContent: CustomAttachmentPickerContent,
ChannelListHeaderNetworkDownIndicator: RenderNull,
ImageComponent: FastImage,
MessageLocation,
NetworkDownIndicator: RenderNull,
ChannelPreviewStatus: CustomChannelPreviewStatus,
...(messageOverlayBackdrop === 'blurview'
? { MessageOverlayBackground: MessageOverlayBlurBackground }
: {}),
}),
[messageOverlayBackdrop],
);
Loading
Loading