feat(i18n): Emojimart localization and fetching entry at en … (#1731)

Co-authored-by: userquin <userquin@gmail.com>
This commit is contained in:
Cesar Gomez 2023-02-15 14:15:11 -05:00 committed by GitHub
parent 3118ed6012
commit 0fdbb17591
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 94 additions and 9 deletions

View file

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import importEmojiLang from 'virtual:emoji-mart-lang-importer'
import type { Picker } from 'emoji-mart' import type { Picker } from 'emoji-mart'
const emit = defineEmits<{ const emit = defineEmits<{
@ -6,12 +7,15 @@ const emit = defineEmits<{
(e: 'selectCustom', image: any): void (e: 'selectCustom', image: any): void
}>() }>()
const { locale } = useI18n()
const el = $ref<HTMLElement>() const el = $ref<HTMLElement>()
let picker = $ref<Picker>() let picker = $ref<Picker>()
const colorMode = useColorMode() const colorMode = useColorMode()
async function openEmojiPicker() { async function openEmojiPicker() {
await updateCustomEmojis() await updateCustomEmojis()
if (picker) { if (picker) {
picker.update({ picker.update({
theme: colorMode.value, theme: colorMode.value,
@ -19,10 +23,14 @@ async function openEmojiPicker() {
}) })
} }
else { else {
const promise = import('@emoji-mart/data/sets/14/twitter.json').then(r => r.default) const [Picker, dataPromise, i18n] = await Promise.all([
const { Picker } = await import('emoji-mart') import('emoji-mart').then(({ Picker }) => Picker),
import('@emoji-mart/data/sets/14/twitter.json').then((r: any) => r.default).catch(() => {}),
importEmojiLang(locale.value.split('-')[0]),
])
picker = new Picker({ picker = new Picker({
data: () => promise, data: () => dataPromise,
onEmojiSelect({ native, src, alt, name }: any) { onEmojiSelect({ native, src, alt, name }: any) {
native native
? emit('select', native) ? emit('select', native)
@ -31,6 +39,7 @@ async function openEmojiPicker() {
set: 'twitter', set: 'twitter',
theme: colorMode.value, theme: colorMode.value,
custom: customEmojisData.value, custom: customEmojisData.value,
i18n,
}) })
} }
await nextTick() await nextTick()

View file

@ -43,7 +43,7 @@ const chooseIcon = (i: number, text: string) => {
<div flex="~ col gap4"> <div flex="~ col gap4">
<div v-for="i in fieldCount" :key="i" flex="~ gap3" items-center> <div v-for="i in fieldCount" :key="i" flex="~ gap3" items-center>
<CommonDropdown ref="dropdown" placement="left"> <CommonDropdown ref="dropdown" placement="left">
<CommonTooltip content="Pick a icon"> <CommonTooltip :content="$t('tooltip.pick_an_icon')">
<button type="button" btn-action-icon> <button type="button" btn-action-icon>
<div :class="fieldIcons[i - 1] || 'i-ri:question-mark'" /> <div :class="fieldIcons[i - 1] || 'i-ri:question-mark'" />
</button> </button>

View file

@ -83,7 +83,7 @@ defineExpose({
<template v-if="isPending"> <template v-if="isPending">
<div flex gap-1 items-center p2 animate-pulse> <div flex gap-1 items-center p2 animate-pulse>
<div i-ri:loader-2-line animate-spin /> <div i-ri:loader-2-line animate-spin />
<span>Fetching...</span> <span>{{ $t('common.fetching') }}</span>
</div> </div>
</template> </template>
<template v-if="items.length"> <template v-if="items.length">

View file

@ -52,7 +52,7 @@ defineExpose({
<div animate-spin preserve-3d> <div animate-spin preserve-3d>
<div i-ri:loader-2-line /> <div i-ri:loader-2-line />
</div> </div>
<span>Fetching...</span> <span>{{ $t('common.fetching') }}</span>
</div> </div>
</template> </template>
<template v-if="items.length"> <template v-if="items.length">

View file

@ -52,7 +52,7 @@ defineExpose({
<div animate-spin preserve-3d> <div animate-spin preserve-3d>
<div i-ri:loader-2-line /> <div i-ri:loader-2-line />
</div> </div>
<span>Fetching...</span> <span>{{ $t('common.fetching') }}</span>
</div> </div>
</template> </template>
<template v-if="items.length"> <template v-if="items.length">

3
emoji-mart-traslation.d.ts vendored Normal file
View file

@ -0,0 +1,3 @@
declare module 'virtual:emoji-mart-lang-importer' {
export default function(lang: string): Promise<any>
}

View file

@ -95,6 +95,7 @@
"common": { "common": {
"end_of_list": "End of the list", "end_of_list": "End of the list",
"error": "ERROR", "error": "ERROR",
"fetching": "Fetching...",
"in": "in", "in": "in",
"not_found": "404 Not Found", "not_found": "404 Not Found",
"offline_desc": "Seems like you are offline. Please check your network connection." "offline_desc": "Seems like you are offline. Please check your network connection."
@ -563,6 +564,7 @@
"explore_posts_intro": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.", "explore_posts_intro": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.",
"explore_tags_intro": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", "explore_tags_intro": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
"open_editor_tools": "Editor tools", "open_editor_tools": "Editor tools",
"pick_an_icon": "Pick an icon",
"publish_failed": "Close failed messages at the top of editor to republish posts", "publish_failed": "Close failed messages at the top of editor to republish posts",
"toggle_bold": "Toggle bold", "toggle_bold": "Toggle bold",
"toggle_code_block": "Toggle code block", "toggle_code_block": "Toggle code block",

View file

@ -37,6 +37,7 @@
}, },
"common": { "common": {
"end_of_list": "Fin de la lista", "end_of_list": "Fin de la lista",
"fetching": "Listando...",
"offline_desc": "No tienes acceso a internet. Por favor, comprueba que tienes una conexión a la red." "offline_desc": "No tienes acceso a internet. Por favor, comprueba que tienes una conexión a la red."
}, },
"confirm": { "confirm": {
@ -150,7 +151,8 @@
"under_construction": "En desarrollo" "under_construction": "En desarrollo"
}, },
"preferences": { "preferences": {
"grayscale_mode": "Tema en escala de grises" "grayscale_mode": "Tema en escala de grises",
"hide_username_emojis_description": "Oculta, de la historia, los emojis en los nombres de usuario. Los emojis seguirán visibles en los perfiles."
}, },
"profile": { "profile": {
"appearance": { "appearance": {
@ -183,6 +185,7 @@
}, },
"tooltip": { "tooltip": {
"add_emojis": "Insertar emoji", "add_emojis": "Insertar emoji",
"add_media": "Insertar imágenes, un video o archivos de audio",
"change_content_visibility": "Cambiar visibilidad" "change_content_visibility": "Cambiar visibilidad"
}, },
"user": { "user": {

View file

@ -95,6 +95,7 @@
"common": { "common": {
"end_of_list": "Fin", "end_of_list": "Fin",
"error": "ERROR", "error": "ERROR",
"fetching": "Cargando...",
"in": "en", "in": "en",
"not_found": "404 No Encontrado", "not_found": "404 No Encontrado",
"offline_desc": "Al parecer no tienes conexión a internet. Por favor, comprueba tu conexión a la red." "offline_desc": "Al parecer no tienes conexión a internet. Por favor, comprueba tu conexión a la red."
@ -413,7 +414,7 @@
"hide_reply_count": "Ocultar número de respuestas", "hide_reply_count": "Ocultar número de respuestas",
"hide_translation": "Ocultar traducción", "hide_translation": "Ocultar traducción",
"hide_username_emojis": "Ocultar emojis en el nombre de usuario", "hide_username_emojis": "Ocultar emojis en el nombre de usuario",
"hide_username_emojis_description": "Se ocultan los emojis en el nombre de usuario en las líneas de tiempo. Los emojis seguirán siendo visibles en sus perfiles.", "hide_username_emojis_description": "Oculta los emojis de los nombres de usuarios en la línea de tiempo. Los emojis permanecerán visibles en sus perfiles.",
"label": "Preferencias", "label": "Preferencias",
"title": "Funcionalidades experimentales", "title": "Funcionalidades experimentales",
"user_picker": "Selector de usuarios", "user_picker": "Selector de usuarios",
@ -428,6 +429,8 @@
"label": "Apariencia", "label": "Apariencia",
"profile_metadata": "Metadatos de perfil", "profile_metadata": "Metadatos de perfil",
"profile_metadata_desc": "Puede mostrar hasta 4 elementos en forma de tabla en tu perfil", "profile_metadata_desc": "Puede mostrar hasta 4 elementos en forma de tabla en tu perfil",
"profile_metadata_label": "Texto",
"profile_metadata_value": "Contenido",
"title": "Editar perfil" "title": "Editar perfil"
}, },
"featured_tags": { "featured_tags": {
@ -559,6 +562,7 @@
"explore_posts_intro": "Estos mensajes de este y otros servidores de la red descentralizada están siendo tendencia ahora mismo en este servidor.", "explore_posts_intro": "Estos mensajes de este y otros servidores de la red descentralizada están siendo tendencia ahora mismo en este servidor.",
"explore_tags_intro": "Estas etiquetas están siendo tendencia ahora mismo entre los usuarios de este y otros servidores de la red descentralizada.", "explore_tags_intro": "Estas etiquetas están siendo tendencia ahora mismo entre los usuarios de este y otros servidores de la red descentralizada.",
"open_editor_tools": "Herramientas de edición", "open_editor_tools": "Herramientas de edición",
"pick_an_icon": "Selecciona un icono",
"publish_failed": "Cierra los mensajes fallidos en la parte superior del editor para volver a publicar", "publish_failed": "Cierra los mensajes fallidos en la parte superior del editor para volver a publicar",
"toggle_bold": "Cambiar a negrita", "toggle_bold": "Cambiar a negrita",
"toggle_code_block": "Cambiar a bloque de código", "toggle_code_block": "Cambiar a bloque de código",

View file

@ -0,0 +1,63 @@
import fs from 'fs-extra'
import { createResolver, defineNuxtModule } from '@nuxt/kit'
import { i18n } from '../config/i18n'
import type { LocaleObject } from '#i18n'
const virtual = 'virtual:emoji-mart-lang-importer'
const resolvedVirtual = `\0${virtual}.mjs`
export default defineNuxtModule({
meta: {
name: 'emoji-mark-translation',
},
setup(_, nuxt) {
const resolver = createResolver(import.meta.url)
nuxt.hook('vite:extendConfig', async (viteInlineConfig) => {
viteInlineConfig.plugins = viteInlineConfig.plugins || []
viteInlineConfig.plugins.push({
name: 'vite-emoji-mart-translation',
enforce: 'pre',
resolveId(id) {
if (id === virtual)
return resolvedVirtual
},
async load(id) {
if (id === resolvedVirtual) {
const locales = await Promise.all(
Array
.from(new Set((i18n.locales as LocaleObject[]).map(l => l.code.split('-')[0])))
.map(async (l) => {
const exists = await isFile(resolver.resolve(`../node_modules/@emoji-mart/data/i18n/${l}.json`))
return [l, exists] as [code: string, exists: boolean]
}))
.then(l => l.filter(l => l[1]).map(l => l[0]))
const switchStmt = locales.filter(l => l[1]).map((l) => {
return `
case "${l}":
return import("@emoji-mart/data/i18n/${l}.json").catch(() => {});`
})
return `export default function(lang) {
switch(lang) {
${switchStmt.join('')}
default:
return import("@emoji-mart/data/i18n/en.json").catch(() => {});
}
}
`
}
},
})
})
},
})
async function isFile(path: string) {
return new Promise<boolean>((resolve) => {
fs.lstat(path, (err, stats) => {
if (err)
resolve(false)
else
resolve(stats.isFile())
})
})
}

View file

@ -25,6 +25,7 @@ export default defineNuxtConfig({
'@nuxtjs/color-mode', '@nuxtjs/color-mode',
'nuxt-vitest', 'nuxt-vitest',
...(isDevelopment || isWindows) ? [] : ['nuxt-security'], ...(isDevelopment || isWindows) ? [] : ['nuxt-security'],
'~/modules/emoji-mart-translation',
'~/modules/purge-comments', '~/modules/purge-comments',
'~/modules/setup-components', '~/modules/setup-components',
'~/modules/build-env', '~/modules/build-env',