Chore: Migrate SidebarView to Typescript (#3478)

Co-authored-by: AlexAlexandre <alexalexandrejr@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Reinaldo Neto 2021-11-10 17:14:45 -03:00 committed by GitHub
parent e17817ae06
commit 64f7b1f84f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 45 deletions

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { StyleProp, TextStyle } from 'react-native';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
import { STATUS_COLORS } from '../../constants/colors'; import { STATUS_COLORS } from '../../constants/colors';
@ -6,14 +7,14 @@ import { STATUS_COLORS } from '../../constants/colors';
interface IStatus { interface IStatus {
status: string; status: string;
size: number; size: number;
style: any; style?: StyleProp<TextStyle>;
} }
const Status = React.memo(({ style, status = 'offline', size = 32, ...props }: IStatus) => { const Status = React.memo(({ style, status = 'offline', size = 32, ...props }: IStatus) => {
const name = `status-${status}`; const name = `status-${status}`;
const isNameValid = CustomIcon.hasIcon(name); const isNameValid = CustomIcon.hasIcon(name);
const iconName = isNameValid ? name : 'status-offline'; const iconName = isNameValid ? name : 'status-offline';
const calculatedStyle = [ const calculatedStyle: StyleProp<TextStyle> = [
{ {
width: size, width: size,
height: size, height: size,

View File

@ -1,13 +1,22 @@
import React from 'react'; import React from 'react';
import { Text, View } from 'react-native'; import { Text, View } from 'react-native';
import PropTypes from 'prop-types';
import Touch from '../../utils/touch'; import Touch from '../../utils/touch';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { withTheme } from '../../theme'; import { withTheme } from '../../theme';
import styles from './styles'; import styles from './styles';
const Item = React.memo(({ left, right, text, onPress, testID, current, theme }) => ( interface SidebarItemProps {
left: JSX.Element;
right: JSX.Element;
text: string;
current: boolean;
onPress(): void;
testID: string;
theme: string;
}
const Item = React.memo(({ left, right, text, onPress, testID, current, theme }: SidebarItemProps) => (
<Touch <Touch
key={testID} key={testID}
testID={testID} testID={testID}
@ -24,14 +33,4 @@ const Item = React.memo(({ left, right, text, onPress, testID, current, theme })
</Touch> </Touch>
)); ));
Item.propTypes = {
left: PropTypes.element,
right: PropTypes.element,
text: PropTypes.string,
current: PropTypes.bool,
onPress: PropTypes.func,
testID: PropTypes.string,
theme: PropTypes.string
};
export default withTheme(Item); export default withTheme(Item);

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import { DrawerNavigationProp } from '@react-navigation/drawer';
import { DrawerNavigationState } from '@react-navigation/native';
import { ScrollView, Text, TouchableWithoutFeedback, View } from 'react-native'; import { ScrollView, Text, TouchableWithoutFeedback, View } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { dequal } from 'dequal'; import { dequal } from 'dequal';
@ -18,38 +19,52 @@ import Navigation from '../../lib/Navigation';
import SidebarItem from './SidebarItem'; import SidebarItem from './SidebarItem';
import styles from './styles'; import styles from './styles';
const Separator = React.memo(({ theme }) => <View style={[styles.separator, { borderColor: themes[theme].separatorColor }]} />); interface ISeparatorProps {
Separator.propTypes = { theme: string;
theme: PropTypes.string }
};
class Sidebar extends Component { // TODO: remove this
static propTypes = { const Separator = React.memo(({ theme }: ISeparatorProps) => (
baseUrl: PropTypes.string, <View style={[styles.separator, { borderColor: themes[theme].separatorColor }]} />
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,
viewStatisticsPermission: PropTypes.object,
viewRoomAdministrationPermission: PropTypes.object,
viewUserAdministrationPermission: PropTypes.object,
viewPrivilegedSettingPermission: PropTypes.object
};
constructor(props) { interface ISidebarState {
showStatus: boolean;
}
interface ISidebarProps {
baseUrl: string;
navigation: DrawerNavigationProp<any, 'Sidebar'>;
state: DrawerNavigationState<any>;
Site_Name: string;
user: {
statusText: string;
status: string;
username: string;
name: string;
roles: string[];
};
theme: string;
loadingServer: boolean;
useRealName: boolean;
allowStatusMessage: boolean;
isMasterDetail: boolean;
viewStatisticsPermission: string[];
viewRoomAdministrationPermission: string[];
viewUserAdministrationPermission: string[];
viewPrivilegedSettingPermission: string[];
}
class Sidebar extends Component<ISidebarProps, ISidebarState> {
constructor(props: ISidebarProps) {
super(props); super(props);
this.state = { this.state = {
showStatus: false showStatus: false
}; };
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps: ISidebarProps, nextState: ISidebarState) {
const { showStatus, isAdmin } = this.state; const { showStatus } = this.state;
const { const {
Site_Name, Site_Name,
user, user,
@ -91,9 +106,6 @@ class Sidebar extends Component {
if (nextProps.useRealName !== useRealName) { if (nextProps.useRealName !== useRealName) {
return true; return true;
} }
if (nextState.isAdmin !== isAdmin) {
return true;
}
if (!dequal(nextProps.viewStatisticsPermission, viewStatisticsPermission)) { if (!dequal(nextProps.viewStatisticsPermission, viewStatisticsPermission)) {
return true; return true;
} }
@ -127,7 +139,7 @@ class Sidebar extends Component {
let isAdmin = false; let isAdmin = false;
if (roles) { if (roles) {
isAdmin = allPermissions.reduce((result, permission) => { isAdmin = allPermissions.reduce((result: boolean, permission) => {
if (permission) { if (permission) {
return result || permission.some(r => roles.indexOf(r) !== -1); return result || permission.some(r => roles.indexOf(r) !== -1);
} }
@ -137,7 +149,8 @@ class Sidebar extends Component {
return isAdmin; return isAdmin;
} }
sidebarNavigate = route => { sidebarNavigate = (route: string) => {
// @ts-ignore
logEvent(events[`SIDEBAR_GO_${route.replace('StackNavigator', '').replace('View', '').toUpperCase()}`]); logEvent(events[`SIDEBAR_GO_${route.replace('StackNavigator', '').replace('View', '').toUpperCase()}`]);
Navigation.navigate(route); Navigation.navigate(route);
}; };
@ -242,7 +255,7 @@ class Sidebar extends Component {
]} ]}
{...scrollPersistTaps}> {...scrollPersistTaps}>
<TouchableWithoutFeedback onPress={this.onPressUser} testID='sidebar-close-drawer'> <TouchableWithoutFeedback onPress={this.onPressUser} testID='sidebar-close-drawer'>
<View style={styles.header} theme={theme}> <View style={styles.header}>
<Avatar text={user.username} style={styles.avatar} size={30} /> <Avatar text={user.username} style={styles.avatar} size={30} />
<View style={styles.headerTextContainer}> <View style={styles.headerTextContainer}>
<View style={styles.headerUsername}> <View style={styles.headerUsername}>
@ -278,7 +291,7 @@ class Sidebar extends Component {
} }
} }
const mapStateToProps = state => ({ const mapStateToProps = (state: any) => ({
Site_Name: state.settings.Site_Name, Site_Name: state.settings.Site_Name,
user: getUserSelector(state), user: getUserSelector(state),
baseUrl: state.server.server, baseUrl: state.server.server,