Remove emoji, mentions and links when calculating text direction

Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
automated-signal 2022-07-11 17:32:40 -07:00 committed by GitHub
parent 908a7cc31f
commit 2d26a9e8ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 1 deletions

View File

@ -5,6 +5,8 @@ import { identity, isEqual, isNumber, isObject, map, omit, pick } from 'lodash';
import { createSelector, createSelectorCreator } from 'reselect';
import filesize from 'filesize';
import getDirection from 'direction';
import emojiRegex from 'emoji-regex';
import LinkifyIt from 'linkify-it';
import type {
LastMessageStatus,
@ -92,6 +94,7 @@ import { DAY, HOUR } from '../../util/durations';
import { getStoryReplyText } from '../../util/getStoryReplyText';
const THREE_HOURS = 3 * HOUR;
const linkify = LinkifyIt();
type FormattedContact = Partial<ConversationType> &
Pick<
@ -709,12 +712,44 @@ function getTextAttachment(
);
}
export function cleanBodyForDirectionCheck(text: string): string {
const MENTIONS_REGEX = /\uFFFC/g;
const EMOJI_REGEX = emojiRegex();
const initial = text.replace(MENTIONS_REGEX, '').replace(EMOJI_REGEX, '');
const linkMatches = linkify.match(initial);
if (!linkMatches || linkMatches.length === 0) {
return initial;
}
let result = '';
let lastIndex = 0;
linkMatches.forEach(match => {
if (lastIndex < match.index) {
result += initial.slice(lastIndex, match.index);
}
// drop the actual contents of the match
lastIndex = match.lastIndex;
});
if (lastIndex < initial.length) {
result += initial.slice(lastIndex);
}
return result;
}
function getTextDirection(body?: string): TextDirection {
if (!body) {
return TextDirection.None;
}
const direction = getDirection(body);
const cleaned = cleanBodyForDirectionCheck(body);
const direction = getDirection(cleaned);
switch (direction) {
case 'ltr':
return TextDirection.LeftToRight;

View File

@ -15,6 +15,7 @@ import {
canDeleteForEveryone,
canReact,
canReply,
cleanBodyForDirectionCheck,
getMessagePropStatus,
isEndSession,
isGroupUpdate,
@ -29,6 +30,39 @@ describe('state/selectors/messages', () => {
ourConversationId = uuid();
});
describe('cleanBodyForDirectionCheck', () => {
it('drops emoji', () => {
const body = "😮😮😮😮 that's wild!";
const expected = " that's wild!";
const actual = cleanBodyForDirectionCheck(body);
assert.strictEqual(actual, expected);
});
it('drops mentions', () => {
const body = "heyo, how's it going \uFFFC? And \uFFFC too!";
const expected = "heyo, how's it going ? And too!";
const actual = cleanBodyForDirectionCheck(body);
assert.strictEqual(actual, expected);
});
it('drops links', () => {
const body =
'You should download it from https://signal.org/download. Then read something on https://signal.org/blog. Then donate at https://signal.org/donate.';
const expected =
'You should download it from . Then read something on . Then donate at .';
const actual = cleanBodyForDirectionCheck(body);
assert.strictEqual(actual, expected);
});
it('drops all of them at the same time', () => {
const body =
'https://signal.org/download 😮 \uFFFC Did you really join Signal?';
const expected = ' Did you really join Signal?';
const actual = cleanBodyForDirectionCheck(body);
assert.strictEqual(actual, expected);
});
});
describe('canDeleteForEveryone', () => {
it('returns false for incoming messages', () => {
const message = {