diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-27 09:08:04 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-27 09:08:04 +0300 |
commit | 5849e597a070c4d5d37657569919150701ca70bd (patch) | |
tree | c70900a50dc2fd5570d72f09444c98dad11e78f6 /app/assets/javascripts/emoji | |
parent | f33d28f789f690bfc01c8b81d95259a9f1c68b79 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/emoji')
-rw-r--r-- | app/assets/javascripts/emoji/components/category.vue | 5 | ||||
-rw-r--r-- | app/assets/javascripts/emoji/components/picker.vue | 12 | ||||
-rw-r--r-- | app/assets/javascripts/emoji/components/utils.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/emoji/constants.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/emoji/index.js | 55 | ||||
-rw-r--r-- | app/assets/javascripts/emoji/queries/custom_emoji.query.graphql | 12 |
6 files changed, 74 insertions, 13 deletions
diff --git a/app/assets/javascripts/emoji/components/category.vue b/app/assets/javascripts/emoji/components/category.vue index 39881979c4f..a72e7df7769 100644 --- a/app/assets/javascripts/emoji/components/category.vue +++ b/app/assets/javascripts/emoji/components/category.vue @@ -33,6 +33,9 @@ export default { this.renderGroup = true; this.$emit('appear', this.category); }, + onClick(emoji) { + this.$emit('click', { category: this.category, emoji }); + }, }, }; </script> @@ -48,7 +51,7 @@ export default { :key="index" :emojis="emojiGroup" :render-group="renderGroup" - :click-emoji="(emoji) => $emit('click', emoji)" + :click-emoji="(emoji) => onClick(emoji)" /> </template> <p v-else> diff --git a/app/assets/javascripts/emoji/components/picker.vue b/app/assets/javascripts/emoji/components/picker.vue index 840297b870a..23f52b61bd0 100644 --- a/app/assets/javascripts/emoji/components/picker.vue +++ b/app/assets/javascripts/emoji/components/picker.vue @@ -2,7 +2,7 @@ import { GlIcon, GlDropdown, GlSearchBoxByType } from '@gitlab/ui'; import { findLastIndex } from 'lodash'; import VirtualList from 'vue-virtual-scroll-list'; -import { CATEGORY_NAMES } from '~/emoji'; +import { CATEGORY_NAMES, getEmojiCategoryMap } from '~/emoji'; import { CATEGORY_ICON_MAP, FREQUENTLY_USED_KEY } from '../constants'; import Category from './category.vue'; import EmojiList from './emoji_list.vue'; @@ -49,6 +49,7 @@ export default { categoryNames() { return CATEGORY_NAMES.filter((c) => { if (c === FREQUENTLY_USED_KEY) return hasFrequentlyUsedEmojis(); + if (c === 'custom') return getEmojiCategoryMap()?.custom.length > 0; return true; }).map((category) => ({ name: category, @@ -66,10 +67,13 @@ export default { this.$refs.virtualScoller.setScrollTop(top); }, - selectEmoji(name) { - this.$emit('click', name); + selectEmoji({ category, emoji }) { + this.$emit('click', emoji); this.$refs.dropdown.hide(); - addToFrequentlyUsed(name); + + if (category !== 'custom') { + addToFrequentlyUsed(emoji); + } }, getBoundaryElement() { return this.boundary || document.querySelector('.content-wrapper') || 'scrollParent'; diff --git a/app/assets/javascripts/emoji/components/utils.js b/app/assets/javascripts/emoji/components/utils.js index 5eec0992896..2c1c968878b 100644 --- a/app/assets/javascripts/emoji/components/utils.js +++ b/app/assets/javascripts/emoji/components/utils.js @@ -52,7 +52,7 @@ export const getEmojiCategories = memoize(async () => { return Object.freeze( Object.keys(categories) - .filter((c) => c !== FREQUENTLY_USED_KEY) + .filter((c) => c !== FREQUENTLY_USED_KEY && categories[c].length) .reduce((acc, category) => { const emojis = chunk(categories[category], EMOJIS_PER_ROW); const height = generateCategoryHeight(emojis.length); diff --git a/app/assets/javascripts/emoji/constants.js b/app/assets/javascripts/emoji/constants.js index 7970a932095..215ecbfe605 100644 --- a/app/assets/javascripts/emoji/constants.js +++ b/app/assets/javascripts/emoji/constants.js @@ -3,6 +3,7 @@ export const FREQUENTLY_USED_COOKIE_KEY = 'frequently_used_emojis'; export const CATEGORY_ICON_MAP = { [FREQUENTLY_USED_KEY]: 'history', + custom: 'tanuki', activity: 'dumbbell', people: 'smiley', nature: 'nature', diff --git a/app/assets/javascripts/emoji/index.js b/app/assets/javascripts/emoji/index.js index 4484bc03737..f781f1f83f8 100644 --- a/app/assets/javascripts/emoji/index.js +++ b/app/assets/javascripts/emoji/index.js @@ -1,14 +1,17 @@ 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 FALLBACK_EMOJI_KEY = 'grey_question'; // Keep the version in sync with `lib/gitlab/emoji.rb` @@ -53,9 +56,42 @@ async function loadEmojiWithNames() { }, {}); } +export async function loadCustomEmojiWithNames() { + if (document.body?.dataset?.group && window.gon?.features?.customEmoji) { + const client = createApolloClient(); + const { data } = await client.query({ + query: customEmojiQuery, + variables: { + groupPath: document.body.dataset.group, + }, + }); + + 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)]; + }); } export function initEmojiMap() { @@ -84,6 +120,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 +216,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 +258,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) { diff --git a/app/assets/javascripts/emoji/queries/custom_emoji.query.graphql b/app/assets/javascripts/emoji/queries/custom_emoji.query.graphql new file mode 100644 index 00000000000..951027ec274 --- /dev/null +++ b/app/assets/javascripts/emoji/queries/custom_emoji.query.graphql @@ -0,0 +1,12 @@ +query getCustomEmoji($groupPath: ID!) { + group(fullPath: $groupPath) { + id + customEmoji { + nodes { + id + name + url + } + } + } +} |