Chore: Migrate MessagesView to Typescript (#3447)
Co-authored-by: Gerzon Z <gerzonc@icloud.com>
This commit is contained in:
parent
251b42ca54
commit
b223a711a2
|
@ -17,7 +17,7 @@ export const useActionSheet = () => useContext(context);
|
||||||
|
|
||||||
const { Provider, Consumer } = context;
|
const { Provider, Consumer } = context;
|
||||||
|
|
||||||
export const withActionSheet = (Component: React.FC) =>
|
export const withActionSheet = <P extends object>(Component: React.ComponentType<P>) =>
|
||||||
forwardRef((props: any, ref: ForwardedRef<any>) => (
|
forwardRef((props: any, ref: ForwardedRef<any>) => (
|
||||||
<Consumer>{(contexts: any) => <Component {...props} {...contexts} ref={ref} />}</Consumer>
|
<Consumer>{(contexts: any) => <Component {...props} {...contexts} ref={ref} />}</Consumer>
|
||||||
));
|
));
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { FlatList, Text, View } from 'react-native';
|
import { FlatList, Text, View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
|
import { RouteProp } from '@react-navigation/core';
|
||||||
|
|
||||||
import Message from '../../containers/message';
|
import Message from '../../containers/message';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
|
@ -18,20 +19,67 @@ import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import getThreadName from '../../lib/methods/getThreadName';
|
import getThreadName from '../../lib/methods/getThreadName';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
class MessagesView extends React.Component {
|
type TMessagesViewRouteParams = {
|
||||||
static propTypes = {
|
MessagesView: {
|
||||||
user: PropTypes.object,
|
rid: string;
|
||||||
baseUrl: PropTypes.string,
|
t: string;
|
||||||
navigation: PropTypes.object,
|
name: string;
|
||||||
route: PropTypes.object,
|
};
|
||||||
customEmojis: PropTypes.object,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
showActionSheet: PropTypes.func,
|
|
||||||
useRealName: PropTypes.bool,
|
|
||||||
isMasterDetail: PropTypes.bool
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
interface IMessagesViewProps {
|
||||||
|
user: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
baseUrl: string;
|
||||||
|
navigation: StackNavigationProp<any, 'MessagesView'>;
|
||||||
|
route: RouteProp<TMessagesViewRouteParams, 'MessagesView'>;
|
||||||
|
customEmojis: { [key: string]: string };
|
||||||
|
theme: string;
|
||||||
|
showActionSheet: Function;
|
||||||
|
useRealName: boolean;
|
||||||
|
isMasterDetail: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMessagesViewState {
|
||||||
|
loading: boolean;
|
||||||
|
messages: [];
|
||||||
|
fileLoading: boolean;
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMessageItem {
|
||||||
|
u?: string;
|
||||||
|
user?: string;
|
||||||
|
editedAt?: Date;
|
||||||
|
attachments?: any;
|
||||||
|
_id: string;
|
||||||
|
tmid?: string;
|
||||||
|
ts?: Date;
|
||||||
|
uploadedAt?: Date;
|
||||||
|
name?: string;
|
||||||
|
description?: string;
|
||||||
|
msg?: string;
|
||||||
|
starred: string;
|
||||||
|
pinned: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IParams {
|
||||||
|
rid?: string;
|
||||||
|
jumpToMessageId: string;
|
||||||
|
t?: string;
|
||||||
|
room: any;
|
||||||
|
tmid?: string;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessagesView extends React.Component<IMessagesViewProps, any> {
|
||||||
|
private rid?: string;
|
||||||
|
private t?: string;
|
||||||
|
private content: any;
|
||||||
|
private room: any;
|
||||||
|
|
||||||
|
constructor(props: IMessagesViewProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -48,7 +96,7 @@ class MessagesView extends React.Component {
|
||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps: IMessagesViewProps, nextState: any) {
|
||||||
const { loading, messages, fileLoading } = this.state;
|
const { loading, messages, fileLoading } = this.state;
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
if (nextProps.theme !== theme) {
|
if (nextProps.theme !== theme) {
|
||||||
|
@ -73,7 +121,7 @@ class MessagesView extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
navToRoomInfo = navParam => {
|
navToRoomInfo = (navParam: { rid: string }) => {
|
||||||
const { navigation, user } = this.props;
|
const { navigation, user } = this.props;
|
||||||
if (navParam.rid === user.id) {
|
if (navParam.rid === user.id) {
|
||||||
return;
|
return;
|
||||||
|
@ -81,9 +129,9 @@ class MessagesView extends React.Component {
|
||||||
navigation.navigate('RoomInfoView', navParam);
|
navigation.navigate('RoomInfoView', navParam);
|
||||||
};
|
};
|
||||||
|
|
||||||
jumpToMessage = async ({ item }) => {
|
jumpToMessage = async ({ item }: { item: IMessageItem }) => {
|
||||||
const { navigation, isMasterDetail } = this.props;
|
const { navigation, isMasterDetail } = this.props;
|
||||||
let params = {
|
let params: IParams = {
|
||||||
rid: this.rid,
|
rid: this.rid,
|
||||||
jumpToMessageId: item._id,
|
jumpToMessageId: item._id,
|
||||||
t: this.t,
|
t: this.t,
|
||||||
|
@ -107,9 +155,9 @@ class MessagesView extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
defineMessagesViewContent = name => {
|
defineMessagesViewContent = (name: string) => {
|
||||||
const { user, baseUrl, theme, useRealName } = this.props;
|
const { user, baseUrl, theme, useRealName } = this.props;
|
||||||
const renderItemCommonProps = item => ({
|
const renderItemCommonProps = (item: IMessageItem) => ({
|
||||||
item,
|
item,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
user,
|
user,
|
||||||
|
@ -137,7 +185,7 @@ class MessagesView extends React.Component {
|
||||||
},
|
},
|
||||||
noDataMsg: I18n.t('No_files'),
|
noDataMsg: I18n.t('No_files'),
|
||||||
testID: 'room-files-view',
|
testID: 'room-files-view',
|
||||||
renderItem: item => (
|
renderItem: (item: IMessageItem) => (
|
||||||
<Message
|
<Message
|
||||||
{...renderItemCommonProps(item)}
|
{...renderItemCommonProps(item)}
|
||||||
item={{
|
item={{
|
||||||
|
@ -165,7 +213,7 @@ class MessagesView extends React.Component {
|
||||||
},
|
},
|
||||||
noDataMsg: I18n.t('No_mentioned_messages'),
|
noDataMsg: I18n.t('No_mentioned_messages'),
|
||||||
testID: 'mentioned-messages-view',
|
testID: 'mentioned-messages-view',
|
||||||
renderItem: item => <Message {...renderItemCommonProps(item)} msg={item.msg} theme={theme} />
|
renderItem: (item: IMessageItem) => <Message {...renderItemCommonProps(item)} msg={item.msg} theme={theme} />
|
||||||
},
|
},
|
||||||
// Starred Messages Screen
|
// Starred Messages Screen
|
||||||
Starred: {
|
Starred: {
|
||||||
|
@ -176,15 +224,15 @@ class MessagesView extends React.Component {
|
||||||
},
|
},
|
||||||
noDataMsg: I18n.t('No_starred_messages'),
|
noDataMsg: I18n.t('No_starred_messages'),
|
||||||
testID: 'starred-messages-view',
|
testID: 'starred-messages-view',
|
||||||
renderItem: item => (
|
renderItem: (item: IMessageItem) => (
|
||||||
<Message {...renderItemCommonProps(item)} msg={item.msg} onLongPress={() => this.onLongPress(item)} theme={theme} />
|
<Message {...renderItemCommonProps(item)} msg={item.msg} onLongPress={() => this.onLongPress(item)} theme={theme} />
|
||||||
),
|
),
|
||||||
action: message => ({
|
action: (message: IMessageItem) => ({
|
||||||
title: I18n.t('Unstar'),
|
title: I18n.t('Unstar'),
|
||||||
icon: message.starred ? 'star-filled' : 'star',
|
icon: message.starred ? 'star-filled' : 'star',
|
||||||
onPress: this.handleActionPress
|
onPress: this.handleActionPress
|
||||||
}),
|
}),
|
||||||
handleActionPress: message => RocketChat.toggleStarMessage(message._id, message.starred)
|
handleActionPress: (message: IMessageItem) => RocketChat.toggleStarMessage(message._id, message.starred)
|
||||||
},
|
},
|
||||||
// Pinned Messages Screen
|
// Pinned Messages Screen
|
||||||
Pinned: {
|
Pinned: {
|
||||||
|
@ -195,12 +243,13 @@ class MessagesView extends React.Component {
|
||||||
},
|
},
|
||||||
noDataMsg: I18n.t('No_pinned_messages'),
|
noDataMsg: I18n.t('No_pinned_messages'),
|
||||||
testID: 'pinned-messages-view',
|
testID: 'pinned-messages-view',
|
||||||
renderItem: item => (
|
renderItem: (item: IMessageItem) => (
|
||||||
<Message {...renderItemCommonProps(item)} msg={item.msg} onLongPress={() => this.onLongPress(item)} theme={theme} />
|
<Message {...renderItemCommonProps(item)} msg={item.msg} onLongPress={() => this.onLongPress(item)} theme={theme} />
|
||||||
),
|
),
|
||||||
action: () => ({ title: I18n.t('Unpin'), icon: 'pin', onPress: this.handleActionPress }),
|
action: () => ({ title: I18n.t('Unpin'), icon: 'pin', onPress: this.handleActionPress }),
|
||||||
handleActionPress: message => RocketChat.togglePinMessage(message._id, message.pinned)
|
handleActionPress: (message: IMessageItem) => RocketChat.togglePinMessage(message._id, message.pinned)
|
||||||
}
|
}
|
||||||
|
// @ts-ignore
|
||||||
}[name];
|
}[name];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,7 +276,7 @@ class MessagesView extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getCustomEmoji = name => {
|
getCustomEmoji = (name: string) => {
|
||||||
const { customEmojis } = this.props;
|
const { customEmojis } = this.props;
|
||||||
const emoji = customEmojis[name];
|
const emoji = customEmojis[name];
|
||||||
if (emoji) {
|
if (emoji) {
|
||||||
|
@ -236,12 +285,12 @@ class MessagesView extends React.Component {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
showAttachment = attachment => {
|
showAttachment = (attachment: any) => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
navigation.navigate('AttachmentView', { attachment });
|
navigation.navigate('AttachmentView', { attachment });
|
||||||
};
|
};
|
||||||
|
|
||||||
onLongPress = message => {
|
onLongPress = (message: IMessageItem) => {
|
||||||
this.setState({ message }, this.showActionSheet);
|
this.setState({ message }, this.showActionSheet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -257,8 +306,8 @@ class MessagesView extends React.Component {
|
||||||
try {
|
try {
|
||||||
const result = await this.content.handleActionPress(message);
|
const result = await this.content.handleActionPress(message);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.setState(prevState => ({
|
this.setState((prevState: IMessagesViewState) => ({
|
||||||
messages: prevState.messages.filter(item => item._id !== message._id),
|
messages: prevState.messages.filter((item: IMessageItem) => item._id !== message._id),
|
||||||
total: prevState.total - 1
|
total: prevState.total - 1
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -267,7 +316,7 @@ class MessagesView extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setFileLoading = fileLoading => {
|
setFileLoading = (fileLoading: boolean) => {
|
||||||
this.setState({ fileLoading });
|
this.setState({ fileLoading });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -280,7 +329,7 @@ class MessagesView extends React.Component {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderItem = ({ item }) => this.content.renderItem(item);
|
renderItem = ({ item }: { item: IMessageItem }) => this.content.renderItem(item);
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { messages, loading } = this.state;
|
const { messages, loading } = this.state;
|
||||||
|
@ -306,7 +355,7 @@ class MessagesView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state: any) => ({
|
||||||
baseUrl: state.server.server,
|
baseUrl: state.server.server,
|
||||||
user: getUserSelector(state),
|
user: getUserSelector(state),
|
||||||
customEmojis: state.customEmojis,
|
customEmojis: state.customEmojis,
|
Loading…
Reference in New Issue