Skip to content

Commit 59003f8

Browse files
authored
chore: migrate SidebarView to hooks (#6506)
1 parent 3c52112 commit 59003f8

File tree

8 files changed

+324
-387
lines changed

8 files changed

+324
-387
lines changed

app/views/SettingsView/index.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,7 @@ const SettingsView = (): React.ReactElement => {
168168
{isMasterDetail ? (
169169
<>
170170
<List.Section>
171-
<List.Separator />
172-
<SidebarView />
173-
<List.Separator />
171+
<SidebarView navigation={navigation as any} />
174172
</List.Section>
175173
<List.Section>
176174
<List.Separator />
@@ -230,6 +228,7 @@ const SettingsView = (): React.ReactElement => {
230228
</List.Section>
231229

232230
<List.Section>
231+
<List.Separator />
233232
<List.Item
234233
title='Get_help'
235234
left={() => <List.Icon name='support' />}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { memo, useMemo } from 'react';
2+
3+
import * as List from '../../../containers/List';
4+
import { useAppSelector, usePermissions } from '../../../lib/hooks';
5+
import { useTheme } from '../../../theme';
6+
import { sidebarNavigate } from '../methods/sidebarNavigate';
7+
8+
const Admin = ({ currentScreen }: { currentScreen: string | null }) => {
9+
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
10+
const { colors } = useTheme();
11+
const [
12+
viewStatisticsPermission,
13+
viewRoomAdministrationPermission,
14+
viewUserAdministrationPermission,
15+
viewPrivilegedSettingPermission
16+
] = usePermissions(['view-statistics', 'view-room-administration', 'view-user-administration', 'view-privileged-setting']);
17+
18+
const isAdmin = useMemo(
19+
() =>
20+
[
21+
viewStatisticsPermission,
22+
viewRoomAdministrationPermission,
23+
viewUserAdministrationPermission,
24+
viewPrivilegedSettingPermission
25+
].some(permission => permission),
26+
[
27+
viewStatisticsPermission,
28+
viewRoomAdministrationPermission,
29+
viewUserAdministrationPermission,
30+
viewPrivilegedSettingPermission
31+
]
32+
);
33+
34+
if (!isAdmin) {
35+
return null;
36+
}
37+
const routeName = isMasterDetail ? 'AdminPanelView' : 'AdminPanelStackNavigator';
38+
return (
39+
<>
40+
<List.Item
41+
title={'Admin_Panel'}
42+
left={() => <List.Icon name='settings' />}
43+
onPress={() => sidebarNavigate(routeName)}
44+
backgroundColor={currentScreen === routeName ? colors.strokeLight : undefined}
45+
/>
46+
<List.Separator />
47+
</>
48+
);
49+
};
50+
51+
export default memo(Admin);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { memo } from 'react';
2+
import { Alert, Linking, View } from 'react-native';
3+
import { shallowEqual, useDispatch } from 'react-redux';
4+
5+
import { CustomIcon } from '../../../containers/CustomIcon';
6+
import Status from '../../../containers/Status/Status';
7+
import * as List from '../../../containers/List';
8+
import styles from '../styles';
9+
import { useTheme } from '../../../theme';
10+
import { useAppSelector } from '../../../lib/hooks';
11+
import { getUserSelector } from '../../../selectors/login';
12+
import { setNotificationPresenceCap } from '../../../actions/app';
13+
import userPreferences from '../../../lib/methods/userPreferences';
14+
import I18n from '../../../i18n';
15+
import { NOTIFICATION_PRESENCE_CAP } from '../../../lib/constants';
16+
import { sidebarNavigate } from '../methods/sidebarNavigate';
17+
18+
const CustomStatus = () => {
19+
const { colors } = useTheme();
20+
const { status: userStatus, statusText } = useAppSelector(getUserSelector, shallowEqual);
21+
const presenceBroadcastDisabled = useAppSelector(state => state.settings.Presence_broadcast_disabled) as boolean;
22+
const notificationPresenceCap = useAppSelector(state => state.app.notificationPresenceCap);
23+
const allowStatusMessage = useAppSelector(state => state.settings.Accounts_AllowUserStatusMessageChange);
24+
const dispatch = useDispatch();
25+
26+
const onPressPresenceLearnMore = () => {
27+
dispatch(setNotificationPresenceCap(false));
28+
userPreferences.setBool(NOTIFICATION_PRESENCE_CAP, false);
29+
30+
Alert.alert(
31+
I18n.t('Presence_Cap_Warning_Title'),
32+
I18n.t('Presence_Cap_Warning_Description'),
33+
[
34+
{
35+
text: I18n.t('Learn_more'),
36+
onPress: () => Linking.openURL('https://go.rocket.chat/i/presence-cap-learn-more'),
37+
style: 'cancel'
38+
},
39+
{
40+
text: I18n.t('Close'),
41+
style: 'default'
42+
}
43+
],
44+
{ cancelable: false }
45+
);
46+
};
47+
48+
let status = userStatus;
49+
if (presenceBroadcastDisabled) {
50+
status = 'disabled';
51+
}
52+
53+
let right: (() => JSX.Element | null) | undefined = () => <CustomIcon name='edit' size={20} color={colors.fontTitlesLabels} />;
54+
if (notificationPresenceCap) {
55+
right = () => <View style={[styles.customStatusDisabled, { backgroundColor: colors.userPresenceDisabled }]} />;
56+
} else if (presenceBroadcastDisabled) {
57+
right = undefined;
58+
}
59+
60+
if (!allowStatusMessage) {
61+
return null;
62+
}
63+
64+
return (
65+
<>
66+
<List.Item
67+
title={statusText || 'Edit_Status'}
68+
left={() => <Status size={24} status={status} />}
69+
right={right}
70+
onPress={() => (presenceBroadcastDisabled ? onPressPresenceLearnMore() : sidebarNavigate('StatusView'))}
71+
translateTitle={!statusText}
72+
testID={`sidebar-custom-status-${status}`}
73+
/>
74+
<List.Separator />
75+
</>
76+
);
77+
};
78+
79+
export default memo(CustomStatus);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { memo } from 'react';
2+
import { DrawerNavigationProp } from '@react-navigation/drawer';
3+
import { Text, TouchableWithoutFeedback, View } from 'react-native';
4+
import { shallowEqual } from 'react-redux';
5+
6+
import Avatar from '../../../containers/Avatar';
7+
import { useTheme } from '../../../theme';
8+
import { getUserSelector } from '../../../selectors/login';
9+
import styles from '../styles';
10+
import { DrawerParamList } from '../../../stacks/types';
11+
import * as List from '../../../containers/List';
12+
import { useAppSelector } from '../../../lib/hooks';
13+
14+
const Profile = ({ navigation }: { navigation: DrawerNavigationProp<DrawerParamList> }) => {
15+
const { colors } = useTheme();
16+
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
17+
const { username, name } = useAppSelector(getUserSelector, shallowEqual);
18+
const useRealName = useAppSelector(state => state.settings.UI_Use_Real_Name);
19+
const server = useAppSelector(state => state.server.server);
20+
const siteName = useAppSelector(state => state.settings.Site_Name) as string;
21+
22+
const onPressUser = () => {
23+
if (isMasterDetail) {
24+
return;
25+
}
26+
navigation.closeDrawer();
27+
};
28+
29+
return (
30+
<>
31+
<List.Separator />
32+
<TouchableWithoutFeedback onPress={onPressUser} testID='sidebar-close-drawer'>
33+
<View style={[styles.header, { backgroundColor: colors.surfaceRoom }]}>
34+
<Avatar text={username} style={styles.avatar} size={30} />
35+
<View style={styles.headerTextContainer}>
36+
<View style={styles.headerUsername}>
37+
<Text numberOfLines={1} style={[styles.username, { color: colors.fontTitlesLabels }]}>
38+
{useRealName ? name : username}
39+
</Text>
40+
</View>
41+
<Text
42+
style={[styles.currentServerText, { color: colors.fontTitlesLabels }]}
43+
numberOfLines={1}
44+
accessibilityLabel={`Connected to ${server}`}>
45+
{siteName}
46+
</Text>
47+
</View>
48+
</View>
49+
</TouchableWithoutFeedback>
50+
<List.Separator />
51+
</>
52+
);
53+
};
54+
55+
export default memo(Profile);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { memo } from 'react';
2+
3+
import { useTheme } from '../../../theme';
4+
import * as List from '../../../containers/List';
5+
import { sidebarNavigate } from '../methods/sidebarNavigate';
6+
import { useAppSelector } from '../../../lib/hooks';
7+
8+
const Stacks = ({ currentScreen }: { currentScreen: string | null }) => {
9+
const { colors } = useTheme();
10+
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
11+
12+
if (isMasterDetail) {
13+
return null;
14+
}
15+
16+
return (
17+
<>
18+
<List.Item
19+
title={'Chats'}
20+
left={() => <List.Icon name='message' />}
21+
onPress={() => sidebarNavigate('ChatsStackNavigator')}
22+
backgroundColor={currentScreen === 'ChatsStackNavigator' ? colors.strokeLight : undefined}
23+
testID='sidebar-chats'
24+
/>
25+
<List.Separator />
26+
<List.Item
27+
title={'Profile'}
28+
left={() => <List.Icon name='user' />}
29+
onPress={() => sidebarNavigate('ProfileStackNavigator')}
30+
backgroundColor={currentScreen === 'ProfileStackNavigator' ? colors.strokeLight : undefined}
31+
testID='sidebar-profile'
32+
/>
33+
<List.Separator />
34+
<List.Item
35+
title={'Accessibility_and_Appearance'}
36+
left={() => <List.Icon name='accessibility' />}
37+
onPress={() => sidebarNavigate('AccessibilityStackNavigator')}
38+
backgroundColor={currentScreen === 'AccessibilityStackNavigator' ? colors.strokeLight : undefined}
39+
testID='sidebar-accessibility'
40+
/>
41+
<List.Separator />
42+
<List.Item
43+
title={'Settings'}
44+
left={() => <List.Icon name='administration' />}
45+
onPress={() => sidebarNavigate('SettingsStackNavigator')}
46+
backgroundColor={currentScreen === 'SettingsStackNavigator' ? colors.strokeLight : undefined}
47+
testID='sidebar-settings'
48+
/>
49+
<List.Separator />
50+
</>
51+
);
52+
};
53+
export default memo(Stacks);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { memo } from 'react';
2+
3+
import { useTheme } from '../../../theme';
4+
import { CustomIcon } from '../../../containers/CustomIcon';
5+
import * as List from '../../../containers/List';
6+
import { useAppSelector } from '../../../lib/hooks';
7+
import { showActionSheetRef } from '../../../containers/ActionSheet';
8+
import Navigation from '../../../lib/navigation/appNavigation';
9+
import { SupportedVersionsWarning } from '../../../containers/SupportedVersions';
10+
11+
const SupportedVersionsWarnItem = () => {
12+
const { colors } = useTheme();
13+
const supportedVersionsStatus = useAppSelector(state => state.supportedVersions.status);
14+
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
15+
16+
const onPressSupportedVersionsWarning = () => {
17+
if (isMasterDetail) {
18+
Navigation.navigate('ModalStackNavigator', { screen: 'SupportedVersionsWarning' });
19+
} else {
20+
showActionSheetRef({ children: <SupportedVersionsWarning /> });
21+
}
22+
};
23+
24+
if (supportedVersionsStatus === 'warn') {
25+
return (
26+
<>
27+
<List.Item
28+
title={'Supported_versions_warning_update_required'}
29+
color={colors.fontDanger}
30+
left={() => <CustomIcon name='warning' size={20} color={colors.buttonBackgroundDangerDefault} />}
31+
onPress={onPressSupportedVersionsWarning}
32+
testID={`sidebar-supported-versions-warn`}
33+
/>
34+
<List.Separator />
35+
</>
36+
);
37+
}
38+
return null;
39+
};
40+
41+
export default memo(SupportedVersionsWarnItem);

0 commit comments

Comments
 (0)