Chore: Migrate RoomItem to Hooks (#4310)

* migrate roomItem to ts and fix some types

* remove unnecessary verification

* fix types

* fix SubscriptionType

* review

* remove theme prop driling and change file to tsx

* Fix component not re-rendering

* Remove a few props from attrs

* Remove accessibilityLabel state

* Fix propsAreEqual

* Fix cleanup

* Remove ts-ignore

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Gleidson Daniel Silva 2022-06-27 15:23:43 -03:00 committed by GitHub
parent 4b25fde8f6
commit 674f0285f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 189 additions and 293 deletions

View File

@ -1,11 +1,11 @@
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import PropTypes from 'prop-types';
import Avatar from '../Avatar'; import Avatar from '../Avatar';
import { DisplayMode } from '../../lib/constants'; import { DisplayMode } from '../../lib/constants';
import TypeIcon from './TypeIcon'; import TypeIcon from './TypeIcon';
import styles from './styles'; import styles from './styles';
import { IIconOrAvatar } from './interfaces';
const IconOrAvatar = ({ const IconOrAvatar = ({
avatar, avatar,
@ -17,10 +17,9 @@ const IconOrAvatar = ({
isGroupChat, isGroupChat,
teamMain, teamMain,
showLastMessage, showLastMessage,
theme,
displayMode, displayMode,
sourceType sourceType
}) => { }: IIconOrAvatar): React.ReactElement | null => {
if (showAvatar) { if (showAvatar) {
return ( return (
<Avatar text={avatar} size={displayMode === DisplayMode.Condensed ? 36 : 48} type={type} style={styles.avatar} rid={rid} /> <Avatar text={avatar} size={displayMode === DisplayMode.Condensed ? 36 : 48} type={type} style={styles.avatar} rid={rid} />
@ -35,7 +34,6 @@ const IconOrAvatar = ({
prid={prid} prid={prid}
status={status} status={status}
isGroupChat={isGroupChat} isGroupChat={isGroupChat}
theme={theme}
teamMain={teamMain} teamMain={teamMain}
size={24} size={24}
style={{ marginRight: 12 }} style={{ marginRight: 12 }}
@ -48,18 +46,4 @@ const IconOrAvatar = ({
return null; return null;
}; };
IconOrAvatar.propTypes = {
avatar: PropTypes.string,
type: PropTypes.string,
theme: PropTypes.string,
rid: PropTypes.string,
showAvatar: PropTypes.bool,
displayMode: PropTypes.string,
prid: PropTypes.string,
status: PropTypes.string,
isGroupChat: PropTypes.bool,
teamMain: PropTypes.bool,
showLastMessage: PropTypes.bool
};
export default IconOrAvatar; export default IconOrAvatar;

View File

@ -4,8 +4,9 @@ import { dequal } from 'dequal';
import I18n from '../../i18n'; import I18n from '../../i18n';
import styles from './styles'; import styles from './styles';
import { MarkdownPreview } from '../markdown'; import { MarkdownPreview } from '../markdown';
import { E2E_MESSAGE_TYPE, E2E_STATUS, themes } from '../../lib/constants'; import { E2E_MESSAGE_TYPE, E2E_STATUS } from '../../lib/constants';
import { ILastMessageProps } from './interfaces'; import { ILastMessageProps } from './interfaces';
import { useTheme } from '../../theme';
const formatMsg = ({ lastMessage, type, showLastMessage, username, useRealName }: Partial<ILastMessageProps>) => { const formatMsg = ({ lastMessage, type, showLastMessage, username, useRealName }: Partial<ILastMessageProps>) => {
if (!showLastMessage) { if (!showLastMessage) {
@ -46,8 +47,9 @@ const formatMsg = ({ lastMessage, type, showLastMessage, username, useRealName }
const arePropsEqual = (oldProps: any, newProps: any) => dequal(oldProps, newProps); const arePropsEqual = (oldProps: any, newProps: any) => dequal(oldProps, newProps);
const LastMessage = React.memo( const LastMessage = React.memo(({ lastMessage, type, showLastMessage, username, alert, useRealName }: ILastMessageProps) => {
({ lastMessage, type, showLastMessage, username, alert, useRealName, theme }: ILastMessageProps) => ( const { colors } = useTheme();
return (
<MarkdownPreview <MarkdownPreview
msg={formatMsg({ msg={formatMsg({
lastMessage, lastMessage,
@ -56,12 +58,11 @@ const LastMessage = React.memo(
username, username,
useRealName useRealName
})} })}
style={[styles.markdownText, { color: alert ? themes[theme].bodyText : themes[theme].auxiliaryText }]} style={[styles.markdownText, { color: alert ? colors.bodyText : colors.auxiliaryText }]}
numberOfLines={2} numberOfLines={2}
testID='room-item-last-message' testID='room-item-last-message'
/> />
), );
arePropsEqual }, arePropsEqual);
);
export default LastMessage; export default LastMessage;

View File

@ -25,7 +25,6 @@ const RoomItem = ({
showLastMessage, showLastMessage,
status = 'offline', status = 'offline',
useRealName, useRealName,
theme,
isFocused, isFocused,
isGroupChat, isGroupChat,
isRead, isRead,
@ -67,14 +66,13 @@ const RoomItem = ({
hideChannel={hideChannel} hideChannel={hideChannel}
testID={testID} testID={testID}
type={type} type={type}
isFocused={isFocused} isFocused={!!isFocused}
swipeEnabled={swipeEnabled} swipeEnabled={swipeEnabled}
displayMode={displayMode}> displayMode={displayMode}>
<Wrapper <Wrapper
accessibilityLabel={accessibilityLabel} accessibilityLabel={accessibilityLabel}
avatar={avatar} avatar={avatar}
type={type} type={type}
theme={theme}
rid={rid} rid={rid}
prid={prid} prid={prid}
status={status} status={status}
@ -82,7 +80,7 @@ const RoomItem = ({
teamMain={teamMain} teamMain={teamMain}
displayMode={displayMode} displayMode={displayMode}
showAvatar={showAvatar} showAvatar={showAvatar}
showLastMessage={showLastMessage} showLastMessage={!!showLastMessage}
sourceType={sourceType}> sourceType={sourceType}>
{showLastMessage && displayMode === DisplayMode.Expanded ? ( {showLastMessage && displayMode === DisplayMode.Expanded ? (
<> <>
@ -97,19 +95,18 @@ const RoomItem = ({
sourceType={sourceType} sourceType={sourceType}
/> />
) : null} ) : null}
<Title name={name} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} /> <Title name={name} hideUnreadStatus={hideUnreadStatus} alert={alert} />
{autoJoin ? <Tag testID='auto-join-tag' name={I18n.t('Auto-join')} /> : null} {autoJoin ? <Tag testID='auto-join-tag' name={I18n.t('Auto-join')} /> : null}
<UpdatedAt date={date} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} /> <UpdatedAt date={date} hideUnreadStatus={hideUnreadStatus} alert={alert} />
</View> </View>
<View style={styles.row}> <View style={styles.row}>
<LastMessage <LastMessage
lastMessage={lastMessage} lastMessage={lastMessage}
type={type} type={type}
showLastMessage={showLastMessage} showLastMessage={showLastMessage}
username={username} username={username || ''}
alert={alert && !hideUnreadStatus} alert={alert && !hideUnreadStatus}
useRealName={useRealName} useRealName={useRealName}
theme={theme}
/> />
<UnreadBadge <UnreadBadge
unread={unread} unread={unread}
@ -135,10 +132,10 @@ const RoomItem = ({
style={{ marginRight: 8 }} style={{ marginRight: 8 }}
sourceType={sourceType} sourceType={sourceType}
/> />
<Title name={name} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} /> <Title name={name} hideUnreadStatus={hideUnreadStatus} alert={alert} />
{autoJoin ? <Tag name={I18n.t('Auto-join')} /> : null} {autoJoin ? <Tag name={I18n.t('Auto-join')} /> : null}
<View style={styles.wrapUpdatedAndBadge}> <View style={styles.wrapUpdatedAndBadge}>
<UpdatedAt date={date} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} /> <UpdatedAt date={date} hideUnreadStatus={hideUnreadStatus} alert={alert} />
<UnreadBadge <UnreadBadge
unread={unread} unread={unread}
userMentions={userMentions} userMentions={userMentions}

View File

@ -2,16 +2,19 @@ import React from 'react';
import { Text } from 'react-native'; import { Text } from 'react-native';
import styles from './styles'; import styles from './styles';
import { themes } from '../../lib/constants';
import { ITitleProps } from './interfaces'; import { ITitleProps } from './interfaces';
import { useTheme } from '../../theme';
const Title = React.memo(({ name, theme, hideUnreadStatus, alert }: ITitleProps) => ( const Title = React.memo(({ name, hideUnreadStatus, alert }: ITitleProps) => {
const { colors } = useTheme();
return (
<Text <Text
style={[styles.title, alert && !hideUnreadStatus && styles.alert, { color: themes[theme].titleText }]} style={[styles.title, alert && !hideUnreadStatus && styles.alert, { color: colors.titleText }]}
ellipsizeMode='tail' ellipsizeMode='tail'
numberOfLines={1}> numberOfLines={1}>
{name} {name}
</Text> </Text>
)); );
});
export default Title; export default Title;

View File

@ -2,11 +2,13 @@ import React from 'react';
import { Text } from 'react-native'; import { Text } from 'react-native';
import styles from './styles'; import styles from './styles';
import { themes } from '../../lib/constants';
import { capitalize } from '../../lib/methods/helpers/room'; import { capitalize } from '../../lib/methods/helpers/room';
import { IUpdatedAtProps } from './interfaces'; import { IUpdatedAtProps } from './interfaces';
import { useTheme } from '../../theme';
const UpdatedAt = React.memo(({ date, hideUnreadStatus, alert }: IUpdatedAtProps) => {
const { colors } = useTheme();
const UpdatedAt = React.memo(({ date, theme, hideUnreadStatus, alert }: IUpdatedAtProps) => {
if (!date) { if (!date) {
return null; return null;
} }
@ -15,13 +17,13 @@ const UpdatedAt = React.memo(({ date, theme, hideUnreadStatus, alert }: IUpdated
style={[ style={[
styles.date, styles.date,
{ {
color: themes[theme].auxiliaryText color: colors.auxiliaryText
}, },
alert && alert &&
!hideUnreadStatus && [ !hideUnreadStatus && [
styles.updateAlert, styles.updateAlert,
{ {
color: themes[theme].tintColor color: colors.tintColor
} }
] ]
]} ]}

View File

@ -1,26 +1,30 @@
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { DisplayMode, themes } from '../../lib/constants'; import { DisplayMode } from '../../lib/constants';
import { useTheme } from '../../theme';
import IconOrAvatar from './IconOrAvatar'; import IconOrAvatar from './IconOrAvatar';
import { IWrapperProps } from './interfaces'; import { IWrapperProps } from './interfaces';
import styles from './styles'; import styles from './styles';
const Wrapper = ({ accessibilityLabel, theme, children, displayMode, ...props }: IWrapperProps): React.ReactElement => ( const Wrapper = ({ accessibilityLabel, children, displayMode, ...props }: IWrapperProps): React.ReactElement => {
const { colors } = useTheme();
return (
<View <View
style={[styles.container, displayMode === DisplayMode.Condensed && styles.containerCondensed]} style={[styles.container, displayMode === DisplayMode.Condensed && styles.containerCondensed]}
accessibilityLabel={accessibilityLabel}> accessibilityLabel={accessibilityLabel}>
<IconOrAvatar theme={theme} displayMode={displayMode} {...props} /> <IconOrAvatar displayMode={displayMode} {...props} />
<View <View
style={[ style={[
styles.centerContainer, styles.centerContainer,
{ {
borderColor: themes[theme].separatorColor borderColor: colors.separatorColor
} }
]}> ]}>
{children} {children}
</View> </View>
</View> </View>
); );
};
export default Wrapper; export default Wrapper;

View File

@ -1,171 +1,111 @@
import React from 'react'; import React, { useEffect, useReducer, useRef } from 'react';
import { connect } from 'react-redux'; import { Subscription } from 'rxjs';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles'; import { useAppSelector } from '../../lib/hooks';
import { getUserPresence } from '../../lib/methods';
import { isGroupChat } from '../../lib/methods/helpers';
import { formatDate } from '../../lib/methods/helpers/room'; import { formatDate } from '../../lib/methods/helpers/room';
import RoomItem from './RoomItem';
import { ISubscription, TUserStatus } from '../../definitions';
import { IRoomItemContainerProps } from './interfaces'; import { IRoomItemContainerProps } from './interfaces';
import RoomItem from './RoomItem';
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED }; export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
const attrs = [ const attrs = ['width', 'isFocused', 'showLastMessage', 'autoJoin', 'showAvatar', 'displayMode'];
'width',
'status',
'connected',
'theme',
'isFocused',
'forceUpdate',
'showLastMessage',
'autoJoin',
'showAvatar',
'displayMode'
];
class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> { const RoomItemContainer = React.memo(
private roomSubscription: ISubscription | undefined; ({
static defaultProps: Partial<IRoomItemContainerProps> = {
status: 'offline',
getUserPresence: () => {},
getRoomTitle: () => 'title',
getRoomAvatar: () => '',
getIsGroupChat: () => false,
getIsRead: () => false,
swipeEnabled: true
};
constructor(props: IRoomItemContainerProps) {
super(props);
this.init();
}
componentDidMount() {
const { connected, getUserPresence, id } = this.props;
if (connected && this.isDirect) {
getUserPresence(id);
}
}
shouldComponentUpdate(nextProps: IRoomItemContainerProps) {
const { props } = this;
return !attrs.every(key => props[key] === nextProps[key]);
}
componentDidUpdate(prevProps: IRoomItemContainerProps) {
const { connected, getUserPresence, id } = this.props;
if (prevProps.connected !== connected && connected && this.isDirect) {
getUserPresence(id);
}
}
componentWillUnmount() {
if (this.roomSubscription?.unsubscribe) {
this.roomSubscription.unsubscribe();
}
}
get isGroupChat() {
const { item, getIsGroupChat } = this.props;
return getIsGroupChat(item);
}
get isDirect() {
const {
item: { t },
id
} = this.props;
return t === 'd' && id && !this.isGroupChat;
}
init = () => {
const { item } = this.props;
if (item?.observe) {
const observable = item.observe();
this.roomSubscription = observable?.subscribe?.(() => {
this.forceUpdate();
});
}
};
onPress = () => {
const { item, onPress } = this.props;
return onPress(item);
};
onLongPress = () => {
const { item, onLongPress } = this.props;
if (onLongPress) {
return onLongPress(item);
}
};
render() {
const {
item, item,
getRoomTitle, id,
getRoomAvatar, onPress,
getIsRead, onLongPress,
width, width,
toggleFav, toggleFav,
toggleRead, toggleRead,
hideChannel, hideChannel,
theme,
isFocused, isFocused,
status,
showLastMessage, showLastMessage,
username, username,
useRealName, useRealName,
swipeEnabled,
autoJoin, autoJoin,
showAvatar, showAvatar,
displayMode displayMode,
} = this.props; getRoomTitle = () => 'title',
getRoomAvatar = () => '',
getIsRead = () => false,
swipeEnabled = true
}: IRoomItemContainerProps) => {
const name = getRoomTitle(item); const name = getRoomTitle(item);
const testID = `rooms-list-view-item-${name}`; const testID = `rooms-list-view-item-${name}`;
const avatar = getRoomAvatar(item); const avatar = getRoomAvatar(item);
const isRead = getIsRead(item); const isRead = getIsRead(item);
const date = item.roomUpdatedAt && formatDate(item.roomUpdatedAt); const date = item.roomUpdatedAt && formatDate(item.roomUpdatedAt);
const alert = item.alert || item.tunread?.length; const alert = item.alert || item.tunread?.length;
const connected = useAppSelector(state => state.meteor.connected);
const userStatus = useAppSelector(state => state.activeUsers[id || '']?.status);
const [_, forceUpdate] = useReducer(x => x + 1, 1);
const roomSubscription = useRef<Subscription | null>(null);
let accessibilityLabel = name; useEffect(() => {
const init = () => {
if (item?.observe) {
const observable = item.observe();
roomSubscription.current = observable?.subscribe?.(() => {
if (_) forceUpdate();
});
}
};
init();
return () => roomSubscription.current?.unsubscribe();
}, []);
useEffect(() => {
const isDirect = !!(item.t === 'd' && id && !isGroupChat(item));
if (connected && isDirect) {
getUserPresence(id);
}
}, [connected]);
const handleOnPress = () => onPress(item);
const handleOnLongPress = () => onLongPress && onLongPress(item);
let accessibilityLabel = '';
if (item.unread === 1) { if (item.unread === 1) {
accessibilityLabel += `, ${item.unread} ${I18n.t('alert')}`; accessibilityLabel = `, ${item.unread} ${I18n.t('alert')}`;
} else if (item.unread > 1) { } else if (item.unread > 1) {
accessibilityLabel += `, ${item.unread} ${I18n.t('alerts')}`; accessibilityLabel = `, ${item.unread} ${I18n.t('alerts')}`;
} }
if (item.userMentions > 0) { if (item.userMentions > 0) {
accessibilityLabel += `, ${I18n.t('you_were_mentioned')}`; accessibilityLabel = `, ${I18n.t('you_were_mentioned')}`;
} }
if (date) { if (date) {
accessibilityLabel += `, ${I18n.t('last_message')} ${date}`; accessibilityLabel = `, ${I18n.t('last_message')} ${date}`;
} }
return ( return (
<RoomItem <RoomItem
name={name} name={name}
avatar={avatar} avatar={avatar}
isGroupChat={this.isGroupChat} isGroupChat={isGroupChat(item)}
isRead={isRead} isRead={isRead}
onPress={this.onPress} onPress={handleOnPress}
onLongPress={this.onLongPress} onLongPress={handleOnLongPress}
date={date} date={date}
accessibilityLabel={accessibilityLabel} accessibilityLabel={accessibilityLabel}
width={width} width={width}
favorite={item.f} favorite={item.f}
toggleFav={toggleFav}
rid={item.rid} rid={item.rid}
toggleFav={toggleFav}
toggleRead={toggleRead} toggleRead={toggleRead}
hideChannel={hideChannel} hideChannel={hideChannel}
testID={testID} testID={testID}
type={item.t} type={item.t}
theme={theme}
isFocused={isFocused} isFocused={isFocused}
prid={item.prid} prid={item.prid}
status={status} status={userStatus}
hideUnreadStatus={item.hideUnreadStatus} hideUnreadStatus={item.hideUnreadStatus}
hideMentionStatus={item.hideMentionStatus} hideMentionStatus={item.hideMentionStatus}
alert={alert} alert={alert}
@ -187,23 +127,8 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
sourceType={item.source} sourceType={item.source}
/> />
); );
} },
} (props, nextProps) => attrs.every(key => props[key] === nextProps[key])
);
const mapStateToProps = (state: any, ownProps: any) => { export default RoomItemContainer;
let status = 'loading';
const { id, type, visitor = {} } = ownProps;
if (state.meteor.connected) {
if (type === 'd') {
status = state.activeUsers[id]?.status || 'loading';
} else if (type === 'l' && visitor?.status) {
({ status } = visitor);
}
}
return {
connected: state.meteor.connected,
status: status as TUserStatus
};
};
export default connect(mapStateToProps)(RoomItemContainer);

View File

@ -23,14 +23,12 @@ export interface IRightActionsProps {
export interface ITitleProps { export interface ITitleProps {
name: string; name: string;
theme: TSupportedThemes;
hideUnreadStatus: boolean; hideUnreadStatus: boolean;
alert: boolean; alert: boolean;
} }
export interface IUpdatedAtProps { export interface IUpdatedAtProps {
date: string; date: string;
theme: TSupportedThemes;
hideUnreadStatus: boolean; hideUnreadStatus: boolean;
alert: boolean; alert: boolean;
} }
@ -39,13 +37,12 @@ export interface IWrapperProps {
accessibilityLabel: string; accessibilityLabel: string;
avatar: string; avatar: string;
type: string; type: string;
theme: TSupportedThemes;
rid: string; rid: string;
children: React.ReactElement; children: React.ReactElement;
displayMode: string; displayMode: string;
prid: string; prid: string;
showLastMessage: boolean; showLastMessage: boolean;
status: string; status: TUserStatus;
isGroupChat: boolean; isGroupChat: boolean;
teamMain: boolean; teamMain: boolean;
showAvatar: boolean; showAvatar: boolean;
@ -64,48 +61,43 @@ export interface ITypeIconProps {
sourceType: IOmnichannelSource; sourceType: IOmnichannelSource;
} }
export interface IRoomItemContainerProps { interface IRoomItemTouchables {
[key: string]: string | boolean | Function | number; toggleFav?: (rid: string, favorite: boolean) => Promise<void>;
item: any; toggleRead?: (rid: string, tIsRead: boolean) => Promise<void>;
showLastMessage: boolean; hideChannel?: (rid: string, type: SubscriptionType) => Promise<void>;
id: string; onPress: (item?: any) => void;
onPress: (item: any) => void; onLongPress?: (item?: any) => void;
onLongPress: (item: any) => Promise<void>;
username: string;
width: number;
status: TUserStatus;
toggleFav(): void;
toggleRead(): void;
hideChannel(): void;
useRealName: boolean;
getUserPresence: (uid: string) => void;
connected: boolean;
theme: TSupportedThemes;
isFocused: boolean;
getRoomTitle: (item: any) => string;
getRoomAvatar: (item: any) => string;
getIsGroupChat: (item: any) => boolean;
getIsRead: (item: any) => boolean;
swipeEnabled: boolean;
autoJoin: boolean;
showAvatar: boolean;
displayMode: string;
} }
export interface IRoomItemProps { interface IBaseRoomItem extends IRoomItemTouchables {
[key: string]: any;
showLastMessage?: boolean;
useRealName: boolean;
isFocused?: boolean;
displayMode: string;
showAvatar: boolean;
swipeEnabled: boolean;
autoJoin?: boolean;
width: number;
username?: string;
}
export interface IRoomItemContainerProps extends IBaseRoomItem {
item: any;
id?: string;
getRoomTitle: (item: any) => string;
getRoomAvatar: (item: any) => string;
getIsRead?: (item: any) => boolean;
}
export interface IRoomItemProps extends IBaseRoomItem {
rid: string; rid: string;
type: SubscriptionType; type: SubscriptionType;
prid: string; prid: string;
name: string; name: string;
avatar: string; avatar: string;
showLastMessage: boolean;
username: string;
testID: string; testID: string;
width: number;
status: TUserStatus; status: TUserStatus;
useRealName: boolean;
theme: TSupportedThemes;
isFocused: boolean;
isGroupChat: boolean; isGroupChat: boolean;
isRead: boolean; isRead: boolean;
teamMain: boolean; teamMain: boolean;
@ -121,22 +113,12 @@ export interface IRoomItemProps {
tunread: []; tunread: [];
tunreadUser: []; tunreadUser: [];
tunreadGroup: []; tunreadGroup: [];
swipeEnabled: boolean;
toggleFav(): void;
toggleRead(): void;
onPress(): void;
onLongPress(): void;
hideChannel(): void;
autoJoin: boolean;
size?: number; size?: number;
showAvatar: boolean;
displayMode: string;
sourceType: IOmnichannelSource; sourceType: IOmnichannelSource;
hideMentionStatus?: boolean; hideMentionStatus?: boolean;
} }
export interface ILastMessageProps { export interface ILastMessageProps {
theme: TSupportedThemes;
lastMessage: ILastMessage; lastMessage: ILastMessage;
type: SubscriptionType; type: SubscriptionType;
showLastMessage: boolean; showLastMessage: boolean;
@ -145,20 +127,29 @@ export interface ILastMessageProps {
alert: boolean; alert: boolean;
} }
export interface ITouchableProps { export interface ITouchableProps extends IRoomItemTouchables {
children: JSX.Element; children: JSX.Element;
type: string; type: SubscriptionType;
onPress(): void;
onLongPress(): void;
testID: string; testID: string;
width: number; width: number;
favorite: boolean; favorite: boolean;
isRead: boolean; isRead: boolean;
rid: string; rid: string;
toggleFav: Function;
toggleRead: Function;
hideChannel: Function;
isFocused: boolean; isFocused: boolean;
swipeEnabled: boolean; swipeEnabled: boolean;
displayMode: string; displayMode: string;
} }
export interface IIconOrAvatar {
avatar: string;
type: string;
rid: string;
showAvatar: boolean;
displayMode: string;
prid: string;
status: TUserStatus;
isGroupChat: boolean;
teamMain: boolean;
showLastMessage: boolean;
sourceType: IOmnichannelSource;
}

View File

@ -37,10 +37,10 @@ const keyExtractor = (item: IOmnichannelRoom) => item.rid;
const QueueListView = React.memo(() => { const QueueListView = React.memo(() => {
const navigation = useNavigation<TNavigation>(); const navigation = useNavigation<TNavigation>();
const getScrollRef = useRef<FlatList<IOmnichannelRoom>>(null); const getScrollRef = useRef<FlatList<IOmnichannelRoom>>(null);
const { theme, colors } = useTheme(); const { colors } = useTheme();
const { width } = useDimensions(); const { width } = useDimensions();
const { userId, token, username } = useSelector( const { username } = useSelector(
(state: IApplicationState) => ({ (state: IApplicationState) => ({
userId: getUserSelector(state).id, userId: getUserSelector(state).id,
username: getUserSelector(state).username, username: getUserSelector(state).username,
@ -58,7 +58,6 @@ const QueueListView = React.memo(() => {
); );
const isMasterDetail = useSelector((state: IApplicationState) => state.app.isMasterDetail); const isMasterDetail = useSelector((state: IApplicationState) => state.app.isMasterDetail);
const server = useSelector((state: IApplicationState) => state.server.server);
const useRealName = useSelector((state: IApplicationState) => state.settings.UI_Use_Real_Name); const useRealName = useSelector((state: IApplicationState) => state.settings.UI_Use_Real_Name);
const queued = useSelector((state: IApplicationState) => getInquiryQueueSelector(state)); const queued = useSelector((state: IApplicationState) => getInquiryQueueSelector(state));
@ -95,20 +94,13 @@ const QueueListView = React.memo(() => {
return ( return (
<RoomItem <RoomItem
item={item} item={item}
theme={theme}
id={id} id={id}
type={item.t}
userId={userId}
username={username} username={username}
token={token}
baseUrl={server}
onPress={onPressItem} onPress={onPressItem}
testID={`queue-list-view-item-${item.name}`}
width={isMasterDetail ? MAX_SIDEBAR_WIDTH : width} width={isMasterDetail ? MAX_SIDEBAR_WIDTH : width}
useRealName={useRealName} useRealName={!!useRealName}
getRoomTitle={getRoomTitle} getRoomTitle={getRoomTitle}
getRoomAvatar={getRoomAvatar} getRoomAvatar={getRoomAvatar}
visitor={item.v}
swipeEnabled={false} swipeEnabled={false}
showAvatar={showAvatar} showAvatar={showAvatar}
displayMode={displayMode} displayMode={displayMode}

View File

@ -38,19 +38,26 @@ import SafeAreaView from '../../containers/SafeAreaView';
import Header, { getHeaderTitlePosition } from '../../containers/Header'; import Header, { getHeaderTitlePosition } from '../../containers/Header';
import { withDimensions } from '../../dimensions'; import { withDimensions } from '../../dimensions';
import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry'; import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry';
import { IApplicationState, IBaseScreen, ISubscription, IUser, RootEnum, TSubscriptionModel } from '../../definitions'; import {
IApplicationState,
IBaseScreen,
ISubscription,
IUser,
RootEnum,
SubscriptionType,
TSubscriptionModel
} from '../../definitions';
import styles from './styles'; import styles from './styles';
import ServerDropdown from './ServerDropdown'; import ServerDropdown from './ServerDropdown';
import ListHeader, { TEncryptionBanner } from './ListHeader'; import ListHeader, { TEncryptionBanner } from './ListHeader';
import RoomsListHeaderView from './Header'; import RoomsListHeaderView from './Header';
import { ChatsStackParamList } from '../../stacks/types'; import { ChatsStackParamList } from '../../stacks/types';
import { getUserPresence, RoomTypes, search } from '../../lib/methods'; import { RoomTypes, search } from '../../lib/methods';
import { import {
getRoomAvatar, getRoomAvatar,
getRoomTitle, getRoomTitle,
getUidDirectMessage, getUidDirectMessage,
hasPermission, hasPermission,
isGroupChat,
isRead, isRead,
debounce, debounce,
isIOS, isIOS,
@ -645,8 +652,6 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
isSwipeEnabled = (item: IRoomItem) => !(item?.search || item?.joinCodeRequired || item?.outside); isSwipeEnabled = (item: IRoomItem) => !(item?.search || item?.joinCodeRequired || item?.outside);
handleGetUserPresence = (uid: string) => getUserPresence(uid);
get isGrouping() { get isGrouping() {
const { showUnread, showFavorites, groupByType } = this.props; const { showUnread, showFavorites, groupByType } = this.props;
return showUnread || showFavorites || groupByType; return showUnread || showFavorites || groupByType;
@ -668,7 +673,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
} }
}; };
toggleFav = async (rid: string, favorite: boolean) => { toggleFav = async (rid: string, favorite: boolean): Promise<void> => {
logEvent(favorite ? events.RL_UNFAVORITE_CHANNEL : events.RL_FAVORITE_CHANNEL); logEvent(favorite ? events.RL_UNFAVORITE_CHANNEL : events.RL_FAVORITE_CHANNEL);
try { try {
const db = database.active; const db = database.active;
@ -718,11 +723,11 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
} }
}; };
hideChannel = async (rid: string, type: RoomTypes) => { hideChannel = async (rid: string, type: SubscriptionType) => {
logEvent(events.RL_HIDE_CHANNEL); logEvent(events.RL_HIDE_CHANNEL);
try { try {
const db = database.active; const db = database.active;
const result = await Services.hideRoom(rid, type); const result = await Services.hideRoom(rid, type as RoomTypes);
if (result.success) { if (result.success) {
const subCollection = db.get('subscriptions'); const subCollection = db.get('subscriptions');
await db.write(async () => { await db.write(async () => {
@ -938,7 +943,6 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
user: { username }, user: { username },
StoreLastMessage, StoreLastMessage,
useRealName, useRealName,
theme,
isMasterDetail, isMasterDetail,
width, width,
showAvatar, showAvatar,
@ -950,9 +954,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
return ( return (
<RoomItem <RoomItem
item={item} item={item}
theme={theme}
id={id} id={id}
type={item.t}
username={username} username={username}
showLastMessage={StoreLastMessage} showLastMessage={StoreLastMessage}
onPress={this.onPressItem} onPress={this.onPressItem}
@ -961,12 +963,9 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
toggleRead={this.toggleRead} toggleRead={this.toggleRead}
hideChannel={this.hideChannel} hideChannel={this.hideChannel}
useRealName={useRealName} useRealName={useRealName}
getUserPresence={this.handleGetUserPresence}
getRoomTitle={getRoomTitle} getRoomTitle={getRoomTitle}
getRoomAvatar={getRoomAvatar} getRoomAvatar={getRoomAvatar}
getIsGroupChat={isGroupChat}
getIsRead={isRead} getIsRead={isRead}
visitor={item.visitor}
isFocused={currentItem?.rid === item.rid} isFocused={currentItem?.rid === item.rid}
swipeEnabled={swipeEnabled} swipeEnabled={swipeEnabled}
showAvatar={showAvatar} showAvatar={showAvatar}

View File

@ -494,12 +494,10 @@ class TeamChannelsView extends React.Component<ITeamChannelsViewProps, ITeamChan
}; };
renderItem = ({ item }: { item: IItem }) => { renderItem = ({ item }: { item: IItem }) => {
const { StoreLastMessage, useRealName, theme, width, showAvatar, displayMode } = this.props; const { StoreLastMessage, useRealName, width, showAvatar, displayMode } = this.props;
return ( return (
<RoomItem <RoomItem
item={item} item={item}
theme={theme}
type={item.t}
showLastMessage={StoreLastMessage} showLastMessage={StoreLastMessage}
onPress={this.onPressItem} onPress={this.onPressItem}
width={width} width={width}