Chore: Hooks - migrate RoomHeader to hook (#4200)
* roomHeader hook * minor tweak * Fix ts stuffs * fix colors * refactor
This commit is contained in:
parent
74a82974f0
commit
a16c271f1f
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -624,7 +624,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
),
|
||||
headerTitle: () => (
|
||||
<RoomHeader
|
||||
rid={rid}
|
||||
prid={prid}
|
||||
tmid={tmid}
|
||||
title={title}
|
||||
|
|
Loading…
Reference in New Issue