Chore: Hooks - migrate RoomHeader to hook (#4200)

* roomHeader hook

* minor tweak

* Fix ts stuffs

* fix colors

* refactor
This commit is contained in:
Reinaldo Neto 2022-06-13 17:16:20 -03:00 committed by GitHub
parent 74a82974f0
commit a16c271f1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 151 deletions

View File

@ -8,6 +8,7 @@ import Header from '../Header';
import { longText } from '../../../storybook/utils';
import { ThemeContext } from '../../theme';
import { store } from '../../../storybook/stories';
import { colors } from '../../lib/constants';
import RoomHeaderComponent from './RoomHeader';
const stories = storiesOf('RoomHeader', module).addDecorator(story => <Provider store={store}>{story()}</Provider>);
@ -82,7 +83,7 @@ stories.add('thread', () => (
));
const ThemeStory = ({ theme }) => (
<ThemeContext.Provider value={{ theme }}>
<ThemeContext.Provider value={{ theme, colors: colors[theme] }}>
<HeaderExample title={() => <RoomHeader subtitle='subtitle' />} />
</ThemeContext.Provider>
);

View File

@ -3,7 +3,6 @@ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import I18n from '../../i18n';
import sharedStyles from '../../views/Styles';
import { themes } from '../../lib/constants';
import { MarkdownPreview } from '../markdown';
import RoomTypeIcon from '../RoomTypeIcon';
import { TUserStatus, IOmnichannelSource } from '../../definitions';
@ -44,39 +43,39 @@ const styles = StyleSheet.create({
type TRoomHeaderSubTitle = {
usersTyping: [];
subtitle: string;
subtitle?: string;
renderFunc?: () => React.ReactElement;
scale: number;
};
type TRoomHeaderHeaderTitle = {
title: string;
tmid: string;
prid: string;
title?: string;
tmid?: string;
prid?: string;
scale: number;
testID: string;
testID?: string;
};
interface IRoomHeader {
title: string;
subtitle: string;
title?: string;
subtitle?: string;
type: string;
width: number;
height: number;
prid: string;
tmid: string;
teamMain: boolean;
prid?: string;
tmid?: string;
teamMain?: boolean;
status: TUserStatus;
usersTyping: [];
isGroupChat: boolean;
parentTitle: string;
onPress: () => void;
testID: string;
isGroupChat?: boolean;
parentTitle?: string;
onPress: Function;
testID?: string;
sourceType?: IOmnichannelSource;
}
const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoomHeaderSubTitle) => {
const { theme } = useTheme();
const { colors } = useTheme();
const fontSize = getSubTitleSize(scale);
// typing
if (usersTyping.length) {
@ -87,7 +86,7 @@ const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoom
usersText = usersTyping.join(', ');
}
return (
<Text style={[styles.subtitle, { fontSize, color: themes[theme].auxiliaryText }]} numberOfLines={1}>
<Text style={[styles.subtitle, { fontSize, color: colors.auxiliaryText }]} numberOfLines={1}>
<Text style={styles.typingUsers}>{usersText} </Text>
{usersTyping.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing')}...
</Text>
@ -101,15 +100,15 @@ const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoom
// subtitle
if (subtitle) {
return <MarkdownPreview msg={subtitle} style={[styles.subtitle, { fontSize, color: themes[theme].auxiliaryText }]} />;
return <MarkdownPreview msg={subtitle} style={[styles.subtitle, { fontSize, color: colors.auxiliaryText }]} />;
}
return null;
});
const HeaderTitle = React.memo(({ title, tmid, prid, scale, testID }: TRoomHeaderHeaderTitle) => {
const { theme } = useTheme();
const titleStyle = { fontSize: TITLE_SIZE * scale, color: themes[theme].headerTitleColor };
const { colors } = useTheme();
const titleStyle = { fontSize: TITLE_SIZE * scale, color: colors.headerTitleColor };
if (!tmid && !prid) {
return (
<Text style={[styles.title, titleStyle]} numberOfLines={1} testID={testID}>
@ -139,7 +138,7 @@ const Header = React.memo(
usersTyping = [],
sourceType
}: IRoomHeader) => {
const { theme } = useTheme();
const { colors } = useTheme();
const portrait = height > width;
let scale = 1;
@ -154,7 +153,7 @@ const Header = React.memo(
renderFunc = () => (
<View style={styles.titleContainer}>
<RoomTypeIcon type={prid ? 'discussion' : type} isGroupChat={isGroupChat} status={status} teamMain={teamMain} />
<Text style={[styles.subtitle, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>
<Text style={[styles.subtitle, { color: colors.auxiliaryText }]} numberOfLines={1}>
{parentTitle}
</Text>
</View>

View File

@ -1,117 +1,56 @@
import { dequal } from 'dequal';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import React from 'react';
import { shallowEqual, useSelector } from 'react-redux';
import { IApplicationState, TUserStatus, IOmnichannelSource } from '../../definitions';
import { withDimensions } from '../../dimensions';
import { IApplicationState, TUserStatus, IOmnichannelSource, IVisitor } from '../../definitions';
import { useDimensions } from '../../dimensions';
import I18n from '../../i18n';
import RoomHeader from './RoomHeader';
interface IRoomHeaderContainerProps {
title: string;
subtitle: string;
title?: string;
subtitle?: string;
type: string;
prid: string;
tmid: string;
teamMain: boolean;
usersTyping: [];
status: TUserStatus;
statusText: string;
connecting: boolean;
connected: boolean;
roomUserId: string;
widthOffset: number;
onPress(): void;
width: number;
height: number;
parentTitle: string;
isGroupChat: boolean;
testID: string;
prid?: string;
tmid?: string;
teamMain?: boolean;
roomUserId?: string | null;
onPress: Function;
parentTitle?: string;
isGroupChat?: boolean;
testID?: string;
sourceType?: IOmnichannelSource;
visitor?: IVisitor;
}
class RoomHeaderContainer extends Component<IRoomHeaderContainerProps, any> {
shouldComponentUpdate(nextProps: IRoomHeaderContainerProps) {
const {
type,
title,
subtitle,
status,
statusText,
connecting,
connected,
onPress,
usersTyping,
width,
height,
teamMain,
sourceType
} = this.props;
if (nextProps.type !== type) {
return true;
}
if (nextProps.title !== title) {
return true;
}
if (nextProps.subtitle !== subtitle) {
return true;
}
if (nextProps.status !== status) {
return true;
}
if (nextProps.statusText !== statusText) {
return true;
}
if (nextProps.connecting !== connecting) {
return true;
}
if (nextProps.connected !== connected) {
return true;
}
if (nextProps.width !== width) {
return true;
}
if (nextProps.height !== height) {
return true;
}
if (!dequal(nextProps.usersTyping, usersTyping)) {
return true;
}
if (!dequal(nextProps.sourceType, sourceType)) {
return true;
}
if (nextProps.onPress !== onPress) {
return true;
}
if (nextProps.teamMain !== teamMain) {
return true;
}
return false;
}
const RoomHeaderContainer = React.memo(
({
isGroupChat,
onPress,
parentTitle,
prid,
roomUserId,
subtitle: subtitleProp,
teamMain,
testID,
title,
tmid,
type,
sourceType,
visitor
}: IRoomHeaderContainerProps) => {
let subtitle: string | undefined;
let status: TUserStatus = 'offline';
let statusText: string | undefined;
const { width, height } = useDimensions();
render() {
const {
title,
subtitle: subtitleProp,
type,
teamMain,
prid,
tmid,
status = 'offline',
statusText,
connecting,
connected,
usersTyping,
onPress,
width,
height,
parentTitle,
isGroupChat,
testID,
sourceType
} = this.props;
const connecting = useSelector((state: IApplicationState) => state.meteor.connecting || state.server.loading);
const usersTyping = useSelector((state: IApplicationState) => state.usersTyping, shallowEqual);
const connected = useSelector((state: IApplicationState) => state.meteor.connected);
const activeUser = useSelector(
(state: IApplicationState) => (roomUserId ? state.activeUsers?.[roomUserId] : undefined),
shallowEqual
);
let subtitle;
if (connecting) {
subtitle = I18n.t('Connecting');
} else if (!connected) {
@ -120,6 +59,17 @@ class RoomHeaderContainer extends Component<IRoomHeaderContainerProps, any> {
subtitle = subtitleProp;
}
if (connected) {
if ((type === 'd' || (tmid && roomUserId)) && activeUser) {
const { status: statusActiveUser, statusText: statusTextActiveUser } = activeUser;
status = statusActiveUser;
statusText = statusTextActiveUser;
} else if (type === 'l' && visitor?.status) {
const { status: statusVisitor } = visitor;
status = statusVisitor;
}
}
return (
<RoomHeader
prid={prid}
@ -140,28 +90,6 @@ class RoomHeaderContainer extends Component<IRoomHeaderContainerProps, any> {
/>
);
}
}
);
const mapStateToProps = (state: IApplicationState, ownProps: any) => {
let statusText = '';
let status = 'offline';
const { roomUserId, type, visitor = {}, tmid } = ownProps;
if (state.meteor.connected) {
if ((type === 'd' || (tmid && roomUserId)) && state.activeUsers[roomUserId]) {
({ status, statusText } = state.activeUsers[roomUserId]);
} else if (type === 'l' && visitor?.status) {
({ status } = visitor);
}
}
return {
connecting: state.meteor.connecting || state.server.loading,
connected: state.meteor.connected,
usersTyping: state.usersTyping,
status: status as TUserStatus,
statusText
};
};
export default connect(mapStateToProps)(withDimensions(RoomHeaderContainer));
export default RoomHeaderContainer;

View File

@ -624,7 +624,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
),
headerTitle: () => (
<RoomHeader
rid={rid}
prid={prid}
tmid={tmid}
title={title}