From 8102bef1d01f7719ce0cd1c3962e6ed09f4733dd Mon Sep 17 00:00:00 2001 From: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:23:11 -0300 Subject: [PATCH] [FIX] Quote message and reply with image (#4715) * send msg with attachment * send quote inside image * minor tweak * remove msg from return * fix the lint and prettier * fix visual bug for iOS * fixing the message box input --- app/containers/MessageBox/index.tsx | 37 +++++++++++++++++++---------- app/definitions/IMessage.ts | 10 +++++++- app/definitions/IUpload.ts | 1 + app/lib/methods/sendFileMessage.ts | 7 ++++++ app/stacks/types.ts | 3 +++ app/views/RoomView/index.tsx | 28 +++++++++++----------- app/views/ShareView/index.tsx | 36 +++++++++++++++++++++++++--- 7 files changed, 91 insertions(+), 31 deletions(-) diff --git a/app/containers/MessageBox/index.tsx b/app/containers/MessageBox/index.tsx index a7e6823db..85b070037 100644 --- a/app/containers/MessageBox/index.tsx +++ b/app/containers/MessageBox/index.tsx @@ -302,7 +302,7 @@ class MessageBox extends Component { if (usedCannedResponse !== nextProps.usedCannedResponse) { this.onChangeText(nextProps.usedCannedResponse ?? ''); } - if (sharing) { + if (sharing && !replying) { this.setInput(nextProps.message.msg ?? ''); return; } @@ -857,14 +857,21 @@ class MessageBox extends Component { }; openShareView = (attachments: any) => { - const { message, replyCancel, replyWithMention } = this.props; + const { message, replyCancel, replyWithMention, replying } = this.props; // Start a thread with an attachment let value: TThreadModel | IMessage = this.thread; if (replyWithMention) { value = message; replyCancel(); } - Navigation.navigate('ShareView', { room: this.room, thread: value, attachments }); + Navigation.navigate('ShareView', { + room: this.room, + thread: value, + attachments, + replying, + replyingMessage: message, + closeReply: replyCancel + }); }; createDiscussion = () => { @@ -1042,16 +1049,7 @@ class MessageBox extends Component { // Legacy reply or quote (quote is a reply without mention) } else { - const { user, roomType } = this.props; - const permalink = await this.getPermalink(replyingMessage); - 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} `; - } - - msg = `${msg} ${message}`; + const msg = await this.formatReplyMessage(replyingMessage, message); onSubmit(msg); } replyCancel(); @@ -1063,6 +1061,19 @@ class MessageBox extends Component { } }; + formatReplyMessage = async (replyingMessage: IMessage, message = '') => { + const { user, roomType, replyWithMention } = this.props; + const permalink = await this.getPermalink(replyingMessage); + 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} `; + } + + return `${msg} ${message}`; + }; + updateMentions = (keyword: any, type: string) => { if (type === MENTIONS_TRACKING_TYPE_USERS) { this.getUsers(keyword); diff --git a/app/definitions/IMessage.ts b/app/definitions/IMessage.ts index 810de1785..88dd7a88d 100644 --- a/app/definitions/IMessage.ts +++ b/app/definitions/IMessage.ts @@ -8,7 +8,15 @@ import { TThreadMessageModel } from './IThreadMessage'; import { TThreadModel } from './IThread'; import { IUrl, IUrlFromServer } from './IUrl'; -export type MessageType = 'jitsi_call_started' | 'discussion-created' | 'e2e' | 'load_more' | 'rm' | 'uj' | MessageTypeLoad | MessageTypesValues; +export type MessageType = + | 'jitsi_call_started' + | 'discussion-created' + | 'e2e' + | 'load_more' + | 'rm' + | 'uj' + | MessageTypeLoad + | MessageTypesValues; export interface IUserMessage { _id: string; diff --git a/app/definitions/IUpload.ts b/app/definitions/IUpload.ts index 52d3c1995..a2935575b 100644 --- a/app/definitions/IUpload.ts +++ b/app/definitions/IUpload.ts @@ -13,6 +13,7 @@ export interface IUpload { progress?: number; error?: boolean; subscription?: { id: string }; + msg?: string; } export type TUploadModel = IUpload & Model; diff --git a/app/lib/methods/sendFileMessage.ts b/app/lib/methods/sendFileMessage.ts index 08033cb60..8886f6064 100644 --- a/app/lib/methods/sendFileMessage.ts +++ b/app/lib/methods/sendFileMessage.ts @@ -100,6 +100,13 @@ export function sendFileMessage( }); } + if (fileInfo.msg) { + formData.push({ + name: 'msg', + data: fileInfo.msg + }); + } + if (tmid) { formData.push({ name: 'tmid', diff --git a/app/stacks/types.ts b/app/stacks/types.ts index cb00e8f1e..4ba63e1ec 100644 --- a/app/stacks/types.ts +++ b/app/stacks/types.ts @@ -272,6 +272,9 @@ export type InsideStackParamList = { text: string; room: TSubscriptionModel; thread: TThreadModel; + replying?: boolean; + replyingMessage?: IMessage; + closeReply?: Function; }; ModalBlockView: { data: any; // TODO: Change; diff --git a/app/views/RoomView/index.tsx b/app/views/RoomView/index.tsx index 96f556674..107491306 100644 --- a/app/views/RoomView/index.tsx +++ b/app/views/RoomView/index.tsx @@ -174,18 +174,18 @@ interface IRoomViewState { [key: string]: any; joined: boolean; room: - | TSubscriptionModel - | { - rid: string; - t: string; - name?: string; - fname?: string; - prid?: string; - joinCodeRequired?: boolean; - status?: string; - lastMessage?: ILastMessage; - sysMes?: boolean; - onHold?: boolean; + | TSubscriptionModel + | { + rid: string; + t: string; + name?: string; + fname?: string; + prid?: string; + joinCodeRequired?: boolean; + status?: string; + lastMessage?: ILastMessage; + sysMes?: boolean; + onHold?: boolean; }; roomUpdate: { [K in TRoomUpdate]?: any; @@ -1502,7 +1502,7 @@ class RoomView extends React.Component { return ( <> (this.messageActions = ref)} + ref={ref => this.messageActions = ref} tmid={this.tmid} room={room} user={user} @@ -1512,7 +1512,7 @@ class RoomView extends React.Component { onReactionPress={this.onReactionPress} isReadOnly={readOnly} /> - (this.messageErrorActions = ref)} tmid={this.tmid} /> + this.messageErrorActions = ref} tmid={this.tmid} /> ); }; diff --git a/app/views/ShareView/index.tsx b/app/views/ShareView/index.tsx index b9379d35e..8a0dffcb6 100644 --- a/app/views/ShareView/index.tsx +++ b/app/views/ShareView/index.tsx @@ -22,7 +22,15 @@ import Thumbs from './Thumbs'; import Preview from './Preview'; import Header from './Header'; import styles from './styles'; -import { IApplicationState, IServer, IShareAttachment, IUser, TSubscriptionModel, TThreadModel } from '../../definitions'; +import { + IApplicationState, + IMessage, + IServer, + IShareAttachment, + IUser, + TSubscriptionModel, + TThreadModel +} from '../../definitions'; import { sendFileMessage, sendMessage } from '../../lib/methods'; import { hasPermission, isAndroid, canUploadFile, isReadOnly, isBlocked } from '../../lib/methods/helpers'; @@ -50,11 +58,14 @@ interface IShareViewProps { server: string; FileUpload_MediaTypeWhiteList?: string; FileUpload_MaxFileSize?: number; + replying?: boolean; + replyingMessage?: IMessage; } interface IMessageBoxShareView { text: string; forceUpdate(): void; + formatReplyMessage: (replyingMessage: IMessage, message?: any) => Promise; } class ShareView extends Component { @@ -62,6 +73,9 @@ class ShareView extends Component { private files: any[]; private isShareExtension: boolean; private serverInfo: IServer; + private replying?: boolean; + private replyingMessage?: IMessage; + private closeReply?: Function; constructor(props: IShareViewProps) { super(props); @@ -69,6 +83,9 @@ class ShareView extends Component { this.files = props.route.params?.attachments ?? []; this.isShareExtension = props.route.params?.isShareExtension; this.serverInfo = props.route.params?.serverInfo ?? {}; + this.replying = props.route.params?.replying; + this.replyingMessage = props.route.params?.replyingMessage; + this.closeReply = props.route.params?.closeReply; this.state = { selected: {} as IShareAttachment, @@ -92,6 +109,12 @@ class ShareView extends Component { componentWillUnmount = () => { console.countReset(`${this.constructor.name}.render calls`); + // close reply from the RoomView + setTimeout(() => { + if (this.closeReply) { + this.closeReply(); + } + }, 300); }; setHeader = () => { @@ -214,6 +237,11 @@ class ShareView extends Component { navigation.pop(); } + let msg: string | undefined; + if (this.replying && this.replyingMessage) { + msg = await this.messagebox.current?.formatReplyMessage(this.replyingMessage); + } + try { // Send attachment if (attachments.length) { @@ -228,7 +256,8 @@ class ShareView extends Component { size, type, path, - store: 'Uploads' + store: 'Uploads', + msg }, thread?.id, server, @@ -313,11 +342,12 @@ class ShareView extends Component { roomType={room.t} theme={theme} onSubmit={this.send} - message={{ msg: selected?.description ?? '' }} + message={this.replyingMessage} navigation={navigation} isFocused={navigation.isFocused} iOSScrollBehavior={NativeModules.KeyboardTrackingViewManager?.KeyboardTrackingScrollBehaviorNone} isActionsEnabled={false} + replying={this.replying} >