diff options
Diffstat (limited to 'app/assets/javascripts/emoji/index.js')
-rw-r--r-- | app/assets/javascripts/emoji/index.js | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/app/assets/javascripts/emoji/index.js b/app/assets/javascripts/emoji/index.js index 4484bc03737..1fa81a000a5 100644 --- a/app/assets/javascripts/emoji/index.js +++ b/app/assets/javascripts/emoji/index.js @@ -1,14 +1,22 @@ +import Vue from 'vue'; import { escape, minBy } from 'lodash'; import emojiRegexFactory from 'emoji-regex'; import emojiAliases from 'emojis/aliases.json'; +import createApolloClient from '~/lib/graphql'; import { setAttributes } from '~/lib/utils/dom_utils'; import { getEmojiScoreWithIntent } from '~/emoji/utils'; import AccessorUtilities from '../lib/utils/accessor'; import axios from '../lib/utils/axios_utils'; +import customEmojiQuery from './queries/custom_emoji.query.graphql'; import { CACHE_KEY, CACHE_VERSION_KEY, CATEGORY_ICON_MAP, FREQUENTLY_USED_KEY } from './constants'; let emojiMap = null; let validEmojiNames = null; + +export const state = Vue.observable({ + loading: true, +}); + export const FALLBACK_EMOJI_KEY = 'grey_question'; // Keep the version in sync with `lib/gitlab/emoji.rb` @@ -53,9 +61,43 @@ async function loadEmojiWithNames() { }, {}); } +export async function loadCustomEmojiWithNames() { + if (document.body?.dataset?.groupFullPath && window.gon?.features?.customEmoji) { + const client = createApolloClient(); + const { data } = await client.query({ + query: customEmojiQuery, + variables: { + groupPath: document.body.dataset.groupFullPath, + }, + }); + + return data?.group?.customEmoji?.nodes?.reduce((acc, e) => { + // Map the custom emoji into the format of the normal emojis + acc[e.name] = { + c: 'custom', + d: e.name, + e: undefined, + name: e.name, + src: e.url, + u: 'custom', + }; + + return acc; + }, {}); + } + + return {}; +} + async function prepareEmojiMap() { - emojiMap = await loadEmojiWithNames(); - validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)]; + return Promise.all([loadEmojiWithNames(), loadCustomEmojiWithNames()]).then((values) => { + emojiMap = { + ...values[0], + ...values[1], + }; + validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)]; + state.loading = false; + }); } export function initEmojiMap() { @@ -84,6 +126,10 @@ export function getAllEmoji() { return emojiMap; } +export function findCustomEmoji(name) { + return emojiMap[name]; +} + function getAliasesMatchingQuery(query) { return Object.keys(emojiAliases) .filter((alias) => alias.includes(query)) @@ -176,7 +222,7 @@ export const CATEGORY_NAMES = Object.keys(CATEGORY_ICON_MAP); let emojiCategoryMap; export function getEmojiCategoryMap() { - if (!emojiCategoryMap) { + if (!emojiCategoryMap && emojiMap) { emojiCategoryMap = CATEGORY_NAMES.reduce((acc, category) => { if (category === FREQUENTLY_USED_KEY) { return acc; @@ -218,10 +264,11 @@ export function getEmojiInfo(query, fallback = true) { } export function emojiFallbackImageSrc(inputName) { - const { name } = getEmojiInfo(inputName); - return `${gon.asset_host || ''}${ - gon.relative_url_root || '' - }/-/emojis/${EMOJI_VERSION}/${name}.png`; + const { name, src } = getEmojiInfo(inputName); + return ( + src || + `${gon.asset_host || ''}${gon.relative_url_root || ''}/-/emojis/${EMOJI_VERSION}/${name}.png` + ); } export function emojiImageTag(name, src) { @@ -232,8 +279,6 @@ export function emojiImageTag(name, src) { title: `:${name}:`, alt: `:${name}:`, src, - width: '16', - height: '16', align: 'absmiddle', }); |