From 601a45a194900039bc6859471f77c5dca86e3f90 Mon Sep 17 00:00:00 2001 From: AlexAlexandre Date: Thu, 29 Jul 2021 15:12:41 -0300 Subject: [PATCH] [IMPROVE] - migrate RoomItem presentation layer --- .../RoomItem/{Actions.js => Actions.tsx} | 39 ++++---- .../{LastMessage.js => LastMessage.tsx} | 36 ++++--- .../RoomItem/{RoomItem.js => RoomItem.tsx} | 94 ++++++++++--------- app/presentation/RoomItem/{Tag.js => Tag.tsx} | 15 ++- .../RoomItem/{Title.js => Title.tsx} | 19 ++-- .../RoomItem/{Touchable.js => Touchable.tsx} | 54 ++++++----- app/presentation/RoomItem/TypeIcon.js | 18 ---- app/presentation/RoomItem/TypeIcon.tsx | 17 ++++ .../RoomItem/{UpdatedAt.js => UpdatedAt.tsx} | 19 ++-- .../RoomItem/{Wrapper.js => Wrapper.tsx} | 23 +++-- .../RoomItem/{index.js => index.tsx} | 80 ++++++++-------- .../RoomItem/{styles.js => styles.ts} | 2 +- 12 files changed, 209 insertions(+), 207 deletions(-) rename app/presentation/RoomItem/{Actions.js => Actions.tsx} (88%) rename app/presentation/RoomItem/{LastMessage.js => LastMessage.tsx} (81%) rename app/presentation/RoomItem/{RoomItem.js => RoomItem.tsx} (73%) rename app/presentation/RoomItem/{Tag.js => Tag.tsx} (72%) rename app/presentation/RoomItem/{Title.js => Title.tsx} (60%) rename app/presentation/RoomItem/{Touchable.js => Touchable.tsx} (86%) delete mode 100644 app/presentation/RoomItem/TypeIcon.js create mode 100644 app/presentation/RoomItem/TypeIcon.tsx rename app/presentation/RoomItem/{UpdatedAt.js => UpdatedAt.tsx} (70%) rename app/presentation/RoomItem/{Wrapper.js => Wrapper.tsx} (70%) rename app/presentation/RoomItem/{index.js => index.tsx} (76%) rename app/presentation/RoomItem/{styles.js => styles.ts} (97%) diff --git a/app/presentation/RoomItem/Actions.js b/app/presentation/RoomItem/Actions.tsx similarity index 88% rename from app/presentation/RoomItem/Actions.js rename to app/presentation/RoomItem/Actions.tsx index 4a557d20e..b87299d5c 100644 --- a/app/presentation/RoomItem/Actions.js +++ b/app/presentation/RoomItem/Actions.tsx @@ -1,18 +1,34 @@ import React from 'react'; import { Animated, View, Text } from 'react-native'; import { RectButton } from 'react-native-gesture-handler'; -import PropTypes from 'prop-types'; import I18n, { isRTL } from '../../i18n'; import styles, { ACTION_WIDTH, LONG_SWIPE } from './styles'; import { CustomIcon } from '../../lib/Icons'; import { themes } from '../../constants/colors'; +interface ILeftActions { + theme: string; + transX: any; + isRead: boolean; + width: number; + onToggleReadPress(): void; +} + +interface IRightActions { + theme: string; + transX: any; + favorite: boolean; + width: number; + toggleFav(): void; + onHidePress(): void; +} + const reverse = new Animated.Value(isRTL() ? -1 : 1); export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleReadPress -}) => { +}: ILeftActions) => { const translateX = Animated.multiply( transX.interpolate({ inputRange: [0, ACTION_WIDTH], @@ -51,7 +67,7 @@ export const LeftActions = React.memo(({ export const RightActions = React.memo(({ transX, favorite, width, toggleFav, onHidePress, theme -}) => { +}: IRightActions) => { const translateXFav = Animated.multiply( transX.interpolate({ inputRange: [-width / 2, -ACTION_WIDTH * 2, 0], @@ -113,20 +129,3 @@ export const RightActions = React.memo(({ ); }); - -LeftActions.propTypes = { - theme: PropTypes.string, - transX: PropTypes.object, - isRead: PropTypes.bool, - width: PropTypes.number, - onToggleReadPress: PropTypes.func -}; - -RightActions.propTypes = { - theme: PropTypes.string, - transX: PropTypes.object, - favorite: PropTypes.bool, - width: PropTypes.number, - toggleFav: PropTypes.func, - onHidePress: PropTypes.func -}; diff --git a/app/presentation/RoomItem/LastMessage.js b/app/presentation/RoomItem/LastMessage.tsx similarity index 81% rename from app/presentation/RoomItem/LastMessage.js rename to app/presentation/RoomItem/LastMessage.tsx index 25fc2c08d..62bd881a1 100644 --- a/app/presentation/RoomItem/LastMessage.js +++ b/app/presentation/RoomItem/LastMessage.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { dequal } from 'dequal'; import I18n from '../../i18n'; @@ -8,9 +7,27 @@ import Markdown from '../../containers/markdown'; import { themes } from '../../constants/colors'; import { E2E_MESSAGE_TYPE, E2E_STATUS } from '../../lib/encryption/constants'; +interface ILastMessage { + theme: string; + 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) => { if (!showLastMessage) { return ''; } @@ -45,11 +62,12 @@ const formatMsg = ({ return `${ prefix }${ lastMessage.msg }`; }; -const arePropsEqual = (oldProps, newProps) => dequal(oldProps, newProps); +const arePropsEqual = (oldProps: any, newProps: any) => dequal(oldProps, newProps); const LastMessage = React.memo(({ lastMessage, type, showLastMessage, username, alert, useRealName, theme -}) => ( +}: ILastMessage) => ( + // @ts-ignore ), arePropsEqual); -LastMessage.propTypes = { - theme: PropTypes.string, - lastMessage: PropTypes.object, - type: PropTypes.string, - showLastMessage: PropTypes.bool, - username: PropTypes.string, - useRealName: PropTypes.bool, - alert: PropTypes.bool -}; - export default LastMessage; diff --git a/app/presentation/RoomItem/RoomItem.js b/app/presentation/RoomItem/RoomItem.tsx similarity index 73% rename from app/presentation/RoomItem/RoomItem.js rename to app/presentation/RoomItem/RoomItem.tsx index 2ac73a0bb..310b0332b 100644 --- a/app/presentation/RoomItem/RoomItem.js +++ b/app/presentation/RoomItem/RoomItem.tsx @@ -13,6 +13,53 @@ import Touchable from './Touchable'; import Tag from './Tag'; import I18n from '../../i18n'; +interface IRoomItem { + rid: string; + type: string; + prid: string; + name: string; + avatar: string; + showLastMessage: boolean; + username: string; + avatarSize: number; + testID: string; + width: number; + status: string; + useRealName: boolean; + theme: string; + 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; + size?: number; +} + const RoomItem = ({ rid, type, @@ -50,7 +97,7 @@ const RoomItem = ({ hideChannel, teamMain, autoJoin -}) => ( +}: IRoomItem) => ( ); -RoomItem.propTypes = { - rid: PropTypes.string.isRequired, - type: PropTypes.string.isRequired, - prid: PropTypes.string, - name: PropTypes.string.isRequired, - avatar: PropTypes.string.isRequired, - showLastMessage: PropTypes.bool, - username: PropTypes.string, - avatarSize: PropTypes.number, - testID: PropTypes.string, - width: PropTypes.number, - status: PropTypes.string, - useRealName: PropTypes.bool, - theme: PropTypes.string, - isFocused: PropTypes.bool, - isGroupChat: PropTypes.bool, - isRead: PropTypes.bool, - teamMain: PropTypes.bool, - date: PropTypes.string, - accessibilityLabel: PropTypes.string, - lastMessage: PropTypes.object, - favorite: PropTypes.bool, - alert: PropTypes.bool, - hideUnreadStatus: PropTypes.bool, - unread: PropTypes.number, - userMentions: PropTypes.number, - groupMentions: PropTypes.number, - tunread: PropTypes.array, - tunreadUser: PropTypes.array, - tunreadGroup: PropTypes.array, - swipeEnabled: PropTypes.bool, - toggleFav: PropTypes.func, - toggleRead: PropTypes.func, - onPress: PropTypes.func, - onLongPress: PropTypes.func, - hideChannel: PropTypes.func, - autoJoin: PropTypes.bool -}; - -RoomItem.defaultProps = { - avatarSize: 48, - status: 'offline', - swipeEnabled: true -}; - export default RoomItem; diff --git a/app/presentation/RoomItem/Tag.js b/app/presentation/RoomItem/Tag.tsx similarity index 72% rename from app/presentation/RoomItem/Tag.js rename to app/presentation/RoomItem/Tag.tsx index 6484b3085..a245b30b6 100644 --- a/app/presentation/RoomItem/Tag.js +++ b/app/presentation/RoomItem/Tag.tsx @@ -1,13 +1,17 @@ import React from 'react'; import { Text, View } from 'react-native'; -import PropTypes from 'prop-types'; import { themes } from '../../constants/colors'; import { useTheme } from '../../theme'; import styles from './styles'; -const Tag = React.memo(({ name, testID }) => { - const { theme } = useTheme(); +interface ITag { + name: string; + testID?: string; +} + +const Tag = React.memo(({ name, testID }: ITag) => { + const { theme }: any = useTheme(); return ( @@ -24,9 +28,4 @@ const Tag = React.memo(({ name, testID }) => { ); }); -Tag.propTypes = { - name: PropTypes.string, - testID: PropTypes.string -}; - export default Tag; diff --git a/app/presentation/RoomItem/Title.js b/app/presentation/RoomItem/Title.tsx similarity index 60% rename from app/presentation/RoomItem/Title.js rename to app/presentation/RoomItem/Title.tsx index 6f4f848d6..613887fb4 100644 --- a/app/presentation/RoomItem/Title.js +++ b/app/presentation/RoomItem/Title.tsx @@ -1,13 +1,17 @@ import React from 'react'; import { Text } from 'react-native'; -import PropTypes from 'prop-types'; import styles from './styles'; import { themes } from '../../constants/colors'; -const Title = React.memo(({ - name, theme, hideUnreadStatus, alert -}) => ( +interface ITitle { + name: string; + theme: string; + hideUnreadStatus: boolean; + alert: boolean; +} + +const Title = React.memo(({ name, theme, hideUnreadStatus, alert }: ITitle) => ( )); -Title.propTypes = { - name: PropTypes.string, - theme: PropTypes.string, - hideUnreadStatus: PropTypes.bool, - alert: PropTypes.bool -}; - export default Title; diff --git a/app/presentation/RoomItem/Touchable.js b/app/presentation/RoomItem/Touchable.tsx similarity index 86% rename from app/presentation/RoomItem/Touchable.js rename to app/presentation/RoomItem/Touchable.tsx index bbf7cbf86..72bd035ab 100644 --- a/app/presentation/RoomItem/Touchable.js +++ b/app/presentation/RoomItem/Touchable.tsx @@ -15,26 +15,34 @@ import { isRTL } from '../../i18n'; import { themes } from '../../constants/colors'; import { LeftActions, RightActions } from './Actions'; -class Touchable extends React.Component { - static propTypes = { - type: PropTypes.string.isRequired, - onPress: PropTypes.func, - onLongPress: PropTypes.func, - testID: PropTypes.string, - width: PropTypes.number, - favorite: PropTypes.bool, - isRead: PropTypes.bool, - rid: PropTypes.string, - toggleFav: PropTypes.func, - toggleRead: PropTypes.func, - hideChannel: PropTypes.func, - children: PropTypes.element, - theme: PropTypes.string, - isFocused: PropTypes.bool, - swipeEnabled: PropTypes.bool - } +interface ITouchableProps { + children: JSX.Element; + type: string; + onPress(): void; + onLongPress(): void; + testID: string; + width: number; + favorite: boolean; + isRead: boolean; + rid: string; + toggleFav({}?, {}?): void; + toggleRead({}?, {}?): void; + hideChannel({}?, {}?): void; + theme: string; + isFocused: boolean; + swipeEnabled: boolean; +} - constructor(props) { +class Touchable extends React.Component { + 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 _value: number; + + constructor(props: ITouchableProps) { super(props); this.dragX = new Animated.Value(0); this.rowOffSet = new Animated.Value(0); @@ -56,20 +64,20 @@ class Touchable extends React.Component { this._value = 0; } - _onHandlerStateChange = ({ nativeEvent }) => { + _onHandlerStateChange = ({ nativeEvent }: any) => { if (nativeEvent.oldState === State.ACTIVE) { this._handleRelease(nativeEvent); } } - onLongPressHandlerStateChange = ({ nativeEvent }) => { + onLongPressHandlerStateChange = ({ nativeEvent }: any) => { if (nativeEvent.state === State.ACTIVE) { this.onLongPress(); } } - _handleRelease = (nativeEvent) => { + _handleRelease = (nativeEvent: any) => { const { translationX } = nativeEvent; const { rowState } = this.state; this._value += translationX; @@ -152,7 +160,7 @@ class Touchable extends React.Component { this._animateRow(toValue); } - _animateRow = (toValue) => { + _animateRow = (toValue: any) => { this.rowOffSet.setValue(this._value); this._value = toValue; this.dragX.setValue(0); diff --git a/app/presentation/RoomItem/TypeIcon.js b/app/presentation/RoomItem/TypeIcon.js deleted file mode 100644 index 425ee6db4..000000000 --- a/app/presentation/RoomItem/TypeIcon.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import RoomTypeIcon from '../../containers/RoomTypeIcon'; - -const TypeIcon = React.memo(({ - type, prid, status, isGroupChat, teamMain -}) => ); - -TypeIcon.propTypes = { - type: PropTypes.string, - status: PropTypes.string, - prid: PropTypes.string, - isGroupChat: PropTypes.bool, - teamMain: PropTypes.bool -}; - -export default TypeIcon; diff --git a/app/presentation/RoomItem/TypeIcon.tsx b/app/presentation/RoomItem/TypeIcon.tsx new file mode 100644 index 000000000..3f1bc4194 --- /dev/null +++ b/app/presentation/RoomItem/TypeIcon.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import RoomTypeIcon from '../../containers/RoomTypeIcon'; + +interface ITypeIcon { + type: string; + status: string; + prid: string; + isGroupChat: boolean; + teamMain: boolean; + theme?: string; +} + +const TypeIcon = React.memo(({ + type, prid, status, isGroupChat, teamMain +}: ITypeIcon) => ); + +export default TypeIcon; diff --git a/app/presentation/RoomItem/UpdatedAt.js b/app/presentation/RoomItem/UpdatedAt.tsx similarity index 70% rename from app/presentation/RoomItem/UpdatedAt.js rename to app/presentation/RoomItem/UpdatedAt.tsx index b8bc9e69a..092709c7d 100644 --- a/app/presentation/RoomItem/UpdatedAt.js +++ b/app/presentation/RoomItem/UpdatedAt.tsx @@ -1,14 +1,18 @@ import React from 'react'; import { Text } from 'react-native'; -import PropTypes from 'prop-types'; import styles from './styles'; import { themes } from '../../constants/colors'; import { capitalize } from '../../utils/room'; -const UpdatedAt = React.memo(({ - date, theme, hideUnreadStatus, alert -}) => { +interface IUpdatedAt { + date: string; + theme: string; + hideUnreadStatus: boolean; + alert: boolean; +} + +const UpdatedAt = React.memo(({ date, theme, hideUnreadStatus, alert }: IUpdatedAt) => { if (!date) { return null; } @@ -38,11 +42,4 @@ const UpdatedAt = React.memo(({ ); }); -UpdatedAt.propTypes = { - date: PropTypes.string, - theme: PropTypes.string, - hideUnreadStatus: PropTypes.bool, - alert: PropTypes.bool -}; - export default UpdatedAt; diff --git a/app/presentation/RoomItem/Wrapper.js b/app/presentation/RoomItem/Wrapper.tsx similarity index 70% rename from app/presentation/RoomItem/Wrapper.js rename to app/presentation/RoomItem/Wrapper.tsx index 52aa0f8a8..6e7459b8e 100644 --- a/app/presentation/RoomItem/Wrapper.js +++ b/app/presentation/RoomItem/Wrapper.tsx @@ -1,11 +1,20 @@ import React from 'react'; import { View } from 'react-native'; -import PropTypes from 'prop-types'; import styles from './styles'; import { themes } from '../../constants/colors'; import Avatar from '../../containers/Avatar'; +interface IWrapper { + accessibilityLabel: string; + avatar: string; + avatarSize: number; + type: string; + theme: string; + rid: string; + children: JSX.Element; +} + const Wrapper = ({ accessibilityLabel, avatar, @@ -14,7 +23,7 @@ const Wrapper = ({ theme, rid, children -}) => ( +}: IWrapper) => ( ); -Wrapper.propTypes = { - accessibilityLabel: PropTypes.string, - avatar: PropTypes.string, - avatarSize: PropTypes.number, - type: PropTypes.string, - theme: PropTypes.string, - rid: PropTypes.string, - children: PropTypes.element -}; - export default Wrapper; diff --git a/app/presentation/RoomItem/index.js b/app/presentation/RoomItem/index.tsx similarity index 76% rename from app/presentation/RoomItem/index.js rename to app/presentation/RoomItem/index.tsx index 0b64437c6..612f12c96 100644 --- a/app/presentation/RoomItem/index.js +++ b/app/presentation/RoomItem/index.tsx @@ -9,6 +9,33 @@ import RoomItem from './RoomItem'; export { ROW_HEIGHT }; + +interface IRoomItemContainerProps { + item: any; + showLastMessage: boolean; + id: string; + onPress({}?): void; + onLongPress({}?): void; + username: string; + avatarSize: number; + width: number; + status: string; + toggleFav(): void; + toggleRead(): void; + hideChannel(): void; + useRealName: boolean; + getUserPresence: Function; + connected: boolean; + theme: string; + isFocused: boolean; + getRoomTitle: Function; + getRoomAvatar: Function; + getIsGroupChat: Function; + getIsRead: Function; + swipeEnabled: boolean; + autoJoin: boolean; +} + const attrs = [ 'width', 'status', @@ -20,45 +47,11 @@ const attrs = [ 'autoJoin' ]; -class RoomItemContainer extends React.Component { - static propTypes = { - item: PropTypes.object.isRequired, - showLastMessage: PropTypes.bool, - id: PropTypes.string, - onPress: PropTypes.func, - onLongPress: PropTypes.func, - username: PropTypes.string, - avatarSize: PropTypes.number, - width: PropTypes.number, - status: PropTypes.string, - toggleFav: PropTypes.func, - toggleRead: PropTypes.func, - hideChannel: PropTypes.func, - useRealName: PropTypes.bool, - getUserPresence: PropTypes.func, - connected: PropTypes.bool, - theme: PropTypes.string, - isFocused: PropTypes.bool, - getRoomTitle: PropTypes.func, - getRoomAvatar: PropTypes.func, - getIsGroupChat: PropTypes.func, - getIsRead: PropTypes.func, - swipeEnabled: PropTypes.bool, - autoJoin: PropTypes.bool - }; +class RoomItemContainer extends React.Component { + private mounted: boolean; + private roomSubscription: any; - static defaultProps = { - avatarSize: 48, - status: 'offline', - getUserPresence: () => {}, - getRoomTitle: () => 'title', - getRoomAvatar: () => '', - getIsGroupChat: () => false, - getIsRead: () => false, - swipeEnabled: true - } - - constructor(props) { + constructor(props: IRoomItemContainerProps) { super(props); this.mounted = false; this.init(); @@ -72,12 +65,12 @@ class RoomItemContainer extends React.Component { } } - shouldComponentUpdate(nextProps) { - const { props } = this; + shouldComponentUpdate(nextProps: any) { + const { props }: any = this; return !attrs.every(key => props[key] === nextProps[key]); } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: any) { const { connected, getUserPresence, id } = this.props; if (prevProps.connected !== connected && connected && this.isDirect) { getUserPresence(id); @@ -96,7 +89,7 @@ class RoomItemContainer extends React.Component { } get isDirect() { - const { item: { t }, id } = this.props; + const { item: { t }, id }: any = this.props; return t === 'd' && id && !this.isGroupChat; } @@ -165,6 +158,7 @@ class RoomItemContainer extends React.Component { } return ( + // @ts-ignore { +const mapStateToProps = (state: any, ownProps: any) => { let status = 'loading'; const { id, type, visitor = {} } = ownProps; if (state.meteor.connected) { diff --git a/app/presentation/RoomItem/styles.js b/app/presentation/RoomItem/styles.ts similarity index 97% rename from app/presentation/RoomItem/styles.js rename to app/presentation/RoomItem/styles.ts index 787546c76..f6c5bf05f 100644 --- a/app/presentation/RoomItem/styles.js +++ b/app/presentation/RoomItem/styles.ts @@ -7,7 +7,7 @@ export const ACTION_WIDTH = 80; export const SMALL_SWIPE = ACTION_WIDTH / 2; export const LONG_SWIPE = ACTION_WIDTH * 3; -export default StyleSheet.create({ +export default StyleSheet.create({ flex: { flex: 1 },