Chore: Migrate methods/loadSurroundingMessages to Typescript (#3733)
* Chore: Migrate methods/loadSurroundingMessages to Typescript * tweaks * tweak * tweak * tweaks to make ts happy * instead as IMessage is optional u * enum to MessageTypeLoad * minor tweaks
This commit is contained in:
parent
16fd64b260
commit
b06be5a2ac
|
@ -1,5 +1,7 @@
|
|||
export const MESSAGE_TYPE_LOAD_MORE = 'load_more';
|
||||
export const MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK = 'load_previous_chunk';
|
||||
export const MESSAGE_TYPE_LOAD_NEXT_CHUNK = 'load_next_chunk';
|
||||
export enum MessageTypeLoad {
|
||||
MORE = 'load_more',
|
||||
PREVIOUS_CHUNK = 'load_previous_chunk',
|
||||
NEXT_CHUNK = 'load_next_chunk'
|
||||
}
|
||||
|
||||
export const MESSAGE_TYPE_ANY_LOAD = [MESSAGE_TYPE_LOAD_MORE, MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK, MESSAGE_TYPE_LOAD_NEXT_CHUNK];
|
||||
export const MESSAGE_TYPE_ANY_LOAD = [MessageTypeLoad.MORE, MessageTypeLoad.PREVIOUS_CHUNK, MessageTypeLoad.NEXT_CHUNK];
|
||||
|
|
|
@ -926,8 +926,8 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
|||
let msg = `[ ](${permalink}) `;
|
||||
|
||||
// if original message wasn't sent by current user and neither from a direct room
|
||||
if (user.username !== replyingMessage.u.username && roomType !== 'd' && replyWithMention) {
|
||||
msg += `@${replyingMessage.u.username} `;
|
||||
if (user.username !== replyingMessage?.u?.username && roomType !== 'd' && replyWithMention) {
|
||||
msg += `@${replyingMessage?.u?.username} `;
|
||||
}
|
||||
|
||||
msg = `${msg} ${message}`;
|
||||
|
|
|
@ -1,27 +1,14 @@
|
|||
import Model from '@nozbe/watermelondb/Model';
|
||||
import { MarkdownAST } from '@rocket.chat/message-parser';
|
||||
|
||||
import { MessageTypeLoad } from '../constants/messageTypeLoad';
|
||||
import { IAttachment } from './IAttachment';
|
||||
import { IReaction } from './IReaction';
|
||||
import {
|
||||
MESSAGE_TYPE_LOAD_MORE,
|
||||
MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK,
|
||||
MESSAGE_TYPE_LOAD_NEXT_CHUNK
|
||||
} from '../constants/messageTypeLoad';
|
||||
import { TThreadMessageModel } from './IThreadMessage';
|
||||
import { TThreadModel } from './IThread';
|
||||
import { IUrlFromServer } from './IUrl';
|
||||
|
||||
export type MessageType =
|
||||
| 'jitsi_call_started'
|
||||
| 'discussion-created'
|
||||
| 'e2e'
|
||||
| 'load_more'
|
||||
| 'rm'
|
||||
| 'uj'
|
||||
| typeof MESSAGE_TYPE_LOAD_MORE
|
||||
| typeof MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK
|
||||
| typeof MESSAGE_TYPE_LOAD_NEXT_CHUNK;
|
||||
export type MessageType = 'jitsi_call_started' | 'discussion-created' | 'e2e' | 'load_more' | 'rm' | 'uj' | MessageTypeLoad;
|
||||
|
||||
export interface IUserMessage {
|
||||
_id: string;
|
||||
|
|
|
@ -30,6 +30,8 @@ export enum ERoomTypes {
|
|||
CHANNEL = 'channel'
|
||||
}
|
||||
|
||||
type RelationModified<T extends Model> = { fetch(): Promise<T[]> } & Relation<T>;
|
||||
|
||||
export interface ISubscription {
|
||||
_id: string; // _id belongs watermelonDB
|
||||
id: string; // id from server
|
||||
|
@ -93,10 +95,10 @@ export interface ISubscription {
|
|||
teamMain?: boolean;
|
||||
separator?: boolean;
|
||||
// https://nozbe.github.io/WatermelonDB/Relation.html#relation-api
|
||||
messages: Relation<TMessageModel>;
|
||||
threads: Relation<TThreadModel>;
|
||||
threadMessages: Relation<TThreadMessageModel>;
|
||||
uploads: Relation<TUploadModel>;
|
||||
messages: RelationModified<TMessageModel>;
|
||||
threads: RelationModified<TThreadModel>;
|
||||
threadMessages: RelationModified<TThreadMessageModel>;
|
||||
uploads: RelationModified<TUploadModel>;
|
||||
}
|
||||
|
||||
export type TSubscriptionModel = ISubscription & Model;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import moment from 'moment';
|
||||
|
||||
import { IMessage, MessageType, TMessageModel } from '../../definitions';
|
||||
import { MessageTypeLoad } from '../../constants/messageTypeLoad';
|
||||
import { IMessage, TMessageModel } from '../../definitions';
|
||||
import log from '../../utils/log';
|
||||
import { getMessageById } from '../database/services/Message';
|
||||
import roomTypeToApiType, { RoomTypes } from '../rocketchat/methods/roomTypeToApiType';
|
||||
|
@ -46,7 +47,7 @@ export default function loadMessagesForRoom(args: {
|
|||
_id: generateLoadMoreId(lastMessage._id as string),
|
||||
rid: lastMessage.rid,
|
||||
ts: moment(lastMessage.ts).subtract(1, 'millisecond').toString(),
|
||||
t: 'load_more' as MessageType,
|
||||
t: MessageTypeLoad.MORE,
|
||||
msg: lastMessage.msg
|
||||
};
|
||||
data.push(loadMoreMessage);
|
||||
|
|
|
@ -4,7 +4,7 @@ import orderBy from 'lodash/orderBy';
|
|||
|
||||
import log from '../../utils/log';
|
||||
import { getMessageById } from '../database/services/Message';
|
||||
import { MESSAGE_TYPE_LOAD_NEXT_CHUNK } from '../../constants/messageTypeLoad';
|
||||
import { MessageTypeLoad } from '../../constants/messageTypeLoad';
|
||||
import { generateLoadMoreId } from '../utils';
|
||||
import updateMessages from './updateMessages';
|
||||
import { TMessageModel } from '../../definitions';
|
||||
|
@ -34,7 +34,7 @@ export default function loadNextMessages(args: ILoadNextMessages): Promise<void>
|
|||
rid: lastMessage.rid,
|
||||
tmid: args.tmid,
|
||||
ts: moment(lastMessage.ts).add(1, 'millisecond'),
|
||||
t: MESSAGE_TYPE_LOAD_NEXT_CHUNK
|
||||
t: MessageTypeLoad.NEXT_CHUNK
|
||||
};
|
||||
messages.push(loadMoreItem);
|
||||
}
|
||||
|
|
|
@ -4,21 +4,23 @@ import orderBy from 'lodash/orderBy';
|
|||
|
||||
import log from '../../utils/log';
|
||||
import { getMessageById } from '../database/services/Message';
|
||||
import { MESSAGE_TYPE_LOAD_NEXT_CHUNK, MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK } from '../../constants/messageTypeLoad';
|
||||
import { MessageTypeLoad } from '../../constants/messageTypeLoad';
|
||||
import sdk from '../rocketchat/services/sdk';
|
||||
import { IMessage } from '../../definitions';
|
||||
import { generateLoadMoreId } from '../utils';
|
||||
import updateMessages from './updateMessages';
|
||||
|
||||
const COUNT = 50;
|
||||
|
||||
export default function loadSurroundingMessages({ messageId, rid }) {
|
||||
export default function loadSurroundingMessages({ messageId, rid }: { messageId: string; rid: string }) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const data = await this.methodCallWrapper('loadSurroundingMessages', { _id: messageId, rid }, COUNT);
|
||||
let messages = EJSON.fromJSONValue(data?.messages);
|
||||
const data = await sdk.methodCallWrapper('loadSurroundingMessages', { _id: messageId, rid }, COUNT);
|
||||
let messages: IMessage[] = EJSON.fromJSONValue(data?.messages);
|
||||
messages = orderBy(messages, 'ts');
|
||||
|
||||
const message = messages.find(m => m._id === messageId);
|
||||
const { tmid } = message;
|
||||
const tmid = message?.tmid;
|
||||
|
||||
if (messages?.length) {
|
||||
if (data?.moreBefore) {
|
||||
|
@ -29,10 +31,10 @@ export default function loadSurroundingMessages({ messageId, rid }) {
|
|||
_id: generateLoadMoreId(firstMessage._id),
|
||||
rid: firstMessage.rid,
|
||||
tmid,
|
||||
ts: moment(firstMessage.ts).subtract(1, 'millisecond'),
|
||||
t: MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK,
|
||||
ts: moment(firstMessage.ts).subtract(1, 'millisecond').toDate(),
|
||||
t: MessageTypeLoad.PREVIOUS_CHUNK,
|
||||
msg: firstMessage.msg
|
||||
};
|
||||
} as IMessage;
|
||||
messages.unshift(loadMoreItem);
|
||||
}
|
||||
}
|
||||
|
@ -45,18 +47,18 @@ export default function loadSurroundingMessages({ messageId, rid }) {
|
|||
_id: generateLoadMoreId(lastMessage._id),
|
||||
rid: lastMessage.rid,
|
||||
tmid,
|
||||
ts: moment(lastMessage.ts).add(1, 'millisecond'),
|
||||
t: MESSAGE_TYPE_LOAD_NEXT_CHUNK,
|
||||
ts: moment(lastMessage.ts).add(1, 'millisecond').toDate(),
|
||||
t: MessageTypeLoad.NEXT_CHUNK,
|
||||
msg: lastMessage.msg
|
||||
};
|
||||
} as IMessage;
|
||||
messages.push(loadMoreItem);
|
||||
}
|
||||
}
|
||||
|
||||
await updateMessages({ rid, update: messages });
|
||||
return resolve(messages);
|
||||
} else {
|
||||
return resolve([]);
|
||||
}
|
||||
return resolve([]);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
reject(e);
|
|
@ -7,11 +7,7 @@ import { longText } from '../../../../storybook/utils';
|
|||
import { ThemeContext } from '../../../theme';
|
||||
import { Message, MessageDecorator, StoryProvider } from '../../../../storybook/stories/Message';
|
||||
import { themes } from '../../../constants/colors';
|
||||
import {
|
||||
MESSAGE_TYPE_LOAD_MORE,
|
||||
MESSAGE_TYPE_LOAD_NEXT_CHUNK,
|
||||
MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK
|
||||
} from '../../../constants/messageTypeLoad';
|
||||
import { MessageTypeLoad } from '../../../constants/messageTypeLoad';
|
||||
import LoadMore from './index';
|
||||
|
||||
const stories = storiesOf('LoadMore', module);
|
||||
|
@ -23,20 +19,20 @@ stories.add('basic', () => (
|
|||
<>
|
||||
<LoadMore load={load} />
|
||||
<LoadMore load={load} runOnRender />
|
||||
<LoadMore load={load} type={MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK} />
|
||||
<LoadMore load={load} type={MESSAGE_TYPE_LOAD_NEXT_CHUNK} />
|
||||
<LoadMore load={load} type={MessageTypeLoad.PREVIOUS_CHUNK} />
|
||||
<LoadMore load={load} type={MessageTypeLoad.NEXT_CHUNK} />
|
||||
</>
|
||||
));
|
||||
|
||||
const ThemeStory = ({ theme }) => (
|
||||
<ThemeContext.Provider value={{ theme }}>
|
||||
<ScrollView style={{ backgroundColor: themes[theme].backgroundColor }}>
|
||||
<LoadMore load={load} type={MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK} />
|
||||
<LoadMore load={load} type={MessageTypeLoad.PREVIOUS_CHUNK} />
|
||||
<Message msg='Hey!' theme={theme} />
|
||||
<Message msg={longText} theme={theme} isHeader={false} />
|
||||
<Message msg='Older message' theme={theme} isHeader={false} />
|
||||
<LoadMore load={load} type={MESSAGE_TYPE_LOAD_NEXT_CHUNK} />
|
||||
<LoadMore load={load} type={MESSAGE_TYPE_LOAD_MORE} />
|
||||
<LoadMore load={load} type={MessageTypeLoad.NEXT_CHUNK} />
|
||||
<LoadMore load={load} type={MessageTypeLoad.MORE} />
|
||||
<Message msg={longText} theme={theme} />
|
||||
<Message msg='This is the third message' isHeader={false} theme={theme} />
|
||||
<Message msg='This is the second message' isHeader={false} theme={theme} />
|
||||
|
|
|
@ -2,7 +2,8 @@ import React, { useCallback, useEffect, useState } from 'react';
|
|||
import { ActivityIndicator, StyleSheet, Text } from 'react-native';
|
||||
|
||||
import { themes } from '../../../constants/colors';
|
||||
import { MESSAGE_TYPE_LOAD_NEXT_CHUNK, MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK } from '../../../constants/messageTypeLoad';
|
||||
import { MessageTypeLoad } from '../../../constants/messageTypeLoad';
|
||||
import { MessageType } from '../../../definitions';
|
||||
import { useTheme } from '../../../theme';
|
||||
import Touch from '../../../utils/touch';
|
||||
import sharedStyles from '../../Styles';
|
||||
|
@ -20,7 +21,15 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const LoadMore = ({ load, type, runOnRender }: { load: Function; type: string; runOnRender: boolean }): React.ReactElement => {
|
||||
const LoadMore = ({
|
||||
load,
|
||||
type,
|
||||
runOnRender
|
||||
}: {
|
||||
load: Function;
|
||||
type: MessageType;
|
||||
runOnRender: boolean;
|
||||
}): React.ReactElement => {
|
||||
const { theme } = useTheme();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
@ -43,10 +52,10 @@ const LoadMore = ({ load, type, runOnRender }: { load: Function; type: string; r
|
|||
}, []);
|
||||
|
||||
let text = 'Load_More';
|
||||
if (type === MESSAGE_TYPE_LOAD_NEXT_CHUNK) {
|
||||
if (type === MessageTypeLoad.NEXT_CHUNK) {
|
||||
text = 'Load_Newer';
|
||||
}
|
||||
if (type === MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK) {
|
||||
if (type === MessageTypeLoad.PREVIOUS_CHUNK) {
|
||||
text = 'Load_Older';
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import I18n from '../../i18n';
|
|||
import RoomHeader from '../../containers/RoomHeader';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import { themes } from '../../constants/colors';
|
||||
import { MESSAGE_TYPE_ANY_LOAD, MESSAGE_TYPE_LOAD_MORE } from '../../constants/messageTypeLoad';
|
||||
import { MESSAGE_TYPE_ANY_LOAD, MessageTypeLoad } from '../../constants/messageTypeLoad';
|
||||
import debounce from '../../utils/debounce';
|
||||
import ReactionsModal from '../../containers/ReactionsModal';
|
||||
import { LISTENER } from '../../containers/Toast';
|
||||
|
@ -851,7 +851,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
* if it's from server, we don't have it saved locally and so we fetch surroundings
|
||||
* we test if it's not from threads because we're fetching from threads currently with `getThreadMessages`
|
||||
*/
|
||||
if (message.fromServer && !message.tmid) {
|
||||
if (message.fromServer && !message.tmid && this.rid) {
|
||||
await RocketChat.loadSurroundingMessages({ messageId, rid: this.rid });
|
||||
}
|
||||
// @ts-ignore
|
||||
|
@ -1161,12 +1161,12 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
}
|
||||
|
||||
let content = null;
|
||||
if (item.t && MESSAGE_TYPE_ANY_LOAD.includes(item.t)) {
|
||||
if (item.t && MESSAGE_TYPE_ANY_LOAD.includes(item.t as MessageTypeLoad)) {
|
||||
content = (
|
||||
<LoadMore
|
||||
load={() => this.onLoadMoreMessages(item)}
|
||||
type={item.t}
|
||||
runOnRender={item.t === MESSAGE_TYPE_LOAD_MORE && !previousItem}
|
||||
runOnRender={item.t === MessageTypeLoad.MORE && !previousItem}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import { MessageType, SubscriptionType, TAnyMessageModel } from '../../../definitions';
|
||||
import { SubscriptionType, TAnyMessageModel } from '../../../definitions';
|
||||
import loadMessagesForRoom from '../../../lib/methods/loadMessagesForRoom';
|
||||
import loadNextMessages from '../../../lib/methods/loadNextMessages';
|
||||
import {
|
||||
MESSAGE_TYPE_LOAD_MORE,
|
||||
MESSAGE_TYPE_LOAD_NEXT_CHUNK,
|
||||
MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK
|
||||
} from '../../../constants/messageTypeLoad';
|
||||
import { MessageTypeLoad } from '../../../constants/messageTypeLoad';
|
||||
|
||||
const getMoreMessages = ({
|
||||
rid,
|
||||
|
@ -18,7 +14,7 @@ const getMoreMessages = ({
|
|||
tmid?: string;
|
||||
loaderItem: TAnyMessageModel;
|
||||
}): Promise<void> => {
|
||||
if ([MESSAGE_TYPE_LOAD_MORE, MESSAGE_TYPE_LOAD_PREVIOUS_CHUNK].includes(loaderItem.t as MessageType)) {
|
||||
if ([MessageTypeLoad.MORE, MessageTypeLoad.PREVIOUS_CHUNK].includes(loaderItem.t as MessageTypeLoad)) {
|
||||
return loadMessagesForRoom({
|
||||
rid,
|
||||
t: t as any,
|
||||
|
@ -27,7 +23,7 @@ const getMoreMessages = ({
|
|||
});
|
||||
}
|
||||
|
||||
if (loaderItem.t === MESSAGE_TYPE_LOAD_NEXT_CHUNK) {
|
||||
if (loaderItem.t === MessageTypeLoad.NEXT_CHUNK) {
|
||||
return loadNextMessages({
|
||||
rid,
|
||||
tmid,
|
||||
|
|
|
@ -7,7 +7,6 @@ import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context';
|
|||
import { HeaderBackButton, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
|
||||
import { RouteProp } from '@react-navigation/native';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import Database from '@nozbe/watermelondb/Database';
|
||||
|
||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import I18n from '../../i18n';
|
||||
|
@ -33,13 +32,12 @@ import EventEmitter from '../../utils/events';
|
|||
import { LISTENER } from '../../containers/Toast';
|
||||
import SearchHeader from '../../containers/SearchHeader';
|
||||
import { ChatsStackParamList } from '../../stacks/types';
|
||||
import { IThreadResult, TThreadModel } from '../../definitions/IThread';
|
||||
import { Filter } from './filters';
|
||||
import DropdownItemHeader from './Dropdown/DropdownItemHeader';
|
||||
import Dropdown from './Dropdown';
|
||||
import Item from './Item';
|
||||
import styles from './styles';
|
||||
import { SubscriptionType, TSubscriptionModel } from '../../definitions/ISubscription';
|
||||
import { IMessage, SubscriptionType, TSubscriptionModel, TThreadModel } from '../../definitions';
|
||||
|
||||
const API_FETCH_COUNT = 50;
|
||||
|
||||
|
@ -259,8 +257,8 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
|||
remove,
|
||||
lastThreadSync
|
||||
}: {
|
||||
update: IThreadResult[];
|
||||
remove?: IThreadResult[];
|
||||
update: IMessage[];
|
||||
remove?: IMessage[];
|
||||
lastThreadSync: Date;
|
||||
}) => {
|
||||
const { subscription } = this.state;
|
||||
|
@ -272,11 +270,9 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
|||
}
|
||||
|
||||
try {
|
||||
const db: Database = database.active;
|
||||
const db = database.active;
|
||||
const threadsCollection = db.get('threads');
|
||||
// TODO: Refactor when migrate room
|
||||
// @ts-ignore
|
||||
const allThreadsRecords = (await subscription.threads.fetch()) as TThreadModel[];
|
||||
const allThreadsRecords = await subscription.threads.fetch();
|
||||
let threadsToCreate: any[] = [];
|
||||
let threadsToUpdate: any[] = [];
|
||||
let threadsToDelete: any[] = [];
|
||||
|
@ -287,7 +283,7 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
|||
}
|
||||
|
||||
if (update && update.length) {
|
||||
update = update.map(m => buildMessage(m)) as IThreadResult[];
|
||||
update = update.map(m => buildMessage(m)) as IMessage[];
|
||||
// filter threads
|
||||
threadsToCreate = update.filter(i1 => !allThreadsRecords.find((i2: { id: string }) => i1._id === i2.id));
|
||||
threadsToUpdate = allThreadsRecords.filter((i1: { id: string }) => update.find(i2 => i1.id === i2._id));
|
||||
|
|
Loading…
Reference in New Issue