Add script to generate emoji picker localization
authorCyperghost <olaf_schmitz_1@t-online.de>
Thu, 17 Oct 2024 12:27:09 +0000 (14:27 +0200)
committerCyperghost <olaf_schmitz_1@t-online.de>
Thu, 17 Oct 2024 12:27:09 +0000 (14:27 +0200)
Add `woltlab-core-emoji-picker` element

extra/package-lock.json
extra/package.json
extra/update-emoji-picker-element-data.ts
ts/WoltLabSuite/Core/BootstrapFrontend.ts
ts/WoltLabSuite/Core/Component/EmojiPicker/Localization.ts [new file with mode: 0644]
ts/WoltLabSuite/Core/Component/EmojiPicker/woltlab-core-emoji-picker.ts [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js
wcfsetup/install/files/js/WoltLabSuite/Core/Component/EmojiPicker/Localization.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Component/EmojiPicker/woltlab-core-emoji-picker.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Element/woltlab-core-emoji-picker.js [new file with mode: 0644]

index 06e9ce197e3f62e92a07c2d53aa4e9484dddcd15..890b133f82e5d9b2334cbe1bdc46d45f3c6db14c 100644 (file)
@@ -7,6 +7,7 @@
       "dependencies": {
         "@woltlab/r.js": "git+https://github.com/WoltLab/r.js.git#ad2413df45fdf6164611243f9870943de3d2bce3",
         "deepmerge": "^4.3.0",
+        "emoji-picker-element": "^1.22.8",
         "emoji-picker-element-data": "^1.6.1",
         "terser": "^5.16.5",
         "ts-node": "^10.9.1"
         "node": ">=0.3.1"
       }
     },
+    "node_modules/emoji-picker-element": {
+      "version": "1.22.8",
+      "resolved": "https://registry.npmjs.org/emoji-picker-element/-/emoji-picker-element-1.22.8.tgz",
+      "integrity": "sha512-EFgRjrlIcdA1ilyMH/f9KjB0Pi/vynrojNgMDZfU1Jv2YLrhdLJWx6xCehizPyxm4/NUuB8DfFvIT4v+1njjPQ=="
+    },
     "node_modules/emoji-picker-element-data": {
       "version": "1.6.1",
       "resolved": "https://registry.npmjs.org/emoji-picker-element-data/-/emoji-picker-element-data-1.6.1.tgz",
       "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
       "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
     },
+    "emoji-picker-element": {
+      "version": "1.22.8",
+      "resolved": "https://registry.npmjs.org/emoji-picker-element/-/emoji-picker-element-1.22.8.tgz",
+      "integrity": "sha512-EFgRjrlIcdA1ilyMH/f9KjB0Pi/vynrojNgMDZfU1Jv2YLrhdLJWx6xCehizPyxm4/NUuB8DfFvIT4v+1njjPQ=="
+    },
     "emoji-picker-element-data": {
       "version": "1.6.1",
       "resolved": "https://registry.npmjs.org/emoji-picker-element-data/-/emoji-picker-element-data-1.6.1.tgz",
index f1ff98f5315f3e3f55032f7afe1184893725d49f..72de2c7cb23fe49e1d1ad2dab5c8d312c878c22f 100644 (file)
@@ -2,6 +2,7 @@
   "dependencies": {
     "@woltlab/r.js": "git+https://github.com/WoltLab/r.js.git#ad2413df45fdf6164611243f9870943de3d2bce3",
     "deepmerge": "^4.3.0",
+    "emoji-picker-element": "^1.22.8",
     "emoji-picker-element-data": "^1.6.1",
     "terser": "^5.16.5",
     "ts-node": "^10.9.1"
index 21a7d812dddd81c2c025e196028be6978416dab2..93267d1d3983aaaeaf1d17e6ebbdfcd5dcb2221b 100644 (file)
@@ -1,11 +1,15 @@
 import * as fs from "fs";
 import { promisify } from "util";
 import * as path from "path";
+import { I18n } from "emoji-picker-element/shared";
 
 const copyFile = promisify(fs.copyFile);
+const writeFile = promisify(fs.writeFile);
 
-if (process.argv.length !== 3) {
-  throw new Error("Expects the path to the directory in which the emoji data is saved as the only argument.");
+if (process.argv.length !== 4) {
+  throw new Error(
+    "Expects the path to the directory in which the emoji data is saved as the #1 argument and the path to the Localisation.ts as the #2 argument.",
+  );
 }
 
 const repository = process.argv[2];
@@ -13,6 +17,11 @@ if (!fs.existsSync(repository)) {
   throw new Error(`The path '${repository}' does not exist.`);
 }
 
+const localisation = process.argv[3];
+if (!fs.existsSync(localisation)) {
+  throw new Error(`The path '${localisation}' does not exist.`);
+}
+
 const languages = [
   "da",
   "nl",
@@ -34,9 +43,44 @@ const languages = [
   "uk",
 ];
 
-languages.forEach(async (language) => {
-  await copyFile(
-    path.join(__dirname, `node_modules/emoji-picker-element-data/${language}/cldr-native/data.json`),
-    path.join(repository, `${language}.json`),
-  );
-});
+(async () => {
+  const en = await import("emoji-picker-element/i18n/en");
+  let importedLanguages = new Map<
+    string,
+    {
+      default: I18n;
+    }
+  >();
+  for (const language of languages.filter((language) => language !== "en")) {
+    try {
+      importedLanguages.set(language, await import(`emoji-picker-element/i18n/${language}`));
+    } catch {
+      // localizations not found, will be fallback to en
+    }
+  }
+
+  let localisationContent = `import { I18n } from "emoji-picker-element/shared";
+
+export function getLocalizationData(localization: string): I18n {
+  switch (localization) {
+    ${Array.from(importedLanguages.entries())
+      .map(([languageCode, language]) => {
+        return `case "${languageCode}":
+      return ${JSON.stringify(language.default)};`;
+      })
+      .join("\n    ")}
+    default:
+      return ${JSON.stringify(en.default)};
+  }
+}
+`;
+
+  for (const language of languages) {
+    await copyFile(
+      path.join(__dirname, `node_modules/emoji-picker-element-data/${language}/cldr-native/data.json`),
+      path.join(repository, `${language}.json`),
+    );
+  }
+
+  await writeFile(localisation, localisationContent);
+})();
index be6881d2a14f2ed674d44be7efb7e208cbbb7c25..01840f3dc6a288288bf7760b510985f7ac58844f 100644 (file)
@@ -127,6 +127,9 @@ export function setup(options: BootstrapOptions): void {
   whenFirstSeen("woltlab-core-comment-response", () => {
     void import("./Component/Comment/Response/woltlab-core-comment-response");
   });
+  whenFirstSeen("woltlab-core-emoji-picker", () => {
+    void import("./Component/EmojiPicker/woltlab-core-emoji-picker");
+  });
   whenFirstSeen("[data-follow-user]", () => {
     void import("./Component/User/Follow").then(({ setup }) => setup());
   });
diff --git a/ts/WoltLabSuite/Core/Component/EmojiPicker/Localization.ts b/ts/WoltLabSuite/Core/Component/EmojiPicker/Localization.ts
new file mode 100644 (file)
index 0000000..652dae1
--- /dev/null
@@ -0,0 +1,20 @@
+import { I18n } from "emoji-picker-element/shared";
+
+export function getLocalizationData(localization: string): I18n {
+  switch (localization) {
+    case "nl":
+      return {"categoriesLabel":"Categorieën","emojiUnsupportedMessage":"Uw browser ondersteunt geen kleurenemoji.","favoritesLabel":"Favorieten","loadingMessage":"Bezig met laden…","networkErrorMessage":"Kan emoji niet laden.","regionLabel":"Emoji-kiezer","searchDescription":"Als er zoekresultaten beschikbaar zijn, drukt u op omhoog of omlaag om te selecteren en op enter om te kiezen.","searchLabel":"Zoeken","searchResultsLabel":"Zoekresultaten","skinToneDescription":"Wanneer uitgevouwen, druk omhoog of omlaag om te selecteren en enter om te kiezen.","skinToneLabel":"Kies een huidskleur (momenteel {skinTone})","skinTonesLabel":"Huidskleuren","skinTones":["Standaard","Licht","Medium-Licht","Medium","Middeldonker","Donker"],"categories":{"custom":"Aangepast","smileys-emotion":"Smileys en emoticons","people-body":"Mensen en lichaam","animals-nature":"Dieren en natuur","food-drink":"Eten en drinken","travel-places":"Reizen en plaatsen","activities":"Activiteiten","objects":"Voorwerpen","symbols":"Symbolen","flags":"Vlaggen"}};
+    case "fr":
+      return {"categoriesLabel":"Catégories","emojiUnsupportedMessage":"Votre navigateur ne supporte pas les emojis en couleur.","favoritesLabel":"Favoris","loadingMessage":"Chargement en cours…","networkErrorMessage":"Impossible de charger les emojis.","regionLabel":"Choisir un emoji","searchDescription":"Lorsque les résultats sont affichés, utilisez les flèches haut/bas pour naviguer et la touche entrée pour sélectionner.","searchLabel":"Rechercher","searchResultsLabel":"Résultats","skinToneDescription":"Quand disponible, utilisez les flèches haut/bas pour naviguer et la touche entrée pour sélectionner.","skinToneLabel":"Choisir une couleur de peau (actuellement {skinTone})","skinTonesLabel":"Couleurs de peau","skinTones":["Par défaut","Clair","Moyennement clair","Moyen","Moyennement sombre","Sombre"],"categories":{"custom":"Personnalisé","smileys-emotion":"Émoticônes","people-body":"Corps et métiers","animals-nature":"Animaux et nature","food-drink":"Nourriture et boissons","travel-places":"Voyages et lieux","activities":"Activités","objects":"Objets","symbols":"Symboles","flags":"Drapeaux"}};
+    case "de":
+      return {"categoriesLabel":"Kategorien","emojiUnsupportedMessage":"Dein Browser unterstützt keine farbigen Emojis.","favoritesLabel":"Favoriten","loadingMessage":"Wird geladen…","networkErrorMessage":"Konnte Emoji nicht laden.","regionLabel":"Emoji auswählen","searchDescription":"Wenn Suchergebnisse verfügbar sind, wähle sie mit Pfeil rauf und runter, dann Eingabetaste, aus.","searchLabel":"Suchen","searchResultsLabel":"Suchergebnisse","skinToneDescription":"Wenn angezeigt, nutze Pfeiltasten rauf und runter zum Auswählen, Eingabe zum Akzeptieren.","skinToneLabel":"Wähle einen Hautton (aktuell {skinTone})","skinTonesLabel":"Hauttöne","skinTones":["Standard","Hell","Mittel-hell","Mittel","Mittel-dunkel","Dunkel"],"categories":{"custom":"Benutzerdefiniert","smileys-emotion":"Smileys und Emoticons","people-body":"Menschen und Körper","animals-nature":"Tiere und Natur","food-drink":"Essen und Trinken","travel-places":"Reisen und Orte","activities":"Aktivitäten","objects":"Objekte","symbols":"Symbole","flags":"Flaggen"}};
+    case "it":
+      return {"categoriesLabel":"Categorie","emojiUnsupportedMessage":"Il tuo browser non supporta le emoji colorate.","favoritesLabel":"Preferiti","loadingMessage":"Caricamento...","networkErrorMessage":"Impossibile caricare le emoji.","regionLabel":"Selezione emoji","searchDescription":"Quando i risultati della ricerca sono disponibili, premi su o giù per selezionare e invio per scegliere.","searchLabel":"Cerca","searchResultsLabel":"Risultati di ricerca","skinToneDescription":"Quando espanso, premi su o giù per selezionare e invio per scegliere.","skinToneLabel":"Scegli una tonalità della pelle (corrente {skinTone})","skinTonesLabel":"Tonalità della pelle","skinTones":["Predefinita","Chiara","Medio-Chiara","Media","Medio-Scura","Scura"],"categories":{"custom":"Personalizzata","smileys-emotion":"Faccine ed emozioni","people-body":"Persone e corpi","animals-nature":"Animali e natura","food-drink":"Cibi e bevande","travel-places":"Viaggi e luoghi","activities":"Attività","objects":"Oggetti","symbols":"Simboli","flags":"Bandiere"}};
+    case "pl":
+      return {"categoriesLabel":"Kategorie","emojiUnsupportedMessage":"Twoja przeglądarka nie wspiera kolorowych emotikon.","favoritesLabel":"Ulubione","loadingMessage":"Ładuję…","networkErrorMessage":"Nie można załadować emoji.","regionLabel":"Selektor emoji","searchDescription":"Kiedy wyniki wyszukiwania będą dostępne, wciśnij góra lub dół aby wybrać oraz enter aby zatwierdzić wybór.","searchLabel":"Wyszukaj","searchResultsLabel":"Wyniki wyszukiwania","skinToneDescription":"Po rozwinięciu wciśnij góra lub dół aby wybrać oraz enter aby zatwierdzić wybór.","skinToneLabel":"Wybierz odcień skóry (aktualnie {skinTone})","skinTonesLabel":"Odcienie skóry","skinTones":["Domyślna","Jasna","Średnio-jasna","Średnia","Średnio-ciemna","Ciemna"],"categories":{"custom":"Własne","smileys-emotion":"Uśmiechy","people-body":"Ludzie","animals-nature":"Zwierzęta i natura","food-drink":"Żywność i napoje","travel-places":"Podróże i miejsca","activities":"Aktywności","objects":"Obiekty","symbols":"Symbole","flags":"Flagi"}};
+    case "es":
+      return {"categoriesLabel":"Categorías","emojiUnsupportedMessage":"El navegador no admite emojis de color.","favoritesLabel":"Favoritos","loadingMessage":"Cargando…","networkErrorMessage":"No se pudo cargar el emoji.","regionLabel":"Selector de emojis","searchDescription":"Cuando estén disponibles los resultados, pulsa la tecla hacia arriba o hacia abajo para seleccionar y la tecla intro para elegir.","searchLabel":"Buscar","searchResultsLabel":"Resultados de búsqueda","skinToneDescription":"Cuando se abran las opciones, pulsa la tecla hacia arriba o hacia abajo para seleccionar y la tecla intro para elegir.","skinToneLabel":"Elige un tono de piel ({skinTone} es el actual)","skinTonesLabel":"Tonos de piel","skinTones":["Predeterminado","Claro","Claro medio","Medio","Oscuro medio","Oscuro"],"categories":{"custom":"Personalizado","smileys-emotion":"Emojis y emoticones","people-body":"Personas y partes del cuerpo","animals-nature":"Animales y naturaleza","food-drink":"Comida y bebida","travel-places":"Viajes y lugares","activities":"Actividades","objects":"Objetos","symbols":"Símbolos","flags":"Banderas"}};
+    default:
+      return {"categoriesLabel":"Categories","emojiUnsupportedMessage":"Your browser does not support color emoji.","favoritesLabel":"Favorites","loadingMessage":"Loading…","networkErrorMessage":"Could not load emoji.","regionLabel":"Emoji picker","searchDescription":"When search results are available, press up or down to select and enter to choose.","searchLabel":"Search","searchResultsLabel":"Search results","skinToneDescription":"When expanded, press up or down to select and enter to choose.","skinToneLabel":"Choose a skin tone (currently {skinTone})","skinTonesLabel":"Skin tones","skinTones":["Default","Light","Medium-Light","Medium","Medium-Dark","Dark"],"categories":{"custom":"Custom","smileys-emotion":"Smileys and emoticons","people-body":"People and body","animals-nature":"Animals and nature","food-drink":"Food and drink","travel-places":"Travel and places","activities":"Activities","objects":"Objects","symbols":"Symbols","flags":"Flags"}};
+  }
+}
diff --git a/ts/WoltLabSuite/Core/Component/EmojiPicker/woltlab-core-emoji-picker.ts b/ts/WoltLabSuite/Core/Component/EmojiPicker/woltlab-core-emoji-picker.ts
new file mode 100644 (file)
index 0000000..c47fe9d
--- /dev/null
@@ -0,0 +1,57 @@
+import de from "emoji-picker-element/i18n/de";
+import en from "emoji-picker-element/i18n/en";
+import es from "emoji-picker-element/i18n/es";
+import fr from "emoji-picker-element/i18n/fr";
+import it from "emoji-picker-element/i18n/it";
+import nl from "emoji-picker-element/i18n/nl";
+import pl from "emoji-picker-element/i18n/pl";
+import pt_BR from "emoji-picker-element/i18n/pt_BR";
+import pt_PT from "emoji-picker-element/i18n/pt_PT";
+import ru_RU from "emoji-picker-element/i18n/ru_RU";
+import "emoji-picker-element";
+import { PickerConstructorOptions, I18n } from "emoji-picker-element/shared";
+import { Picker } from "emoji-picker-element";
+
+const EmojiPickerLocales: { [key: string]: I18n } = {
+  de,
+  en,
+  es,
+  fr,
+  it,
+  nl,
+  pl,
+  "pt-br": pt_BR,
+  "pt-pt": pt_PT,
+  "ru-ru": ru_RU,
+};
+
+function getDataSource(locale: string): string {
+  return `${window.WSC_API_URL}emoji/${locale}.json`;
+}
+
+export class WoltlabCoreEmojiPicker extends Picker {
+  constructor(props: PickerConstructorOptions | null | undefined) {
+    const locale = (props && props.locale) || document.documentElement.lang;
+
+    super({
+      locale: locale,
+      ...(props || {}),
+      dataSource: getDataSource(locale),
+      ...(Object.hasOwn(EmojiPickerLocales, locale) ? { i18n: EmojiPickerLocales[locale] } : {}),
+    });
+  }
+
+  static get observedAttributes(): string[] {
+    return [];
+  }
+
+  focus() {
+    this.shadowRoot!.querySelector<HTMLInputElement>(".search")!.focus();
+  }
+}
+
+void customElements.whenDefined("emoji-picker").then(() => {
+  customElements.define("woltlab-core-emoji-picker", WoltlabCoreEmojiPicker, {
+    extends: "emoji-picker",
+  });
+});
index 2ec14797d0b8fd1bf27d135138a78bc860fa6701..26090aa4b4c7d8a6767a9e96e636da4a864b7398 100644 (file)
@@ -90,11 +90,14 @@ define(["require", "exports", "tslib", "./BackgroundQueue", "./Bootstrap", "./Ui
         (0, LazyLoader_1.whenFirstSeen)("woltlab-core-comment-response", () => {
             void new Promise((resolve_5, reject_5) => { require(["./Component/Comment/Response/woltlab-core-comment-response"], resolve_5, reject_5); }).then(tslib_1.__importStar);
         });
+        (0, LazyLoader_1.whenFirstSeen)("woltlab-core-emoji-picker", () => {
+            void new Promise((resolve_6, reject_6) => { require(["./Component/EmojiPicker/woltlab-core-emoji-picker"], resolve_6, reject_6); }).then(tslib_1.__importStar);
+        });
         (0, LazyLoader_1.whenFirstSeen)("[data-follow-user]", () => {
-            void new Promise((resolve_6, reject_6) => { require(["./Component/User/Follow"], resolve_6, reject_6); }).then(tslib_1.__importStar).then(({ setup }) => setup());
+            void new Promise((resolve_7, reject_7) => { require(["./Component/User/Follow"], resolve_7, reject_7); }).then(tslib_1.__importStar).then(({ setup }) => setup());
         });
         (0, LazyLoader_1.whenFirstSeen)("[data-ignore-user]", () => {
-            void new Promise((resolve_7, reject_7) => { require(["./Component/User/Ignore"], resolve_7, reject_7); }).then(tslib_1.__importStar).then(({ setup }) => setup());
+            void new Promise((resolve_8, reject_8) => { require(["./Component/User/Ignore"], resolve_8, reject_8); }).then(tslib_1.__importStar).then(({ setup }) => setup());
         });
     }
 });
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/EmojiPicker/Localization.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/EmojiPicker/Localization.js
new file mode 100644 (file)
index 0000000..529bc4e
--- /dev/null
@@ -0,0 +1,23 @@
+define(["require", "exports"], function (require, exports) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.getLocalizationData = getLocalizationData;
+    function getLocalizationData(localization) {
+        switch (localization) {
+            case "nl":
+                return { "categoriesLabel": "Categorieën", "emojiUnsupportedMessage": "Uw browser ondersteunt geen kleurenemoji.", "favoritesLabel": "Favorieten", "loadingMessage": "Bezig met laden…", "networkErrorMessage": "Kan emoji niet laden.", "regionLabel": "Emoji-kiezer", "searchDescription": "Als er zoekresultaten beschikbaar zijn, drukt u op omhoog of omlaag om te selecteren en op enter om te kiezen.", "searchLabel": "Zoeken", "searchResultsLabel": "Zoekresultaten", "skinToneDescription": "Wanneer uitgevouwen, druk omhoog of omlaag om te selecteren en enter om te kiezen.", "skinToneLabel": "Kies een huidskleur (momenteel {skinTone})", "skinTonesLabel": "Huidskleuren", "skinTones": ["Standaard", "Licht", "Medium-Licht", "Medium", "Middeldonker", "Donker"], "categories": { "custom": "Aangepast", "smileys-emotion": "Smileys en emoticons", "people-body": "Mensen en lichaam", "animals-nature": "Dieren en natuur", "food-drink": "Eten en drinken", "travel-places": "Reizen en plaatsen", "activities": "Activiteiten", "objects": "Voorwerpen", "symbols": "Symbolen", "flags": "Vlaggen" } };
+            case "fr":
+                return { "categoriesLabel": "Catégories", "emojiUnsupportedMessage": "Votre navigateur ne supporte pas les emojis en couleur.", "favoritesLabel": "Favoris", "loadingMessage": "Chargement en cours…", "networkErrorMessage": "Impossible de charger les emojis.", "regionLabel": "Choisir un emoji", "searchDescription": "Lorsque les résultats sont affichés, utilisez les flèches haut/bas pour naviguer et la touche entrée pour sélectionner.", "searchLabel": "Rechercher", "searchResultsLabel": "Résultats", "skinToneDescription": "Quand disponible, utilisez les flèches haut/bas pour naviguer et la touche entrée pour sélectionner.", "skinToneLabel": "Choisir une couleur de peau (actuellement {skinTone})", "skinTonesLabel": "Couleurs de peau", "skinTones": ["Par défaut", "Clair", "Moyennement clair", "Moyen", "Moyennement sombre", "Sombre"], "categories": { "custom": "Personnalisé", "smileys-emotion": "Émoticônes", "people-body": "Corps et métiers", "animals-nature": "Animaux et nature", "food-drink": "Nourriture et boissons", "travel-places": "Voyages et lieux", "activities": "Activités", "objects": "Objets", "symbols": "Symboles", "flags": "Drapeaux" } };
+            case "de":
+                return { "categoriesLabel": "Kategorien", "emojiUnsupportedMessage": "Dein Browser unterstützt keine farbigen Emojis.", "favoritesLabel": "Favoriten", "loadingMessage": "Wird geladen…", "networkErrorMessage": "Konnte Emoji nicht laden.", "regionLabel": "Emoji auswählen", "searchDescription": "Wenn Suchergebnisse verfügbar sind, wähle sie mit Pfeil rauf und runter, dann Eingabetaste, aus.", "searchLabel": "Suchen", "searchResultsLabel": "Suchergebnisse", "skinToneDescription": "Wenn angezeigt, nutze Pfeiltasten rauf und runter zum Auswählen, Eingabe zum Akzeptieren.", "skinToneLabel": "Wähle einen Hautton (aktuell {skinTone})", "skinTonesLabel": "Hauttöne", "skinTones": ["Standard", "Hell", "Mittel-hell", "Mittel", "Mittel-dunkel", "Dunkel"], "categories": { "custom": "Benutzerdefiniert", "smileys-emotion": "Smileys und Emoticons", "people-body": "Menschen und Körper", "animals-nature": "Tiere und Natur", "food-drink": "Essen und Trinken", "travel-places": "Reisen und Orte", "activities": "Aktivitäten", "objects": "Objekte", "symbols": "Symbole", "flags": "Flaggen" } };
+            case "it":
+                return { "categoriesLabel": "Categorie", "emojiUnsupportedMessage": "Il tuo browser non supporta le emoji colorate.", "favoritesLabel": "Preferiti", "loadingMessage": "Caricamento...", "networkErrorMessage": "Impossibile caricare le emoji.", "regionLabel": "Selezione emoji", "searchDescription": "Quando i risultati della ricerca sono disponibili, premi su o giù per selezionare e invio per scegliere.", "searchLabel": "Cerca", "searchResultsLabel": "Risultati di ricerca", "skinToneDescription": "Quando espanso, premi su o giù per selezionare e invio per scegliere.", "skinToneLabel": "Scegli una tonalità della pelle (corrente {skinTone})", "skinTonesLabel": "Tonalità della pelle", "skinTones": ["Predefinita", "Chiara", "Medio-Chiara", "Media", "Medio-Scura", "Scura"], "categories": { "custom": "Personalizzata", "smileys-emotion": "Faccine ed emozioni", "people-body": "Persone e corpi", "animals-nature": "Animali e natura", "food-drink": "Cibi e bevande", "travel-places": "Viaggi e luoghi", "activities": "Attività", "objects": "Oggetti", "symbols": "Simboli", "flags": "Bandiere" } };
+            case "pl":
+                return { "categoriesLabel": "Kategorie", "emojiUnsupportedMessage": "Twoja przeglądarka nie wspiera kolorowych emotikon.", "favoritesLabel": "Ulubione", "loadingMessage": "Ładuję…", "networkErrorMessage": "Nie można załadować emoji.", "regionLabel": "Selektor emoji", "searchDescription": "Kiedy wyniki wyszukiwania będą dostępne, wciśnij góra lub dół aby wybrać oraz enter aby zatwierdzić wybór.", "searchLabel": "Wyszukaj", "searchResultsLabel": "Wyniki wyszukiwania", "skinToneDescription": "Po rozwinięciu wciśnij góra lub dół aby wybrać oraz enter aby zatwierdzić wybór.", "skinToneLabel": "Wybierz odcień skóry (aktualnie {skinTone})", "skinTonesLabel": "Odcienie skóry", "skinTones": ["Domyślna", "Jasna", "Średnio-jasna", "Średnia", "Średnio-ciemna", "Ciemna"], "categories": { "custom": "Własne", "smileys-emotion": "Uśmiechy", "people-body": "Ludzie", "animals-nature": "Zwierzęta i natura", "food-drink": "Żywność i napoje", "travel-places": "Podróże i miejsca", "activities": "Aktywności", "objects": "Obiekty", "symbols": "Symbole", "flags": "Flagi" } };
+            case "es":
+                return { "categoriesLabel": "Categorías", "emojiUnsupportedMessage": "El navegador no admite emojis de color.", "favoritesLabel": "Favoritos", "loadingMessage": "Cargando…", "networkErrorMessage": "No se pudo cargar el emoji.", "regionLabel": "Selector de emojis", "searchDescription": "Cuando estén disponibles los resultados, pulsa la tecla hacia arriba o hacia abajo para seleccionar y la tecla intro para elegir.", "searchLabel": "Buscar", "searchResultsLabel": "Resultados de búsqueda", "skinToneDescription": "Cuando se abran las opciones, pulsa la tecla hacia arriba o hacia abajo para seleccionar y la tecla intro para elegir.", "skinToneLabel": "Elige un tono de piel ({skinTone} es el actual)", "skinTonesLabel": "Tonos de piel", "skinTones": ["Predeterminado", "Claro", "Claro medio", "Medio", "Oscuro medio", "Oscuro"], "categories": { "custom": "Personalizado", "smileys-emotion": "Emojis y emoticones", "people-body": "Personas y partes del cuerpo", "animals-nature": "Animales y naturaleza", "food-drink": "Comida y bebida", "travel-places": "Viajes y lugares", "activities": "Actividades", "objects": "Objetos", "symbols": "Símbolos", "flags": "Banderas" } };
+            default:
+                return { "categoriesLabel": "Categories", "emojiUnsupportedMessage": "Your browser does not support color emoji.", "favoritesLabel": "Favorites", "loadingMessage": "Loading…", "networkErrorMessage": "Could not load emoji.", "regionLabel": "Emoji picker", "searchDescription": "When search results are available, press up or down to select and enter to choose.", "searchLabel": "Search", "searchResultsLabel": "Search results", "skinToneDescription": "When expanded, press up or down to select and enter to choose.", "skinToneLabel": "Choose a skin tone (currently {skinTone})", "skinTonesLabel": "Skin tones", "skinTones": ["Default", "Light", "Medium-Light", "Medium", "Medium-Dark", "Dark"], "categories": { "custom": "Custom", "smileys-emotion": "Smileys and emoticons", "people-body": "People and body", "animals-nature": "Animals and nature", "food-drink": "Food and drink", "travel-places": "Travel and places", "activities": "Activities", "objects": "Objects", "symbols": "Symbols", "flags": "Flags" } };
+        }
+    }
+});
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/EmojiPicker/woltlab-core-emoji-picker.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/EmojiPicker/woltlab-core-emoji-picker.js
new file mode 100644 (file)
index 0000000..c4b30de
--- /dev/null
@@ -0,0 +1,53 @@
+define(["require", "exports", "tslib", "emoji-picker-element/i18n/de", "emoji-picker-element/i18n/en", "emoji-picker-element/i18n/es", "emoji-picker-element/i18n/fr", "emoji-picker-element/i18n/it", "emoji-picker-element/i18n/nl", "emoji-picker-element/i18n/pl", "emoji-picker-element/i18n/pt_BR", "emoji-picker-element/i18n/pt_PT", "emoji-picker-element/i18n/ru_RU", "emoji-picker-element", "emoji-picker-element"], function (require, exports, tslib_1, de_1, en_1, es_1, fr_1, it_1, nl_1, pl_1, pt_BR_1, pt_PT_1, ru_RU_1, emoji_picker_element_1) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.WoltlabCoreEmojiPicker = void 0;
+    de_1 = tslib_1.__importDefault(de_1);
+    en_1 = tslib_1.__importDefault(en_1);
+    es_1 = tslib_1.__importDefault(es_1);
+    fr_1 = tslib_1.__importDefault(fr_1);
+    it_1 = tslib_1.__importDefault(it_1);
+    nl_1 = tslib_1.__importDefault(nl_1);
+    pl_1 = tslib_1.__importDefault(pl_1);
+    pt_BR_1 = tslib_1.__importDefault(pt_BR_1);
+    pt_PT_1 = tslib_1.__importDefault(pt_PT_1);
+    ru_RU_1 = tslib_1.__importDefault(ru_RU_1);
+    const EmojiPickerLocales = {
+        de: de_1.default,
+        en: en_1.default,
+        es: es_1.default,
+        fr: fr_1.default,
+        it: it_1.default,
+        nl: nl_1.default,
+        pl: pl_1.default,
+        "pt-br": pt_BR_1.default,
+        "pt-pt": pt_PT_1.default,
+        "ru-ru": ru_RU_1.default,
+    };
+    function getDataSource(locale) {
+        return `${window.WSC_API_URL}emoji/${locale}.json`;
+    }
+    class WoltlabCoreEmojiPicker extends emoji_picker_element_1.Picker {
+        constructor(props) {
+            const locale = (props && props.locale) || document.documentElement.lang;
+            super({
+                locale: locale,
+                ...(props || {}),
+                dataSource: getDataSource(locale),
+                ...(Object.hasOwn(EmojiPickerLocales, locale) ? { i18n: EmojiPickerLocales[locale] } : {}),
+            });
+        }
+        static get observedAttributes() {
+            return [];
+        }
+        focus() {
+            this.shadowRoot.querySelector(".search").focus();
+        }
+    }
+    exports.WoltlabCoreEmojiPicker = WoltlabCoreEmojiPicker;
+    void customElements.whenDefined("emoji-picker").then(() => {
+        customElements.define("woltlab-core-emoji-picker", WoltlabCoreEmojiPicker, {
+            extends: "emoji-picker",
+        });
+    });
+});
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Element/woltlab-core-emoji-picker.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Element/woltlab-core-emoji-picker.js
new file mode 100644 (file)
index 0000000..c4b30de
--- /dev/null
@@ -0,0 +1,53 @@
+define(["require", "exports", "tslib", "emoji-picker-element/i18n/de", "emoji-picker-element/i18n/en", "emoji-picker-element/i18n/es", "emoji-picker-element/i18n/fr", "emoji-picker-element/i18n/it", "emoji-picker-element/i18n/nl", "emoji-picker-element/i18n/pl", "emoji-picker-element/i18n/pt_BR", "emoji-picker-element/i18n/pt_PT", "emoji-picker-element/i18n/ru_RU", "emoji-picker-element", "emoji-picker-element"], function (require, exports, tslib_1, de_1, en_1, es_1, fr_1, it_1, nl_1, pl_1, pt_BR_1, pt_PT_1, ru_RU_1, emoji_picker_element_1) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.WoltlabCoreEmojiPicker = void 0;
+    de_1 = tslib_1.__importDefault(de_1);
+    en_1 = tslib_1.__importDefault(en_1);
+    es_1 = tslib_1.__importDefault(es_1);
+    fr_1 = tslib_1.__importDefault(fr_1);
+    it_1 = tslib_1.__importDefault(it_1);
+    nl_1 = tslib_1.__importDefault(nl_1);
+    pl_1 = tslib_1.__importDefault(pl_1);
+    pt_BR_1 = tslib_1.__importDefault(pt_BR_1);
+    pt_PT_1 = tslib_1.__importDefault(pt_PT_1);
+    ru_RU_1 = tslib_1.__importDefault(ru_RU_1);
+    const EmojiPickerLocales = {
+        de: de_1.default,
+        en: en_1.default,
+        es: es_1.default,
+        fr: fr_1.default,
+        it: it_1.default,
+        nl: nl_1.default,
+        pl: pl_1.default,
+        "pt-br": pt_BR_1.default,
+        "pt-pt": pt_PT_1.default,
+        "ru-ru": ru_RU_1.default,
+    };
+    function getDataSource(locale) {
+        return `${window.WSC_API_URL}emoji/${locale}.json`;
+    }
+    class WoltlabCoreEmojiPicker extends emoji_picker_element_1.Picker {
+        constructor(props) {
+            const locale = (props && props.locale) || document.documentElement.lang;
+            super({
+                locale: locale,
+                ...(props || {}),
+                dataSource: getDataSource(locale),
+                ...(Object.hasOwn(EmojiPickerLocales, locale) ? { i18n: EmojiPickerLocales[locale] } : {}),
+            });
+        }
+        static get observedAttributes() {
+            return [];
+        }
+        focus() {
+            this.shadowRoot.querySelector(".search").focus();
+        }
+    }
+    exports.WoltlabCoreEmojiPicker = WoltlabCoreEmojiPicker;
+    void customElements.whenDefined("emoji-picker").then(() => {
+        customElements.define("woltlab-core-emoji-picker", WoltlabCoreEmojiPicker, {
+            extends: "emoji-picker",
+        });
+    });
+});