diff --git a/.gitignore b/.gitignore
index 7bf0fa18..fdf14967 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@
/static/icons.svg
/static/robots.txt
/static/inline-script.js.map
-/static/emoji-all-en.json
+/static/emoji-*.json
/src/inline-script/checksum.js
yarn-error.log
diff --git a/bin/build-assets.js b/bin/build-assets.js
index 14a908e1..5dc271e0 100644
--- a/bin/build-assets.js
+++ b/bin/build-assets.js
@@ -1,17 +1,48 @@
import path from 'path'
import fs from 'fs'
import { promisify } from 'util'
+import { LOCALE } from '../src/routes/_static/intl'
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
+// Try 'en-US' first, then 'en' if that doesn't exist
+const PREFERRED_LOCALES = [LOCALE, LOCALE.split('-')[0]]
+
+// emojibase seems like the most "neutral" shortcodes, but cldr is available in every language
+const PREFERRED_SHORTCODES = ['emojibase', 'cldr']
+
+async function getEmojiI18nFile (locale, shortcode) {
+ const filename = path.resolve(__dirname,
+ '../node_modules/emoji-picker-element-data',
+ locale,
+ shortcode,
+ 'data.json')
+ try {
+ return JSON.parse(await readFile(filename, 'utf8'))
+ } catch (err) { /* ignore */ }
+}
+
+async function getFirstExistingEmojiI18nFile () {
+ for (const locale of PREFERRED_LOCALES) {
+ for (const shortcode of PREFERRED_SHORTCODES) {
+ const json = await getEmojiI18nFile(locale, shortcode)
+ if (json) {
+ return json
+ }
+ }
+ }
+}
+
async function main () {
- const json = JSON.parse(await readFile(
- path.resolve(__dirname, '../node_modules/emoji-picker-element-data/en/emojibase-legacy/data.json'),
- 'utf8')
- )
+ const json = await getFirstExistingEmojiI18nFile()
+
+ if (!json) {
+ throw new Error(`Couldn't find i18n data for locale ${LOCALE}. Is it supported in emoji-picker-element-data?`)
+ }
+
await writeFile(
- path.resolve(__dirname, '../static/emoji-all-en.json'),
+ path.resolve(__dirname, `../static/emoji-${LOCALE}.json`),
JSON.stringify(json),
'utf8'
)
diff --git a/package.json b/package.json
index 0b65ff9b..e546a616 100644
--- a/package.json
+++ b/package.json
@@ -49,7 +49,7 @@
"compression": "^1.7.4",
"cross-env": "^7.0.2",
"css-dedoupe": "^0.1.1",
- "emoji-picker-element": "^1.3.0",
+ "emoji-picker-element": "^1.3.1",
"emoji-picker-element-data": "^1.0.0",
"emoji-regex": "^9.0.0",
"encoding": "^0.1.13",
diff --git a/src/intl/emoji-picker/fr.js b/src/intl/emoji-picker/fr.js
new file mode 100644
index 00000000..f2df4db7
--- /dev/null
+++ b/src/intl/emoji-picker/fr.js
@@ -0,0 +1,34 @@
+export default {
+ categoriesLabel: 'Catégories',
+ emojiUnsupportedMessage: 'Votre navigateur ne soutient pas les emojis en couleur.',
+ favoritesLabel: 'Favoris',
+ loadingMessage: 'Chargement en cours…',
+ networkErrorMessage: 'Impossible de charger les emojis. Veuillez essayer de recharger.',
+ regionLabel: 'Choisir un emoji',
+ searchDescription: 'Quand les résultats sont disponisbles, appuyez la fleche vers le haut ou le bas et la touche entrée pour choisir.',
+ searchLabel: 'Rechercher',
+ searchResultsLabel: 'Résultats',
+ skinToneDescription: 'Quand disponible, appuyez la fleche vers le haut ou le bas et la touch entrée pour choisir.',
+ skinToneLabel: 'Choisir une couleur de peau (actuellement {skinTone})',
+ skinTonesLabel: 'Couleurs de peau',
+ skinTones: [
+ 'Défaut',
+ 'Clair',
+ 'Moyennement clair',
+ 'Moyen',
+ 'Moyennement sombre',
+ 'Sombre'
+ ],
+ categories: {
+ custom: 'Customisé',
+ 'smileys-emotion': 'Les smileyes et les émoticônes',
+ 'people-body': 'Les gens et le corps',
+ 'animals-nature': 'Les animaux et la nature',
+ 'food-drink': 'La nourriture et les boissons',
+ 'travel-places': 'Les voyages et les endroits',
+ activities: 'Les activités',
+ objects: 'Les objets',
+ symbols: 'Les symbols',
+ flags: 'Les drapeaux'
+ }
+}
diff --git a/src/routes/_components/dialog/components/EmojiDialog.html b/src/routes/_components/dialog/components/EmojiDialog.html
index 3cf94b60..c2b8aa7f 100644
--- a/src/routes/_components/dialog/components/EmojiDialog.html
+++ b/src/routes/_components/dialog/components/EmojiDialog.html
@@ -8,7 +8,8 @@
store,
+ data: () => ({
+ emojiPickerLocale,
+ emojiPickerDataSource
+ }),
computed: {
darkMode: ({ $currentTheme }) => isDarkTheme($currentTheme),
customEmoji: ({ $currentCustomEmoji, $autoplayGifs }) => (
diff --git a/src/routes/_static/emojiPickerIntl.js b/src/routes/_static/emojiPickerIntl.js
new file mode 100644
index 00000000..56407273
--- /dev/null
+++ b/src/routes/_static/emojiPickerIntl.js
@@ -0,0 +1,11 @@
+import { LOCALE } from './intl'
+
+export const emojiPickerDataSource = `/emoji-${LOCALE}.json`
+
+// this should be undefined for English; it's already bundled with emoji-picker-element
+export const emojiPickerI18n = process.env.EMOJI_PICKER_I18N
+
+// To avoid creating a new IDB database named emoji-picker-en-US, just
+// reuse the existing default "en" one (otherwise people will end up with
+// a stale database taking up useless space)
+export const emojiPickerLocale = LOCALE === 'en-US' ? 'en' : LOCALE
diff --git a/src/routes/_utils/emojiDatabase.js b/src/routes/_utils/emojiDatabase.js
index 18ab738a..5f3b386c 100644
--- a/src/routes/_utils/emojiDatabase.js
+++ b/src/routes/_utils/emojiDatabase.js
@@ -1,5 +1,6 @@
import Database from 'emoji-picker-element/database'
import { lifecycle } from './lifecycle'
+import { emojiPickerLocale, emojiPickerDataSource } from '../_static/emojiPickerIntl'
let database
@@ -23,7 +24,8 @@ function applySkinToneToEmoji (emoji, skinTone) {
export function init () {
if (!database) {
database = new Database({
- dataSource: '/emoji-all-en.json'
+ locale: emojiPickerLocale,
+ dataSource: emojiPickerDataSource
})
}
}
diff --git a/src/service-worker.js b/src/service-worker.js
index 722c3748..e992f184 100644
--- a/src/service-worker.js
+++ b/src/service-worker.js
@@ -27,7 +27,7 @@ const assets = __assets__
.filter(filename => filename !== '/robots.txt')
.filter(filename => !filename.includes('traineddata.gz')) // cache on-demand
.filter(filename => !filename.endsWith('.webapp')) // KaiOS manifest
- .filter(filename => !filename.includes('emoji-all-en.json')) // useless to cache; it already goes in IndexedDB
+ .filter(filename => !/emoji-.*?\.json$/.test(filename)) // useless to cache; it already goes in IndexedDB
// `shell` is an array of all the files generated by webpack
// also contains '/index.html' for some reason
diff --git a/tests/spec/018-compose-autosuggest.js b/tests/spec/018-compose-autosuggest.js
index 4a337a08..d6afb27f 100644
--- a/tests/spec/018-compose-autosuggest.js
+++ b/tests/spec/018-compose-autosuggest.js
@@ -100,6 +100,16 @@ test('autosuggest handles works with regular emoji - clicking', async t => {
.expect(composeInput.value).eql('\ud83c\udf4d @quux ')
})
+test('autosuggest can suggest native emoji', async t => {
+ await loginAsFoobar(t)
+ await t
+ .hover(composeInput)
+ .typeText(composeInput, ':slight')
+ .expect(getNthAutosuggestionResult(1).innerText).contains(':slightly_smiling_face:', { timeout })
+ .click(getNthAutosuggestionResult(1))
+ .expect(composeInput.value).eql('\ud83d\ude42 ')
+})
+
test('autosuggest only shows for one input', async t => {
await loginAsFoobar(t)
await t
diff --git a/webpack/client.config.js b/webpack/client.config.js
index 5dd46c51..238ef547 100644
--- a/webpack/client.config.js
+++ b/webpack/client.config.js
@@ -1,4 +1,4 @@
-import { LOCALE } from '../src/routes/_static/intl'
+import { DEFAULT_LOCALE, LOCALE } from '../src/routes/_static/intl'
const path = require('path')
const webpack = require('webpack')
@@ -19,6 +19,9 @@ const output = Object.assign(config.client.output(), {
chunkFilename: dev ? '[hash]/[id].js' : '[id].[contenthash].js'
})
+const emojiPickerI18n = LOCALE !== DEFAULT_LOCALE &&
+ require(path.join(__dirname, '../src/intl/emoji-picker/', `${LOCALE}.js`)).default
+
module.exports = {
entry: config.client.entry(),
output,
@@ -101,7 +104,8 @@ module.exports = {
'process.env.INLINE_SVGS': JSON.stringify(inlineSvgs),
'process.env.ALL_SVGS': JSON.stringify(allSvgs),
'process.env.URL_REGEX': urlRegex.toString(),
- 'process.env.LOCALE': JSON.stringify(LOCALE)
+ 'process.env.LOCALE': JSON.stringify(LOCALE),
+ 'process.env.EMOJI_PICKER_I18N': emojiPickerI18n ? JSON.stringify(emojiPickerI18n) : 'undefined'
}),
new webpack.NormalModuleReplacementPlugin(
/\/_database\/database\.js$/, // this version plays nicer with IDEs
diff --git a/yarn.lock b/yarn.lock
index b68344cc..316116d5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2904,10 +2904,10 @@ emoji-picker-element-data@^1.0.0:
resolved "https://registry.yarnpkg.com/emoji-picker-element-data/-/emoji-picker-element-data-1.0.0.tgz#1e9c4b399ce6e1858514df4c25b65284d981f92f"
integrity sha512-Ch6Ibuc2DJAh9MMyaH0hxsfkCoGAkYVWf9i1JC30PsaC4L9rmS7LMvu1iR396NHecdMYToJEQEOneatPVGe/IQ==
-emoji-picker-element@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/emoji-picker-element/-/emoji-picker-element-1.3.0.tgz#d78deba0ebc4b87731bb2c16f7be00ec458d7647"
- integrity sha512-Zg+8rtr3vXKuAgBXWpSBghHq+I6o7+35N+25MN3P07pUyk07GXJ6B+gKr8ttUo2LZrLDZVoqKOVMzowkNwwZIg==
+emoji-picker-element@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/emoji-picker-element/-/emoji-picker-element-1.3.1.tgz#844e1ed261b6cda431423a1652da977202cb2090"
+ integrity sha512-+WtNPw28snGd5ZXVS5mAAKsAJ1+hJVRdXNQ9ZCdWSLVCK1mtJjcHl2dMxtB1LxSpX6m79DAAHMmDJRjqbRA+5w==
emoji-regex@^7.0.1:
version "7.0.3"