2019-03-12 16:23:06 +00:00
|
|
|
import React, { Component } from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import {
|
2020-06-15 14:00:46 +00:00
|
|
|
ScrollView, Text, View, TouchableWithoutFeedback
|
2019-03-12 16:23:06 +00:00
|
|
|
} from 'react-native';
|
|
|
|
import { connect } from 'react-redux';
|
2021-02-26 16:01:45 +00:00
|
|
|
import { dequal } from 'dequal';
|
2019-03-12 16:23:06 +00:00
|
|
|
import Avatar from '../../containers/Avatar';
|
|
|
|
import Status from '../../containers/Status/Status';
|
2021-02-25 16:41:44 +00:00
|
|
|
import { logEvent, events } from '../../utils/log';
|
2019-03-12 16:23:06 +00:00
|
|
|
import I18n from '../../i18n';
|
|
|
|
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
|
|
|
import { CustomIcon } from '../../lib/Icons';
|
|
|
|
import styles from './styles';
|
|
|
|
import SidebarItem from './SidebarItem';
|
2019-12-04 16:39:53 +00:00
|
|
|
import { themes } from '../../constants/colors';
|
|
|
|
import { withTheme } from '../../theme';
|
2020-02-11 14:09:14 +00:00
|
|
|
import { getUserSelector } from '../../selectors/login';
|
2020-06-15 14:00:46 +00:00
|
|
|
import SafeAreaView from '../../containers/SafeAreaView';
|
2020-08-19 17:09:36 +00:00
|
|
|
import Navigation from '../../lib/Navigation';
|
2019-03-12 16:23:06 +00:00
|
|
|
|
2019-12-04 16:39:53 +00:00
|
|
|
const Separator = React.memo(({ theme }) => <View style={[styles.separator, { borderColor: themes[theme].separatorColor }]} />);
|
|
|
|
Separator.propTypes = {
|
|
|
|
theme: PropTypes.string
|
|
|
|
};
|
2019-03-12 16:23:06 +00:00
|
|
|
|
2019-08-07 13:51:34 +00:00
|
|
|
class Sidebar extends Component {
|
2019-03-12 16:23:06 +00:00
|
|
|
static propTypes = {
|
|
|
|
baseUrl: PropTypes.string,
|
|
|
|
navigation: PropTypes.object,
|
|
|
|
Site_Name: PropTypes.string.isRequired,
|
|
|
|
user: PropTypes.object,
|
2020-06-15 14:00:46 +00:00
|
|
|
state: PropTypes.string,
|
2019-12-04 16:39:53 +00:00
|
|
|
theme: PropTypes.string,
|
2019-11-25 20:01:17 +00:00
|
|
|
loadingServer: PropTypes.bool,
|
2020-02-21 16:13:05 +00:00
|
|
|
useRealName: PropTypes.bool,
|
2020-03-30 20:19:01 +00:00
|
|
|
allowStatusMessage: PropTypes.bool,
|
2021-02-25 16:41:44 +00:00
|
|
|
isMasterDetail: PropTypes.bool,
|
|
|
|
viewStatisticsPermission: PropTypes.object,
|
|
|
|
viewRoomAdministrationPermission: PropTypes.object,
|
|
|
|
viewUserAdministrationPermission: PropTypes.object,
|
|
|
|
viewPrivilegedSettingPermission: PropTypes.object
|
2019-03-12 16:23:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
2021-02-25 16:41:44 +00:00
|
|
|
showStatus: false
|
2019-03-12 16:23:06 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldComponentUpdate(nextProps, nextState) {
|
2020-03-30 20:19:01 +00:00
|
|
|
const { showStatus, isAdmin } = this.state;
|
2019-03-12 16:23:06 +00:00
|
|
|
const {
|
2021-02-25 16:41:44 +00:00
|
|
|
Site_Name, user, baseUrl, state, isMasterDetail, useRealName, theme, viewStatisticsPermission, viewRoomAdministrationPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission
|
2019-03-12 16:23:06 +00:00
|
|
|
} = this.props;
|
2020-06-15 14:00:46 +00:00
|
|
|
// Drawer navigation state
|
|
|
|
if (state?.index !== nextProps.state?.index) {
|
|
|
|
return true;
|
|
|
|
}
|
2019-03-12 16:23:06 +00:00
|
|
|
if (nextState.showStatus !== showStatus) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (nextProps.Site_Name !== Site_Name) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (nextProps.Site_Name !== Site_Name) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (nextProps.baseUrl !== baseUrl) {
|
|
|
|
return true;
|
|
|
|
}
|
2019-12-04 16:39:53 +00:00
|
|
|
if (nextProps.theme !== theme) {
|
|
|
|
return true;
|
|
|
|
}
|
2021-02-26 16:01:45 +00:00
|
|
|
if (!dequal(nextProps.user, user)) {
|
2020-10-30 13:12:02 +00:00
|
|
|
return true;
|
2019-03-12 16:23:06 +00:00
|
|
|
}
|
2020-06-15 14:00:46 +00:00
|
|
|
if (nextProps.isMasterDetail !== isMasterDetail) {
|
2019-11-25 20:01:17 +00:00
|
|
|
return true;
|
|
|
|
}
|
2020-02-21 16:13:05 +00:00
|
|
|
if (nextProps.useRealName !== useRealName) {
|
|
|
|
return true;
|
|
|
|
}
|
2019-09-24 20:10:50 +00:00
|
|
|
if (nextState.isAdmin !== isAdmin) {
|
|
|
|
return true;
|
|
|
|
}
|
2021-02-26 16:01:45 +00:00
|
|
|
if (!dequal(nextProps.viewStatisticsPermission, viewStatisticsPermission)) {
|
2021-02-25 16:41:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
2021-02-26 16:01:45 +00:00
|
|
|
if (!dequal(nextProps.viewRoomAdministrationPermission, viewRoomAdministrationPermission)) {
|
2021-02-25 16:41:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
2021-02-26 16:01:45 +00:00
|
|
|
if (!dequal(nextProps.viewUserAdministrationPermission, viewUserAdministrationPermission)) {
|
2021-02-25 16:41:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
2021-02-26 16:01:45 +00:00
|
|
|
if (!dequal(nextProps.viewPrivilegedSettingPermission, viewPrivilegedSettingPermission)) {
|
2021-02-25 16:41:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
2019-03-12 16:23:06 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-02-25 16:41:44 +00:00
|
|
|
|
|
|
|
getIsAdmin() {
|
|
|
|
const {
|
|
|
|
user, viewStatisticsPermission, viewRoomAdministrationPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission
|
|
|
|
} = this.props;
|
2019-09-16 20:26:32 +00:00
|
|
|
const { roles } = user;
|
2021-02-25 16:41:44 +00:00
|
|
|
const allPermissions = [viewStatisticsPermission, viewRoomAdministrationPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission];
|
|
|
|
let isAdmin = false;
|
|
|
|
|
|
|
|
if (roles) {
|
|
|
|
isAdmin = allPermissions.reduce((result, permission) => {
|
|
|
|
if (permission) {
|
|
|
|
return (
|
|
|
|
result || permission.some(r => roles.indexOf(r) !== -1)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
false);
|
2019-09-16 20:26:32 +00:00
|
|
|
}
|
2021-02-25 16:41:44 +00:00
|
|
|
return isAdmin;
|
2019-03-12 16:23:06 +00:00
|
|
|
}
|
|
|
|
|
2019-09-16 20:26:32 +00:00
|
|
|
sidebarNavigate = (route) => {
|
2020-08-05 13:15:56 +00:00
|
|
|
logEvent(events[`SIDEBAR_GO_${ route.replace('StackNavigator', '').replace('View', '').toUpperCase() }`]);
|
2020-08-19 17:09:36 +00:00
|
|
|
Navigation.navigate(route);
|
2019-09-16 20:26:32 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 14:00:46 +00:00
|
|
|
get currentItemKey() {
|
|
|
|
const { state } = this.props;
|
2020-07-08 17:00:23 +00:00
|
|
|
return state?.routeNames[state?.index];
|
2020-06-15 14:00:46 +00:00
|
|
|
}
|
|
|
|
|
2020-07-08 19:40:10 +00:00
|
|
|
onPressUser = () => {
|
|
|
|
const { navigation, isMasterDetail } = this.props;
|
|
|
|
if (isMasterDetail) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
navigation.closeDrawer();
|
|
|
|
}
|
|
|
|
|
2020-06-15 14:00:46 +00:00
|
|
|
renderAdmin = () => {
|
|
|
|
const { theme, isMasterDetail } = this.props;
|
2021-02-25 16:41:44 +00:00
|
|
|
if (!this.getIsAdmin()) {
|
2020-06-15 14:00:46 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
const routeName = isMasterDetail ? 'AdminPanelView' : 'AdminPanelStackNavigator';
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Separator theme={theme} />
|
|
|
|
<SidebarItem
|
|
|
|
text={I18n.t('Admin_Panel')}
|
2020-07-27 19:53:33 +00:00
|
|
|
left={<CustomIcon name='settings' size={20} color={themes[theme].titleText} />}
|
2020-07-30 13:26:17 +00:00
|
|
|
onPress={() => this.sidebarNavigate(routeName)}
|
2020-06-15 14:00:46 +00:00
|
|
|
testID='sidebar-settings'
|
|
|
|
current={this.currentItemKey === routeName}
|
|
|
|
/>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
renderNavigation = () => {
|
|
|
|
const { theme } = this.props;
|
2019-03-12 16:23:06 +00:00
|
|
|
return (
|
2019-09-24 20:26:56 +00:00
|
|
|
<>
|
2019-03-12 16:23:06 +00:00
|
|
|
<SidebarItem
|
|
|
|
text={I18n.t('Chats')}
|
2019-12-04 16:39:53 +00:00
|
|
|
left={<CustomIcon name='message' size={20} color={themes[theme].titleText} />}
|
2020-06-15 14:00:46 +00:00
|
|
|
onPress={() => this.sidebarNavigate('ChatsStackNavigator')}
|
2019-03-12 16:23:06 +00:00
|
|
|
testID='sidebar-chats'
|
2020-06-15 14:00:46 +00:00
|
|
|
current={this.currentItemKey === 'ChatsStackNavigator'}
|
2019-03-12 16:23:06 +00:00
|
|
|
/>
|
|
|
|
<SidebarItem
|
|
|
|
text={I18n.t('Profile')}
|
2019-12-04 16:39:53 +00:00
|
|
|
left={<CustomIcon name='user' size={20} color={themes[theme].titleText} />}
|
2020-06-15 14:00:46 +00:00
|
|
|
onPress={() => this.sidebarNavigate('ProfileStackNavigator')}
|
2019-03-12 16:23:06 +00:00
|
|
|
testID='sidebar-profile'
|
2020-06-15 14:00:46 +00:00
|
|
|
current={this.currentItemKey === 'ProfileStackNavigator'}
|
2019-03-12 16:23:06 +00:00
|
|
|
/>
|
|
|
|
<SidebarItem
|
|
|
|
text={I18n.t('Settings')}
|
2020-07-27 19:53:33 +00:00
|
|
|
left={<CustomIcon name='administration' size={20} color={themes[theme].titleText} />}
|
2020-06-15 14:00:46 +00:00
|
|
|
onPress={() => this.sidebarNavigate('SettingsStackNavigator')}
|
2019-03-12 16:23:06 +00:00
|
|
|
testID='sidebar-settings'
|
2020-06-15 14:00:46 +00:00
|
|
|
current={this.currentItemKey === 'SettingsStackNavigator'}
|
2019-03-12 16:23:06 +00:00
|
|
|
/>
|
2020-06-15 14:00:46 +00:00
|
|
|
{this.renderAdmin()}
|
2019-09-24 20:26:56 +00:00
|
|
|
</>
|
2019-03-12 16:23:06 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-03-30 20:19:01 +00:00
|
|
|
renderCustomStatus = () => {
|
|
|
|
const { user, theme } = this.props;
|
2019-03-12 16:23:06 +00:00
|
|
|
return (
|
2020-03-30 20:19:01 +00:00
|
|
|
<SidebarItem
|
|
|
|
text={user.statusText || I18n.t('Edit_Status')}
|
2021-03-31 17:47:17 +00:00
|
|
|
left={<Status size={24} status={user?.status} />}
|
2020-03-30 20:19:01 +00:00
|
|
|
right={<CustomIcon name='edit' size={20} color={themes[theme].titleText} />}
|
2020-07-30 13:26:17 +00:00
|
|
|
onPress={() => this.sidebarNavigate('StatusView')}
|
2020-03-30 20:19:01 +00:00
|
|
|
testID='sidebar-custom-status'
|
2019-03-12 16:23:06 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2019-11-25 20:01:17 +00:00
|
|
|
const {
|
2020-07-08 19:40:10 +00:00
|
|
|
user, Site_Name, baseUrl, useRealName, allowStatusMessage, isMasterDetail, theme
|
2019-11-25 20:01:17 +00:00
|
|
|
} = this.props;
|
2019-03-12 16:23:06 +00:00
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return (
|
2020-10-30 13:59:44 +00:00
|
|
|
<SafeAreaView testID='sidebar-view' style={{ backgroundColor: themes[theme].focusedBackground }} vertical={isMasterDetail}>
|
2019-12-04 16:39:53 +00:00
|
|
|
<ScrollView
|
|
|
|
style={[
|
|
|
|
styles.container,
|
|
|
|
{
|
2020-06-15 14:00:46 +00:00
|
|
|
backgroundColor: isMasterDetail
|
2019-12-04 16:39:53 +00:00
|
|
|
? themes[theme].backgroundColor
|
|
|
|
: themes[theme].focusedBackground
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
{...scrollPersistTaps}
|
|
|
|
>
|
2020-07-08 19:40:10 +00:00
|
|
|
<TouchableWithoutFeedback onPress={this.onPressUser} testID='sidebar-close-drawer'>
|
2020-06-15 14:00:46 +00:00
|
|
|
<View style={styles.header} theme={theme}>
|
|
|
|
<Avatar
|
|
|
|
text={user.username}
|
|
|
|
style={styles.avatar}
|
2020-10-30 13:12:02 +00:00
|
|
|
size={30}
|
2020-06-15 14:00:46 +00:00
|
|
|
/>
|
|
|
|
<View style={styles.headerTextContainer}>
|
|
|
|
<View style={styles.headerUsername}>
|
|
|
|
<Text numberOfLines={1} style={[styles.username, { color: themes[theme].titleText }]}>{useRealName ? user.name : user.username}</Text>
|
|
|
|
</View>
|
|
|
|
<Text
|
|
|
|
style={[styles.currentServerText, { color: themes[theme].titleText }]}
|
|
|
|
numberOfLines={1}
|
|
|
|
accessibilityLabel={`Connected to ${ baseUrl }`}
|
|
|
|
>{Site_Name}
|
|
|
|
</Text>
|
2019-03-12 16:23:06 +00:00
|
|
|
</View>
|
|
|
|
</View>
|
2020-06-15 14:00:46 +00:00
|
|
|
</TouchableWithoutFeedback>
|
2019-03-12 16:23:06 +00:00
|
|
|
|
2020-03-30 20:19:01 +00:00
|
|
|
<Separator theme={theme} />
|
2019-03-12 16:23:06 +00:00
|
|
|
|
2020-03-30 20:19:01 +00:00
|
|
|
{allowStatusMessage ? this.renderCustomStatus() : null}
|
2020-06-15 14:00:46 +00:00
|
|
|
{!isMasterDetail ? (
|
2020-03-30 20:19:01 +00:00
|
|
|
<>
|
|
|
|
<Separator theme={theme} />
|
|
|
|
{this.renderNavigation()}
|
|
|
|
<Separator theme={theme} />
|
|
|
|
</>
|
2020-06-15 14:00:46 +00:00
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
{this.renderAdmin()}
|
|
|
|
</>
|
|
|
|
)}
|
2019-03-12 16:23:06 +00:00
|
|
|
</ScrollView>
|
|
|
|
</SafeAreaView>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-08-07 13:51:34 +00:00
|
|
|
|
|
|
|
const mapStateToProps = state => ({
|
|
|
|
Site_Name: state.settings.Site_Name,
|
2020-02-11 14:09:14 +00:00
|
|
|
user: getUserSelector(state),
|
|
|
|
baseUrl: state.server.server,
|
2020-02-21 16:13:05 +00:00
|
|
|
loadingServer: state.server.loading,
|
2020-03-30 20:19:01 +00:00
|
|
|
useRealName: state.settings.UI_Use_Real_Name,
|
2020-06-15 14:00:46 +00:00
|
|
|
allowStatusMessage: state.settings.Accounts_AllowUserStatusMessageChange,
|
2021-02-25 16:41:44 +00:00
|
|
|
isMasterDetail: state.app.isMasterDetail,
|
|
|
|
viewStatisticsPermission: state.permissions['view-statistics'],
|
|
|
|
viewRoomAdministrationPermission: state.permissions['view-room-administration'],
|
|
|
|
viewUserAdministrationPermission: state.permissions['view-user-administration'],
|
|
|
|
viewPrivilegedSettingPermission: state.permissions['view-privileged-setting']
|
2019-08-07 13:51:34 +00:00
|
|
|
});
|
|
|
|
|
2020-06-15 14:00:46 +00:00
|
|
|
export default connect(mapStateToProps)(withTheme(Sidebar));
|