Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/ui-message/client/message.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<span class="toggle-hidden icon-right-dir" data-message="{{msg._id}}"> {{_ "Message_Ignored"}} </span>
{{/if}}
</div>
<div class="body {{bodyClass}}" dir="auto" data-unread-text="{{_ "Unread_Messages"}}">
<div id="selectable" class="body {{bodyClass}}" dir="auto" data-unread-text="{{_ "Unread_Messages"}}">
{{#if isSnippet}}
<div class="snippet-name">{{_ "Snippet_name"}}: {{snippetName}}</div>
{{/if}}
Expand Down Expand Up @@ -126,7 +126,7 @@
{{#if msg.drid}}
{{> DiscussionMetric count=msg.dcount drid=msg.drid lm=msg.dlm openDiscussion=actions.openDiscussion }}
{{/if}}

{{#if $and settings.showReplyButton msg.tcount}}
{{> ThreadMetric counter=msg.tcount following=following lm=msg.tlm rid=msg.rid mid=msg._id unread=unread mention=mention all=all openThread=actions.openThread }}
{{/if}}
Expand Down
13 changes: 13 additions & 0 deletions app/ui-message/client/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ const renderBody = (msg, settings) => {
return msg;
};

Template.message.events({
'mousedown #selectable'() {
document.getSelection().empty();
MessageAction.setSelection();
},
'mouseup #selectable'() {
const selected = document.getSelection().toString();
if (selected.length) {
MessageAction.setSelection(selected);
}
},
});

Template.message.helpers({
unread() {
const { msg, subscription } = this;
Expand Down
10 changes: 9 additions & 1 deletion app/ui-message/client/messageBox/messageBoxReplyPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ import { Template } from 'meteor/templating';
import './messageBoxReplyPreview.html';


const getMessageTextPreview = ({ msg, start, end }) => {
if (start || end) {
return `[...] ${ msg.slice(start, end) } [...]`;
}
return msg;
};

Template.messageBoxReplyPreview.helpers({
attachments() {
const { replyMessageData } = this;
return [{ text: replyMessageData.msg, author_name: replyMessageData.u.username }];
const message = getMessageTextPreview(replyMessageData);
return [{ text: message, author_name: replyMessageData.u.username }];
},
});

Expand Down
54 changes: 53 additions & 1 deletion app/ui-utils/client/lib/MessageAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ export const MessageAction = new class {

constructor() {
this.buttons = new ReactiveVar({});
this.selection = '';
}

setSelection(selection = '') {
this.selection = selection;
}

getSelection() {
return this.selection;
}

addButton(config) {
Expand Down Expand Up @@ -150,7 +159,13 @@ export const MessageAction = new class {
Meteor.startup(async function() {
const { chatMessages } = await import('../../../ui');

const flushStartEnd = (msg) => {
delete msg.start;
delete msg.end;
};

const getChatMessagesFrom = (msg) => {
flushStartEnd(msg);
const { rid = Session.get('openedRoom'), tmid = msg._id } = msg;

return chatMessages[`${ rid }-${ tmid }`] || chatMessages[rid];
Expand Down Expand Up @@ -190,6 +205,43 @@ Meteor.startup(async function() {
group: 'menu',
});

MessageAction.addButton({
id: 'quote-message-fragment',
icon: 'quote',
label: 'Quote_fragment',
context: ['message', 'message-mobile', 'threads'],
action() {
const { msg: message } = messageArgs(this);
const { input } = getChatMessagesFrom(message);
const $input = $(input);
const substring = MessageAction.getSelection();

message.start = message.msg.indexOf(substring);
message.end = message.start + substring.length;

let messages = $input.data('reply') || [];
messages = addMessageToList(messages, message);

$input
.focus()
.data('mention-user', false)
.data('reply', messages)
.trigger('dataChange');

MessageAction.setSelection();
},
condition({ msg: message, subscription }) {
const substring = MessageAction.getSelection();
if (subscription == null || !substring || message.msg.indexOf(substring) === -1) {
return false;
}

return true;
},
order: -4,
group: ['message', 'menu'],
});

MessageAction.addButton({
id: 'quote-message',
icon: 'quote',
Expand All @@ -202,7 +254,7 @@ Meteor.startup(async function() {

let messages = $input.data('reply') || [];

messages = addMessageToList(messages, message, input);
messages = addMessageToList(messages, message);

$input
.focus()
Expand Down
17 changes: 15 additions & 2 deletions app/ui-utils/client/lib/prependReplies.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@ import { Meteor } from 'meteor/meteor';
import { MessageAction } from './MessageAction';
import { Rooms, Users } from '../../../models/client';

const getStartEnd = (start, end) => {
let parameters = '';
if (start !== undefined) {
parameters += `&start=${ start }`;
}
if (end !== undefined) {
parameters += `&end=${ end }`;
}
return parameters;
};

export const prependReplies = async (msg, replies = [], mention = false) => {
const { username } = Users.findOne({ _id: Meteor.userId() }, { fields: { username: 1 } });

const chunks = await Promise.all(replies.map(async ({ _id, rid, u }) => {
const chunks = await Promise.all(replies.map(async ({ _id, rid, u, start, end }) => {
const permalink = await MessageAction.getPermaLink(_id);
const room = Rooms.findOne(rid, { fields: { t: 1 } });

let chunk = `[ ](${ permalink })`;
const query_params = getStartEnd(start, end);

let chunk = `[ ](${ permalink }${ query_params })`;
if (room.t === 'd' && u.username !== username && mention) {
chunk += ` @${ u.username }`;
}
Expand Down
5 changes: 5 additions & 0 deletions client/components/Message/Attachments/QuoteAttachment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import colors from '@rocket.chat/fuselage-tokens/colors';
import { Attachment, AttachmentPropsBase } from './Attachment';
import { useTimeAgo } from '../../../hooks/useTimeAgo';
import MarkdownText from '../../MarkdownText';
import { findSlice } from '../helpers/getUrlParamsQuote';

import Attachments from '.';

Expand All @@ -31,6 +32,10 @@ const hover = css`

export const QuoteAttachment: FC<QuoteAttachmentProps> = ({ author_icon: url, author_name: name, author_link: authorLink, message_link: messageLink, ts, text, attachments }) => {
const format = useTimeAgo();
const slice = findSlice(messageLink, text);
if (slice) {
text = `[...] ${ slice } [...]`;
}
return <>
<Attachment.Content className={hover} width='full'>
<Attachment.Details is='blockquote' borderRadius='x2' borderWidth='x2' borderStyle='solid' borderColor='neutral-200' borderInlineStartColor='neutral-600'>
Expand Down
15 changes: 15 additions & 0 deletions client/components/Message/helpers/getUrlParamsQuote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export function findSlice(messageUrl: string|undefined, string: string): string {
if (messageUrl !== undefined) {
const url = new URL(messageUrl);
const params = new URLSearchParams(url.search);

const start = params.get('start');
const end = params.get('end');

return string.slice(
start !== null ? +start : undefined,
end !== null ? +end : undefined,
);
}
return '';
}
1 change: 1 addition & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -3201,6 +3201,7 @@
"Queue_Time": "Queue Time",
"quote": "quote",
"Quote": "Quote",
"Quote_fragment": "Quote Fragment",
"Random": "Random",
"RD Station": "RD Station",
"RDStation_Token": "RD Station Token",
Expand Down
1 change: 1 addition & 0 deletions packages/rocketchat-i18n/i18n/pt-BR.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2685,6 +2685,7 @@
"Queue_Time": "Tempo na fila",
"quote": "citação",
"Quote": "Citar",
"Quote_fragment": "Citar Fragmento",
"Random": "Aleatória",
"RD Station": "RD Station",
"RDStation_Token": "RD Station Token",
Expand Down