import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
ScrollView, Text, View, TouchableWithoutFeedback
} from 'react-native';
import { connect } from 'react-redux';
import { Q } from '@nozbe/watermelondb';
import Avatar from '../../containers/Avatar';
import Status from '../../containers/Status/Status';
import log, { logEvent, events } from '../../utils/log';
import I18n from '../../i18n';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { CustomIcon } from '../../lib/Icons';
import styles from './styles';
import SidebarItem from './SidebarItem';
import { themes } from '../../constants/colors';
import database from '../../lib/database';
import { withTheme } from '../../theme';
import { getUserSelector } from '../../selectors/login';
import SafeAreaView from '../../containers/SafeAreaView';
const Separator = React.memo(({ theme }) => );
Separator.propTypes = {
theme: PropTypes.string
};
const permissions = [
'view-statistics',
'view-room-administration',
'view-user-administration',
'view-privileged-setting'
];
class Sidebar extends Component {
static propTypes = {
baseUrl: PropTypes.string,
navigation: PropTypes.object,
Site_Name: PropTypes.string.isRequired,
user: PropTypes.object,
state: PropTypes.string,
theme: PropTypes.string,
loadingServer: PropTypes.bool,
useRealName: PropTypes.bool,
allowStatusMessage: PropTypes.bool,
isMasterDetail: PropTypes.bool
}
constructor(props) {
super(props);
this.state = {
showStatus: false,
isAdmin: false
};
}
componentDidMount() {
this.setIsAdmin();
}
UNSAFE_componentWillReceiveProps(nextProps) {
const { loadingServer } = this.props;
if (loadingServer && nextProps.loadingServer !== loadingServer) {
this.setIsAdmin();
}
}
shouldComponentUpdate(nextProps, nextState) {
const { showStatus, isAdmin } = this.state;
const {
Site_Name, user, baseUrl, state, isMasterDetail, useRealName, theme
} = this.props;
// Drawer navigation state
if (state?.index !== nextProps.state?.index) {
return true;
}
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;
}
if (nextProps.theme !== theme) {
return true;
}
if (nextProps.user && user) {
if (nextProps.user.language !== user.language) {
return true;
}
if (nextProps.user.status !== user.status) {
return true;
}
if (nextProps.user.username !== user.username) {
return true;
}
if (nextProps.user.statusText !== user.statusText) {
return true;
}
}
if (nextProps.isMasterDetail !== isMasterDetail) {
return true;
}
if (nextProps.useRealName !== useRealName) {
return true;
}
if (nextState.isAdmin !== isAdmin) {
return true;
}
return false;
}
async setIsAdmin() {
const db = database.active;
const { user } = this.props;
const { roles } = user;
try {
if (roles) {
const permissionsCollection = db.collections.get('permissions');
const permissionsFiltered = await permissionsCollection.query(Q.where('id', Q.oneOf(permissions))).fetch();
const isAdmin = permissionsFiltered.reduce((result, permission) => (
result || permission.roles.some(r => roles.indexOf(r) !== -1)),
false);
this.setState({ isAdmin });
}
} catch (e) {
log(e);
}
}
sidebarNavigate = (route) => {
logEvent(events[`SIDEBAR_NAVIGATE_TO_${ route.replace('StackNavigator', '').replace('View', '').toUpperCase() }`]);
const { navigation } = this.props;
navigation.navigate(route);
}
get currentItemKey() {
const { state } = this.props;
return state?.routeNames[state?.index];
}
onPressUser = () => {
const { navigation, isMasterDetail } = this.props;
if (isMasterDetail) {
return;
}
navigation.closeDrawer();
}
renderAdmin = () => {
const { isAdmin } = this.state;
const { theme, isMasterDetail } = this.props;
if (!isAdmin) {
return null;
}
const routeName = isMasterDetail ? 'AdminPanelView' : 'AdminPanelStackNavigator';
return (
<>
}
onPress={() => this.sidebarNavigate(routeName)}
testID='sidebar-settings'
current={this.currentItemKey === routeName}
/>
>
);
}
renderNavigation = () => {
const { theme } = this.props;
return (
<>
}
onPress={() => this.sidebarNavigate('ChatsStackNavigator')}
testID='sidebar-chats'
current={this.currentItemKey === 'ChatsStackNavigator'}
/>
}
onPress={() => this.sidebarNavigate('ProfileStackNavigator')}
testID='sidebar-profile'
current={this.currentItemKey === 'ProfileStackNavigator'}
/>
}
onPress={() => this.sidebarNavigate('SettingsStackNavigator')}
testID='sidebar-settings'
current={this.currentItemKey === 'SettingsStackNavigator'}
/>
{this.renderAdmin()}
>
);
}
renderCustomStatus = () => {
const { user, theme } = this.props;
return (
}
right={}
onPress={() => this.sidebarNavigate('StatusView')}
testID='sidebar-custom-status'
/>
);
}
render() {
const {
user, Site_Name, baseUrl, useRealName, allowStatusMessage, isMasterDetail, theme
} = this.props;
if (!user) {
return null;
}
return (
{useRealName ? user.name : user.username}
{Site_Name}
{allowStatusMessage ? this.renderCustomStatus() : null}
{!isMasterDetail ? (
<>
{this.renderNavigation()}
>
) : (
<>
{this.renderAdmin()}
>
)}
);
}
}
const mapStateToProps = state => ({
Site_Name: state.settings.Site_Name,
user: getUserSelector(state),
baseUrl: state.server.server,
loadingServer: state.server.loading,
useRealName: state.settings.UI_Use_Real_Name,
allowStatusMessage: state.settings.Accounts_AllowUserStatusMessageChange,
isMasterDetail: state.app.isMasterDetail
});
export default connect(mapStateToProps)(withTheme(Sidebar));