From cc32979f8ac89510573916a56377772b90a4f479 Mon Sep 17 00:00:00 2001 From: Anton Alexeyev Date: Wed, 7 May 2025 11:43:40 +0700 Subject: [PATCH] Remove emoji from packages Signed-off-by: Anton Alexeyev --- models/emoji/src/models.ts | 1 - .../src/components/markup/NodeContent.svelte | 2 +- packages/text/src/nodes/emoji.ts | 12 +- .../src/components/emoji/ActionsPopup.svelte | 116 ----- .../src/components/emoji/EmojiButton.svelte | 150 ------ .../ui/src/components/emoji/EmojiGroup.svelte | 105 ----- .../components/emoji/EmojiGroupPalette.svelte | 59 --- .../ui/src/components/emoji/EmojiPopup.svelte | 428 ------------------ .../src/components/emoji/SkinTonePopup.svelte | 40 -- .../components/emoji/SkinToneTooltip.svelte | 37 -- .../components/emoji/icons/Activities.svelte | 20 - .../emoji/icons/AnimalsAndNature.svelte | 16 - .../src/components/emoji/icons/Flags.svelte | 14 - .../emoji/icons/FoodAndDrink.svelte | 20 - .../emoji/icons/FrequentlyUsed.svelte | 17 - .../emoji/icons/GettingWorkDone.svelte | 14 - .../src/components/emoji/icons/Objects.svelte | 15 - .../src/components/emoji/icons/Search.svelte | 14 - .../emoji/icons/SmileysAndPeople.svelte | 23 - .../src/components/emoji/icons/Symbols.svelte | 23 - .../emoji/icons/TravelAndPlaces.svelte | 17 - packages/ui/src/components/emoji/index.ts | 97 ---- packages/ui/src/components/emoji/store.ts | 29 -- packages/ui/src/components/emoji/types.ts | 44 -- packages/ui/src/components/emoji/utils.ts | 201 -------- .../ui/src/components/internal/Root.svelte | 5 +- packages/ui/src/index.ts | 1 - plugins/activity-resources/src/utils.ts | 3 +- .../src/components/ActionsPopup.svelte | 4 +- .../src/components/EmojiButton.svelte | 7 +- .../src/components/EmojiPopup.svelte | 59 +-- plugins/emoji-resources/src/index.ts | 2 + plugins/emoji-resources/src/store.ts | 6 +- plugins/emoji-resources/src/types.ts | 21 +- plugins/emoji-resources/src/utils.ts | 9 +- .../components/state/CreateStatePopup.svelte | 3 +- plugins/text-editor-resources/package.json | 1 + .../src/components/extension/emoji.ts | 8 +- .../src/components/IconPicker.svelte | 6 +- 39 files changed, 85 insertions(+), 1564 deletions(-) delete mode 100644 packages/ui/src/components/emoji/ActionsPopup.svelte delete mode 100644 packages/ui/src/components/emoji/EmojiButton.svelte delete mode 100644 packages/ui/src/components/emoji/EmojiGroup.svelte delete mode 100644 packages/ui/src/components/emoji/EmojiGroupPalette.svelte delete mode 100644 packages/ui/src/components/emoji/EmojiPopup.svelte delete mode 100644 packages/ui/src/components/emoji/SkinTonePopup.svelte delete mode 100644 packages/ui/src/components/emoji/SkinToneTooltip.svelte delete mode 100644 packages/ui/src/components/emoji/icons/Activities.svelte delete mode 100644 packages/ui/src/components/emoji/icons/AnimalsAndNature.svelte delete mode 100644 packages/ui/src/components/emoji/icons/Flags.svelte delete mode 100644 packages/ui/src/components/emoji/icons/FoodAndDrink.svelte delete mode 100644 packages/ui/src/components/emoji/icons/FrequentlyUsed.svelte delete mode 100644 packages/ui/src/components/emoji/icons/GettingWorkDone.svelte delete mode 100644 packages/ui/src/components/emoji/icons/Objects.svelte delete mode 100644 packages/ui/src/components/emoji/icons/Search.svelte delete mode 100644 packages/ui/src/components/emoji/icons/SmileysAndPeople.svelte delete mode 100644 packages/ui/src/components/emoji/icons/Symbols.svelte delete mode 100644 packages/ui/src/components/emoji/icons/TravelAndPlaces.svelte delete mode 100644 packages/ui/src/components/emoji/index.ts delete mode 100644 packages/ui/src/components/emoji/store.ts delete mode 100644 packages/ui/src/components/emoji/types.ts delete mode 100644 packages/ui/src/components/emoji/utils.ts diff --git a/models/emoji/src/models.ts b/models/emoji/src/models.ts index d0103d0362..0c56ed7ff6 100644 --- a/models/emoji/src/models.ts +++ b/models/emoji/src/models.ts @@ -12,4 +12,3 @@ // See the License for the specific language governing permissions and // limitations under the License. // - diff --git a/packages/presentation/src/components/markup/NodeContent.svelte b/packages/presentation/src/components/markup/NodeContent.svelte index 4cb53b3628..baf73a0f60 100644 --- a/packages/presentation/src/components/markup/NodeContent.svelte +++ b/packages/presentation/src/components/markup/NodeContent.svelte @@ -84,7 +84,7 @@ {#if node.attrs?.kind === 'custom'} {@const src = toString(attrs.url)} {@const alt = toString(attrs.emoji)} - + {:else} {node.attrs?.emoji} {/if} diff --git a/packages/text/src/nodes/emoji.ts b/packages/text/src/nodes/emoji.ts index 6a6c062aee..36d0a0a487 100644 --- a/packages/text/src/nodes/emoji.ts +++ b/packages/text/src/nodes/emoji.ts @@ -84,13 +84,11 @@ export const EmojiNode = Node.create({ ), [ 'img', - mergeAttributes( - { - 'data-type': this.name, - src: node.attrs.url, - alt: node.attrs.emoji - } - ) + mergeAttributes({ + 'data-type': this.name, + src: node.attrs.url, + alt: node.attrs.emoji + }) ] ] } diff --git a/packages/ui/src/components/emoji/ActionsPopup.svelte b/packages/ui/src/components/emoji/ActionsPopup.svelte deleted file mode 100644 index 3637df7bcb..0000000000 --- a/packages/ui/src/components/emoji/ActionsPopup.svelte +++ /dev/null @@ -1,116 +0,0 @@ - - -
- {#if haveSkins} - {#if combinedEmoji && emojiParts?.length === 2} -
- {#each new Array(2) as _, index} - { - updateSkinTone(result, index) - } - }} - /> - {#if index === 0} - { - dispatch('close', getEmojiByTone(emoji, combinedTones)) - }} - > - {getEmojiStringByTone(emoji, combinedTones)} - - {/if} - {/each} -
- {:else} -
- {#each new Array((skins?.length ?? 5) + 1) as _, skin} - dispatch('close', result.detail)} /> - {/each} -
- {/if} - {/if} - {#if remove} - {#if haveSkins}
{/if} -
- -
- {/if} -
- - diff --git a/packages/ui/src/components/emoji/EmojiButton.svelte b/packages/ui/src/components/emoji/EmojiButton.svelte deleted file mode 100644 index ba4e90b8f8..0000000000 --- a/packages/ui/src/components/emoji/EmojiButton.svelte +++ /dev/null @@ -1,150 +0,0 @@ - - -{#if emoji} - -{/if} - - diff --git a/packages/ui/src/components/emoji/EmojiGroup.svelte b/packages/ui/src/components/emoji/EmojiGroup.svelte deleted file mode 100644 index 2123a4ebef..0000000000 --- a/packages/ui/src/components/emoji/EmojiGroup.svelte +++ /dev/null @@ -1,105 +0,0 @@ - - - - -
-
-
- {#if lazy} - - - - {:else} - - {/if} -
- - diff --git a/packages/ui/src/components/emoji/EmojiGroupPalette.svelte b/packages/ui/src/components/emoji/EmojiGroupPalette.svelte deleted file mode 100644 index 0c83de9bd7..0000000000 --- a/packages/ui/src/components/emoji/EmojiGroupPalette.svelte +++ /dev/null @@ -1,59 +0,0 @@ - - - - -
- {#each emojis as emoji} - { - dispatch('touchstart', { event, emoji }) - }} - on:contextmenu={(event) => { - dispatch('contextmenu', { event, emoji }) - }} - /> - {/each} -
-
- - diff --git a/packages/ui/src/components/emoji/EmojiPopup.svelte b/packages/ui/src/components/emoji/EmojiPopup.svelte deleted file mode 100644 index b5995324cc..0000000000 --- a/packages/ui/src/components/emoji/EmojiPopup.svelte +++ /dev/null @@ -1,428 +0,0 @@ - - -
-
-
- {#each categoryTabs as category (category.id)} - - {/each} -
ec.id === currentCategory.id)) * (isMobile ? 1.875 : 2.125) - }rem`} - class="hulyPopupEmoji-header__tab-cursor" - /> -
-
-
- { - if (result.detail !== undefined) $searchEmoji = result.detail - else if (result.detail !== '') currentCategory = searchCategory[0] - }} - /> - - {getUnicodeEmojiByShortCode(':hand:', skinTone)?.emoji} - -
- - {#each outputGroups as group (group.id)} - {@const canRemove = group.id === 'frequently-used'} - { - const { event, emoji } = ev.detail - clampedContextMenu(event, emoji, canRemove) - }} - on:contextmenu={(ev) => { - const { event, emoji } = ev.detail - handleContextMenu(event, emoji, canRemove) - }} - /> - {/each} - - {#if !hidden && kind === 'fade'} - - diff --git a/packages/ui/src/components/emoji/SkinTonePopup.svelte b/packages/ui/src/components/emoji/SkinTonePopup.svelte deleted file mode 100644 index d29b077ddd..0000000000 --- a/packages/ui/src/components/emoji/SkinTonePopup.svelte +++ /dev/null @@ -1,40 +0,0 @@ - - -
-
- {#each skins as skin, index} - {@const disabled = selected === index} - {@const label = skinTones.get(index)} - - {/each} -
-
diff --git a/packages/ui/src/components/emoji/SkinToneTooltip.svelte b/packages/ui/src/components/emoji/SkinToneTooltip.svelte deleted file mode 100644 index 3f92c90f45..0000000000 --- a/packages/ui/src/components/emoji/SkinToneTooltip.svelte +++ /dev/null @@ -1,37 +0,0 @@ - - -
- {#each skins as skin, index} - {@const disabled = selected === index} - { - if (disabled) return undefined - dispatch('update', index) - closeTooltip() - }} - > - {skin.emoji} - - {/each} -
diff --git a/packages/ui/src/components/emoji/icons/Activities.svelte b/packages/ui/src/components/emoji/icons/Activities.svelte deleted file mode 100644 index 143be0e17d..0000000000 --- a/packages/ui/src/components/emoji/icons/Activities.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/packages/ui/src/components/emoji/icons/AnimalsAndNature.svelte b/packages/ui/src/components/emoji/icons/AnimalsAndNature.svelte deleted file mode 100644 index ea23a6fd63..0000000000 --- a/packages/ui/src/components/emoji/icons/AnimalsAndNature.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/packages/ui/src/components/emoji/icons/Flags.svelte b/packages/ui/src/components/emoji/icons/Flags.svelte deleted file mode 100644 index d20ae0da0e..0000000000 --- a/packages/ui/src/components/emoji/icons/Flags.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/packages/ui/src/components/emoji/icons/FoodAndDrink.svelte b/packages/ui/src/components/emoji/icons/FoodAndDrink.svelte deleted file mode 100644 index e95481f1fe..0000000000 --- a/packages/ui/src/components/emoji/icons/FoodAndDrink.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/packages/ui/src/components/emoji/icons/FrequentlyUsed.svelte b/packages/ui/src/components/emoji/icons/FrequentlyUsed.svelte deleted file mode 100644 index 1f0e024d6b..0000000000 --- a/packages/ui/src/components/emoji/icons/FrequentlyUsed.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - diff --git a/packages/ui/src/components/emoji/icons/GettingWorkDone.svelte b/packages/ui/src/components/emoji/icons/GettingWorkDone.svelte deleted file mode 100644 index 8d7e546c19..0000000000 --- a/packages/ui/src/components/emoji/icons/GettingWorkDone.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/packages/ui/src/components/emoji/icons/Objects.svelte b/packages/ui/src/components/emoji/icons/Objects.svelte deleted file mode 100644 index d8eef6e907..0000000000 --- a/packages/ui/src/components/emoji/icons/Objects.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/packages/ui/src/components/emoji/icons/Search.svelte b/packages/ui/src/components/emoji/icons/Search.svelte deleted file mode 100644 index 571a86260d..0000000000 --- a/packages/ui/src/components/emoji/icons/Search.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/packages/ui/src/components/emoji/icons/SmileysAndPeople.svelte b/packages/ui/src/components/emoji/icons/SmileysAndPeople.svelte deleted file mode 100644 index 20488a923b..0000000000 --- a/packages/ui/src/components/emoji/icons/SmileysAndPeople.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - diff --git a/packages/ui/src/components/emoji/icons/Symbols.svelte b/packages/ui/src/components/emoji/icons/Symbols.svelte deleted file mode 100644 index fa30e221df..0000000000 --- a/packages/ui/src/components/emoji/icons/Symbols.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - diff --git a/packages/ui/src/components/emoji/icons/TravelAndPlaces.svelte b/packages/ui/src/components/emoji/icons/TravelAndPlaces.svelte deleted file mode 100644 index 3fe8401ca2..0000000000 --- a/packages/ui/src/components/emoji/icons/TravelAndPlaces.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - diff --git a/packages/ui/src/components/emoji/index.ts b/packages/ui/src/components/emoji/index.ts deleted file mode 100644 index ffcbf02d60..0000000000 --- a/packages/ui/src/components/emoji/index.ts +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright © 2025 Hardcore Engineering Inc. -// -// Licensed under the Eclipse Public License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may -// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// -import type { IntlString } from '@hcengineering/platform' -import IconFrequentlyUsed from './icons/FrequentlyUsed.svelte' -import IconGettingWorkDone from './icons/GettingWorkDone.svelte' -import IconSmileysAndPeople from './icons/SmileysAndPeople.svelte' -import IconAnimalsAndNature from './icons/AnimalsAndNature.svelte' -import IconFoodAndDrink from './icons/FoodAndDrink.svelte' -import IconTravelAndPlaces from './icons/TravelAndPlaces.svelte' -import IconActivities from './icons/Activities.svelte' -import IconObjects from './icons/Objects.svelte' -import IconSymbols from './icons/Symbols.svelte' -import IconFlags from './icons/Flags.svelte' - -import plugin from '../../plugin' -import type { EmojiCategory } from './types' - -export * from './types' -export * from './store' -export * from './utils' - -export { default as EmojiPopup } from './EmojiPopup.svelte' -export { default as EmojiButton } from './EmojiButton.svelte' - -export const emojiCategories: EmojiCategory[] = [ - { id: 'frequently-used', label: plugin.string.FrequentlyUsed, icon: IconFrequentlyUsed }, - { - id: 'getting-work-done', - label: plugin.string.GettingWorkDone, - icon: IconGettingWorkDone, - emojisString: [ - '2705', - '1F440', - '1F64C', - '1F64F', - '2795', - '2796', - '1F44F', - '1F4A1', - '1F3AF', - '1F44B', - '1F44D', - '1F389', - '0031-FE0F-20E3', - '0032-FE0F-20E3', - '0033-FE0F-20E3', - '1F4E3', - '26AA', - '1F535', - '1F534', - '1F3CE' - ] - }, - { - id: 'smileys-people', - label: plugin.string.SmileysAndPeople, - icon: IconSmileysAndPeople, - categories: ['smileys-emotion', 'people-body'] - }, - { - id: 'animals-nature', - label: plugin.string.AnimalsAndNature, - icon: IconAnimalsAndNature, - categories: 'animals-nature' - }, - { id: 'food-drink', label: plugin.string.FoodAndDrink, icon: IconFoodAndDrink, categories: 'food-drink' }, - { id: 'travel-places', label: plugin.string.TravelAndPlaces, icon: IconTravelAndPlaces, categories: 'travel-places' }, - { id: 'activities', label: plugin.string.Activities, icon: IconActivities, categories: 'activities' }, - { id: 'objects', label: plugin.string.Objects, icon: IconObjects, categories: 'objects' }, - { id: 'symbols', label: plugin.string.Symbols, icon: IconSymbols, categories: 'symbols' }, - { id: 'flags', label: plugin.string.Flags, icon: IconFlags, categories: 'flags' } -] - -export const skinTonesCodes = [0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff] - -export const skinTones: Map = new Map( - [ - plugin.string.NoTone, - plugin.string.Light, - plugin.string.MediumLight, - plugin.string.Medium, - plugin.string.MediumDark, - plugin.string.Dark - ].map((label, index) => [index, label]) -) diff --git a/packages/ui/src/components/emoji/store.ts b/packages/ui/src/components/emoji/store.ts deleted file mode 100644 index 5b056fd2d4..0000000000 --- a/packages/ui/src/components/emoji/store.ts +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright © 2025 Hardcore Engineering Inc. -// -// Licensed under the Eclipse Public License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may -// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// -import { writable, derived } from 'svelte/store' -import type { EmojiWithGroup } from '.' - -export const emojiStore = writable([]) -export const searchEmoji = writable('') - -export const resultEmojis = derived([emojiStore, searchEmoji], ([emojis, search]) => { - return search !== '' - ? emojis.filter( - (emoji) => - (emoji.tags?.some((tag: string) => tag.toLowerCase().startsWith(search.toLowerCase())) ?? false) || - emoji.label.toLowerCase().includes(search.toLowerCase()) - ) - : emojis -}) diff --git a/packages/ui/src/components/emoji/types.ts b/packages/ui/src/components/emoji/types.ts deleted file mode 100644 index d390df12ae..0000000000 --- a/packages/ui/src/components/emoji/types.ts +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright © 2025 Hardcore Engineering Inc. -// -// Licensed under the Eclipse Public License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may -// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// -import type { IntlString } from '@hcengineering/platform' -import type { AnySvelteComponent } from '../..' -import type { Emoji } from 'emojibase' - -export type ExtendedEmoji = Emoji | CustomEmoji -export type EmojiWithGroup = ExtendedEmoji & { key: string } - -export interface CustomEmoji { - shortcode: string - label: string - url: string - tags?: string[] -} - -export interface EmojiCategory { - id: string - label: IntlString - icon: AnySvelteComponent - categories?: string[] | string - emojisString?: string[] - emojis?: EmojiWithGroup[] -} - -export function isCustomEmoji (emoji: ExtendedEmoji): emoji is CustomEmoji { - return 'url' in emoji -} - -/* export function isCustomEmoji (emoji: ExtendedEmoji): boolean { - return false -} */ diff --git a/packages/ui/src/components/emoji/utils.ts b/packages/ui/src/components/emoji/utils.ts deleted file mode 100644 index eb2b16f99b..0000000000 --- a/packages/ui/src/components/emoji/utils.ts +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright © 2025 Hardcore Engineering Inc. -// -// Licensed under the Eclipse Public License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may -// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// -import { get } from 'svelte/store' -import type { Emoji, Locale } from 'emojibase' -import { fetchEmojis, fetchMessages } from 'emojibase' -import EMOJI_REGEX from 'emojibase-regex' -import EMOTICON_REGEX from 'emojibase-regex/emoticon' -import SHORTCODE_REGEX from 'emojibase-regex/shortcode' -import { getCurrentAccount } from '@hcengineering/core' -import { deviceOptionsStore as deviceInfo, type ExtendedEmoji, isCustomEmoji } from '../..' -import type { EmojiWithGroup } from '.' -import { emojiCategories, emojiStore } from '.' - -export const emojiRegex = EMOJI_REGEX -export const emojiGlobalRegex = new RegExp(EMOJI_REGEX.source, EMOJI_REGEX.flags + 'g') - -export const emoticonRegex = new RegExp(`(?:^|\\s)(${EMOTICON_REGEX.source})$`) -export const emoticonGlobalRegex = new RegExp(`(? { - const local = lang ?? get(deviceInfo).language ?? 'en' - const englishEmojis = - local === 'en' - ? await fetchEmojis('en', { version: '15.0', shortcodes: ['iamcal'] }) - : await fetchEmojis('en', { compact: true, version: '15.0', shortcodes: ['iamcal'] }) - const languageEmojis = local === 'en' ? null : await fetchEmojis(local as Locale, { version: '15.0' }) - const messages = await fetchMessages(local as Locale) - const groups = messages.groups - const groupKeys = new Map(groups.map((group, index) => [index, group.key])) - - const categories = new Map() - emojiCategories.forEach((cat) => { - if (Array.isArray(cat.categories)) cat.categories.forEach((c) => categories.set(c, cat.id)) - else if (typeof cat.categories === 'string') categories.set(cat.categories, cat.id) - }) - - const emojis = - languageEmojis !== null - ? languageEmojis.map((langEmoji, index) => { - return { - ...langEmoji, - tags: [...(englishEmojis[index]?.tags ?? []), ...(langEmoji?.tags ?? [])], - shortcodes: [...(englishEmojis[index]?.shortcodes ?? []), ...(langEmoji?.shortcodes ?? [])] - } - }) - : (englishEmojis as Emoji[]) - - return emojis - .filter((e) => e.group !== 2 && e.group !== undefined) - .map((e) => { - return { ...e, key: categories.get(groupKeys.get(e?.group ?? 0) ?? '') ?? '' } - }) -} - -export async function updateEmojis (lang?: string): Promise { - const emojis = await loadEmojis(lang) - emojis.push({ - shortcode: 'huly', - label: 'huly', - url: 'https://fonts.gstatic.com/s/e/notoemoji/latest/1f979/512.gif', - tags: ['huly'], - key: 'flags' - }) - emojiStore.set(emojis) -} - -export function getEmojiByHexcode (hexcode: string): EmojiWithGroup | undefined { - return get(emojiStore).find((e) => !isCustomEmoji(e) && e.hexcode === hexcode) -} - -export function getEmojiByEmoticon (emoticon: string | undefined): string | undefined { - if (emoticon === undefined) return undefined - const matchEmoji = findEmoji(e => !isCustomEmoji(e) && (Array.isArray(e.emoticon) ? e.emoticon.includes(emoticon) : e.emoticon === emoticon)) - if (matchEmoji === undefined) return undefined - return !isCustomEmoji(matchEmoji) ? matchEmoji.emoji : undefined -} - -export function getUnicodeEmojiByShortCode (shortcode: string | undefined, skinTone?: number): Emoji | undefined { - const emoji = getEmojiByShortCode(shortcode, skinTone) - if (emoji === undefined || isCustomEmoji(emoji)) return undefined - return emoji -} - -export function getEmojiByShortCode (shortcode: string | undefined, skinTone?: number): ExtendedEmoji | undefined { - if (shortcode === undefined) return undefined - const pureShortcode = shortcode.replaceAll(':', '') - return findEmoji((e) => { - if (isCustomEmoji(e)) return e.shortcode === pureShortcode - return e.shortcodes?.includes(pureShortcode) - }, skinTone) -} - -function findEmoji (predicate: (e: EmojiWithGroup) => boolean | undefined, skinTone?: number): ExtendedEmoji | undefined { - const emojis = get(emojiStore) - const matchEmoji = emojis.find(predicate) - if (matchEmoji === undefined) return undefined - if (isCustomEmoji(matchEmoji)) return matchEmoji - if (skinTone === undefined) skinTone = getSkinTone() - if (skinTone === 0 || matchEmoji.skins === undefined) return matchEmoji - return matchEmoji.skins[skinTone - 1] -} - -export const removeFrequentlyEmojis = (emoji: EmojiWithGroup): void => { - const hexcode = isCustomEmoji(emoji) ? emoji.shortcode : emoji.hexcode - if (hexcode === undefined) return - - const frequentlyEmojisKey = getEmojisLocalStorageKey() - const frequentlyEmojis = window.localStorage.getItem(frequentlyEmojisKey) - if (frequentlyEmojis != null) { - const parsedEmojis = JSON.parse(frequentlyEmojis) - if (Array.isArray(parsedEmojis)) { - window.localStorage.setItem( - frequentlyEmojisKey, - JSON.stringify(parsedEmojis.filter((pe) => pe.hexcode !== hexcode)) - ) - } - } -} -export const addFrequentlyEmojis = (emoji: EmojiWithGroup): void => { - if (emoji === undefined) return - const hexcode = isCustomEmoji(emoji) ? emoji.shortcode : emoji.hexcode - - const frequentlyEmojisKey = getEmojisLocalStorageKey() - const frequentlyEmojis = window.localStorage.getItem(frequentlyEmojisKey) - const empty = frequentlyEmojis == null - - if (!empty) { - const parsedEmojis = JSON.parse(frequentlyEmojis) - if (Array.isArray(parsedEmojis)) { - const index = parsedEmojis.findIndex((pe) => pe.hexcode === hexcode) - if (index === -1) parsedEmojis.push({ hexcode, count: 1 }) - else parsedEmojis[index].count++ - parsedEmojis.sort((a, b) => b.count - a.count) - window.localStorage.setItem(frequentlyEmojisKey, JSON.stringify(parsedEmojis)) - return undefined - } - } - window.localStorage.setItem(frequentlyEmojisKey, JSON.stringify([{ hexcode, count: 1 }])) -} -export const getFrequentlyEmojis = (): EmojiWithGroup[] | undefined => { - const frequentlyEmojisKey = getEmojisLocalStorageKey() - const frequentlyEmojis = window.localStorage.getItem(frequentlyEmojisKey) - if (frequentlyEmojis == null) return undefined - - try { - const parsedEmojis = JSON.parse(frequentlyEmojis) - if (!Array.isArray(parsedEmojis)) return undefined - const emojis = get(emojiStore) - return emojis.filter((e) => { - if (isCustomEmoji(e)) { - return parsedEmojis.find(pe => pe.hexcode === e.shortcode) !== undefined - } - return parsedEmojis.find(pe => pe.hexcode === e.hexcode || e.skins?.find(s => s.hexcode === pe.hexcode) !== undefined) !== undefined - }) - } catch (e) { - console.error(e) - return undefined - } -} - -export function getEmojiSkins (emoji: ExtendedEmoji): Emoji[] | undefined { - if (isCustomEmoji(emoji)) return undefined - return emoji.skins -} - -export const setSkinTone = (skinTone: number): void => { - const skinToneKey = getEmojisLocalStorageKey('skinTone') - window.localStorage.setItem(skinToneKey, JSON.stringify(skinTone)) -} -export const getSkinTone = (): number => { - const skinToneKey = getEmojisLocalStorageKey('skinTone') - const skinTone = window.localStorage.getItem(skinToneKey) - if (skinTone == null) return 0 - - try { - return JSON.parse(skinTone) - } catch (e) { - console.error(e) - return 0 - } -} - -function getEmojisLocalStorageKey (suffix: string = 'frequently'): string { - const me = getCurrentAccount() - return `emojis.${suffix}.${me.uuid}` -} diff --git a/packages/ui/src/components/internal/Root.svelte b/packages/ui/src/components/internal/Root.svelte index a97d2470fa..d0c21117ae 100644 --- a/packages/ui/src/components/internal/Root.svelte +++ b/packages/ui/src/components/internal/Root.svelte @@ -11,8 +11,7 @@ checkMobile, deviceOptionsStore as deviceInfo, checkAdaptiveMatching, - getLocalWeekStart, - updateEmojis + getLocalWeekStart } from '../../' import { desktopPlatform, getCurrentLocation, location, locationStorageKeyId, navigate } from '../../location' import uiPlugin from '../../plugin' @@ -93,8 +92,6 @@ $: document.documentElement.style.setProperty('--app-height', `${docHeight}px`) - $: void updateEmojis($themeStore.language) - let doubleTouchStartTimestamp = 0 document.addEventListener('touchstart', (event) => { const now = +new Date() diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 01d7ea0ea1..e946cc7be4 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -302,7 +302,6 @@ export * from './colors' export * from './focus' export * from './resize' export * from './lazy' -export * from './components/emoji' export function createApp (target: HTMLElement): SvelteComponent { return new Root({ target }) diff --git a/plugins/activity-resources/src/utils.ts b/plugins/activity-resources/src/utils.ts index 53d480128e..333cc8ba77 100644 --- a/plugins/activity-resources/src/utils.ts +++ b/plugins/activity-resources/src/utils.ts @@ -6,8 +6,7 @@ import { getCurrentResolvedLocation, getEventPositionElement, showPopup, - type Location, - type EmojiWithGroup, isCustomEmoji + type Location } from '@hcengineering/ui' import { type AttributeModel } from '@hcengineering/view' import emojiPlugin from '@hcengineering/emoji' diff --git a/plugins/emoji-resources/src/components/ActionsPopup.svelte b/plugins/emoji-resources/src/components/ActionsPopup.svelte index 98598202d8..53ad99d191 100644 --- a/plugins/emoji-resources/src/components/ActionsPopup.svelte +++ b/plugins/emoji-resources/src/components/ActionsPopup.svelte @@ -5,7 +5,7 @@ // import { createEventDispatcher } from 'svelte' import emojiPlugin, { ExtendedEmoji, Emoji } from '@hcengineering/emoji' - import { getEmojiByHexcode, getEmojiSkins } from '../utils' + import { getEmojiByHexcode, getEmojiSkins } from '../utils' import EmojiButton from './EmojiButton.svelte' import { getSkinTone, emojiStore } from '../store' import { Label, IconDelete, closeTooltip, ButtonBase } from '@hcengineering/ui' @@ -50,7 +50,7 @@ const equal = a === b const noTone = a === 0 return equal && noTone - ? e as Emoji.Emoji + ? (e as Emoji.Emoji) : getEmojiSkins(e)?.find((skin) => equal ? skin.tone === a : Array.isArray(skin.tone) && skin.tone[0] === a && skin.tone[1] === b ) diff --git a/plugins/emoji-resources/src/components/EmojiButton.svelte b/plugins/emoji-resources/src/components/EmojiButton.svelte index 578886a043..4a4af0a1ef 100644 --- a/plugins/emoji-resources/src/components/EmojiButton.svelte +++ b/plugins/emoji-resources/src/components/EmojiButton.svelte @@ -5,8 +5,9 @@ // import { createEventDispatcher } from 'svelte' import { getEmbeddedLabel } from '@hcengineering/platform' - import { tooltip, capitalizeFirstLetter, type LabelAndProps, type ExtendedEmoji, getEmojiSkins } from '@hcengineering/ui' - import { isCustomEmoji } from '@hcengineering/emoji' + import { tooltip, capitalizeFirstLetter, type LabelAndProps } from '@hcengineering/ui' + import { isCustomEmoji, type ExtendedEmoji } from '@hcengineering/emoji' + import { getEmojiSkins } from '../utils' export let emoji: ExtendedEmoji export let selected: boolean = false @@ -42,7 +43,7 @@ }} > {#if isCustomEmoji(displayedEmoji)} - {displayedEmoji.shortcode} + {displayedEmoji.shortcode} {:else} {displayedEmoji.emoji} {/if} diff --git a/plugins/emoji-resources/src/components/EmojiPopup.svelte b/plugins/emoji-resources/src/components/EmojiPopup.svelte index 9c3ab690fd..db110c18c5 100644 --- a/plugins/emoji-resources/src/components/EmojiPopup.svelte +++ b/plugins/emoji-resources/src/components/EmojiPopup.svelte @@ -12,8 +12,10 @@ showPopup, eventToHTMLElement, ButtonBase, - closeTooltip, getEmojiByShortCode, getEmojiSkins, getUnicodeEmojiByShortCode, Icon, icon + closeTooltip, + Icon } from '@hcengineering/ui' + import { getEmojiByShortCode, getEmojiSkins, getUnicodeEmojiByShortCode } from '../utils' import { searchEmoji, emojiStore, @@ -29,7 +31,6 @@ import EmojiGroup from './EmojiGroup.svelte' import emojiPlugin, { isCustomEmoji } from '@hcengineering/emoji' import { emojiCategories, EmojiCategory } from '../types' - import { Asset, getMetadata } from '@hcengineering/platform' export let embedded = false export let selected: string | undefined @@ -119,27 +120,22 @@ clearTimer() shownContext = true - showPopup( - ActionsPopup, - { emoji, remove }, - eventToHTMLElement(event), - (result: 'remove' | EmojiWithGroup) => { - if (result === 'remove') { - removeFrequentlyEmojis(emoji) - const index = emojisCat.findIndex((ec) => ec.id === 'frequently-used') - if (index > -1) emojisCat[index].emojis = getFrequentlyEmojis() - emojisCat = emojisCat.filter( - (em) => em.categories !== undefined || (Array.isArray(em.emojis) && em.emojis.length > 0) - ) - if (currentCategory.emojis?.length === 0) { - currentCategory = emojisCat.find((ec) => ec.emojis !== undefined && ec.emojis.length > 0) ?? emojisCat[0] - } - } else if (result !== undefined) { - sendEmoji(result) + showPopup(ActionsPopup, { emoji, remove }, eventToHTMLElement(event), (result: 'remove' | EmojiWithGroup) => { + if (result === 'remove') { + removeFrequentlyEmojis(emoji) + const index = emojisCat.findIndex((ec) => ec.id === 'frequently-used') + if (index > -1) emojisCat[index].emojis = getFrequentlyEmojis() + emojisCat = emojisCat.filter( + (em) => em.categories !== undefined || (Array.isArray(em.emojis) && em.emojis.length > 0) + ) + if (currentCategory.emojis?.length === 0) { + currentCategory = emojisCat.find((ec) => ec.emojis !== undefined && ec.emojis.length > 0) ?? emojisCat[0] } - shownContext = false + } else if (result !== undefined) { + sendEmoji(result) } - ) + shownContext = false + }) } function handleContextMenu (event: MouseEvent, emoji: EmojiWithGroup, remove: boolean): void { event.preventDefault() @@ -169,13 +165,18 @@ const showSkinMenu = (event: MouseEvent): void => { shownSTM = true - showPopup(SkinTonePopup, { emoji: getEmojiByShortCode(':hand:', 0), selected: skinTone }, eventToHTMLElement(event), (result) => { - if (typeof result === 'number') { - skinTone = result - setSkinTone(skinTone) + showPopup( + SkinTonePopup, + { emoji: getEmojiByShortCode(':hand:', 0), selected: skinTone }, + eventToHTMLElement(event), + (result) => { + if (typeof result === 'number') { + skinTone = result + setSkinTone(skinTone) + } + shownSTM = false } - shownSTM = false - }) + ) } let hidden: boolean = true @@ -195,7 +196,7 @@ const tempEmojis: string[] = em.emojisString const emojis: EmojiWithGroup[] = [] tempEmojis.forEach((te) => { - const e = $emojiStore.find((es) => isCustomEmoji(es) ? es.shortcode === te : es.hexcode === te) + const e = $emojiStore.find((es) => (isCustomEmoji(es) ? es.shortcode === te : es.hexcode === te)) if (e !== undefined) emojis.push(e) }) emojiCategories[index].emojis = emojis @@ -236,7 +237,7 @@ handleScrollToCategory(category.id) }} > - + {/each} diff --git a/plugins/emoji-resources/src/index.ts b/plugins/emoji-resources/src/index.ts index 4ae250fdc5..becb07ff1f 100644 --- a/plugins/emoji-resources/src/index.ts +++ b/plugins/emoji-resources/src/index.ts @@ -2,6 +2,8 @@ import type { Resources } from '@hcengineering/platform' import EmojiPopup from './components/EmojiPopup.svelte' import WorkbenchExtension from './components/WorkbenchExtension.svelte' +export * from './utils' + export default async (): Promise => ({ component: { EmojiPopup, diff --git a/plugins/emoji-resources/src/store.ts b/plugins/emoji-resources/src/store.ts index 7c21eef316..302f1568c7 100644 --- a/plugins/emoji-resources/src/store.ts +++ b/plugins/emoji-resources/src/store.ts @@ -10,7 +10,7 @@ export const resultEmojis = derived([emojiStore, searchEmoji], ([emojis, search] ? emojis.filter( (emoji) => (emoji.tags?.some((tag: string) => tag.toLowerCase().startsWith(search.toLowerCase())) ?? false) || - emoji.label.toLowerCase().includes(search.toLowerCase()) + emoji.label.toLowerCase().includes(search.toLowerCase()) ) : emojis }) @@ -81,14 +81,14 @@ export const getFrequentlyEmojis = (): EmojiWithGroup[] | undefined => { const result: EmojiWithGroup[] = [] emojis.forEach((emoji: EmojiWithGroup) => { if (isCustomEmoji(emoji)) { - if (parsedEmojis.find(pe => pe.hexcode === emoji.shortcode) !== undefined) result.push(emoji) + if (parsedEmojis.find((pe) => pe.hexcode === emoji.shortcode) !== undefined) result.push(emoji) } else { parsedEmojis.forEach((parsedEmoji: any) => { if (parsedEmoji.hexcode === emoji.hexcode) { result.push(emoji) return } - const skinEmoji = emoji.skins?.find(s => s.hexcode === parsedEmoji.hexcode) + const skinEmoji = emoji.skins?.find((s) => s.hexcode === parsedEmoji.hexcode) if (skinEmoji === undefined) return result.push({ ...skinEmoji, key: '' }) }) diff --git a/plugins/emoji-resources/src/types.ts b/plugins/emoji-resources/src/types.ts index 1db5abd7eb..5ce4143a9e 100644 --- a/plugins/emoji-resources/src/types.ts +++ b/plugins/emoji-resources/src/types.ts @@ -52,9 +52,24 @@ export const emojiCategories: EmojiCategory[] = [ icon: emojiPlugin.icon.AnimalsAndNature, categories: 'animals-nature' }, - { id: 'food-drink', label: emojiPlugin.string.FoodAndDrink, icon: emojiPlugin.icon.FoodAndDrink, categories: 'food-drink' }, - { id: 'travel-places', label: emojiPlugin.string.TravelAndPlaces, icon: emojiPlugin.icon.TravelAndPlaces, categories: 'travel-places' }, - { id: 'activities', label: emojiPlugin.string.Activities, icon: emojiPlugin.icon.Activities, categories: 'activities' }, + { + id: 'food-drink', + label: emojiPlugin.string.FoodAndDrink, + icon: emojiPlugin.icon.FoodAndDrink, + categories: 'food-drink' + }, + { + id: 'travel-places', + label: emojiPlugin.string.TravelAndPlaces, + icon: emojiPlugin.icon.TravelAndPlaces, + categories: 'travel-places' + }, + { + id: 'activities', + label: emojiPlugin.string.Activities, + icon: emojiPlugin.icon.Activities, + categories: 'activities' + }, { id: 'objects', label: emojiPlugin.string.Objects, icon: emojiPlugin.icon.Objects, categories: 'objects' }, { id: 'symbols', label: emojiPlugin.string.Symbols, icon: emojiPlugin.icon.Symbols, categories: 'symbols' }, { id: 'flags', label: emojiPlugin.string.Flags, icon: emojiPlugin.icon.Flags, categories: 'flags' } diff --git a/plugins/emoji-resources/src/utils.ts b/plugins/emoji-resources/src/utils.ts index 2530ddec6a..6278bda2ca 100644 --- a/plugins/emoji-resources/src/utils.ts +++ b/plugins/emoji-resources/src/utils.ts @@ -51,7 +51,9 @@ export function getEmojiByHexcode (hexcode: string): EmojiWithGroup | undefined export function getEmojiByEmoticon (emoticon: string | undefined): string | undefined { if (emoticon === undefined) return undefined - const matchEmoji = findEmoji(e => !isCustomEmoji(e) && (Array.isArray(e.emoticon) ? e.emoticon.includes(emoticon) : e.emoticon === emoticon)) + const matchEmoji = findEmoji( + (e) => !isCustomEmoji(e) && (Array.isArray(e.emoticon) ? e.emoticon.includes(emoticon) : e.emoticon === emoticon) + ) if (matchEmoji === undefined) return undefined return !isCustomEmoji(matchEmoji) ? matchEmoji.emoji : undefined } @@ -71,7 +73,10 @@ export function getEmojiByShortCode (shortcode: string | undefined, skinTone?: n }, skinTone) } -function findEmoji (predicate: (e: EmojiWithGroup) => boolean | undefined, skinTone?: number): ExtendedEmoji | undefined { +function findEmoji ( + predicate: (e: EmojiWithGroup) => boolean | undefined, + skinTone?: number +): ExtendedEmoji | undefined { const emojis = get(emojiStore) const matchEmoji = emojis.find(predicate) if (matchEmoji === undefined) return undefined diff --git a/plugins/task-resources/src/components/state/CreateStatePopup.svelte b/plugins/task-resources/src/components/state/CreateStatePopup.svelte index 0a13b0f0c0..b6535b11e8 100644 --- a/plugins/task-resources/src/components/state/CreateStatePopup.svelte +++ b/plugins/task-resources/src/components/state/CreateStatePopup.svelte @@ -433,7 +433,8 @@ }} /> {:else} - {:else} -