Chore: Migrate SearchMessagesView to Typescript

* Chore: Migrate SearchMessagesView to Typescript

* feat: minor tweak

* minor tweaks

* minor tweak

* minor tweak scrollPersist

Co-authored-by: AlexAlexandre <alexalexandrejr@gmail.com>
This commit is contained in:
Reinaldo Neto 2021-11-10 14:56:19 -03:00 committed by GitHub
parent a54d568f2f
commit 0600c091d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 30 deletions

View File

@ -59,6 +59,7 @@ export interface IUser {
export type UserMention = Pick<IUser, '_id' | 'username' | 'name'>; export type UserMention = Pick<IUser, '_id' | 'username' | 'name'>;
export interface IMessageContent { export interface IMessageContent {
_id: string;
isTemp: boolean; isTemp: boolean;
isInfo: boolean; isInfo: boolean;
tmid: string; tmid: string;

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
import { RouteProp } from '@react-navigation/core';
import { FlatList, Text, View } from 'react-native'; import { FlatList, Text, View } from 'react-native';
import { Q } from '@nozbe/watermelondb'; import { Q } from '@nozbe/watermelondb';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -12,6 +13,7 @@ import debounce from '../../utils/debounce';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import Message from '../../containers/message'; import Message from '../../containers/message';
import scrollPersistTaps from '../../utils/scrollPersistTaps'; import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { IMessage, IMessageAttachments } from '../../containers/message/interfaces';
import I18n from '../../i18n'; import I18n from '../../i18n';
import StatusBar from '../../containers/StatusBar'; import StatusBar from '../../containers/StatusBar';
import log from '../../utils/log'; import log from '../../utils/log';
@ -29,9 +31,52 @@ import { compareServerVersion, methods } from '../../lib/utils';
import styles from './styles'; import styles from './styles';
const QUERY_SIZE = 50; const QUERY_SIZE = 50;
class SearchMessagesView extends React.Component {
static navigationOptions = ({ navigation, route }) => { type TRouteParams = {
const options = { SearchMessagesView: {
showCloseModal?: boolean;
rid: string;
t?: string;
encrypted?: boolean;
};
};
interface ISearchMessagesViewState {
loading: boolean;
messages: IMessage[];
searchText: string;
}
interface INavigationOption {
navigation: StackNavigationProp<any, 'SearchMessagesView'>;
route: RouteProp<TRouteParams, 'SearchMessagesView'>;
}
interface ISearchMessagesViewProps extends INavigationOption {
user: { id: string };
baseUrl: string;
serverVersion: string;
customEmojis: {
[key: string]: {
name: string;
extension: string;
};
};
theme: string;
useRealName: boolean;
}
class SearchMessagesView extends React.Component<ISearchMessagesViewProps, ISearchMessagesViewState> {
private offset: number;
private rid: string;
private t: string | undefined;
private encrypted: boolean | undefined;
private room: { rid: any; name: any; fname: any; t: any } | null | undefined;
static navigationOptions = ({ navigation, route }: INavigationOption) => {
const options: StackNavigationOptions = {
title: I18n.t('Search') title: I18n.t('Search')
}; };
const showCloseModal = route.params?.showCloseModal; const showCloseModal = route.params?.showCloseModal;
@ -41,18 +86,7 @@ class SearchMessagesView extends React.Component {
return options; return options;
}; };
static propTypes = { constructor(props: ISearchMessagesViewProps) {
navigation: PropTypes.object,
route: PropTypes.object,
user: PropTypes.object,
baseUrl: PropTypes.string,
serverVersion: PropTypes.string,
customEmojis: PropTypes.object,
theme: PropTypes.string,
useRealName: PropTypes.bool
};
constructor(props) {
super(props); super(props);
this.state = { this.state = {
loading: false, loading: false,
@ -60,7 +94,7 @@ class SearchMessagesView extends React.Component {
searchText: '' searchText: ''
}; };
this.offset = 0; this.offset = 0;
this.rid = props.route.params?.rid; this.rid = props.route.params.rid;
this.t = props.route.params?.t; this.t = props.route.params?.t;
this.encrypted = props.route.params?.encrypted; this.encrypted = props.route.params?.encrypted;
} }
@ -69,7 +103,7 @@ class SearchMessagesView extends React.Component {
this.room = await getRoomInfo(this.rid); this.room = await getRoomInfo(this.rid);
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps: ISearchMessagesViewProps, nextState: ISearchMessagesViewState) {
const { loading, searchText, messages } = this.state; const { loading, searchText, messages } = this.state;
const { theme } = this.props; const { theme } = this.props;
if (nextProps.theme !== theme) { if (nextProps.theme !== theme) {
@ -88,11 +122,11 @@ class SearchMessagesView extends React.Component {
} }
componentWillUnmount() { componentWillUnmount() {
this.search?.stop?.(); this.searchDebounced?.stop?.();
} }
// Handle encrypted rooms search messages // Handle encrypted rooms search messages
searchMessages = async searchText => { searchMessages = async (searchText: string) => {
if (!searchText) { if (!searchText) {
return []; return [];
} }
@ -117,7 +151,7 @@ class SearchMessagesView extends React.Component {
} }
}; };
getMessages = async (searchText, debounced) => { getMessages = async (searchText: string, debounced?: boolean) => {
try { try {
const messages = await this.searchMessages(searchText); const messages = await this.searchMessages(searchText);
this.setState(prevState => ({ this.setState(prevState => ({
@ -130,17 +164,17 @@ class SearchMessagesView extends React.Component {
} }
}; };
search = searchText => { search = (searchText: string) => {
this.offset = 0; this.offset = 0;
this.setState({ searchText, loading: true, messages: [] }); this.setState({ searchText, loading: true, messages: [] });
this.searchDebounced(searchText); this.searchDebounced(searchText);
}; };
searchDebounced = debounce(async searchText => { searchDebounced = debounce(async (searchText: string) => {
await this.getMessages(searchText, true); await this.getMessages(searchText, true);
}, 1000); }, 1000);
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) {
@ -149,12 +183,12 @@ class SearchMessagesView extends React.Component {
return null; return null;
}; };
showAttachment = attachment => { showAttachment = (attachment: IMessageAttachments) => {
const { navigation } = this.props; const { navigation } = this.props;
navigation.navigate('AttachmentView', { attachment }); navigation.navigate('AttachmentView', { attachment });
}; };
navToRoomInfo = navParam => { navToRoomInfo = (navParam: IMessage) => {
const { navigation, user } = this.props; const { navigation, user } = this.props;
if (navParam.rid === user.id) { if (navParam.rid === user.id) {
return; return;
@ -162,9 +196,9 @@ class SearchMessagesView extends React.Component {
navigation.navigate('RoomInfoView', navParam); navigation.navigate('RoomInfoView', navParam);
}; };
jumpToMessage = async ({ item }) => { jumpToMessage = async ({ item }: { item: IMessage }) => {
const { navigation } = this.props; const { navigation } = this.props;
let params = { let params: any = {
rid: this.rid, rid: this.rid,
jumpToMessageId: item._id, jumpToMessageId: item._id,
t: this.t, t: this.t,
@ -210,7 +244,7 @@ class SearchMessagesView extends React.Component {
); );
}; };
renderItem = ({ item }) => { renderItem = ({ item }: { item: IMessage }) => {
const { user, baseUrl, theme, useRealName } = this.props; const { user, baseUrl, theme, useRealName } = this.props;
return ( return (
<Message <Message
@ -268,6 +302,7 @@ class SearchMessagesView extends React.Component {
testID='search-message-view-input' testID='search-message-view-input'
theme={theme} theme={theme}
/> />
{/* @ts-ignore */}
<Markdown msg={I18n.t('You_can_search_using_RegExp_eg')} username='' baseUrl='' theme={theme} /> <Markdown msg={I18n.t('You_can_search_using_RegExp_eg')} username='' baseUrl='' theme={theme} />
<View style={[styles.divider, { backgroundColor: themes[theme].separatorColor }]} /> <View style={[styles.divider, { backgroundColor: themes[theme].separatorColor }]} />
</View> </View>
@ -277,7 +312,7 @@ class SearchMessagesView extends React.Component {
} }
} }
const mapStateToProps = state => ({ const mapStateToProps = (state: any) => ({
serverVersion: state.server.version, serverVersion: state.server.version,
baseUrl: state.server.server, baseUrl: state.server.server,
user: getUserSelector(state), user: getUserSelector(state),