11import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
2- import Animated , { useAnimatedStyle , useSharedValue , withSpring , withTiming } from 'react-native-reanimated' ;
3- import { LayoutChangeEvent , Text , TouchableOpacity , View , Platform , StyleSheet } from 'react-native' ;
4- import { Close , Notification , Check , Delete , useTheme } from 'stream-chat-react-native' ;
2+ import Animated , {
3+ useAnimatedStyle ,
4+ useSharedValue ,
5+ withSpring ,
6+ withTiming ,
7+ } from 'react-native-reanimated' ;
8+ import {
9+ LayoutChangeEvent ,
10+ Text ,
11+ TouchableOpacity ,
12+ View ,
13+ Platform ,
14+ StyleSheet ,
15+ } from 'react-native' ;
16+ import { Close , Notification , Delete , useTheme } from 'stream-chat-react-native' ;
517import { styles as menuDrawerStyles } from './MenuDrawer.tsx' ;
618import AsyncStore from '../utils/AsyncStore.ts' ;
719import { StreamChat } from 'stream-chat' ;
20+ import { LabeledTextInput } from '../screens/AdvancedUserSelectorScreen.tsx' ;
821
9- export const SlideInView = ( { visible, children } : { visible : boolean ; children : React . ReactNode } ) => {
22+ export const SlideInView = ( {
23+ visible,
24+ children,
25+ } : {
26+ visible : boolean ;
27+ children : React . ReactNode ;
28+ } ) => {
1029 const animatedHeight = useSharedValue ( 0 ) ;
1130
1231 const onLayout = ( event : LayoutChangeEvent ) => {
1332 const { height } = event . nativeEvent . layout ;
1433 animatedHeight . value = height ;
1534 } ;
1635
17- const animatedStyle = useAnimatedStyle ( ( ) => ( {
18- height : withSpring ( visible ? animatedHeight . value : 0 , { damping : 10 } ) ,
19- opacity : withTiming ( visible ? 1 : 0 , { duration : 500 } ) ,
20- } ) , [ visible ] ) ;
36+ const animatedStyle = useAnimatedStyle (
37+ ( ) => ( {
38+ height : withSpring ( visible ? animatedHeight . value : 0 , { damping : 10 } ) ,
39+ opacity : withTiming ( visible ? 1 : 0 , { duration : 500 } ) ,
40+ } ) ,
41+ [ visible ] ,
42+ ) ;
2143
2244 return (
2345 < Animated . View style = { animatedStyle } >
24- { visible ? < View onLayout = { onLayout } style = { { position : 'absolute' , width : '100%' } } >
25- { children }
26- </ View > : null }
46+ { visible ? (
47+ < View onLayout = { onLayout } style = { { position : 'absolute' , width : '100%' } } >
48+ { children }
49+ </ View >
50+ ) : null }
2751 </ Animated . View >
2852 ) ;
2953} ;
3054
3155const isAndroid = Platform . OS === 'android' ;
3256
33- export const SecretMenu = ( { close, visible, chatClient } : { close : ( ) => void , visible : boolean , chatClient : StreamChat } ) => {
57+ type NotificationConfigItem = { label : string ; name : string ; id : string } ;
58+
59+ const SecretMenuNotificationConfigItem = ( {
60+ notificationConfigItem,
61+ storeProvider,
62+ isSelected,
63+ } : {
64+ notificationConfigItem : NotificationConfigItem ;
65+ storeProvider : ( item : NotificationConfigItem ) => void ;
66+ isSelected : boolean ;
67+ } ) => {
68+ const [ providerNameOverride , setProviderNameOverride ] = useState < string > ( '' ) ;
69+ const [ lastSubmittedOverride , setLastSubmittedOverride ] = useState < string | null > ( null ) ;
70+
71+ const asyncStorageKey = useMemo (
72+ ( ) => `@stream-rn-sampleapp-push-provider-${ notificationConfigItem . id } -override` ,
73+ [ notificationConfigItem ] ,
74+ ) ;
75+
76+ useEffect ( ( ) => {
77+ const getProviderNameOverride = async ( ) => {
78+ const nameOverride = await AsyncStore . getItem ( asyncStorageKey , '' ) ;
79+ setLastSubmittedOverride ( nameOverride ?? '' ) ;
80+ } ;
81+ getProviderNameOverride ( ) ;
82+ } , [ asyncStorageKey ] ) ;
83+
84+ const storeProviderNameOverride = useCallback ( async ( ) => {
85+ await AsyncStore . setItem ( asyncStorageKey , providerNameOverride ) ;
86+ setLastSubmittedOverride ( providerNameOverride ) ;
87+ } , [ asyncStorageKey , providerNameOverride ] ) ;
88+
89+ return (
90+ < View
91+ style = { [ styles . notificationItemContainer , { borderColor : isSelected ? 'green' : 'gray' } ] }
92+ >
93+ < TouchableOpacity
94+ style = { { flexDirection : 'row' } }
95+ onPress = { ( ) => storeProvider ( notificationConfigItem ) }
96+ >
97+ < Text style = { styles . notificationItem } > { notificationConfigItem . label } </ Text >
98+ < Text
99+ numberOfLines = { 1 }
100+ style = { { opacity : 0.7 , fontSize : 14 , marginLeft : 4 , maxWidth : 145 } }
101+ >
102+ { lastSubmittedOverride && lastSubmittedOverride . length > 0
103+ ? lastSubmittedOverride
104+ : notificationConfigItem . name }
105+ </ Text >
106+ </ TouchableOpacity >
107+ { isSelected ? (
108+ < >
109+ < LabeledTextInput
110+ onChangeText = { setProviderNameOverride }
111+ label = { 'PN Provider name override' }
112+ value = { providerNameOverride }
113+ />
114+ < TouchableOpacity style = { styles . submitButton } onPress = { storeProviderNameOverride } >
115+ < Text style = { { color : 'white' , fontSize : 12 } } > Submit</ Text >
116+ </ TouchableOpacity >
117+ </ >
118+ ) : null }
119+ </ View >
120+ ) ;
121+ } ;
122+
123+ export const SecretMenu = ( {
124+ close,
125+ visible,
126+ chatClient,
127+ } : {
128+ close : ( ) => void ;
129+ visible : boolean ;
130+ chatClient : StreamChat ;
131+ } ) => {
34132 const [ selectedProvider , setSelectedProvider ] = useState < string | null > ( null ) ;
35133 const {
36134 theme : {
37135 colors : { black, grey } ,
38136 } ,
39137 } = useTheme ( ) ;
40138
41- const notificationConfigItems = useMemo ( ( ) => [ { label : 'Firebase' , name : 'rn-fcm' , id : 'firebase' } , { label : 'APNs' , name : 'APN' , id : 'apn' } ] , [ ] ) ;
139+ const notificationConfigItems = useMemo (
140+ ( ) => [
141+ { label : 'Firebase' , name : 'rn-fcm' , id : 'firebase' } ,
142+ ...( isAndroid ? [ ] : [ { label : 'APNs' , name : 'APN' , id : 'apn' } ] ) ,
143+ ] ,
144+ [ ] ,
145+ ) ;
42146
43147 useEffect ( ( ) => {
44148 const getSelectedProvider = async ( ) => {
45- const provider = await AsyncStore . getItem ( '@stream-rn-sampleapp-push-provider' , notificationConfigItems [ 0 ] ) ;
149+ const provider = await AsyncStore . getItem (
150+ '@stream-rn-sampleapp-push-provider' ,
151+ notificationConfigItems [ 0 ] ,
152+ ) ;
46153 setSelectedProvider ( provider ?. id ?? 'firebase' ) ;
47154 } ;
48155 getSelectedProvider ( ) ;
49156 } , [ notificationConfigItems ] ) ;
50157
51- const storeProvider = useCallback ( async ( item : { label : string , name : string , id : string } ) => {
52- await AsyncStore . setItem ( '@stream-rn-sampleapp-push-provider' , item ) ;
53- setSelectedProvider ( item . id ) ;
158+ const storeProvider = useCallback ( async ( item : NotificationConfigItem ) => {
159+ await AsyncStore . setItem ( '@stream-rn-sampleapp-push-provider' , item ) ;
160+ setSelectedProvider ( item . id ) ;
54161 } , [ ] ) ;
55162
56163 const removeAllDevices = useCallback ( async ( ) => {
@@ -65,7 +172,7 @@ export const SecretMenu = ({ close, visible, chatClient }: { close: () => void,
65172 < View
66173 style = { [
67174 menuDrawerStyles . menuItem ,
68- { opacity : isAndroid ? 0.3 : 1 , alignItems : 'flex-start' } ,
175+ { alignItems : 'flex-start' } ,
69176 ] }
70177 >
71178 < Notification height = { 24 } pathFill = { grey } width = { 24 } />
@@ -81,14 +188,16 @@ export const SecretMenu = ({ close, visible, chatClient }: { close: () => void,
81188 >
82189 Notification Provider
83190 </ Text >
84- { isAndroid ? null : < View style = { { marginLeft : 16 } } >
191+ < View style = { { marginLeft : 16 } } >
85192 { notificationConfigItems . map ( ( item ) => (
86- < TouchableOpacity key = { item . id } style = { { paddingTop : 8 , flexDirection : 'row' } } onPress = { ( ) => storeProvider ( item ) } >
87- < Text style = { styles . notificationItem } > { item . label } </ Text >
88- { item . id === selectedProvider ? < Check height = { 16 } pathFill = { 'green' } width = { 16 } style = { { marginLeft : 12 } } /> : null }
89- </ TouchableOpacity >
193+ < SecretMenuNotificationConfigItem
194+ key = { item . id }
195+ notificationConfigItem = { item }
196+ storeProvider = { storeProvider }
197+ isSelected = { item . id === selectedProvider }
198+ />
90199 ) ) }
91- </ View > }
200+ </ View >
92201 </ View >
93202 </ View >
94203 < TouchableOpacity onPress = { removeAllDevices } style = { menuDrawerStyles . menuItem } >
@@ -126,9 +235,24 @@ export const SecretMenu = ({ close, visible, chatClient }: { close: () => void,
126235
127236export const styles = StyleSheet . create ( {
128237 separator : { height : 1 , width : '100%' , opacity : 0.2 } ,
129- notificationContainer : { } ,
238+ notificationItemContainer : {
239+ paddingTop : 8 ,
240+ marginTop : 12 ,
241+ borderRadius : 15 ,
242+ borderWidth : 2 ,
243+ padding : 8 ,
244+ width : 225 ,
245+ } ,
130246 notificationItem : {
131- fontSize : 13 ,
247+ fontSize : 15 ,
132248 fontWeight : '500' ,
133249 } ,
250+ submitButton : {
251+ flex : 1 ,
252+ marginTop : 8 ,
253+ borderRadius : 5 ,
254+ backgroundColor : 'lightskyblue' ,
255+ padding : 8 ,
256+ alignItems : 'center' ,
257+ } ,
134258} ) ;
0 commit comments