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 { longText } from '../../../storybook/utils';
|
||||||
import { ThemeContext } from '../../theme';
|
import { ThemeContext } from '../../theme';
|
||||||
import { store } from '../../../storybook/stories';
|
import { store } from '../../../storybook/stories';
|
||||||
|
import { colors } from '../../lib/constants';
|
||||||
import RoomHeaderComponent from './RoomHeader';
|
import RoomHeaderComponent from './RoomHeader';
|
||||||
|
|
||||||
const stories = storiesOf('RoomHeader', module).addDecorator(story => <Provider store={store}>{story()}</Provider>);
|
const stories = storiesOf('RoomHeader', module).addDecorator(story => <Provider store={store}>{story()}</Provider>);
|
||||||
|
@ -82,7 +83,7 @@ stories.add('thread', () => (
|
||||||
));
|
));
|
||||||
|
|
||||||
const ThemeStory = ({ theme }) => (
|
const ThemeStory = ({ theme }) => (
|
||||||
<ThemeContext.Provider value={{ theme }}>
|
<ThemeContext.Provider value={{ theme, colors: colors[theme] }}>
|
||||||
<HeaderExample title={() => <RoomHeader subtitle='subtitle' />} />
|
<HeaderExample title={() => <RoomHeader subtitle='subtitle' />} />
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||||
|
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import sharedStyles from '../../views/Styles';
|
import sharedStyles from '../../views/Styles';
|
||||||
import { themes } from '../../lib/constants';
|
|
||||||
import { MarkdownPreview } from '../markdown';
|
import { MarkdownPreview } from '../markdown';
|
||||||
import RoomTypeIcon from '../RoomTypeIcon';
|
import RoomTypeIcon from '../RoomTypeIcon';
|
||||||
import { TUserStatus, IOmnichannelSource } from '../../definitions';
|
import { TUserStatus, IOmnichannelSource } from '../../definitions';
|
||||||
|
@ -44,39 +43,39 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
type TRoomHeaderSubTitle = {
|
type TRoomHeaderSubTitle = {
|
||||||
usersTyping: [];
|
usersTyping: [];
|
||||||
subtitle: string;
|
subtitle?: string;
|
||||||
renderFunc?: () => React.ReactElement;
|
renderFunc?: () => React.ReactElement;
|
||||||
scale: number;
|
scale: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TRoomHeaderHeaderTitle = {
|
type TRoomHeaderHeaderTitle = {
|
||||||
title: string;
|
title?: string;
|
||||||
tmid: string;
|
tmid?: string;
|
||||||
prid: string;
|
prid?: string;
|
||||||
scale: number;
|
scale: number;
|
||||||
testID: string;
|
testID?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IRoomHeader {
|
interface IRoomHeader {
|
||||||
title: string;
|
title?: string;
|
||||||
subtitle: string;
|
subtitle?: string;
|
||||||
type: string;
|
type: string;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
prid: string;
|
prid?: string;
|
||||||
tmid: string;
|
tmid?: string;
|
||||||
teamMain: boolean;
|
teamMain?: boolean;
|
||||||
status: TUserStatus;
|
status: TUserStatus;
|
||||||
usersTyping: [];
|
usersTyping: [];
|
||||||
isGroupChat: boolean;
|
isGroupChat?: boolean;
|
||||||
parentTitle: string;
|
parentTitle?: string;
|
||||||
onPress: () => void;
|
onPress: Function;
|
||||||
testID: string;
|
testID?: string;
|
||||||
sourceType?: IOmnichannelSource;
|
sourceType?: IOmnichannelSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoomHeaderSubTitle) => {
|
const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoomHeaderSubTitle) => {
|
||||||
const { theme } = useTheme();
|
const { colors } = useTheme();
|
||||||
const fontSize = getSubTitleSize(scale);
|
const fontSize = getSubTitleSize(scale);
|
||||||
// typing
|
// typing
|
||||||
if (usersTyping.length) {
|
if (usersTyping.length) {
|
||||||
|
@ -87,7 +86,7 @@ const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoom
|
||||||
usersText = usersTyping.join(', ');
|
usersText = usersTyping.join(', ');
|
||||||
}
|
}
|
||||||
return (
|
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>
|
<Text style={styles.typingUsers}>{usersText} </Text>
|
||||||
{usersTyping.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing')}...
|
{usersTyping.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing')}...
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -101,15 +100,15 @@ const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoom
|
||||||
|
|
||||||
// subtitle
|
// subtitle
|
||||||
if (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;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
const HeaderTitle = React.memo(({ title, tmid, prid, scale, testID }: TRoomHeaderHeaderTitle) => {
|
const HeaderTitle = React.memo(({ title, tmid, prid, scale, testID }: TRoomHeaderHeaderTitle) => {
|
||||||
const { theme } = useTheme();
|
const { colors } = useTheme();
|
||||||
const titleStyle = { fontSize: TITLE_SIZE * scale, color: themes[theme].headerTitleColor };
|
const titleStyle = { fontSize: TITLE_SIZE * scale, color: colors.headerTitleColor };
|
||||||
if (!tmid && !prid) {
|
if (!tmid && !prid) {
|
||||||
return (
|
return (
|
||||||
<Text style={[styles.title, titleStyle]} numberOfLines={1} testID={testID}>
|
<Text style={[styles.title, titleStyle]} numberOfLines={1} testID={testID}>
|
||||||
|
@ -139,7 +138,7 @@ const Header = React.memo(
|
||||||
usersTyping = [],
|
usersTyping = [],
|
||||||
sourceType
|
sourceType
|
||||||
}: IRoomHeader) => {
|
}: IRoomHeader) => {
|
||||||
const { theme } = useTheme();
|
const { colors } = useTheme();
|
||||||
const portrait = height > width;
|
const portrait = height > width;
|
||||||
let scale = 1;
|
let scale = 1;
|
||||||
|
|
||||||
|
@ -154,7 +153,7 @@ const Header = React.memo(
|
||||||
renderFunc = () => (
|
renderFunc = () => (
|
||||||
<View style={styles.titleContainer}>
|
<View style={styles.titleContainer}>
|
||||||
<RoomTypeIcon type={prid ? 'discussion' : type} isGroupChat={isGroupChat} status={status} teamMain={teamMain} />
|
<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}
|
{parentTitle}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,117 +1,56 @@
|
||||||
import { dequal } from 'dequal';
|
import React from 'react';
|
||||||
import React, { Component } from 'react';
|
import { shallowEqual, useSelector } from 'react-redux';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { IApplicationState, TUserStatus, IOmnichannelSource } from '../../definitions';
|
import { IApplicationState, TUserStatus, IOmnichannelSource, IVisitor } from '../../definitions';
|
||||||
import { withDimensions } from '../../dimensions';
|
import { useDimensions } from '../../dimensions';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import RoomHeader from './RoomHeader';
|
import RoomHeader from './RoomHeader';
|
||||||
|
|
||||||
interface IRoomHeaderContainerProps {
|
interface IRoomHeaderContainerProps {
|
||||||
title: string;
|
title?: string;
|
||||||
subtitle: string;
|
subtitle?: string;
|
||||||
type: string;
|
type: string;
|
||||||
prid: string;
|
prid?: string;
|
||||||
tmid: string;
|
tmid?: string;
|
||||||
teamMain: boolean;
|
teamMain?: boolean;
|
||||||
usersTyping: [];
|
roomUserId?: string | null;
|
||||||
status: TUserStatus;
|
onPress: Function;
|
||||||
statusText: string;
|
parentTitle?: string;
|
||||||
connecting: boolean;
|
isGroupChat?: boolean;
|
||||||
connected: boolean;
|
testID?: string;
|
||||||
roomUserId: string;
|
|
||||||
widthOffset: number;
|
|
||||||
onPress(): void;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
parentTitle: string;
|
|
||||||
isGroupChat: boolean;
|
|
||||||
testID: string;
|
|
||||||
sourceType?: IOmnichannelSource;
|
sourceType?: IOmnichannelSource;
|
||||||
|
visitor?: IVisitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoomHeaderContainer extends Component<IRoomHeaderContainerProps, any> {
|
const RoomHeaderContainer = React.memo(
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
title,
|
|
||||||
subtitle: subtitleProp,
|
|
||||||
type,
|
|
||||||
teamMain,
|
|
||||||
prid,
|
|
||||||
tmid,
|
|
||||||
status = 'offline',
|
|
||||||
statusText,
|
|
||||||
connecting,
|
|
||||||
connected,
|
|
||||||
usersTyping,
|
|
||||||
onPress,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
parentTitle,
|
|
||||||
isGroupChat,
|
isGroupChat,
|
||||||
|
onPress,
|
||||||
|
parentTitle,
|
||||||
|
prid,
|
||||||
|
roomUserId,
|
||||||
|
subtitle: subtitleProp,
|
||||||
|
teamMain,
|
||||||
testID,
|
testID,
|
||||||
sourceType
|
title,
|
||||||
} = this.props;
|
tmid,
|
||||||
|
type,
|
||||||
|
sourceType,
|
||||||
|
visitor
|
||||||
|
}: IRoomHeaderContainerProps) => {
|
||||||
|
let subtitle: string | undefined;
|
||||||
|
let status: TUserStatus = 'offline';
|
||||||
|
let statusText: string | undefined;
|
||||||
|
const { width, height } = useDimensions();
|
||||||
|
|
||||||
|
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) {
|
if (connecting) {
|
||||||
subtitle = I18n.t('Connecting');
|
subtitle = I18n.t('Connecting');
|
||||||
} else if (!connected) {
|
} else if (!connected) {
|
||||||
|
@ -120,6 +59,17 @@ class RoomHeaderContainer extends Component<IRoomHeaderContainerProps, any> {
|
||||||
subtitle = subtitleProp;
|
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 (
|
return (
|
||||||
<RoomHeader
|
<RoomHeader
|
||||||
prid={prid}
|
prid={prid}
|
||||||
|
@ -140,28 +90,6 @@ class RoomHeaderContainer extends Component<IRoomHeaderContainerProps, any> {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
const mapStateToProps = (state: IApplicationState, ownProps: any) => {
|
export default RoomHeaderContainer;
|
||||||
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));
|
|
||||||
|
|
|
@ -624,7 +624,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
),
|
),
|
||||||
headerTitle: () => (
|
headerTitle: () => (
|
||||||
<RoomHeader
|
<RoomHeader
|
||||||
rid={rid}
|
|
||||||
prid={prid}
|
prid={prid}
|
||||||
tmid={tmid}
|
tmid={tmid}
|
||||||
title={title}
|
title={title}
|
||||||
|
|
Loading…
Reference in New Issue