Chore: Hooks app/views/UserNotificationPreferenceView (#4502)
* Chore: Hooks app/views/UserNotificationPreferenceView * added trycatch and userId Co-authored-by: Gleidson Daniel Silva <gleidson10daniel@hotmail.com>
This commit is contained in:
parent
2a1bacaead
commit
ed66246d0a
|
@ -110,7 +110,7 @@ export interface INotificationPreferences {
|
||||||
enableMessageParserEarlyAdoption: boolean;
|
enableMessageParserEarlyAdoption: boolean;
|
||||||
desktopNotifications: TNotifications;
|
desktopNotifications: TNotifications;
|
||||||
pushNotifications: TNotifications;
|
pushNotifications: TNotifications;
|
||||||
emailNotificationMode?: 'mentions' | 'nothing';
|
emailNotificationMode: 'mentions' | 'nothing';
|
||||||
language?: string;
|
language?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,11 +150,7 @@ const ProfileStackNavigator = () => {
|
||||||
>
|
>
|
||||||
<ProfileStack.Screen name='ProfileView' component={ProfileView} options={ProfileView.navigationOptions} />
|
<ProfileStack.Screen name='ProfileView' component={ProfileView} options={ProfileView.navigationOptions} />
|
||||||
<ProfileStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
|
<ProfileStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
|
||||||
<ProfileStack.Screen
|
<ProfileStack.Screen name='UserNotificationPrefView' component={UserNotificationPrefView} />
|
||||||
name='UserNotificationPrefView'
|
|
||||||
component={UserNotificationPrefView}
|
|
||||||
options={UserNotificationPrefView.navigationOptions}
|
|
||||||
/>
|
|
||||||
<ProfileStack.Screen name='PickerView' component={PickerView} options={PickerView.navigationOptions} />
|
<ProfileStack.Screen name='PickerView' component={PickerView} options={PickerView.navigationOptions} />
|
||||||
</ProfileStack.Navigator>
|
</ProfileStack.Navigator>
|
||||||
);
|
);
|
||||||
|
|
|
@ -195,11 +195,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
|
||||||
<ModalStack.Screen name='E2EHowItWorksView' component={E2EHowItWorksView} />
|
<ModalStack.Screen name='E2EHowItWorksView' component={E2EHowItWorksView} />
|
||||||
<ModalStack.Screen name='E2EEnterYourPasswordView' component={E2EEnterYourPasswordView} />
|
<ModalStack.Screen name='E2EEnterYourPasswordView' component={E2EEnterYourPasswordView} />
|
||||||
<ModalStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
|
<ModalStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
|
||||||
<ModalStack.Screen
|
<ModalStack.Screen name='UserNotificationPrefView' component={UserNotificationPrefView} />
|
||||||
name='UserNotificationPrefView'
|
|
||||||
component={UserNotificationPrefView}
|
|
||||||
options={UserNotificationPrefView.navigationOptions}
|
|
||||||
/>
|
|
||||||
<ModalStack.Screen name='SecurityPrivacyView' component={SecurityPrivacyView} />
|
<ModalStack.Screen name='SecurityPrivacyView' component={SecurityPrivacyView} />
|
||||||
<ModalStack.Screen
|
<ModalStack.Screen
|
||||||
name='E2EEncryptionSecurityView'
|
name='E2EEncryptionSecurityView'
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { StyleSheet, Text } from 'react-native';
|
||||||
|
|
||||||
|
import * as List from '../../containers/List';
|
||||||
|
import I18n from '../../i18n';
|
||||||
|
import { useTheme } from '../../theme';
|
||||||
|
import sharedStyles from '../Styles';
|
||||||
|
import { OPTIONS } from './options';
|
||||||
|
import { CustomIcon } from '../../containers/CustomIcon';
|
||||||
|
import { useActionSheet } from '../../containers/ActionSheet';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
pickerText: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
type TKey = 'desktopNotifications' | 'pushNotifications' | 'emailNotificationMode';
|
||||||
|
|
||||||
|
interface IBaseParams {
|
||||||
|
preference: TKey;
|
||||||
|
value: string;
|
||||||
|
onChangeValue: (param: { [key: string]: string }, onError: () => void) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListPicker = ({
|
||||||
|
preference,
|
||||||
|
value,
|
||||||
|
title,
|
||||||
|
testID,
|
||||||
|
onChangeValue
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
testID: string;
|
||||||
|
} & IBaseParams) => {
|
||||||
|
const { showActionSheet, hideActionSheet } = useActionSheet();
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const [option, setOption] = useState(
|
||||||
|
value ? OPTIONS[preference].find(option => option.value === value) : OPTIONS[preference][0]
|
||||||
|
);
|
||||||
|
|
||||||
|
const getOptions = () =>
|
||||||
|
OPTIONS[preference].map(i => ({
|
||||||
|
title: I18n.t(i.label, { defaultValue: i.label }),
|
||||||
|
onPress: () => {
|
||||||
|
hideActionSheet();
|
||||||
|
onChangeValue({ [preference]: i.value.toString() }, () => setOption(option));
|
||||||
|
setOption(i);
|
||||||
|
},
|
||||||
|
right: option?.value === i.value ? () => <CustomIcon name={'check'} size={20} color={colors.tintActive} /> : undefined
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<List.Item
|
||||||
|
title={title}
|
||||||
|
testID={testID}
|
||||||
|
onPress={() => showActionSheet({ options: getOptions() })}
|
||||||
|
right={() => (
|
||||||
|
<Text style={[styles.pickerText, { color: colors.actionTintColor }]}>
|
||||||
|
{option?.label ? I18n.t(option?.label, { defaultValue: option?.label }) : option?.label}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPicker;
|
|
@ -1,124 +1,63 @@
|
||||||
import React from 'react';
|
import React, { useEffect, useLayoutEffect, useState } from 'react';
|
||||||
import { StyleSheet, Text } from 'react-native';
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { themes } from '../../lib/constants';
|
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import * as List from '../../containers/List';
|
import * as List from '../../containers/List';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { TSupportedThemes, withTheme } from '../../theme';
|
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import { getUserSelector } from '../../selectors/login';
|
import { getUserSelector } from '../../selectors/login';
|
||||||
import sharedStyles from '../Styles';
|
|
||||||
import { OPTIONS } from './options';
|
|
||||||
import { ProfileStackParamList } from '../../stacks/types';
|
import { ProfileStackParamList } from '../../stacks/types';
|
||||||
import { IApplicationState, INotificationPreferences, IUser } from '../../definitions';
|
import { INotificationPreferences } from '../../definitions';
|
||||||
import { Services } from '../../lib/services';
|
import { Services } from '../../lib/services';
|
||||||
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
|
import ListPicker from './ListPicker';
|
||||||
|
import log from '../../lib/methods/helpers/log';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const UserNotificationPreferencesView = () => {
|
||||||
pickerText: {
|
const [preferences, setPreferences] = useState({} as INotificationPreferences);
|
||||||
...sharedStyles.textRegular,
|
const [loading, setLoading] = useState(false);
|
||||||
fontSize: 16
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
type TKey = 'desktopNotifications' | 'pushNotifications' | 'emailNotificationMode';
|
const navigation = useNavigation<StackNavigationProp<ProfileStackParamList, 'UserNotificationPrefView'>>();
|
||||||
|
const userId = useAppSelector(state => getUserSelector(state).id);
|
||||||
|
|
||||||
interface IUserNotificationPreferencesViewState {
|
useLayoutEffect(() => {
|
||||||
preferences: INotificationPreferences;
|
navigation.setOptions({
|
||||||
loading: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IUserNotificationPreferencesViewProps {
|
|
||||||
navigation: StackNavigationProp<ProfileStackParamList, 'UserNotificationPrefView'>;
|
|
||||||
theme: TSupportedThemes;
|
|
||||||
user: IUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
class UserNotificationPreferencesView extends React.Component<
|
|
||||||
IUserNotificationPreferencesViewProps,
|
|
||||||
IUserNotificationPreferencesViewState
|
|
||||||
> {
|
|
||||||
static navigationOptions = (): StackNavigationOptions => ({
|
|
||||||
title: I18n.t('Notification_Preferences')
|
title: I18n.t('Notification_Preferences')
|
||||||
});
|
});
|
||||||
|
}, [navigation]);
|
||||||
|
|
||||||
constructor(props: IUserNotificationPreferencesViewProps) {
|
useEffect(() => {
|
||||||
super(props);
|
async function getPreferences() {
|
||||||
this.state = {
|
try {
|
||||||
preferences: {} as INotificationPreferences,
|
const result = await Services.getUserPreferences(userId);
|
||||||
loading: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async componentDidMount() {
|
|
||||||
const { user } = this.props;
|
|
||||||
const { id } = user;
|
|
||||||
const result = await Services.getUserPreferences(id);
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
const { preferences } = result;
|
setLoading(true);
|
||||||
this.setState({ preferences, loading: true });
|
setPreferences(result.preferences);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
getPreferences();
|
||||||
|
}, [userId]);
|
||||||
|
|
||||||
findDefaultOption = (key: TKey) => {
|
const onValueChangePicker = async (param: { [key: string]: string }, onError: () => void) => {
|
||||||
const { preferences } = this.state;
|
try {
|
||||||
const option = preferences[key] ? OPTIONS[key].find(item => item.value === preferences[key]) : OPTIONS[key][0];
|
const result = await Services.setUserPreferences(userId, param);
|
||||||
return option;
|
|
||||||
};
|
|
||||||
|
|
||||||
renderPickerOption = (key: TKey) => {
|
|
||||||
const { theme } = this.props;
|
|
||||||
const text = this.findDefaultOption(key);
|
|
||||||
return (
|
|
||||||
<Text style={[styles.pickerText, { color: themes[theme].actionTintColor }]}>
|
|
||||||
{text?.label ? I18n.t(text?.label) : text?.label}
|
|
||||||
</Text>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
pickerSelection = (title: string, key: TKey) => {
|
|
||||||
const { preferences } = this.state;
|
|
||||||
const { navigation } = this.props;
|
|
||||||
let values = OPTIONS[key];
|
|
||||||
|
|
||||||
const defaultOption = this.findDefaultOption(key);
|
|
||||||
if (OPTIONS[key][0]?.value !== 'default') {
|
|
||||||
const defaultValue = {
|
|
||||||
label: `${I18n.t('Default')} (${defaultOption?.label ? I18n.t(defaultOption?.label) : defaultOption?.label})`
|
|
||||||
} as {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
values = [defaultValue, ...OPTIONS[key]];
|
|
||||||
}
|
|
||||||
|
|
||||||
navigation.navigate('PickerView', {
|
|
||||||
title,
|
|
||||||
data: values,
|
|
||||||
value: preferences[key],
|
|
||||||
onChangeValue: (value: string) => this.onValueChangePicker(key, value ?? defaultOption?.value)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onValueChangePicker = (key: TKey, value: string) => this.saveNotificationPreferences({ [key]: value.toString() });
|
|
||||||
|
|
||||||
saveNotificationPreferences = async (params: { [key: string]: string }) => {
|
|
||||||
const { user } = this.props;
|
|
||||||
const { id } = user;
|
|
||||||
const result = await Services.setUserPreferences(id, params);
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
const {
|
const {
|
||||||
user: { settings }
|
user: { settings }
|
||||||
} = result;
|
} = result;
|
||||||
this.setState({ preferences: settings.preferences });
|
setPreferences(settings.preferences);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log(error);
|
||||||
|
onError();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
|
||||||
const { loading } = this.state;
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView testID='user-notification-preference-view'>
|
<SafeAreaView testID='user-notification-preference-view'>
|
||||||
<StatusBar />
|
<StatusBar />
|
||||||
|
@ -127,11 +66,12 @@ class UserNotificationPreferencesView extends React.Component<
|
||||||
<>
|
<>
|
||||||
<List.Section title='Desktop_Notifications'>
|
<List.Section title='Desktop_Notifications'>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
<List.Item
|
<ListPicker
|
||||||
|
onChangeValue={onValueChangePicker}
|
||||||
|
preference={'desktopNotifications'}
|
||||||
title='Alert'
|
title='Alert'
|
||||||
testID='user-notification-preference-view-alert'
|
testID='user-notification-preference-view-alert'
|
||||||
onPress={(title: string) => this.pickerSelection(title, 'desktopNotifications')}
|
value={preferences.desktopNotifications}
|
||||||
right={() => this.renderPickerOption('desktopNotifications')}
|
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
<List.Info info='Desktop_Alert_info' />
|
<List.Info info='Desktop_Alert_info' />
|
||||||
|
@ -139,11 +79,12 @@ class UserNotificationPreferencesView extends React.Component<
|
||||||
|
|
||||||
<List.Section title='Push_Notifications'>
|
<List.Section title='Push_Notifications'>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
<List.Item
|
<ListPicker
|
||||||
|
onChangeValue={onValueChangePicker}
|
||||||
|
preference={'pushNotifications'}
|
||||||
title='Alert'
|
title='Alert'
|
||||||
testID='user-notification-preference-view-push-notification'
|
testID='user-notification-preference-view-push-notification'
|
||||||
onPress={(title: string) => this.pickerSelection(title, 'pushNotifications')}
|
value={preferences.pushNotifications}
|
||||||
right={() => this.renderPickerOption('pushNotifications')}
|
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
<List.Info info='Push_Notifications_Alert_Info' />
|
<List.Info info='Push_Notifications_Alert_Info' />
|
||||||
|
@ -151,11 +92,12 @@ class UserNotificationPreferencesView extends React.Component<
|
||||||
|
|
||||||
<List.Section title='Email'>
|
<List.Section title='Email'>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
<List.Item
|
<ListPicker
|
||||||
|
onChangeValue={onValueChangePicker}
|
||||||
|
preference={'emailNotificationMode'}
|
||||||
title='Alert'
|
title='Alert'
|
||||||
testID='user-notification-preference-view-email-alert'
|
testID='user-notification-preference-view-email-alert'
|
||||||
onPress={(title: string) => this.pickerSelection(title, 'emailNotificationMode')}
|
value={preferences.emailNotificationMode}
|
||||||
right={() => this.renderPickerOption('emailNotificationMode')}
|
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
<List.Info info='You_need_to_verifiy_your_email_address_to_get_notications' />
|
<List.Info info='You_need_to_verifiy_your_email_address_to_get_notications' />
|
||||||
|
@ -167,11 +109,6 @@ class UserNotificationPreferencesView extends React.Component<
|
||||||
</List.Container>
|
</List.Container>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const mapStateToProps = (state: IApplicationState) => ({
|
export default UserNotificationPreferencesView;
|
||||||
user: getUserSelector(state)
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withTheme(UserNotificationPreferencesView));
|
|
||||||
|
|
Loading…
Reference in New Issue