aboutsummaryrefslogtreecommitdiff
path: root/src/modules/instance.js
diff options
context:
space:
mode:
authorHenry Jameson <me@hjkos.com>2022-10-09 18:51:42 +0300
committerHenry Jameson <me@hjkos.com>2022-10-09 18:51:42 +0300
commit5fa533fbb7b3d507c0136044fd51db033c25db05 (patch)
treefd7d50093d2bc44884cf76244d3becc2b3413c0e /src/modules/instance.js
parent0331e42ee8576893dab2c6319ee5c0d62895b8d8 (diff)
parentc807254d3eadbd57de292360c5200358261cbc0f (diff)
Merge remote-tracking branch 'origin/develop' into scrolltotop
* origin/develop: (89 commits) Update dependency @vuelidate/validators to v2.0.0 Remove lolex package Remove diff package Pin dependencies Update dependency sass to v1.55.0 Make suggestor suggest according to cldr annotations Make chunks named Use import() for emoji.json Add regional indicators Support filtering by keywords from cldr Display localized unicode emoji names Load unicode emoji annotations Extract language list to its own file using the half-shit approach since proper approach is full-shit Make unicode emoji phrases match with _ Use console.info Fix non-square emojis being truncated Fix emoji picker lint Fix emoji picker lint Tweak efficiency when changing filter keywords in emoji picker ...
Diffstat (limited to 'src/modules/instance.js')
-rw-r--r--src/modules/instance.js149
1 files changed, 133 insertions, 16 deletions
diff --git a/src/modules/instance.js b/src/modules/instance.js
index bfce6f38..b1bc9779 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -2,6 +2,39 @@ import { getPreset, applyTheme } from '../services/style_setter/style_setter.js'
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
import apiService from '../services/api/api.service.js'
import { instanceDefaultProperties } from './config.js'
+import { langCodeToCldrName, ensureFinalFallback } from '../i18n/languages.js'
+
+const SORTED_EMOJI_GROUP_IDS = [
+ 'smileys-and-emotion',
+ 'people-and-body',
+ 'animals-and-nature',
+ 'food-and-drink',
+ 'travel-and-places',
+ 'activities',
+ 'objects',
+ 'symbols',
+ 'flags'
+]
+
+const REGIONAL_INDICATORS = (() => {
+ const start = 0x1F1E6
+ const end = 0x1F1FF
+ const A = 'A'.codePointAt(0)
+ const res = new Array(end - start + 1)
+ for (let i = start; i <= end; ++i) {
+ const letter = String.fromCodePoint(A + i - start)
+ res[i - start] = {
+ replacement: String.fromCodePoint(i),
+ imageUrl: false,
+ displayText: 'regional_indicator_' + letter,
+ displayTextI18n: {
+ key: 'emoji.regional_indicator',
+ args: { letter }
+ }
+ }
+ }
+ return res
+})()
const defaultState = {
// Stuff from apiConfig
@@ -64,8 +97,9 @@ const defaultState = {
// Nasty stuff
customEmoji: [],
customEmojiFetched: false,
- emoji: [],
+ emoji: {},
emojiFetched: false,
+ unicodeEmojiAnnotations: {},
pleromaBackend: true,
postFormats: [],
restrictedNicknames: [],
@@ -97,6 +131,31 @@ const defaultState = {
}
}
+const loadAnnotations = (lang) => {
+ return import(
+ /* webpackChunkName: "emoji-annotations/[request]" */
+ `@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json`
+ )
+ .then(k => k.default)
+}
+
+const injectAnnotations = (emoji, annotations) => {
+ const availableLangs = Object.keys(annotations)
+
+ return {
+ ...emoji,
+ annotations: availableLangs.reduce((acc, cur) => {
+ acc[cur] = annotations[cur][emoji.replacement]
+ return acc
+ }, {})
+ }
+}
+
+const injectRegionalIndicators = groups => {
+ groups.symbols.push(...REGIONAL_INDICATORS)
+ return groups
+}
+
const instance = {
state: defaultState,
mutations: {
@@ -107,6 +166,9 @@ const instance = {
},
setKnownDomains (state, domains) {
state.knownDomains = domains
+ },
+ setUnicodeEmojiAnnotations (state, { lang, annotations }) {
+ state.unicodeEmojiAnnotations[lang] = annotations
}
},
getters: {
@@ -115,6 +177,41 @@ const instance = {
.map(key => [key, state[key]])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
},
+ groupedCustomEmojis (state) {
+ const packsOf = emoji => {
+ return emoji.tags
+ .filter(k => k.startsWith('pack:'))
+ .map(k => k.slice(5)) // remove 'pack:' prefix
+ }
+
+ return state.customEmoji
+ .reduce((res, emoji) => {
+ packsOf(emoji).forEach(packName => {
+ const packId = `custom-${packName}`
+ if (!res[packId]) {
+ res[packId] = ({
+ id: packId,
+ text: packName,
+ image: emoji.imageUrl,
+ emojis: []
+ })
+ }
+ res[packId].emojis.push(emoji)
+ })
+ return res
+ }, {})
+ },
+ standardEmojiList (state) {
+ return SORTED_EMOJI_GROUP_IDS
+ .map(groupId => (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations)))
+ .reduce((a, b) => a.concat(b), [])
+ },
+ standardEmojiGroupList (state) {
+ return SORTED_EMOJI_GROUP_IDS.map(groupId => ({
+ id: groupId,
+ emojis: (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations))
+ }))
+ },
instanceDomain (state) {
return new URL(state.server).hostname
}
@@ -138,32 +235,52 @@ const instance = {
},
async getStaticEmoji ({ commit }) {
try {
- const res = await window.fetch('/static/emoji.json')
- if (res.ok) {
- const values = await res.json()
- const emoji = Object.keys(values).map((key) => {
- return {
- displayText: key,
- imageUrl: false,
- replacement: values[key]
- }
- }).sort((a, b) => a.name > b.name ? 1 : -1)
- commit('setInstanceOption', { name: 'emoji', value: emoji })
- } else {
- throw (res)
- }
+ const values = (await import(/* webpackChunkName: 'emoji' */ '../../static/emoji.json')).default
+
+ const emoji = Object.keys(values).reduce((res, groupId) => {
+ res[groupId] = values[groupId].map(e => ({
+ displayText: e.slug,
+ imageUrl: false,
+ replacement: e.emoji
+ }))
+ return res
+ }, {})
+ commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) })
} catch (e) {
console.warn("Can't load static emoji")
console.warn(e)
}
},
+ loadUnicodeEmojiData ({ commit, state }, language) {
+ const langList = ensureFinalFallback(language)
+
+ return Promise.all(
+ langList
+ .map(async lang => {
+ if (!state.unicodeEmojiAnnotations[lang]) {
+ const annotations = await loadAnnotations(lang)
+ commit('setUnicodeEmojiAnnotations', { lang, annotations })
+ }
+ }))
+ },
+
async getCustomEmoji ({ commit, state }) {
try {
const res = await window.fetch('/api/pleroma/emoji.json')
if (res.ok) {
const result = await res.json()
const values = Array.isArray(result) ? Object.assign({}, ...result) : result
+ const caseInsensitiveStrCmp = (a, b) => {
+ const la = a.toLowerCase()
+ const lb = b.toLowerCase()
+ return la > lb ? 1 : (la < lb ? -1 : 0)
+ }
+ const byPackThenByName = (a, b) => {
+ const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5)
+ return caseInsensitiveStrCmp(packOf(a), packOf(b)) || caseInsensitiveStrCmp(a.displayText, b.displayText)
+ }
+
const emoji = Object.entries(values).map(([key, value]) => {
const imageUrl = value.image_url
return {
@@ -174,7 +291,7 @@ const instance = {
}
// Technically could use tags but those are kinda useless right now,
// should have been "pack" field, that would be more useful
- }).sort((a, b) => a.displayText.toLowerCase() > b.displayText.toLowerCase() ? 1 : -1)
+ }).sort(byPackThenByName)
commit('setInstanceOption', { name: 'customEmoji', value: emoji })
} else {
throw (res)