From 1466a081934331c4a37718c3f706e29d1e98c61e Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 10 Apr 2022 15:44:51 -0500 Subject: [PATCH] Perform better normalization of allowedEmoji --- app/soapbox/actions/__tests__/soapbox.test.ts | 19 ++++++++ app/soapbox/actions/soapbox.js | 48 +++++++------------ app/soapbox/utils/features.ts | 2 +- 3 files changed, 37 insertions(+), 32 deletions(-) create mode 100644 app/soapbox/actions/__tests__/soapbox.test.ts diff --git a/app/soapbox/actions/__tests__/soapbox.test.ts b/app/soapbox/actions/__tests__/soapbox.test.ts new file mode 100644 index 000000000..e3dcf9a85 --- /dev/null +++ b/app/soapbox/actions/__tests__/soapbox.test.ts @@ -0,0 +1,19 @@ +import { rootState } from '../../jest/test-helpers'; +import { getSoapboxConfig } from '../soapbox'; + +const ASCII_HEART = '❤'; // '\u2764\uFE0F' +const RED_HEART_RGI = '❤️'; // '\u2764' + +describe('getSoapboxConfig()', () => { + it('returns RGI heart on Pleroma > 2.3', () => { + const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.3.0)'); + expect(getSoapboxConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(true); + expect(getSoapboxConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(false); + }); + + it('returns an ASCII heart on Pleroma < 2.3', () => { + const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.0.0)'); + expect(getSoapboxConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(true); + expect(getSoapboxConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(false); + }); +}); diff --git a/app/soapbox/actions/soapbox.js b/app/soapbox/actions/soapbox.js index bc3bdc82f..fd08d0300 100644 --- a/app/soapbox/actions/soapbox.js +++ b/app/soapbox/actions/soapbox.js @@ -1,9 +1,9 @@ -import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { createSelector } from 'reselect'; import { getHost } from 'soapbox/actions/instance'; import { normalizeSoapboxConfig } from 'soapbox/normalizers'; import KVStore from 'soapbox/storage/kv_store'; +import { removeVS16s } from 'soapbox/utils/emoji'; import { getFeatures } from 'soapbox/utils/features'; import api, { staticClient } from '../api'; @@ -15,38 +15,24 @@ export const SOAPBOX_CONFIG_REMEMBER_REQUEST = 'SOAPBOX_CONFIG_REMEMBER_REQUEST' export const SOAPBOX_CONFIG_REMEMBER_SUCCESS = 'SOAPBOX_CONFIG_REMEMBER_SUCCESS'; export const SOAPBOX_CONFIG_REMEMBER_FAIL = 'SOAPBOX_CONFIG_REMEMBER_FAIL'; -const allowedEmoji = ImmutableList([ - '👍', - '❤', - '😆', - '😮', - '😢', - '😩', -]); - -// https://git.pleroma.social/pleroma/pleroma/-/issues/2355 -const allowedEmojiRGI = ImmutableList([ - '👍', - '❤️', - '😆', - '😮', - '😢', - '😩', -]); - -export const makeDefaultConfig = features => { - return ImmutableMap({ - allowedEmoji: features.emojiReactsRGI ? allowedEmojiRGI : allowedEmoji, - displayFqn: Boolean(features.federating), - }); -}; - export const getSoapboxConfig = createSelector([ - state => state.get('soapbox'), - state => getFeatures(state.get('instance')), + state => state.soapbox, + state => getFeatures(state.instance), ], (soapbox, features) => { - const defaultConfig = makeDefaultConfig(features); - return normalizeSoapboxConfig(soapbox).merge(defaultConfig); + // Do some additional normalization with the state + return normalizeSoapboxConfig(soapbox).withMutations(soapboxConfig => { + + // If displayFqn isn't set, infer it from federation + if (soapbox.get('displayFqn') === undefined) { + soapboxConfig.set('displayFqn', features.federating); + } + + // If RGI reacts aren't supported, strip VS16s + // // https://git.pleroma.social/pleroma/pleroma/-/issues/2355 + if (!features.emojiReactsRGI) { + soapboxConfig.set('allowedEmoji', soapboxConfig.allowedEmoji.map(emoji => removeVS16s(emoji))); + } + }); }); export function rememberSoapboxConfig(host) { diff --git a/app/soapbox/utils/features.ts b/app/soapbox/utils/features.ts index 4f70f9341..93529f21e 100644 --- a/app/soapbox/utils/features.ts +++ b/app/soapbox/utils/features.ts @@ -83,7 +83,7 @@ const getInstanceFeatures = (instance: Instance) => { chats: v.software === PLEROMA && gte(v.version, '2.1.0'), chatsV2: v.software === PLEROMA && gte(v.version, '2.3.0'), scopes: v.software === PLEROMA ? 'read write follow push admin' : 'read write follow push', - federating: federation.get('enabled', true), // Assume true unless explicitly false + federating: federation.get('enabled', true) === true, // Assume true unless explicitly false richText: v.software === PLEROMA, securityAPI: any([ v.software === PLEROMA,