Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Code scanning - action / CodeQL-Build (push) Failing after 2s
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
136 lines
4.7 KiB
TypeScript
136 lines
4.7 KiB
TypeScript
import type { IEmoji } from '@rocket.chat/core-typings';
|
|
import { escapeRegExp } from '@rocket.chat/tools';
|
|
|
|
import { emoji, removeFromRecent, replaceEmojiInRecent } from './emoji';
|
|
import { getURL } from './getURL';
|
|
|
|
const isSetNotNull = (fn: () => unknown) => {
|
|
let value;
|
|
try {
|
|
value = fn();
|
|
} catch (e) {
|
|
value = null;
|
|
}
|
|
return value !== null && value !== undefined;
|
|
};
|
|
|
|
export const updateEmojiCustom = (emojiData: IEmoji) => {
|
|
const previousExists = isSetNotNull(() => emojiData.previousName);
|
|
const currentAliases = isSetNotNull(() => emojiData.aliases);
|
|
|
|
if (previousExists && isSetNotNull(() => emoji.list[`:${emojiData.previousName}:`].aliases)) {
|
|
for (const alias of emoji.list[`:${emojiData.previousName}:`].aliases ?? []) {
|
|
delete emoji.list[`:${alias}:`];
|
|
const aliasIndex = emoji.packages.emojiCustom.list?.indexOf(`:${alias}:`) ?? -1;
|
|
if (aliasIndex !== -1) {
|
|
emoji.packages.emojiCustom.list?.splice(aliasIndex, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (previousExists && emojiData.name !== emojiData.previousName) {
|
|
const arrayIndex = emoji.packages.emojiCustom.emojisByCategory.rocket.indexOf(emojiData.previousName);
|
|
if (arrayIndex !== -1) {
|
|
emoji.packages.emojiCustom.emojisByCategory.rocket.splice(arrayIndex, 1);
|
|
}
|
|
const arrayIndexList = emoji.packages.emojiCustom.list?.indexOf(`:${emojiData.previousName}:`) ?? -1;
|
|
if (arrayIndexList !== -1) {
|
|
emoji.packages.emojiCustom.list?.splice(arrayIndexList, 1);
|
|
}
|
|
delete emoji.list[`:${emojiData.previousName}:`];
|
|
}
|
|
|
|
const categoryIndex = emoji.packages.emojiCustom.emojisByCategory.rocket.indexOf(`${emojiData.name}`);
|
|
if (categoryIndex === -1) {
|
|
emoji.packages.emojiCustom.emojisByCategory.rocket.push(`${emojiData.name}`);
|
|
emoji.packages.emojiCustom.list?.push(`:${emojiData.name}:`);
|
|
}
|
|
// Don't inherit fields from a native emoji being overridden (e.g. its unicode), or the pick would output the native emoji
|
|
// TODO: Fix the IEmoji type and standardize the emoji packs types
|
|
emoji.list[`:${emojiData.name}:`] = {
|
|
...emojiData,
|
|
emojiPackage: 'emojiCustom',
|
|
} as unknown as (typeof emoji.list)[keyof typeof emoji.list];
|
|
if (currentAliases) {
|
|
for (const alias of emojiData.aliases) {
|
|
emoji.packages.emojiCustom.list?.push(`:${alias}:`);
|
|
emoji.list[`:${alias}:`] = {
|
|
emojiPackage: 'emojiCustom',
|
|
aliasOf: emojiData.name,
|
|
};
|
|
}
|
|
}
|
|
|
|
if (previousExists) {
|
|
replaceEmojiInRecent({ oldEmoji: emojiData.previousName, newEmoji: emojiData.name });
|
|
}
|
|
|
|
emoji.dispatchUpdate();
|
|
};
|
|
|
|
export const deleteEmojiCustom = (emojiData: IEmoji) => {
|
|
delete emoji.list[`:${emojiData.name}:`];
|
|
const arrayIndex = emoji.packages.emojiCustom.emojisByCategory.rocket.indexOf(emojiData.name);
|
|
if (arrayIndex !== -1) {
|
|
emoji.packages.emojiCustom.emojisByCategory.rocket.splice(arrayIndex, 1);
|
|
}
|
|
const arrayIndexList = emoji.packages.emojiCustom.list?.indexOf(`:${emojiData.name}:`) ?? -1;
|
|
if (arrayIndexList !== -1) {
|
|
emoji.packages.emojiCustom.list?.splice(arrayIndexList, 1);
|
|
}
|
|
if (emojiData.aliases) {
|
|
for (const alias of emojiData.aliases) {
|
|
delete emoji.list[`:${alias}:`];
|
|
const aliasIndex = emoji.packages.emojiCustom.list?.indexOf(`:${alias}:`) ?? -1;
|
|
if (aliasIndex !== -1) {
|
|
emoji.packages.emojiCustom.list?.splice(aliasIndex, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
removeFromRecent(emojiData.name, emoji.packages.base.emojisByCategory.recent);
|
|
emoji.dispatchUpdate();
|
|
};
|
|
|
|
const getEmojiUrlFromName = (name: string, extension: string, etag?: string) => {
|
|
if (!name) {
|
|
return;
|
|
}
|
|
|
|
return getURL(`/emoji-custom/${encodeURIComponent(name)}.${extension}${etag ? `?etag=${etag}` : ''}`);
|
|
};
|
|
|
|
export const customRender = (html: string) => {
|
|
const emojisMatchGroup = emoji.packages.emojiCustom.list?.map(escapeRegExp).join('|');
|
|
if (emojisMatchGroup !== emoji.packages.emojiCustom._regexpSignature) {
|
|
emoji.packages.emojiCustom._regexpSignature = emojisMatchGroup;
|
|
emoji.packages.emojiCustom._regexp = new RegExp(
|
|
`<object[^>]*>.*?<\/object>|<span[^>]*>.*?<\/span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(${emojisMatchGroup})`,
|
|
'gi',
|
|
);
|
|
emoji.dispatchUpdate();
|
|
}
|
|
|
|
html = html.replace(emoji.packages.emojiCustom._regexp!, (shortname) => {
|
|
if (typeof shortname === 'undefined' || shortname === '' || (emoji.packages.emojiCustom.list?.indexOf(shortname) ?? -1) === -1) {
|
|
return shortname;
|
|
}
|
|
|
|
let emojiAlias = shortname.replace(/:/g, '');
|
|
|
|
let dataCheck = emoji.list[shortname];
|
|
if (dataCheck.aliasOf) {
|
|
emojiAlias = dataCheck.aliasOf;
|
|
dataCheck = emoji.list[`:${emojiAlias}:`];
|
|
}
|
|
|
|
return `<span class="emoji emoji--custom" style="background-image:url(${getEmojiUrlFromName(
|
|
emojiAlias,
|
|
dataCheck.extension!,
|
|
dataCheck.etag,
|
|
)});" data-emoji="${emojiAlias}" title="${shortname}">${shortname}</span>`;
|
|
});
|
|
|
|
return html;
|
|
};
|