Chore: evaluate `RoomItem` (#4023)

* chore: evaluate `RoomItem`

* update: `RoomItem.storyshot`

* update: interfaces for RoomItem components

* update: UnreadBadge import and RoomItem interfaces

* remove: `avatarSize` from interfaces

* update: `RoomItem.storyshot`
This commit is contained in:
Gerzon Z 2022-04-20 17:37:54 -04:00 committed by GitHub
parent a2baca63cb
commit 8a75dcf87b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 232 additions and 214 deletions

View File

@ -10,7 +10,7 @@ import { CustomIcon } from '../../lib/Icons';
import sharedStyles from '../../views/Styles';
import { themes } from '../../lib/constants';
import { useTheme } from '../../theme';
import { ROW_HEIGHT } from '../../presentation/RoomItem';
import { ROW_HEIGHT } from '../RoomItem';
import { goRoom } from '../../utils/goRoom';
import Navigation from '../../lib/navigation/appNavigation';
import { useOrientation } from '../../dimensions';

View File

@ -6,32 +6,13 @@ import { isRTL } from '../../i18n';
import { CustomIcon } from '../../lib/Icons';
import { DisplayMode, themes } from '../../lib/constants';
import styles, { ACTION_WIDTH, LONG_SWIPE, ROW_HEIGHT_CONDENSED } from './styles';
import { TSupportedThemes } from '../../theme';
interface ILeftActions {
theme: TSupportedThemes;
transX: any;
isRead: boolean;
width: number;
onToggleReadPress(): void;
displayMode: string;
}
interface IRightActions {
theme: TSupportedThemes;
transX: any;
favorite: boolean;
width: number;
toggleFav(): void;
onHidePress(): void;
displayMode: string;
}
import { ILeftActionsProps, IRightActionsProps } from './interfaces';
const reverse = new Animated.Value(isRTL() ? -1 : 1);
const CONDENSED_ICON_SIZE = 24;
const EXPANDED_ICON_SIZE = 28;
export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleReadPress, displayMode }: ILeftActions) => {
export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleReadPress, displayMode }: ILeftActionsProps) => {
const translateX = Animated.multiply(
transX.interpolate({
inputRange: [0, ACTION_WIDTH],
@ -71,7 +52,7 @@ export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleR
});
export const RightActions = React.memo(
({ transX, favorite, width, toggleFav, onHidePress, theme, displayMode }: IRightActions) => {
({ transX, favorite, width, toggleFav, onHidePress, theme, displayMode }: IRightActionsProps) => {
const translateXFav = Animated.multiply(
transX.interpolate({
inputRange: [-width / 2, -ACTION_WIDTH * 2, 0],

View File

@ -2,7 +2,7 @@ import React from 'react';
import { View } from 'react-native';
import PropTypes from 'prop-types';
import Avatar from '../../containers/Avatar';
import Avatar from '../Avatar';
import { DisplayMode } from '../../lib/constants';
import TypeIcon from './TypeIcon';
import styles from './styles';

View File

@ -3,28 +3,11 @@ import { dequal } from 'dequal';
import I18n from '../../i18n';
import styles from './styles';
import { MarkdownPreview } from '../../containers/markdown';
import { MarkdownPreview } from '../markdown';
import { E2E_MESSAGE_TYPE, E2E_STATUS, themes } from '../../lib/constants';
import { TSupportedThemes } from '../../theme';
import { ILastMessageProps } from './interfaces';
interface ILastMessage {
theme: TSupportedThemes;
lastMessage: {
u: any;
pinned: boolean;
t: string;
attachments: any;
msg: string;
e2e: string;
};
type: string;
showLastMessage: boolean;
username: string;
useRealName: boolean;
alert: boolean;
}
const formatMsg = ({ lastMessage, type, showLastMessage, username, useRealName }: Partial<ILastMessage>) => {
const formatMsg = ({ lastMessage, type, showLastMessage, username, useRealName }: Partial<ILastMessageProps>) => {
if (!showLastMessage) {
return '';
}
@ -64,7 +47,7 @@ const formatMsg = ({ lastMessage, type, showLastMessage, username, useRealName }
const arePropsEqual = (oldProps: any, newProps: any) => dequal(oldProps, newProps);
const LastMessage = React.memo(
({ lastMessage, type, showLastMessage, username, alert, useRealName, theme }: ILastMessage) => (
({ lastMessage, type, showLastMessage, username, alert, useRealName, theme }: ILastMessageProps) => (
<MarkdownPreview
msg={formatMsg({
lastMessage,

View File

@ -3,7 +3,7 @@ import { View } from 'react-native';
import styles from './styles';
import Wrapper from './Wrapper';
import UnreadBadge from '../../containers/UnreadBadge';
import UnreadBadge from '../UnreadBadge';
import TypeIcon from './TypeIcon';
import LastMessage from './LastMessage';
import Title from './Title';
@ -12,56 +12,7 @@ import Touchable from './Touchable';
import Tag from './Tag';
import I18n from '../../i18n';
import { DisplayMode } from '../../lib/constants';
import { TUserStatus, IOmnichannelSource } from '../../definitions';
import { TSupportedThemes } from '../../theme';
interface IRoomItem {
rid: string;
type: string;
prid: string;
name: string;
avatar: string;
showLastMessage: boolean;
username: string;
testID: string;
width: number;
status: TUserStatus;
useRealName: boolean;
theme: TSupportedThemes;
isFocused: boolean;
isGroupChat: boolean;
isRead: boolean;
teamMain: boolean;
date: string;
accessibilityLabel: string;
lastMessage: {
u: any;
pinned: boolean;
t: string;
attachments: any;
msg: string;
e2e: string;
};
favorite: boolean;
alert: boolean;
hideUnreadStatus: boolean;
unread: number;
userMentions: number;
groupMentions: number;
tunread: [];
tunreadUser: [];
tunreadGroup: [];
swipeEnabled: boolean;
toggleFav(): void;
toggleRead(): void;
onPress(): void;
onLongPress(): void;
hideChannel(): void;
autoJoin: boolean;
showAvatar: boolean;
displayMode: string;
sourceType: IOmnichannelSource;
}
import { IRoomItemProps } from './interfaces';
const RoomItem = ({
rid,
@ -102,7 +53,7 @@ const RoomItem = ({
showAvatar,
displayMode,
sourceType
}: IRoomItem) => (
}: IRoomItemProps) => (
<Touchable
onPress={onPress}
onLongPress={onLongPress}

View File

@ -3,16 +3,9 @@ import { Text } from 'react-native';
import styles from './styles';
import { themes } from '../../lib/constants';
import { TSupportedThemes } from '../../theme';
import { ITitleProps } from './interfaces';
interface ITitle {
name: string;
theme: TSupportedThemes;
hideUnreadStatus: boolean;
alert: boolean;
}
const Title = React.memo(({ name, theme, hideUnreadStatus, alert }: ITitle) => (
const Title = React.memo(({ name, theme, hideUnreadStatus, alert }: ITitleProps) => (
<Text
style={[styles.title, alert && !hideUnreadStatus && styles.alert, { color: themes[theme].titleText }]}
ellipsizeMode='tail'

View File

@ -1,46 +1,28 @@
import React from 'react';
import { Animated } from 'react-native';
import { LongPressGestureHandler, PanGestureHandler, State } from 'react-native-gesture-handler';
import {
GestureEvent,
HandlerStateChangeEventPayload,
LongPressGestureHandler,
PanGestureHandler,
PanGestureHandlerEventPayload,
State
} from 'react-native-gesture-handler';
import Touch from '../../utils/touch';
import { ACTION_WIDTH, LONG_SWIPE, SMALL_SWIPE } from './styles';
import { isRTL } from '../../i18n';
import { themes } from '../../lib/constants';
import { LeftActions, RightActions } from './Actions';
import { TSupportedThemes } from '../../theme';
interface ITouchableProps {
children: JSX.Element;
type: string;
onPress(): void;
onLongPress(): void;
testID: string;
width: number;
favorite: boolean;
isRead: boolean;
rid: string;
toggleFav: Function;
toggleRead: Function;
hideChannel: Function;
theme: TSupportedThemes;
isFocused: boolean;
swipeEnabled: boolean;
displayMode: string;
}
import { ITouchableProps } from './interfaces';
class Touchable extends React.Component<ITouchableProps, any> {
private dragX: Animated.Value;
private rowOffSet: Animated.Value;
private reverse: Animated.Value;
private transX: Animated.AnimatedAddition;
private transXReverse: Animated.AnimatedMultiplication;
private _onGestureEvent: (...args: any[]) => void;
private _onGestureEvent: (event: GestureEvent<PanGestureHandlerEventPayload>) => void;
private _value: number;
constructor(props: ITouchableProps) {
@ -57,19 +39,19 @@ class Touchable extends React.Component<ITouchableProps, any> {
this._value = 0;
}
_onHandlerStateChange = ({ nativeEvent }: any) => {
_onHandlerStateChange = ({ nativeEvent }: { nativeEvent: HandlerStateChangeEventPayload & PanGestureHandlerEventPayload }) => {
if (nativeEvent.oldState === State.ACTIVE) {
this._handleRelease(nativeEvent);
}
};
onLongPressHandlerStateChange = ({ nativeEvent }: any) => {
onLongPressHandlerStateChange = ({ nativeEvent }: { nativeEvent: HandlerStateChangeEventPayload }) => {
if (nativeEvent.state === State.ACTIVE) {
this.onLongPress();
}
};
_handleRelease = (nativeEvent: any) => {
_handleRelease = (nativeEvent: PanGestureHandlerEventPayload) => {
const { translationX } = nativeEvent;
const { rowState } = this.state;
this._value += translationX;
@ -155,7 +137,7 @@ class Touchable extends React.Component<ITouchableProps, any> {
this._animateRow(toValue);
};
_animateRow = (toValue: any) => {
_animateRow = (toValue: number) => {
this.rowOffSet.setValue(this._value);
this._value = toValue;
this.dragX.setValue(0);

View File

@ -0,0 +1,17 @@
import React from 'react';
import RoomTypeIcon from '../RoomTypeIcon';
import { ITypeIconProps } from './interfaces';
const TypeIcon = React.memo(({ type, prid, status, isGroupChat, teamMain, size, style }: ITypeIconProps) => (
<RoomTypeIcon
type={prid ? 'discussion' : type}
isGroupChat={isGroupChat}
status={status}
teamMain={teamMain}
size={size}
style={style}
/>
));
export default TypeIcon;

View File

@ -4,16 +4,9 @@ import { Text } from 'react-native';
import styles from './styles';
import { themes } from '../../lib/constants';
import { capitalize } from '../../utils/room';
import { TSupportedThemes } from '../../theme';
import { IUpdatedAtProps } from './interfaces';
interface IUpdatedAt {
date: string;
theme: TSupportedThemes;
hideUnreadStatus: boolean;
alert: boolean;
}
const UpdatedAt = React.memo(({ date, theme, hideUnreadStatus, alert }: IUpdatedAt) => {
const UpdatedAt = React.memo(({ date, theme, hideUnreadStatus, alert }: IUpdatedAtProps) => {
if (!date) {
return null;
}

View File

@ -2,29 +2,11 @@ import React from 'react';
import { View } from 'react-native';
import { DisplayMode, themes } from '../../lib/constants';
import { IOmnichannelSource } from '../../definitions';
import { TSupportedThemes } from '../../theme';
import IconOrAvatar from './IconOrAvatar';
import { IWrapperProps } from './interfaces';
import styles from './styles';
interface IWrapper {
accessibilityLabel: string;
avatar: string;
type: string;
theme: TSupportedThemes;
rid: string;
children: JSX.Element;
displayMode: string;
prid: string;
showLastMessage: boolean;
status: string;
isGroupChat: boolean;
teamMain: boolean;
showAvatar: boolean;
sourceType: IOmnichannelSource;
}
const Wrapper = ({ accessibilityLabel, theme, children, displayMode, ...props }: IWrapper) => (
const Wrapper = ({ accessibilityLabel, theme, children, displayMode, ...props }: IWrapperProps): React.ReactElement => (
<View
style={[styles.container, displayMode === DisplayMode.Condensed && styles.containerCondensed]}
accessibilityLabel={accessibilityLabel}>

View File

@ -5,36 +5,10 @@ import I18n from '../../i18n';
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
import { formatDate } from '../../utils/room';
import RoomItem from './RoomItem';
import { TUserStatus } from '../../definitions';
import { TSupportedThemes } from '../../theme';
import { ISubscription, TUserStatus } from '../../definitions';
import { IRoomItemContainerProps } from './interfaces';
export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
interface IRoomItemContainerProps {
item: any;
showLastMessage: boolean;
id: string;
onPress: Function;
onLongPress: Function;
username: string;
width: number;
status: TUserStatus;
toggleFav(): void;
toggleRead(): void;
hideChannel(): void;
useRealName: boolean;
getUserPresence: Function;
connected: boolean;
theme: TSupportedThemes;
isFocused: boolean;
getRoomTitle: Function;
getRoomAvatar: Function;
getIsGroupChat: Function;
getIsRead: Function;
swipeEnabled: boolean;
autoJoin: boolean;
showAvatar: boolean;
displayMode: string;
}
const attrs = [
'width',
@ -50,9 +24,7 @@ const attrs = [
];
class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
private mounted: boolean;
private roomSubscription: any;
private roomSubscription: ISubscription | undefined;
static defaultProps: Partial<IRoomItemContainerProps> = {
status: 'offline',
@ -66,24 +38,22 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
constructor(props: IRoomItemContainerProps) {
super(props);
this.mounted = false;
this.init();
}
componentDidMount() {
this.mounted = true;
const { connected, getUserPresence, id } = this.props;
if (connected && this.isDirect) {
getUserPresence(id);
}
}
shouldComponentUpdate(nextProps: any) {
const { props }: any = this;
shouldComponentUpdate(nextProps: IRoomItemContainerProps) {
const { props } = this;
return !attrs.every(key => props[key] === nextProps[key]);
}
componentDidUpdate(prevProps: any) {
componentDidUpdate(prevProps: IRoomItemContainerProps) {
const { connected, getUserPresence, id } = this.props;
if (prevProps.connected !== connected && connected && this.isDirect) {
getUserPresence(id);
@ -105,7 +75,7 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
const {
item: { t },
id
}: any = this.props;
} = this.props;
return t === 'd' && id && !this.isGroupChat;
}
@ -175,7 +145,6 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
}
return (
// @ts-ignore
<RoomItem
name={name}
avatar={avatar}

View File

@ -0,0 +1,166 @@
import React from 'react';
import { Animated } from 'react-native';
import { TSupportedThemes } from '../../theme';
import { TUserStatus, ILastMessage, SubscriptionType, IOmnichannelSource } from '../../definitions';
export interface ILeftActionsProps {
theme: TSupportedThemes;
transX: Animated.AnimatedAddition | Animated.AnimatedMultiplication;
isRead: boolean;
width: number;
onToggleReadPress(): void;
displayMode: string;
}
export interface IRightActionsProps {
theme: TSupportedThemes;
transX: Animated.AnimatedAddition | Animated.AnimatedMultiplication;
favorite: boolean;
width: number;
toggleFav(): void;
onHidePress(): void;
displayMode: string;
}
export interface ITitleProps {
name: string;
theme: TSupportedThemes;
hideUnreadStatus: boolean;
alert: boolean;
}
export interface IUpdatedAtProps {
date: string;
theme: TSupportedThemes;
hideUnreadStatus: boolean;
alert: boolean;
}
export interface IWrapperProps {
accessibilityLabel: string;
avatar: string;
type: string;
theme: TSupportedThemes;
rid: string;
children: React.ReactElement;
displayMode: string;
prid: string;
showLastMessage: boolean;
status: string;
isGroupChat: boolean;
teamMain: boolean;
showAvatar: boolean;
sourceType: IOmnichannelSource;
}
export interface ITypeIconProps {
type: string;
status: TUserStatus;
prid: string;
isGroupChat: boolean;
teamMain: boolean;
theme?: TSupportedThemes;
size?: number;
style?: object;
sourceType: IOmnichannelSource;
}
export interface IRoomItemContainerProps {
[key: string]: string | boolean | Function | number;
item: any;
showLastMessage: boolean;
id: string;
onPress: (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 {
rid: string;
type: SubscriptionType;
prid: string;
name: string;
avatar: string;
showLastMessage: boolean;
username: string;
testID: string;
width: number;
status: TUserStatus;
useRealName: boolean;
theme: TSupportedThemes;
isFocused: boolean;
isGroupChat: boolean;
isRead: boolean;
teamMain: boolean;
date: string;
accessibilityLabel: string;
lastMessage: ILastMessage;
favorite: boolean;
alert: boolean;
hideUnreadStatus: boolean;
unread: number;
userMentions: number;
groupMentions: number;
tunread: [];
tunreadUser: [];
tunreadGroup: [];
swipeEnabled: boolean;
toggleFav(): void;
toggleRead(): void;
onPress(): void;
onLongPress(): void;
hideChannel(): void;
autoJoin: boolean;
size?: number;
showAvatar: boolean;
displayMode: string;
sourceType: IOmnichannelSource;
}
export interface ILastMessageProps {
theme: TSupportedThemes;
lastMessage: ILastMessage;
type: SubscriptionType;
showLastMessage: boolean;
username: string;
useRealName: boolean;
alert: boolean;
}
export interface ITouchableProps {
children: JSX.Element;
type: string;
onPress(): void;
onLongPress(): void;
testID: string;
width: number;
favorite: boolean;
isRead: boolean;
rid: string;
toggleFav: Function;
toggleRead: Function;
hideChannel: Function;
theme: TSupportedThemes;
isFocused: boolean;
swipeEnabled: boolean;
displayMode: string;
}

View File

@ -42,16 +42,16 @@ export interface ITranslations {
export type E2EType = 'pending' | 'done';
export interface ILastMessage {
_id: string;
rid: string;
_id?: string;
rid?: string;
tshow?: boolean;
t?: MessageType;
tmid?: string;
msg?: string;
e2e?: E2EType;
ts: string | Date;
ts?: string | Date;
u: IUserMessage;
_updatedAt: string | Date;
_updatedAt?: string | Date;
urls?: IUrlFromServer[];
mentions?: IUserMention[];
channels?: IUserChannel[];
@ -59,6 +59,7 @@ export interface ILastMessage {
attachments?: IAttachment[];
reactions?: IReaction[];
unread?: boolean;
pinned?: boolean;
status?: number;
token?: string;
}

View File

@ -6,7 +6,7 @@ import { connect } from 'react-redux';
import { dequal } from 'dequal';
import I18n from '../../../i18n';
import RoomItem, { ROW_HEIGHT } from '../../../presentation/RoomItem';
import RoomItem, { ROW_HEIGHT } from '../../../containers/RoomItem';
import { isIOS, isTablet } from '../../../utils/deviceInfo';
import { getUserSelector } from '../../../selectors/login';
import { TSupportedThemes, withTheme } from '../../../theme';

View File

@ -10,7 +10,7 @@ import { StackNavigationOptions } from '@react-navigation/stack';
import database from '../../lib/database';
import RocketChat from '../../lib/rocketchat';
import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../presentation/RoomItem';
import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../containers/RoomItem';
import log, { logEvent, events } from '../../utils/log';
import I18n from '../../i18n';
import { closeSearchHeader, closeServerDropdown, openSearchHeader, roomsRequest } from '../../actions/rooms';

View File

@ -24,7 +24,7 @@ import I18n from '../i18n';
import database from '../lib/database';
import { CustomIcon } from '../lib/Icons';
import RocketChat from '../lib/rocketchat';
import RoomItem, { ROW_HEIGHT } from '../presentation/RoomItem';
import RoomItem, { ROW_HEIGHT } from '../containers/RoomItem';
import { getUserSelector } from '../selectors/login';
import { ChatsStackParamList } from '../stacks/types';
import { TSupportedThemes, withTheme } from '../theme';

View File

@ -4,7 +4,7 @@ import { Dimensions, ScrollView } from 'react-native';
import { storiesOf } from '@storybook/react-native';
import { Provider } from 'react-redux';
import RoomItemComponent from '../../app/presentation/RoomItem/RoomItem';
import RoomItemComponent from '../../app/containers/RoomItem/RoomItem';
import { longText } from '../utils';
import { DisplayMode, themes } from '../../app/lib/constants';
import { store } from './index';

File diff suppressed because one or more lines are too long