Add asPlain to messages

This commit is contained in:
Diego Mello 2022-11-29 10:58:57 -03:00
parent 7beaa62003
commit fad04765d4
14 changed files with 186 additions and 88 deletions

View File

@ -8,12 +8,12 @@ import { debounce } from '../../lib/methods/helpers';
import { getMessageTranslation } from './utils';
import { TSupportedThemes, withTheme } from '../../theme';
import openLink from '../../lib/methods/helpers/openLink';
import { IAttachment, TAnyMessageModel, TGetCustomEmoji } from '../../definitions';
import { IAttachment, TAnyMessage, TGetCustomEmoji } from '../../definitions';
import { IRoomInfoParam } from '../../views/SearchMessagesView';
import { E2E_MESSAGE_TYPE, E2E_STATUS, messagesStatus } from '../../lib/constants';
interface IMessageContainerProps {
item: TAnyMessageModel;
interface TAnyMessageContainerProps {
item: TAnyMessage;
user: {
id: string;
username: string;
@ -25,7 +25,7 @@ interface IMessageContainerProps {
style?: ViewStyle;
archived?: boolean;
broadcast?: boolean;
previousItem?: TAnyMessageModel;
previousItem?: TAnyMessage;
baseUrl: string;
Message_GroupingPeriod?: number;
isReadReceiptEnabled?: boolean;
@ -38,17 +38,17 @@ interface IMessageContainerProps {
isIgnored?: boolean;
highlighted?: boolean;
getCustomEmoji: TGetCustomEmoji;
onLongPress?: (item: TAnyMessageModel) => void;
onLongPress?: (item: TAnyMessage) => void;
onReactionPress?: (emoji: string, id: string) => void;
onEncryptedPress?: () => void;
onDiscussionPress?: (item: TAnyMessageModel) => void;
onThreadPress?: (item: TAnyMessageModel) => void;
errorActionsShow?: (item: TAnyMessageModel) => void;
replyBroadcast?: (item: TAnyMessageModel) => void;
reactionInit?: (item: TAnyMessageModel) => void;
onDiscussionPress?: (item: TAnyMessage) => void;
onThreadPress?: (item: TAnyMessage) => void;
errorActionsShow?: (item: TAnyMessage) => void;
replyBroadcast?: (item: TAnyMessage) => void;
reactionInit?: (item: TAnyMessage) => void;
fetchThreadName?: (tmid: string, id: string) => Promise<string | undefined>;
showAttachment: (file: IAttachment) => void;
onReactionLongPress?: (item: TAnyMessageModel) => void;
onReactionLongPress?: (item: TAnyMessage) => void;
navToRoomInfo: (navParam: IRoomInfoParam) => void;
callJitsi?: () => void;
blockAction?: (params: { actionId: string; appId: string; value: string; blockId: string; rid: string; mid: string }) => void;
@ -61,11 +61,11 @@ interface IMessageContainerProps {
closeEmojiAndAction?: (action?: Function, params?: any) => void;
}
interface IMessageContainerState {
interface TAnyMessageContainerState {
isManualUnignored: boolean;
}
class MessageContainer extends React.Component<IMessageContainerProps, IMessageContainerState> {
class MessageContainer extends React.Component<TAnyMessageContainerProps, TAnyMessageContainerState> {
static defaultProps = {
getCustomEmoji: () => null,
onLongPress: () => {},
@ -97,7 +97,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
// }
// }
// shouldComponentUpdate(nextProps: IMessageContainerProps, nextState: IMessageContainerState) {
// shouldComponentUpdate(nextProps: TAnyMessageContainerProps, nextState: TAnyMessageContainerState) {
// const { isManualUnignored } = this.state;
// const { threadBadgeColor, isIgnored, highlighted, previousItem } = this.props;
// if (nextProps.highlighted !== highlighted) {
@ -233,11 +233,11 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
try {
if (
previousItem &&
// @ts-ignore TODO: IMessage vs IMessageFromServer non-sense
// @ts-ignore TODO: TAnyMessage vs TAnyMessageFromServer non-sense
previousItem.ts.toDateString() === item.ts.toDateString() &&
previousItem.u.username === item.u.username &&
!(previousItem.groupable === false || item.groupable === false || broadcast === true) &&
// @ts-ignore TODO: IMessage vs IMessageFromServer non-sense
// @ts-ignore TODO: TAnyMessage vs TAnyMessageFromServer non-sense
item.ts - previousItem.ts < Message_GroupingPeriod * 1000 &&
previousItem.tmid === item.tmid
) {

View File

@ -1,5 +1,5 @@
/* eslint-disable complexity */
import { MessageTypesValues, TMessageModel } from '../../definitions/IMessage';
import { MessageTypesValues, TAnyMessage } from '../../definitions/IMessage';
import I18n from '../../i18n';
import { DISCUSSION } from './constants';
@ -182,7 +182,7 @@ export const getInfoMessage = ({ type, role, msg, author, comment }: TInfoMessag
}
};
export const getMessageTranslation = (message: TMessageModel, autoTranslateLanguage: string): string | null => {
export const getMessageTranslation = (message: TAnyMessage, autoTranslateLanguage: string): string | null => {
if (!autoTranslateLanguage) {
return null;
}

View File

@ -4,8 +4,8 @@ import { MarkdownAST } from '@rocket.chat/message-parser';
import { MessageTypeLoad } from '../lib/constants';
import { IAttachment } from './IAttachment';
import { IReaction } from './IReaction';
import { TThreadMessageModel } from './IThreadMessage';
import { TThreadModel } from './IThread';
import { IThreadMessage, TThreadMessageModel } from './IThreadMessage';
import { IThread, TThreadModel } from './IThread';
import { IUrl, IUrlFromServer } from './IUrl';
export type MessageType =
@ -146,9 +146,13 @@ export interface IMessage extends IMessageFromServer {
editedAt?: string | Date;
}
export type TMessageModel = IMessage & Model;
export type TMessageModel = IMessage &
Model & {
asPlain: () => IMessage;
};
export type TAnyMessageModel = TMessageModel | TThreadModel | TThreadMessageModel;
export type TAnyMessage = IMessage | IThread | IThreadMessage;
export type TTypeMessages = IMessageFromServer | ILoadMoreMessage | IMessage;
// Read receipts to ReadReceiptView and chat.getMessageReadReceipts

View File

@ -109,7 +109,6 @@ export interface ISubscription {
export type TSubscriptionModel = ISubscription &
Model & {
unsubscribe: () => Promise<any>;
asPlain: () => ISubscription;
};
export type TSubscription = TSubscriptionModel | ISubscription;

View File

@ -38,4 +38,7 @@ export interface IThread extends IMessage {
draftMessage?: string;
}
export type TThreadModel = IThread & Model;
export type TThreadModel = IThread &
Model & {
asPlain: () => IThread;
};

View File

@ -6,4 +6,7 @@ export interface IThreadMessage extends IMessage {
tmsg?: string;
}
export type TThreadMessageModel = IThreadMessage & Model;
export type TThreadMessageModel = IThreadMessage &
Model & {
asPlain: () => IThreadMessage;
};

View File

@ -85,4 +85,45 @@ export default class Message extends Model {
@json('md', sanitizer) md;
@field('comment') comment;
asPlain() {
return {
msg: this.msg,
t: this.t,
ts: this.ts,
u: this.u,
alias: this.alias,
parseUrls: this.parseUrls,
groupable: this.groupable,
avatar: this.avatar,
emoji: this.emoji,
attachments: this.attachments,
urls: this.urls,
_updatedAt: this._updatedAt,
status: this.status,
pinned: this.pinned,
starred: this.starred,
editedBy: this.editedBy,
reactions: this.reactions,
role: this.role,
drid: this.drid,
dcount: this.dcount,
dlm: this.dlm,
tmid: this.tmid,
tcount: this.tcount,
tlm: this.tlm,
replies: this.replies,
mentions: this.mentions,
channels: this.channels,
unread: this.unread,
autoTranslate: this.autoTranslate,
translations: this.translations,
tmsg: this.tmsg,
blocks: this.blocks,
e2e: this.e2e,
tshow: this.tshow,
md: this.md,
comment: this.comment
};
}
}

View File

@ -77,4 +77,41 @@ export default class Thread extends Model {
@field('e2e') e2e;
@field('draft_message') draftMessage;
asPlain() {
return {
msg: this.msg,
t: this.t,
ts: this.ts,
u: this.u,
alias: this.alias,
parseUrls: this.parseUrls,
groupable: this.groupable,
avatar: this.avatar,
emoji: this.emoji,
attachments: this.attachments,
urls: this.urls,
_updatedAt: this._updatedAt,
status: this.status,
pinned: this.pinned,
starred: this.starred,
editedBy: this.editedBy,
reactions: this.reactions,
role: this.role,
drid: this.drid,
dcount: this.dcount,
dlm: this.dlm,
tmid: this.tmid,
tcount: this.tcount,
tlm: this.tlm,
replies: this.replies,
mentions: this.mentions,
channels: this.channels,
unread: this.unread,
autoTranslate: this.autoTranslate,
translations: this.translations,
e2e: this.e2e,
draftMessage: this.draftMessage
};
}
}

View File

@ -77,4 +77,41 @@ export default class ThreadMessage extends Model {
@field('draft_message') draftMessage;
@field('e2e') e2e;
asPlain() {
return {
msg: this.msg,
t: this.t,
ts: this.ts,
u: this.u,
rid: this.rid,
alias: this.alias,
parseUrls: this.parseUrls,
groupable: this.groupable,
avatar: this.avatar,
emoji: this.emoji,
attachments: this.attachments,
urls: this.urls,
_updatedAt: this._updatedAt,
status: this.status,
pinned: this.pinned,
starred: this.starred,
editedBy: this.editedBy,
reactions: this.reactions,
role: this.role,
drid: this.drid,
dcount: this.dcount,
dlm: this.dlm,
tcount: this.tcount,
tlm: this.tlm,
replies: this.replies,
mentions: this.mentions,
channels: this.channels,
unread: this.unread,
autoTranslate: this.autoTranslate,
translations: this.translations,
draftMessage: this.draftMessage,
e2e: this.e2e
};
}
}

View File

@ -14,7 +14,7 @@ import { addUserTyping, clearUserTyping, removeUserTyping } from '../../../actio
import { debounce } from '../helpers';
import { subscribeRoom, unsubscribeRoom } from '../../../actions/room';
import { Encryption } from '../../encryption';
import { IMessage, TMessageModel, TSubscriptionModel, TThreadMessageModel, TThreadModel } from '../../../definitions';
import { IMessage, TMessageModel, TThreadMessageModel, TThreadModel } from '../../../definitions';
import { IDDPMessage } from '../../../definitions/IDDPMessage';
import sdk from '../../services/sdk';
import { readMessages } from '../readMessages';
@ -33,7 +33,7 @@ export default class RoomSubscription {
private _threadsBatch: { [key: string]: TThreadModel };
private threadMessagesBatch: {};
private _threadMessagesBatch: { [key: string]: TThreadMessageModel };
private promises?: Promise<TSubscriptionModel[]>;
private promises?: Promise<any>;
private connectedListener?: Promise<any>;
private disconnectedListener?: Promise<any>;
private notifyRoomListener?: Promise<any>;
@ -79,7 +79,7 @@ export default class RoomSubscription {
if (this.promises) {
try {
const subscriptions = (await this.promises) || [];
subscriptions.forEach(sub => sub.unsubscribe().catch(() => console.log('unsubscribeRoom')));
subscriptions.forEach((sub: any) => sub.unsubscribe().catch(() => console.log('unsubscribeRoom')));
} catch (e) {
// do nothing
}

View File

@ -7,7 +7,7 @@ import { event, Value } from 'react-native-reanimated';
import { Observable, Subscription } from 'rxjs';
import ActivityIndicator from '../../../containers/ActivityIndicator';
import { MessageType, TAnyMessageModel, TMessageModel, TThreadMessageModel, TThreadModel } from '../../../definitions';
import { MessageType, TAnyMessage, TMessageModel, TThreadMessageModel, TThreadModel } from '../../../definitions';
import database from '../../../lib/database';
import { compareServerVersion, debounce } from '../../../lib/methods/helpers';
import { animateNextTransition } from '../../../lib/methods/helpers/layoutAnimation';
@ -20,6 +20,7 @@ import { loadMissedMessages, loadThreadMessages } from '../../../lib/methods';
import { Services } from '../../../lib/services';
import { TSupportedThemes, withTheme } from '../../../theme';
import { MESSAGE_TYPE_ANY_LOAD, themes } from '../../../lib/constants';
import { TMessage } from '../definitions';
const QUERY_SIZE = 50;
@ -53,7 +54,7 @@ export interface IListContainerProps {
}
interface IListContainerState {
messages: TAnyMessageModel[];
messages: TMessage[];
refreshing: boolean;
highlightedMessage: string | null;
}
@ -185,47 +186,16 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
if (rid) {
this.unsubscribeMessages();
this.messagesSubscription = this.messagesObservable?.subscribe(messages => {
// @ts-ignore is this enough cols?
messages = messages.map(m => {
let data = messages.map(m => {
if ((MESSAGE_TYPE_ANY_LOAD as MessageType[]).includes(m.t)) {
return m;
}
return {
id: m.id,
_id: m._id,
msg: m.msg,
ts: m.ts,
status: m.status,
attachments: m.attachments,
urls: m.urls,
reactions: m.reactions,
t: m.t,
avatar: m.avatar,
emoji: m.emoji,
u: m.u,
alias: m.alias,
editedBy: m.editedBy,
role: m.role,
drid: m.drid,
dcount: m.dcount,
dlm: m.dlm,
tmid: m.tmid,
tcount: m.tcount,
tlm: m.tlm,
tmsg: m.tmsg,
mentions: m.mentions,
channels: m.channels,
unread: m.unread,
blocks: m.blocks,
autoTranslate: m.autoTranslate,
replies: m.replies,
md: m.md,
comment: m.comment
};
return m.asPlain();
});
if (tmid && this.thread) {
messages = [...messages, this.thread];
data = [...messages, this.thread];
}
/**
@ -233,7 +203,7 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
* hide system message is enabled
*/
if (compareServerVersion(serverVersion, 'lowerThan', '3.16.0') || hideSystemMessages.length) {
messages = messages.filter(m => !m.t || !hideSystemMessages?.includes(m.t));
data = messages.filter(m => !m.t || !hideSystemMessages?.includes(m.t));
}
if (this.mounted) {
@ -241,10 +211,10 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
listRef.current?.prepareForLayoutAnimationRender();
animateNextTransition();
}
this.setState({ messages });
this.setState({ messages: data });
} else {
// @ts-ignore
this.state.messages = messages;
this.state.messages = data;
}
// TODO: move it away from here
this.readThreads();
@ -297,7 +267,7 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
}
};
getLastMessage = (): TMessageModel | TThreadMessageModel | null => {
getLastMessage = (): TAnyMessage | null => {
const { messages } = this.state;
if (messages.length > 0) {
return messages[0];

View File

@ -0,0 +1,3 @@
import { TAnyMessage, TMessageModel } from '../../definitions';
export type TMessage = TAnyMessage | TMessageModel;

View File

@ -69,7 +69,7 @@ import {
ISubscription,
IVisitor,
SubscriptionType,
TAnyMessageModel,
TAnyMessage,
TMessageModel,
TSubscriptionModel,
TThreadModel,
@ -101,6 +101,7 @@ import {
import { Services } from '../../lib/services';
import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet';
import { goRoom, TGoRoomItem } from '../../lib/methods/helpers/goRoom';
import { TMessage } from './definitions';
type TStateAttrsUpdate = keyof IRoomViewState;
@ -193,7 +194,7 @@ interface IRoomViewState {
member: any;
lastOpen: Date | null;
reactionsModalVisible: boolean;
selectedMessage?: TAnyMessageModel;
selectedMessage?: TAnyMessage;
canAutoTranslate: boolean;
loading: boolean;
editing: boolean;
@ -225,7 +226,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
private retryFindTimeout?: ReturnType<typeof setTimeout>;
private messageErrorActions?: IMessageErrorActions | null;
private messageActions?: IMessageActions | null;
private replyInDM?: TAnyMessageModel;
private replyInDM?: TAnyMessage;
// Type of InteractionManager.runAfterInteractions
private didMountInteraction?: {
then: (onfulfilled?: (() => any) | undefined, onrejected?: (() => any) | undefined) => Promise<any>;
@ -781,7 +782,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
});
};
errorActionsShow = (message: TAnyMessageModel) => {
errorActionsShow = (message: TAnyMessage) => {
this.messagebox?.current?.closeEmojiAndAction(this.messageErrorActions?.showMessageErrorActions, message);
};
@ -790,7 +791,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
this.messagebox?.current?.closeEmojiAndAction(showActionSheet, options);
};
onEditInit = (message: TAnyMessageModel) => {
onEditInit = (message: TAnyMessage) => {
const newMessage = {
id: message.id,
subscription: {
@ -806,7 +807,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
this.setState({ selectedMessage: undefined, editing: false });
};
onEditRequest = async (message: TAnyMessageModel) => {
onEditRequest = async (message: TAnyMessage) => {
this.setState({ selectedMessage: undefined, editing: false });
try {
await Services.editMessage(message);
@ -815,7 +816,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
};
onReplyInit = (message: TAnyMessageModel, mention: boolean) => {
onReplyInit = (message: TAnyMessage, mention: boolean) => {
// If there's a thread already, we redirect to it
if (mention && !!message.tlm) {
return this.onThreadPress(message);
@ -843,7 +844,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
});
};
onReactionInit = (message: TAnyMessageModel) => {
onReactionInit = (message: TAnyMessage) => {
this.messagebox?.current?.closeEmojiAndAction(() => {
this.setState({ selectedMessage: message }, this.showReactionPicker);
});
@ -854,7 +855,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
this.setState({ selectedMessage: undefined }, hideActionSheet);
};
onMessageLongPress = (message: TAnyMessageModel) => {
onMessageLongPress = (message: TAnyMessage) => {
// if it's a thread message on main room, we disable the long press
if (message.tmid && !this.tmid) {
return;
@ -884,7 +885,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
};
onReactionLongPress = (message: TAnyMessageModel) => {
onReactionLongPress = (message: TAnyMessage) => {
this.setState({ selectedMessage: message });
const { showActionSheet } = this.props;
const { selectedMessage } = this.state;
@ -910,7 +911,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
};
onDiscussionPress = debounce(
async (item: TAnyMessageModel) => {
async (item: TAnyMessage) => {
const { isMasterDetail } = this.props;
if (!item.drid) return;
const sub = await getRoomInfo(item.drid);
@ -945,7 +946,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
});
};
onThreadPress = debounce((item: TAnyMessageModel) => this.navToThread(item), 1000, true);
onThreadPress = debounce((item: TAnyMessage) => this.navToThread(item), 1000, true);
shouldNavigateToRoom = (message: IMessage) => {
if (message.tmid && message.tmid === this.tmid) {
@ -1154,7 +1155,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
};
navToThread = async (item: TAnyMessageModel | { tmid: string }) => {
navToThread = async (item: TAnyMessage | { tmid: string }) => {
const { roomUserId } = this.state;
const { navigation } = this.props;
@ -1203,7 +1204,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
};
navToRoom = async (message: TAnyMessageModel) => {
navToRoom = async (message: TAnyMessage) => {
const { isMasterDetail } = this.props;
const roomInfo = await getRoomInfo(message.rid);
@ -1292,7 +1293,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
};
isIgnored = (message: TAnyMessageModel): boolean => {
isIgnored = (message: TAnyMessage): boolean => {
const { room } = this.state;
if ('id' in room) {
return room?.ignored?.includes?.(message?.u?._id) ?? false;
@ -1300,7 +1301,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
return false;
};
onLoadMoreMessages = (loaderItem: TAnyMessageModel) => {
onLoadMoreMessages = (loaderItem: TMessageModel) => {
const { room } = this.state;
return RoomServices.getMoreMessages({
rid: room.rid,
@ -1315,7 +1316,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
Navigation.navigate('CannedResponsesListView', { rid: room.rid });
};
renderItem = (item: TAnyMessageModel, previousItem: TAnyMessageModel, highlightedMessage?: string) => {
renderItem = (item: TMessage, previousItem: TMessage, highlightedMessage?: string) => {
const { room, lastOpen, canAutoTranslate } = this.state;
const { user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, Message_Read_Receipt_Enabled, theme } =
this.props;
@ -1336,7 +1337,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
if (item.t && MESSAGE_TYPE_ANY_LOAD.includes(item.t as MessageTypeLoad)) {
content = (
<LoadMore
load={() => this.onLoadMoreMessages(item)}
load={() => this.onLoadMoreMessages(item as TMessageModel)}
type={item.t}
runOnRender={item.t === MessageTypeLoad.MORE && !previousItem}
/>

View File

@ -1,4 +1,4 @@
import { SubscriptionType, TAnyMessageModel } from '../../../definitions';
import { SubscriptionType, TMessageModel } from '../../../definitions';
import { loadNextMessages, loadMessagesForRoom } from '../../../lib/methods';
import { MessageTypeLoad } from '../../../lib/constants';
@ -11,7 +11,7 @@ const getMoreMessages = ({
rid: string;
t: SubscriptionType;
tmid?: string;
loaderItem: TAnyMessageModel;
loaderItem: TMessageModel;
}): Promise<void> => {
if ([MessageTypeLoad.MORE, MessageTypeLoad.PREVIOUS_CHUNK].includes(loaderItem.t as MessageTypeLoad)) {
return loadMessagesForRoom({