From 595cdd66c7b17d3612e64b7df92edae83cb01862 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2020 19:28:19 +0100 Subject: [PATCH] :sparkles: Improve i18n module. --- docs/02-Frontend-Guide.md | 19 ++- frontend/resources/locales.json | 153 +++++++++--------- frontend/src/uxbox/main.cljs | 4 +- .../src/uxbox/main/ui/dashboard/projects.cljs | 2 +- .../src/uxbox/main/ui/profile/recovery.cljs | 20 +-- .../main/ui/profile/recovery_request.cljs | 17 +- .../main/ui/workspace/sidebar/layers.cljs | 9 +- .../main/ui/workspace/sidebar/sitemap.cljs | 6 +- frontend/src/uxbox/util/i18n.cljs | 32 ++-- frontend/translations.clj | 29 ++-- 10 files changed, 150 insertions(+), 141 deletions(-) diff --git a/docs/02-Frontend-Guide.md b/docs/02-Frontend-Guide.md index 8124474a8..294a059d1 100644 --- a/docs/02-Frontend-Guide.md +++ b/docs/02-Frontend-Guide.md @@ -79,9 +79,9 @@ The `uxbox.util.i18n/tr` is the general purpose function. This is a simple use case example: ```clojure -(require '[uxbox.util.i18n :as i18n]) +(require '[uxbox.util.i18n :refer [tr]) -(i18n/tr "auth.email-or-username") +(tr "auth.email-or-username") ;; => "Email or Username" ``` @@ -90,23 +90,26 @@ need to pass an additional parameter marked as counter in order to allow the system know when to show the plural: ```clojure -(require '[uxbox.util.i18n :as i18n]) +(require '[uxbox.util.i18n :as i18n :refer [tr]]) -(i18n/tr "ds.num-projects" (i18n/c 10)) +(tr "ds.num-projects" (i18n/c 10)) ;; => "10 projects" -(i18n/tr "ds.num-projects" (i18n/c 1)) +(tr "ds.num-projects" (i18n/c 1)) ;; => "1 project" ``` -For React components, you have `uxbox.util.i18n/use-translations` hook: +For React components, you have `uxbox.util.i18n/use-locale` hook +and the `uxbox.util.i18n/t` function: ```clojure +(require '[uxbox.util.i18n :as i18n :refer [t]]) + (mf/defc my-component [props] - (let [tr (i18n/use-translations)] + (let [locale (i18n/use-locale)] [:div - [:span (tr "auth.email-or-username")]])) + [:span (t locale "auth.email-or-username")]])) ``` You can use the general purpose function in React component but when diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json index 8f134c1ff..ee3ac7132 100644 --- a/frontend/resources/locales.json +++ b/frontend/resources/locales.json @@ -14,21 +14,21 @@ } }, "ds.color-lightbox.add" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:49", "src/uxbox/main/ui/dashboard/colors.cljs:52" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:49" ], "translations" : { "en" : "+ Add color", "fr" : "+ Ajouter couleur" } }, "ds.color-lightbox.title" : { + "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:43" ], "translations" : { "en" : null, "fr" : null - }, - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:43" ] + } }, "ds.color-new" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:146", "src/uxbox/main/ui/dashboard/colors.cljs:149" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:146" ], "translations" : { "en" : "+ New color", "fr" : "+ Nouvelle couleur" @@ -42,7 +42,7 @@ } }, "ds.colors-collection.new" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:131", "src/uxbox/main/ui/dashboard/colors.cljs:134" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:131" ], "translations" : { "en" : "+ New library", "fr" : "+ Nouvelle librairie" @@ -70,13 +70,14 @@ } }, "ds.default-library-title" : { - "used-in" : [ "src/uxbox/main/data/images.cljs:99", "src/uxbox/main/data/icons.cljs:87", "src/uxbox/main/data/colors.cljs:68" ], + "used-in" : [ "src/uxbox/main/data/colors.cljs:68", "src/uxbox/main/data/icons.cljs:87", "src/uxbox/main/data/images.cljs:99" ], "translations" : { "en" : "Unnamed Collection (%s)", "fr" : "Collection sans nom (%s)" } }, "ds.foobar" : { + "used-in" : [ ], "translations" : { "en" : null, "fr" : null @@ -147,35 +148,35 @@ } }, "ds.multiselect-bar.copy" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:221", "src/uxbox/main/ui/dashboard/colors.cljs:198", "src/uxbox/main/ui/dashboard/images.cljs:196", "src/uxbox/main/ui/dashboard/images.cljs:171", "src/uxbox/main/ui/dashboard/colors.cljs:224", "src/uxbox/main/ui/dashboard/colors.cljs:201" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:171", "src/uxbox/main/ui/dashboard/images.cljs:196", "src/uxbox/main/ui/dashboard/colors.cljs:198", "src/uxbox/main/ui/dashboard/colors.cljs:221" ], "translations" : { "en" : "Copy", "fr" : "Copier" } }, "ds.multiselect-bar.copy-to-library" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:225", "src/uxbox/main/ui/dashboard/colors.cljs:202", "src/uxbox/main/ui/dashboard/images.cljs:200", "src/uxbox/main/ui/dashboard/images.cljs:175", "src/uxbox/main/ui/dashboard/colors.cljs:228", "src/uxbox/main/ui/dashboard/colors.cljs:205" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:175", "src/uxbox/main/ui/dashboard/images.cljs:200", "src/uxbox/main/ui/dashboard/colors.cljs:202", "src/uxbox/main/ui/dashboard/colors.cljs:225" ], "translations" : { "en" : "Copy to library", "fr" : "Copier vers la librairie" } }, "ds.multiselect-bar.delete" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:214", "src/uxbox/main/ui/dashboard/images.cljs:190", "src/uxbox/main/ui/dashboard/colors.cljs:217" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:190", "src/uxbox/main/ui/dashboard/colors.cljs:214" ], "translations" : { "en" : "Delete", "fr" : "Supprimer" } }, "ds.multiselect-bar.move" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:206", "src/uxbox/main/ui/dashboard/images.cljs:179", "src/uxbox/main/ui/dashboard/colors.cljs:209" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:179", "src/uxbox/main/ui/dashboard/colors.cljs:206" ], "translations" : { "en" : "Move", "fr" : "Déplacer" } }, "ds.multiselect-bar.move-to-library" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:210", "src/uxbox/main/ui/dashboard/images.cljs:183", "src/uxbox/main/ui/dashboard/colors.cljs:213" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:183", "src/uxbox/main/ui/dashboard/colors.cljs:210" ], "translations" : { "en" : "Move to library", "fr" : "Déplacer vers la librairie" @@ -189,7 +190,7 @@ } }, "ds.new-file" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:142", "src/uxbox/main/ui/dashboard/projects.cljs:143" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:146" ], "translations" : { "en" : "+ New File", "fr" : null @@ -217,7 +218,7 @@ } }, "ds.search.placeholder" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:191", "src/uxbox/main/ui/dashboard/projects.cljs:192" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:195" ], "translations" : { "en" : "Search...", "fr" : "Rechercher..." @@ -238,7 +239,7 @@ } }, "ds.store-colors-title" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:126", "src/uxbox/main/ui/dashboard/colors.cljs:129" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:126" ], "translations" : { "en" : "COLORS STORE", "fr" : "BOUTIQUE" @@ -252,21 +253,21 @@ } }, "ds.store-images-title" : { - "used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:146", "src/uxbox/main/ui/dashboard/images.cljs:102" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:102", "src/uxbox/main/ui/workspace/images.cljs:146" ], "translations" : { "en" : "IMAGES STORE", "fr" : "BOUTIQUE" } }, "ds.updated-at" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:109", "src/uxbox/main/ui/dashboard/projects.cljs:110" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:82" ], "translations" : { - "en" : "Updated %s", - "fr" : "Mis à jour %s" + "en" : "Updated: %s", + "fr" : "Mis à jour: %s" } }, "ds.uploaded-at" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/icons.cljs:303", "src/uxbox/main/ui/dashboard/images.cljs:237" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:237", "src/uxbox/main/ui/dashboard/icons.cljs:303" ], "translations" : { "en" : "Uploaded at %s", "fr" : "Mise en ligne : %s" @@ -308,7 +309,7 @@ } }, "ds.your-colors-title" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:123", "src/uxbox/main/ui/dashboard/colors.cljs:126" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:123" ], "translations" : { "en" : "YOUR COLORS", "fr" : "VOS COULEURS" @@ -322,7 +323,7 @@ } }, "ds.your-images-title" : { - "used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:143", "src/uxbox/main/ui/dashboard/images.cljs:99" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:99", "src/uxbox/main/ui/workspace/images.cljs:143" ], "translations" : { "en" : "YOUR IMAGES", "fr" : "VOS IMAGES" @@ -336,42 +337,42 @@ } }, "errors.api.form.registration-disabled" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:39", "src/uxbox/main/ui/auth/register.cljs:39" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:39" ], "translations" : { "en" : "The registration is currently disabled.", "fr" : "L'enregistrement est actuellement désactivé." } }, "errors.api.form.unexpected-error" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:51", "src/uxbox/main/ui/auth/register.cljs:51" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:51" ], "translations" : { "en" : "An unexpected error occurred.", "fr" : "Une erreur inattendue c'est produite" } }, "errors.auth.unauthorized" : { - "used-in" : [ "src/uxbox/main/data/auth.cljs:62", "src/uxbox/main/data/auth.cljs:59" ], + "used-in" : [ "src/uxbox/main/data/auth.cljs:62" ], "translations" : { "en" : "Username or password seems to be wrong.", "fr" : "Le nom d'utilisateur ou le mot de passe semble être faux." } }, "errors.generic" : { - "used-in" : [ "src/uxbox/main/ui.cljs:127", "src/uxbox/main/ui.cljs:86" ], + "used-in" : [ "src/uxbox/main/ui.cljs:127" ], "translations" : { "en" : "Something wrong has happened.", "fr" : "Quelque chose c'est mal passé." } }, "errors.network" : { - "used-in" : [ "src/uxbox/main/ui.cljs:121", "src/uxbox/main/ui.cljs:80" ], + "used-in" : [ "src/uxbox/main/ui.cljs:121" ], "translations" : { "en" : "Unable to connect to backend server.", "fr" : "Impossible de se connecter au serveur principal." } }, "header.sitemap" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:83" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:85" ], "translations" : { "en" : null, "fr" : null @@ -427,49 +428,49 @@ } }, "login.email-or-username" : { - "used-in" : [ "src/uxbox/main/ui/login.cljs:63", "src/uxbox/main/ui/auth/login.cljs:61" ], + "used-in" : [ "src/uxbox/main/ui/login.cljs:63" ], "translations" : { "en" : "Email or Username", "fr" : "adresse email ou nom d'utilisateur" } }, "login.forgot-password" : { - "used-in" : [ "src/uxbox/main/ui/login.cljs:85", "src/uxbox/main/ui/auth/login.cljs:83" ], + "used-in" : [ "src/uxbox/main/ui/login.cljs:85" ], "translations" : { "en" : "Forgot your password?", "fr" : "Mot de passe oublié ?" } }, "login.password" : { - "used-in" : [ "src/uxbox/main/ui/login.cljs:72", "src/uxbox/main/ui/auth/login.cljs:70" ], + "used-in" : [ "src/uxbox/main/ui/login.cljs:72" ], "translations" : { "en" : "Password", "fr" : "Mot de passe" } }, "login.register" : { - "used-in" : [ "src/uxbox/main/ui/login.cljs:88", "src/uxbox/main/ui/auth/login.cljs:86" ], + "used-in" : [ "src/uxbox/main/ui/login.cljs:88" ], "translations" : { "en" : "Don't have an account?", "fr" : "Vous n'avez pas de compte ?" } }, "login.submit" : { - "used-in" : [ "src/uxbox/main/ui/login.cljs:79", "src/uxbox/main/ui/auth/login.cljs:77" ], + "used-in" : [ "src/uxbox/main/ui/login.cljs:79" ], "translations" : { "en" : "Sign in", "fr" : "Se connecter" } }, "profile.recovery.go-to-login" : { - "used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:81", "src/uxbox/main/ui/profile/recovery_request.cljs:64" ], + "used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:65", "src/uxbox/main/ui/profile/recovery.cljs:81" ], "translations" : { "en" : "Go back!", "fr" : "Retour!" } }, "profile.recovery.invalid-token" : { - "used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:45", "src/uxbox/main/data/auth.cljs:174", "src/uxbox/main/data/auth.cljs:151" ], + "used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:45" ], "translations" : { "en" : "The recovery token is invalid.", "fr" : "Le jeton de récupération n'est pas valide." @@ -483,14 +484,14 @@ } }, "profile.recovery.password-changed" : { - "used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:40", "src/uxbox/main/data/auth.cljs:178" ], + "used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:40" ], "translations" : { "en" : "Password successfully changed", "fr" : "TODO" } }, "profile.recovery.recovery-token-sent" : { - "used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:38", "src/uxbox/main/data/auth.cljs:141" ], + "used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:39" ], "translations" : { "en" : "Password recovery link sent to your inbox.", "fr" : "Lien de récupération de mot de passe envoyé." @@ -504,7 +505,7 @@ } }, "profile.recovery.submit-request" : { - "used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:59" ], + "used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:60" ], "translations" : { "en" : "Recover Password", "fr" : null @@ -518,49 +519,49 @@ } }, "profile.recovery.username-or-email" : { - "used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:53" ], + "used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:54" ], "translations" : { "en" : "Username or Email Address", "fr" : "adresse email ou nom d'utilisateur" } }, "profile.register.already-have-account" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:131", "src/uxbox/main/ui/auth/register.cljs:131" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:131" ], "translations" : { "en" : "Already have an account?", "fr" : "Vous avez déjà un compte ?" } }, "profile.register.email" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:101", "src/uxbox/main/ui/settings/profile.cljs:111", "src/uxbox/main/ui/auth/register.cljs:101" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:101" ], "translations" : { "en" : "Your email", "fr" : "Votre adresse email" } }, "profile.register.fullname" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:72", "src/uxbox/main/ui/auth/register.cljs:72" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:72" ], "translations" : { "en" : "Full Name", "fr" : "Nom complet" } }, "profile.register.get-started" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:127", "src/uxbox/main/ui/auth/register.cljs:127" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:127" ], "translations" : { "en" : "Get started", "fr" : "Commencer" } }, "profile.register.password" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:115", "src/uxbox/main/ui/auth/register.cljs:115" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:115" ], "translations" : { "en" : "Password", "fr" : "Mot de passe" } }, "profile.register.username" : { - "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:87", "src/uxbox/main/ui/settings/profile.cljs:98", "src/uxbox/main/ui/auth/register.cljs:87" ], + "used-in" : [ "src/uxbox/main/ui/profile/register.cljs:87" ], "translations" : { "en" : "Your username", "fr" : "Votre nom d'utilisateur" @@ -581,21 +582,21 @@ } }, "settings.notifications.every-day" : { - "used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:38" ], + "used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:38", "src/uxbox/main/ui/settings/notifications.cljs:38" ], "translations" : { "en" : "Every day", "fr" : "Chaque jour" } }, "settings.notifications.every-hour" : { - "used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:32" ], + "used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:32", "src/uxbox/main/ui/settings/notifications.cljs:32" ], "translations" : { "en" : "Every hour", "fr" : "Chaque heure" } }, "settings.notifications.none" : { - "used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:26" ], + "used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:26", "src/uxbox/main/ui/settings/notifications.cljs:26" ], "translations" : { "en" : "None", "fr" : "Aucune" @@ -686,11 +687,11 @@ } }, "settings.profile.your-email" : { + "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:111" ], "translations" : { "en" : null, "fr" : null - }, - "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:111" ] + } }, "settings.profile.your-name" : { "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:86" ], @@ -700,126 +701,126 @@ } }, "settings.profile.your-username" : { + "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:98" ], "translations" : { "en" : null, "fr" : null - }, - "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:98" ] + } }, "settings.update-settings" : { - "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:130", "src/uxbox/main/ui/settings/password.cljs:86", "src/uxbox/main/ui/settings/notifications.cljs:42" ], + "used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:42", "src/uxbox/main/ui/settings/password.cljs:86", "src/uxbox/main/ui/settings/profile.cljs:130" ], "translations" : { "en" : "Update settings", "fr" : "Mettre à jour les paramètres" } }, "workspace.header.canvas" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:93" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:95" ], "translations" : { "en" : "Canvas", "fr" : "Calque" } }, "workspace.header.circle" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:103" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:105" ], "translations" : { "en" : "Circle (Ctrl + E)", "fr" : "Cercle (Ctrl + E)" } }, "workspace.header.color-palette" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:123" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:125" ], "translations" : { "en" : "Color Palette (---)", "fr" : "Palette de couleurs (---)" } }, "workspace.header.curve" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:118" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:120" ], "translations" : { "en" : "Curve", "fr" : "Courbe" } }, "workspace.header.document-history" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:143" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:145" ], "translations" : { "en" : "History (Ctrl + Shift + H)", "fr" : "Historique du document (Ctrl + Maj + H)" } }, "workspace.header.download" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:156" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:158" ], "translations" : { "en" : "Download (Ctrl + E)", "fr" : "Télécharger (Ctrl + E)" } }, "workspace.header.grid" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:170" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:172" ], "translations" : { "en" : "Grid (Ctrl + G)", "fr" : "Grille (Ctrl + G)" } }, "workspace.header.grid-snap" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:175" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:177" ], "translations" : { "en" : "Snap to grid", "fr" : "Coller à la grille" } }, "workspace.header.icons" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:128" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:130" ], "translations" : { "en" : "Icons (Ctrl + Shift + I)", "fr" : "Icônes (Ctrl + Maj + I)" } }, "workspace.header.image" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:161" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:163" ], "translations" : { "en" : "Image (Ctrl + I)", "fr" : "Image (Ctrl + I)" } }, "workspace.header.path" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:113" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:115" ], "translations" : { "en" : "Path", "fr" : "Chemin" } }, "workspace.header.rect" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:98" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:100" ], "translations" : { "en" : "Box (Ctrl + B)", "fr" : "Boîte (Ctrl + B)" } }, "workspace.header.rules" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:165" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:167" ], "translations" : { "en" : "Rules", "fr" : "Règles" } }, "workspace.header.text" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:108" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:110" ], "translations" : { "en" : "Text", "fr" : "Texte" } }, "workspace.header.view-mode" : { - "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:186" ], + "used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:188" ], "translations" : { "en" : "View mode (Ctrl + P)", "fr" : "Mode visualisation (Ctrl + P)" } }, "workspace.options.color" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:81", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:124", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:47", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:125" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:47", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:124", "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:81" ], "translations" : { "en" : "Color", "fr" : "Couleur" @@ -847,7 +848,7 @@ } }, "workspace.options.grid-options" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:113" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:112" ], "translations" : { "en" : "Grid settings", "fr" : "Paramètres de la grille" @@ -861,35 +862,35 @@ } }, "workspace.options.measures" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:70", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:65", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:62", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:115" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:115", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:62", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:65", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:70" ], "translations" : { "en" : "Size, position & rotation", "fr" : "Taille, position et rotation" } }, "workspace.options.opacity" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:89", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:58" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:58", "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:89" ], "translations" : { "en" : "Opacity", "fr" : "Opacité" } }, "workspace.options.position" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:99", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:93", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:93", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:91", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:74" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:74", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:91", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:93", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:93", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:99" ], "translations" : { "en" : "Position", "fr" : "Position" } }, "workspace.options.rotation-radius" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:116", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:110", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:92" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:92", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:110", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:116" ], "translations" : { "en" : "Rotation & Radius", "fr" : "TODO" } }, "workspace.options.size" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:72", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:38", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:115" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:38", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:72" ], "translations" : { "en" : "Size", "fr" : "Taille" @@ -952,14 +953,14 @@ } }, "workspace.sidebar.layers" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/layers.cljs:261", "src/uxbox/main/ui/workspace/sidebar/layers.cljs:260" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/layers.cljs:261" ], "translations" : { "en" : "Layers", "fr" : "Couches" } }, "workspace.sidebar.sitemap" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:135", "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:134" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:135" ], "translations" : { "en" : "Sitemap", "fr" : "Plan du site" diff --git a/frontend/src/uxbox/main.cljs b/frontend/src/uxbox/main.cljs index a0e8e1582..03d80b899 100644 --- a/frontend/src/uxbox/main.cljs +++ b/frontend/src/uxbox/main.cljs @@ -30,15 +30,13 @@ ;; --- i18n (declare reinit) -(rx/sub! i18n/locale-sub #(reinit)) +;; (rx/sub! i18n/locale-sub #(reinit)) ;; --- Error Handling (defn- on-navigate [router path] (let [match (rt/match router path)] - (prn "main$on-navigate" path) - (cond (and (= path "") (:auth storage)) (st/emit! (rt/nav :dashboard-projects)) diff --git a/frontend/src/uxbox/main/ui/dashboard/projects.cljs b/frontend/src/uxbox/main/ui/dashboard/projects.cljs index 4d1c558f6..bbb5e358c 100644 --- a/frontend/src/uxbox/main/ui/dashboard/projects.cljs +++ b/frontend/src/uxbox/main/ui/dashboard/projects.cljs @@ -22,7 +22,7 @@ [uxbox.main.ui.dashboard.common :as common] [uxbox.util.data :refer [read-string]] [uxbox.util.dom :as dom] - [uxbox.util.i18n :as t :refer [tr]] + [uxbox.util.i18n :as i18n :refer [t tr]] [uxbox.util.router :as rt] [uxbox.util.time :as dt])) diff --git a/frontend/src/uxbox/main/ui/profile/recovery.cljs b/frontend/src/uxbox/main/ui/profile/recovery.cljs index 7f183587b..db07a5e52 100644 --- a/frontend/src/uxbox/main/ui/profile/recovery.cljs +++ b/frontend/src/uxbox/main/ui/profile/recovery.cljs @@ -5,8 +5,8 @@ ;; This Source Code Form is "Incompatible With Secondary Licenses", as ;; defined by the Mozilla Public License, v. 2.0. ;; -;; Copyright (c) 2015-2017 Andrey Antukh -;; Copyright (c) 2015-2017 Juan de la Cruz +;; Copyright (c) 2015-2020 Andrey Antukh +;; Copyright (c) 2015-2020 Juan de la Cruz (ns uxbox.main.ui.profile.recovery (:require @@ -23,7 +23,7 @@ [uxbox.util.messages :as um] [uxbox.util.dom :as dom] [uxbox.util.forms :as fm] - [uxbox.util.i18n :as i18n] + [uxbox.util.i18n :as i18n :refer [t]] [uxbox.util.router :as rt])) (s/def ::token ::us/not-empty-string) @@ -33,16 +33,16 @@ (mf/defc recovery-form [] (let [{:keys [data] :as form} (fm/use-form ::recovery-form {}) - tr (i18n/use-translations) + locale (i18n/use-locale) on-success (fn [] - (st/emit! (um/info (tr "profile.recovery.password-changed")) + (st/emit! (um/info (t locale "profile.recovery.password-changed")) (rt/nav :login))) on-error (fn [] - (st/emit! (um/error (tr "profile.recovery.invalid-token")))) + (st/emit! (um/error (t locale "profile.recovery.invalid-token")))) on-submit (fn [event] @@ -58,7 +58,7 @@ :class (fm/error-class form :token) :on-blur (fm/on-input-blur form :token) :on-change (fm/on-input-change form :token) - :placeholder (tr "profile.recovery.token") + :placeholder (t locale "profile.recovery.token") :auto-complete "off" :type "text"}] [:input.input-text @@ -67,18 +67,18 @@ :class (fm/error-class form :password) :on-blur (fm/on-input-blur form :password) :on-change (fm/on-input-change form :password) - :placeholder (tr "profile.recovery.password") + :placeholder (t locale "profile.recovery.password") :type "password"}] [:input.btn-primary {:name "recover" :class (when-not (:valid form) "btn-disabled") :disabled (not (:valid form)) - :value (tr "profile.recovery.submit-recover") + :value (t locale "profile.recovery.submit-recover") :type "submit"}] [:div.login-links [:a {:on-click #(st/emit! (rt/nav :login))} - (tr "profile.recovery.go-to-login")]]]])) + (t locale "profile.recovery.go-to-login")]]]])) ;; --- Recovery Request Page diff --git a/frontend/src/uxbox/main/ui/profile/recovery_request.cljs b/frontend/src/uxbox/main/ui/profile/recovery_request.cljs index c77615aa8..134c2a791 100644 --- a/frontend/src/uxbox/main/ui/profile/recovery_request.cljs +++ b/frontend/src/uxbox/main/ui/profile/recovery_request.cljs @@ -5,8 +5,8 @@ ;; This Source Code Form is "Incompatible With Secondary Licenses", as ;; defined by the Mozilla Public License, v. 2.0. ;; -;; Copyright (c) 2015-2017 Andrey Antukh -;; Copyright (c) 2015-2017 Juan de la Cruz +;; Copyright (c) 2015-2020 Andrey Antukh +;; Copyright (c) 2015-2020 Juan de la Cruz (ns uxbox.main.ui.profile.recovery-request (:require @@ -23,7 +23,7 @@ [uxbox.util.messages :as um] [uxbox.util.dom :as dom] [uxbox.util.forms :as fm] - [uxbox.util.i18n :as i18n] + [uxbox.util.i18n :as i18n :refer [t]] [uxbox.util.router :as rt])) (s/def ::username ::us/not-empty-string) @@ -32,10 +32,11 @@ (mf/defc recovery-form [] (let [{:keys [data] :as form} (fm/use-form ::recovery-request-form {}) - tr (i18n/use-translations) + locale (i18n/use-locale) + on-success (fn [] - (st/emit! (um/info (tr "profile.recovery.recovery-token-sent")) + (st/emit! (um/info (t locale "profile.recovery.recovery-token-sent")) (rt/nav :profile-recovery))) on-submit @@ -50,18 +51,18 @@ :class (fm/error-class form :username) :on-blur (fm/on-input-blur form :username) :on-change (fm/on-input-change form :username) - :placeholder (tr "profile.recovery.username-or-email") + :placeholder (t locale "profile.recovery.username-or-email") :type "text"}] [:input.btn-primary {:name "login" :class (when-not (:valid form) "btn-disabled") :disabled (not (:valid form)) - :value (tr "profile.recovery.submit-request") + :value (t locale "profile.recovery.submit-request") :type "submit"}] [:div.login-links [:a {:on-click #(st/emit! (rt/nav :login))} - (tr "profile.recovery.go-to-login")]]]])) + (t locale "profile.recovery.go-to-login")]]]])) ;; --- Recovery Request Page diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs index 1a6d0a2c2..e98fbbeb9 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs @@ -18,7 +18,7 @@ [uxbox.main.ui.workspace.sortable :refer [use-sortable]] [uxbox.util.data :refer [classnames enumerate]] [uxbox.util.dom :as dom] - [uxbox.util.i18n :as i18n])) + [uxbox.util.i18n :as i18n :refer [t]])) (def ^:private shapes-iref (-> (l/key :shapes) @@ -235,7 +235,7 @@ (mf/defc layers-toolbox [{:keys [page] :as props}] - (let [tr (i18n/use-translations) + (let [locale (i18n/use-locale) on-click #(st/emit! (dw/toggle-layout-flag :layers)) selected (mf/deref refs/selected-shapes) @@ -258,9 +258,8 @@ [:div#layers.tool-window [:div.tool-window-bar [:div.tool-window-icon i/layers] - [:span (tr "workspace.sidebar.layers")] - ;; [:div.tool-window-close {:on-click on-click} i/close] - ] + [:span (t locale "workspace.sidebar.layers")] + #_[:div.tool-window-close {:on-click on-click} i/close]] [:div.tool-window-content [:& canvas-list {:canvas canvas :shapes all-shapes diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs index 340b4e32c..e09f924a4 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs @@ -21,7 +21,7 @@ [uxbox.main.ui.workspace.sortable :refer [use-sortable]] [uxbox.util.data :refer [classnames enumerate]] [uxbox.util.dom :as dom] - [uxbox.util.i18n :as i18n :refer [tr]] + [uxbox.util.i18n :as i18n :refer [t]] [uxbox.util.router :as rt])) ;; --- Page Item @@ -129,10 +129,10 @@ (mf/defc sitemap-toolbox [{:keys [file page] :as props}] (let [on-create-click #(st/emit! dp/create-empty-page) - tr (i18n/use-translations)] + locale (i18n/use-locale)] [:div.sitemap.tool-window [:div.tool-window-bar - [:span (tr "workspace.sidebar.sitemap")] + [:span (t locale "workspace.sidebar.sitemap")] [:div.add-page {:on-click on-create-click} i/close]] [:div.tool-window-content [:& pages-list {:file file :current-page page}]]])) diff --git a/frontend/src/uxbox/util/i18n.cljs b/frontend/src/uxbox/util/i18n.cljs index 4ec8d453d..099cdf803 100644 --- a/frontend/src/uxbox/util/i18n.cljs +++ b/frontend/src/uxbox/util/i18n.cljs @@ -48,7 +48,16 @@ [r] (instance? C r)) -(defn- internal-tr +;; A main public api for translate strings. + +;; A marker type that is used just for mark +;; a parameter that reprsentes the counter. + +(defn c + [x] + (C. x)) + +(defn t ([locale code] (let [code (name code) value (gobj/getValueByKeys translations code locale) @@ -66,27 +75,16 @@ value)] (apply str/format value (map #(if (c? %) @% %) args))))) -;; A main public api for translate strings. - -;; A marker type that is used just for mark -;; a parameter that reprsentes the counter. - -(defn c - [x] - (C. x)) - (defn tr - ([code] (internal-tr locale code)) - ([code & args] (apply internal-tr locale code args))) + ([code] (t locale code)) + ([code & args] (apply t locale code args))) -(defn use-translations +(defn use-locale [] - (let [[locale set-locale] (mf/useState locale) - tr-fn (mf/useMemo (fn [] (partial internal-tr locale)) - #js [locale])] + (let [[locale set-locale] (mf/useState locale)] (mf/useEffect (fn [] (let [sub (rx/sub! locale-sub #(set-locale %))] #(rx/dispose! sub))) #js []) - tr-fn)) + locale)) diff --git a/frontend/translations.clj b/frontend/translations.clj index be5db53ef..48d122137 100644 --- a/frontend/translations.clj +++ b/frontend/translations.clj @@ -30,11 +30,21 @@ (->> form (walk/postwalk (fn [fm] - (when (and (list? fm) - (= (first fm) 'tr) - (string? (second fm))) + (cond + (and (list? fm) + (= (first fm) 'tr) + (string? (second fm))) (let [m (meta (first fm))] (swap! env conj {:code (second fm) + :file (:file m) + :line (:line m)})) + + (and (list? fm) + (= (first fm) 't) + (symbol? (second fm))) + (let [m (meta (first fm)) + code (first (drop 2 fm))] + (swap! env conj {:code code :file (:file m) :line (:line m)}))) fm)))) @@ -99,9 +109,7 @@ state (-> state (dissoc "unused") - (assoc "used-in" (->> (get state "used-in" []) - (remove #(= rpath %)) - (into [rpath]))))))) + (update "used-in" conj rpath))))) (assoc data code {"translations" {"en" nil "fr" nil} "used-in" [rpath]})))) @@ -118,18 +126,19 @@ data toremove))) -(defn- ensure-translations-format +(defn- initial-cleanup [data] (reduce-kv (fn [data k v] (if (string? v) - (assoc data k {:translations {:en v}}) - data)) + (assoc data k {"used-in" [] + "translations" {:en v}}) + (update data k assoc "used-in" []))) data data)) (defn- synchronize-translations [data translations] - (loop [data (ensure-translations-format data) + (loop [data (initial-cleanup data) imported #{} c (first translations) r (rest translations)]