Skip to content

Commit eea5f9a

Browse files
committed
feat: introduce custom overlay background component
1 parent 3d03fc5 commit eea5f9a

File tree

16 files changed

+206
-91
lines changed

16 files changed

+206
-91
lines changed

examples/SampleApp/App.tsx

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import React, { useEffect, useState } from 'react';
2-
import { DevSettings, LogBox, Platform, useColorScheme } from 'react-native';
2+
import { DevSettings, LogBox, Platform, StyleSheet, useColorScheme, View } from 'react-native';
33
import { createDrawerNavigator } from '@react-navigation/drawer';
44
import { DarkTheme, DefaultTheme, NavigationContainer } from '@react-navigation/native';
55
import { createNativeStackNavigator } from '@react-navigation/native-stack';
66
import { SafeAreaProvider } from 'react-native-safe-area-context';
7+
import { BlurView } from '@react-native-community/blur';
78
import {
89
Chat,
910
createTextComposerEmojiMiddleware,
@@ -14,7 +15,9 @@ import {
1415
Streami18n,
1516
ThemeProvider,
1617
useOverlayContext,
18+
useTheme,
1719
} from 'stream-chat-react-native';
20+
import type { MessageOverlayBackgroundProps } from 'stream-chat-react-native';
1821

1922
import { getMessaging } from '@react-native-firebase/messaging';
2023
import notifee, { EventType } from '@notifee/react-native';
@@ -96,6 +99,35 @@ const Drawer = createDrawerNavigator();
9699
const Stack = createNativeStackNavigator<StackNavigatorParamList>();
97100
const UserSelectorStack = createNativeStackNavigator<UserSelectorParamList>();
98101

102+
const MessageOverlayBlurBackground = ({ style }: MessageOverlayBackgroundProps) => {
103+
const {
104+
theme: { semantics },
105+
} = useTheme();
106+
const scheme = useColorScheme();
107+
const isDark = scheme === 'dark';
108+
const isIOS = Platform.OS === 'ios';
109+
110+
return (
111+
<>
112+
<BlurView
113+
blurAmount={isIOS ? 10 : 6}
114+
blurType={isDark ? 'dark' : 'light'}
115+
blurRadius={isIOS ? undefined : 6}
116+
downsampleFactor={isIOS ? undefined : 12}
117+
pointerEvents='none'
118+
reducedTransparencyFallbackColor='rgba(0, 0, 0, 0.8)'
119+
style={[styles.messageOverlayBlurBackground, style]}
120+
/>
121+
<View
122+
style={[
123+
styles.messageOverlayBlurBackground,
124+
{ backgroundColor: semantics.backgroundCoreScrim },
125+
]}
126+
/>
127+
</>
128+
);
129+
};
130+
99131
const App = () => {
100132
const { chatClient, isConnecting, loginUser, logout, switchUser } = useChatClient();
101133
const [messageListImplementation, setMessageListImplementation] = useState<
@@ -198,7 +230,7 @@ const App = () => {
198230
},
199231
linkPreviews: {
200232
enabled: true,
201-
}
233+
},
202234
});
203235

204236
setupCommandUIMiddlewares(composer);
@@ -226,7 +258,11 @@ const App = () => {
226258
}}
227259
>
228260
<GestureHandlerRootView style={{ flex: 1 }}>
229-
<OverlayProvider value={{ style: streamChatTheme }} i18nInstance={streami18n}>
261+
<OverlayProvider
262+
MessageOverlayBackground={MessageOverlayBlurBackground}
263+
value={{ style: streamChatTheme }}
264+
i18nInstance={streami18n}
265+
>
230266
<ThemeProvider style={streamChatTheme}>
231267
<NavigationContainer
232268
ref={RootNavigationRef}
@@ -416,3 +452,9 @@ const HomeScreen = () => {
416452
};
417453

418454
export default App;
455+
456+
const styles = StyleSheet.create({
457+
messageOverlayBlurBackground: {
458+
...StyleSheet.absoluteFillObject,
459+
},
460+
});

examples/SampleApp/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"@react-native-clipboard/clipboard": "^1.16.3",
3636
"@react-native-community/geolocation": "^3.4.0",
3737
"@react-native-community/netinfo": "^11.4.1",
38+
"@react-native-community/blur": "^4.4.1",
3839
"@react-native-documents/picker": "^10.1.3",
3940
"@react-native-firebase/app": "22.2.1",
4041
"@react-native-firebase/messaging": "22.2.1",

examples/SampleApp/yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,6 +2199,11 @@
21992199
resolved "https://registry.yarnpkg.com/@react-native-clipboard/clipboard/-/clipboard-1.16.3.tgz#7807a90fd9984bf4d3a96faf2eee20457984a9bd"
22002200
integrity sha512-cMIcvoZKIrShzJHEaHbTAp458R9WOv0fB6UyC7Ek4Qk561Ow/DrzmmJmH/rAZg21Z6ixJ4YSdFDC14crqIBmCQ==
22012201

2202+
"@react-native-community/blur@^4.4.1":
2203+
version "4.4.1"
2204+
resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-4.4.1.tgz#72cbc0be5a84022c33091683ec6888925ebcca6e"
2205+
integrity sha512-XBSsRiYxE/MOEln2ayunShfJtWztHwUxLFcSL20o+HNNRnuUDv+GXkF6FmM2zE8ZUfrnhQ/zeTqvnuDPGw6O8A==
2206+
22022207
"@react-native-community/cli-clean@19.1.2":
22032208
version "19.1.2"
22042209
resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-19.1.2.tgz#10be56a6ab966c141090176e54937cb7b7618a9b"

package/src/components/Message/MessageSimple/Headers/MessagePinnedHeader.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ import { useTheme } from '../../../../contexts/themeContext/ThemeContext';
1010
import { useTranslationContext } from '../../../../contexts/translationContext/TranslationContext';
1111
import { Pin } from '../../../../icons/Pin';
1212
import { primitives } from '../../../../theme';
13+
import { useShouldUseOverlayStyles } from '../../hooks/useShouldUseOverlayStyles';
1314

1415
export type MessagePinnedHeaderProps = Partial<Pick<MessageContextValue, 'message'>>;
1516

1617
export const MessagePinnedHeader = (props: MessagePinnedHeaderProps) => {
1718
const { message: propMessage } = props;
1819
const { message: contextMessage } = useMessageContext();
1920
const message = propMessage || contextMessage;
20-
const {
21-
theme: { semantics },
22-
} = useTheme();
2321
const styles = useStyles();
2422
const { t } = useTranslationContext();
2523
const { client } = useChatContext();
@@ -30,7 +28,7 @@ export const MessagePinnedHeader = (props: MessagePinnedHeaderProps) => {
3028

3129
return (
3230
<View accessibilityLabel='Message Pinned Header' style={styles.container}>
33-
<Pin height={16} width={16} stroke={semantics.textPrimary} />
31+
<Pin height={16} width={16} stroke={styles.label.color} />
3432
<Text style={styles.label}>
3533
{t('Pinned by')}{' '}
3634
{message?.pinned_by?.id === client?.user?.id ? t('You') : message?.pinned_by?.name}
@@ -48,6 +46,7 @@ const useStyles = () => {
4846
},
4947
},
5048
} = useTheme();
49+
const shouldUseOverlayStyles = useShouldUseOverlayStyles();
5150

5251
return useMemo(() => {
5352
return StyleSheet.create({
@@ -59,12 +58,12 @@ const useStyles = () => {
5958
...container,
6059
},
6160
label: {
62-
color: semantics.textPrimary,
61+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textPrimary,
6362
fontSize: primitives.typographyFontSizeXs,
6463
fontWeight: primitives.typographyFontWeightSemiBold,
6564
lineHeight: primitives.typographyLineHeightTight,
6665
...label,
6766
},
6867
});
69-
}, [semantics, container, label]);
68+
}, [shouldUseOverlayStyles, semantics, container, label]);
7069
};

package/src/components/Message/MessageSimple/Headers/MessageReminderHeader.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useMessageReminder } from '../../../../hooks/useMessageReminder';
1111
import { useStateStore } from '../../../../hooks/useStateStore';
1212
import { Bell } from '../../../../icons';
1313
import { primitives } from '../../../../theme';
14+
import { useShouldUseOverlayStyles } from '../../hooks/useShouldUseOverlayStyles';
1415

1516
const reminderStateSelector = (state: ReminderState) => ({
1617
timeLeftMs: state.timeLeftMs,
@@ -23,15 +24,12 @@ type MessageReminderHeaderPropsWithContext = {
2324

2425
const MessageReminderHeaderWithContext = (props: MessageReminderHeaderPropsWithContext) => {
2526
const { timeLeftMs, isReminderTimeLeft } = props;
26-
const {
27-
theme: { semantics },
28-
} = useTheme();
2927
const { t } = useTranslationContext();
3028
const styles = useStyles();
3129

3230
return (
3331
<View accessibilityLabel='Message Saved For Later Header' style={styles.container}>
34-
<Bell height={16} width={16} stroke={semantics.textPrimary} />
32+
<Bell height={16} width={16} stroke={styles.time.color} />
3533
<Text style={styles.label}>
3634
{isReminderTimeLeft ? t('Reminder set') : t('Reminder overdue')}
3735
</Text>
@@ -72,6 +70,7 @@ const useStyles = () => {
7270
},
7371
},
7472
} = useTheme();
73+
const shouldUseOverlayStyles = useShouldUseOverlayStyles();
7574

7675
return useMemo(() => {
7776
return StyleSheet.create({
@@ -83,26 +82,26 @@ const useStyles = () => {
8382
...container,
8483
},
8584
label: {
86-
color: semantics.textPrimary,
85+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textPrimary,
8786
fontSize: primitives.typographyFontSizeXs,
8887
fontWeight: primitives.typographyFontWeightSemiBold,
8988
lineHeight: primitives.typographyLineHeightTight,
9089
...label,
9190
},
9291
dot: {
93-
color: semantics.textPrimary,
92+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textPrimary,
9493
fontSize: primitives.typographyFontSizeXs,
9594
fontWeight: primitives.typographyFontWeightRegular,
9695
lineHeight: primitives.typographyLineHeightTight,
9796
...dot,
9897
},
9998
time: {
100-
color: semantics.textPrimary,
99+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textPrimary,
101100
fontSize: primitives.typographyFontSizeXs,
102101
fontWeight: primitives.typographyFontWeightRegular,
103102
lineHeight: primitives.typographyLineHeightTight,
104103
...time,
105104
},
106105
});
107-
}, [container, semantics, label, dot, time]);
106+
}, [shouldUseOverlayStyles, container, semantics, label, dot, time]);
108107
};

package/src/components/Message/MessageSimple/Headers/MessageSavedForLaterHeader.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,17 @@ import { useTheme } from '../../../../contexts/themeContext/ThemeContext';
66
import { useTranslationContext } from '../../../../contexts/translationContext/TranslationContext';
77
import { Bookmark } from '../../../../icons/Bookmark';
88
import { primitives } from '../../../../theme';
9+
import { useShouldUseOverlayStyles } from '../../hooks/useShouldUseOverlayStyles';
910

1011
export type MessageSavedForLaterHeaderProps = Partial<Pick<MessageContextValue, 'message'>>;
1112

1213
export const MessageSavedForLaterHeader = () => {
13-
const {
14-
theme: { semantics },
15-
} = useTheme();
1614
const styles = useStyles();
1715
const { t } = useTranslationContext();
1816

1917
return (
2018
<View accessibilityLabel='Message Saved For Later Header' style={styles.container}>
21-
<Bookmark height={16} width={16} stroke={semantics.accentPrimary} />
19+
<Bookmark height={16} width={16} stroke={styles.label.color} />
2220
<Text style={styles.label}>{t('Saved For Later')}</Text>
2321
</View>
2422
);
@@ -33,6 +31,7 @@ const useStyles = () => {
3331
},
3432
},
3533
} = useTheme();
34+
const shouldUseOverlayStyles = useShouldUseOverlayStyles();
3635

3736
return useMemo(() => {
3837
return StyleSheet.create({
@@ -44,12 +43,12 @@ const useStyles = () => {
4443
...container,
4544
},
4645
label: {
47-
color: semantics.accentPrimary,
46+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.accentPrimary,
4847
fontSize: primitives.typographyFontSizeXs,
4948
fontWeight: primitives.typographyFontWeightSemiBold,
5049
lineHeight: primitives.typographyLineHeightTight,
5150
...label,
5251
},
5352
});
54-
}, [semantics, container, label]);
53+
}, [shouldUseOverlayStyles, semantics, container, label]);
5554
};

package/src/components/Message/MessageSimple/Headers/SentToChannelHeader.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { useTranslationContext } from '../../../../contexts/translationContext/T
1515
import { useStableCallback } from '../../../../hooks';
1616
import { ArrowUpRight } from '../../../../icons/ArrowUpRight';
1717
import { primitives } from '../../../../theme';
18+
import { useShouldUseOverlayStyles } from '../../hooks/useShouldUseOverlayStyles';
1819

1920
type SentToChannelHeaderPropsWithContext = Pick<ChannelContextValue, 'threadList'> & {
2021
/**
@@ -31,15 +32,12 @@ type SentToChannelHeaderPropsWithContext = Pick<ChannelContextValue, 'threadList
3132

3233
const SentToChannelHeaderWithContext = (props: SentToChannelHeaderPropsWithContext) => {
3334
const { threadList, onPress, showViewText } = props;
34-
const {
35-
theme: { semantics },
36-
} = useTheme();
3735
const { t } = useTranslationContext();
3836
const styles = useStyles();
3937

4038
return (
4139
<View accessibilityLabel='Message Saved For Later Header' style={styles.container}>
42-
<ArrowUpRight height={16} width={16} stroke={semantics.textPrimary} />
40+
<ArrowUpRight height={16} width={16} stroke={styles.link.color} />
4341
<Text style={styles.label}>
4442
{threadList ? t('Also sent in channel') : t('Replied to a thread')}
4543
</Text>
@@ -118,6 +116,7 @@ const useStyles = () => {
118116
},
119117
},
120118
} = useTheme();
119+
const shouldUseOverlayStyles = useShouldUseOverlayStyles();
121120

122121
return useMemo(() => {
123122
return StyleSheet.create({
@@ -129,26 +128,28 @@ const useStyles = () => {
129128
...container,
130129
},
131130
label: {
132-
color: semantics.textPrimary,
131+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textPrimary,
133132
fontSize: primitives.typographyFontSizeXs,
134133
fontWeight: primitives.typographyFontWeightSemiBold,
135134
lineHeight: primitives.typographyLineHeightTight,
136135
...label,
137136
},
138137
dot: {
139-
color: semantics.textPrimary,
138+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textPrimary,
140139
fontSize: primitives.typographyFontSizeXs,
141140
fontWeight: primitives.typographyFontWeightSemiBold,
142141
lineHeight: primitives.typographyLineHeightTight,
143142
...dot,
144143
},
145144
link: {
146-
color: semantics.accentPrimary,
145+
color: shouldUseOverlayStyles
146+
? semantics.buttonPrimaryTextOnAccent
147+
: semantics.accentPrimary,
147148
fontSize: primitives.typographyFontSizeXs,
148149
fontWeight: primitives.typographyFontWeightRegular,
149150
lineHeight: primitives.typographyLineHeightTight,
150151
...link,
151152
},
152153
});
153-
}, [container, semantics, label, dot, link]);
154+
}, [shouldUseOverlayStyles, container, semantics, label, dot, link]);
154155
};

package/src/components/Message/MessageSimple/MessageFooter.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { useTranslationContext } from '../../../contexts/translationContext/Tran
2121

2222
import { primitives } from '../../../theme';
2323
import { isEditedMessage, MessageStatusTypes } from '../../../utils/utils';
24+
import { useShouldUseOverlayStyles } from '../hooks/useShouldUseOverlayStyles';
2425

2526
type MessageFooterComponentProps = {
2627
date?: string | Date;
@@ -196,6 +197,7 @@ const useStyles = () => {
196197
const {
197198
theme: { semantics },
198199
} = useTheme();
200+
const shouldUseOverlayStyles = useShouldUseOverlayStyles();
199201
return useMemo(() => {
200202
return StyleSheet.create({
201203
container: {
@@ -206,17 +208,22 @@ const useStyles = () => {
206208
gap: primitives.spacingXs,
207209
},
208210
name: {
209-
color: semantics.chatTextUsername,
211+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextUsername,
210212
fontSize: primitives.typographyFontSizeXs,
211213
fontWeight: primitives.typographyFontWeightSemiBold,
212214
lineHeight: primitives.typographyLineHeightTight,
213215
},
214216
editedText: {
215-
color: semantics.chatTextTimestamp,
217+
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
216218
fontSize: primitives.typographyFontSizeXs,
217219
fontWeight: primitives.typographyFontWeightRegular,
218220
lineHeight: primitives.typographyLineHeightTight,
219221
},
220222
});
221-
}, [semantics]);
223+
}, [
224+
shouldUseOverlayStyles,
225+
semantics.chatTextTimestamp,
226+
semantics.chatTextUsername,
227+
semantics.textOnAccent,
228+
]);
222229
};

0 commit comments

Comments
 (0)