From 406157c06c5c0d1fac883d6456c290507c469c40 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 24 Jul 2019 00:48:24 +0200 Subject: [PATCH] :recycle: Refactor profile & language loading. --- frontend/src/uxbox/config.cljs | 1 + frontend/src/uxbox/main.cljs | 22 +++++++------- frontend/src/uxbox/main/data/auth.cljs | 18 +++++++++--- frontend/src/uxbox/main/data/users.cljs | 29 ++++++++++++------- .../src/uxbox/main/ui/settings/profile.cljs | 28 ++++++++++-------- frontend/src/uxbox/util/i18n.cljs | 9 ++++-- frontend/src/uxbox/util/storage.cljs | 6 +++- 7 files changed, 74 insertions(+), 39 deletions(-) diff --git a/frontend/src/uxbox/config.cljs b/frontend/src/uxbox/config.cljs index 87881c1dd..ad4bf358c 100644 --- a/frontend/src/uxbox/config.cljs +++ b/frontend/src/uxbox/config.cljs @@ -9,3 +9,4 @@ (goog-define url "http://127.0.0.1:6060/api") (goog-define viewurl "/view/index.html") (goog-define isdemo false) +(goog-define default-language "en") diff --git a/frontend/src/uxbox/main.cljs b/frontend/src/uxbox/main.cljs index 5f0098767..0571d053b 100644 --- a/frontend/src/uxbox/main.cljs +++ b/frontend/src/uxbox/main.cljs @@ -6,7 +6,7 @@ (ns ^:figwheel-hooks uxbox.main (:require - [rumext.core :as mx] + [rumext.alpha :as mf] [uxbox.main.data.auth :refer [logout]] [uxbox.main.data.users :as udu] [uxbox.main.locales.en :as en] @@ -20,6 +20,7 @@ [uxbox.util.i18n :as i18n :refer [tr]] [uxbox.util.messages :as uum] [uxbox.util.router :as rt] + [uxbox.util.storage :refer [storage]] [uxbox.util.timers :as ts])) ;; --- i18n @@ -28,8 +29,8 @@ (i18n/update-locales! (fn [locales] (-> locales - (assoc :en en/locales) - (assoc :fr fr/locales)))) + (assoc "en" en/locales) + (assoc "fr" fr/locales)))) (i18n/on-locale-change! (fn [new old] @@ -60,11 +61,12 @@ (st/emit! #(assoc % :router router)) (add-watch html-history/path ::main #(on-navigate router %4)) - (st/emit! (udu/fetch-profile)) + (when (:auth storage) + (st/emit! (udu/fetch-profile))) - (mx/mount (ui/app) (dom/get-element "app")) - (mx/mount (lightbox) (dom/get-element "lightbox")) - (mx/mount (loader) (dom/get-element "loader")) + (mf/mount (ui/app) (dom/get-element "app")) + (mf/mount (lightbox) (dom/get-element "lightbox")) + (mf/mount (loader) (dom/get-element "loader")) (on-navigate router cpath))) @@ -76,9 +78,9 @@ (defn reinit [] (remove-watch html-history/path ::main) - (.unmountComponentAtNode js/ReactDOM (dom/get-element "app")) - (.unmountComponentAtNode js/ReactDOM (dom/get-element "lightbox")) - (.unmountComponentAtNode js/ReactDOM (dom/get-element "loader")) + (mf/unmount (dom/get-element "app")) + (mf/unmount (dom/get-element "lightbox")) + (mf/unmount (dom/get-element "loader")) (init-ui)) (defn ^:after-load after-load diff --git a/frontend/src/uxbox/main/data/auth.cljs b/frontend/src/uxbox/main/data/auth.cljs index 63a87ef28..eb05e6cbf 100644 --- a/frontend/src/uxbox/main/data/auth.cljs +++ b/frontend/src/uxbox/main/data/auth.cljs @@ -16,7 +16,7 @@ [uxbox.util.messages :as uum] [uxbox.util.router :as rt] [uxbox.util.spec :as us] - [uxbox.util.i18n :refer (tr)] + [uxbox.util.i18n :as i18n :refer [tr]] [uxbox.util.storage :refer [storage]])) (s/def ::username string?) @@ -74,16 +74,26 @@ ;; --- Logout -(defrecord Logout [] +(defrecord ClearUserData [] ptk/UpdateEvent (update [_ state] - (swap! storage dissoc :auth) (merge state (dissoc initial-state :route :router))) ptk/WatchEvent (watch [_ state s] (->> (rp/req :auth/logout) - (rx/map (constantly (rt/nav :auth/login)))))) + (rx/ignore))) + + ptk/EffectEvent + (effect [_ state s] + (reset! storage {}) + (i18n/set-default-locale!))) + +(defrecord Logout [] + ptk/WatchEvent + (watch [_ state s] + (rx/of (rt/nav :auth/login) + (->ClearUserData)))) (defn logout [] diff --git a/frontend/src/uxbox/main/data/users.cljs b/frontend/src/uxbox/main/data/users.cljs index 5043f2dbc..639fbebf0 100644 --- a/frontend/src/uxbox/main/data/users.cljs +++ b/frontend/src/uxbox/main/data/users.cljs @@ -10,7 +10,7 @@ [cljs.spec.alpha :as s] [potok.core :as ptk] [uxbox.main.repo :as rp] - [uxbox.util.i18n :refer (tr)] + [uxbox.util.i18n :as i18n :refer (tr)] [uxbox.util.messages :as uum] [uxbox.util.spec :as us] [uxbox.util.storage :refer [storage]])) @@ -24,7 +24,10 @@ ptk/EffectEvent (effect [this state stream] - (swap! storage assoc :profile data))) + (swap! storage assoc :profile data) + ;; (prn "profile-fetched" data) + (when-let [lang (get-in data [:metadata :language])] + (i18n/set-current-locale! lang)))) (defn profile-fetched [data] @@ -63,22 +66,28 @@ (letfn [(handle-error [{payload :payload}] (on-error payload) (rx/empty))] - (->> (rp/req :update/profile data) - (rx/map :payload) - (rx/do on-success) - (rx/map profile-updated) - (rx/catch rp/client-error? handle-error))))) + (let [data (-> (:profile state) + (assoc :fullname (:fullname data)) + (assoc :email (:email data)) + (assoc :username (:username data)) + (assoc-in [:metadata :language] (:language data)))] + (prn "update-profile" data) + (->> (rp/req :update/profile data) + (rx/map :payload) + (rx/do on-success) + (rx/map profile-updated) + (rx/catch rp/client-error? handle-error)))))) (s/def ::fullname string?) (s/def ::email us/email?) (s/def ::username string?) -(s/def ::theme string?) +(s/def ::language string?) (s/def ::update-profile (s/keys :req-un [::fullname ::email - ::username - ::theme])) + ::language + ::username])) (defn update-profile [data on-success on-error] diff --git a/frontend/src/uxbox/main/ui/settings/profile.cljs b/frontend/src/uxbox/main/ui/settings/profile.cljs index e8857d2ea..e2036ff69 100644 --- a/frontend/src/uxbox/main/ui/settings/profile.cljs +++ b/frontend/src/uxbox/main/ui/settings/profile.cljs @@ -28,17 +28,26 @@ (def assoc-error (partial fm/assoc-error :profile)) (def clear-form (partial fm/clear-form :profile)) +(defn profile->form + [profile] + (let [language (get-in profile [:metadata :language])] + (-> (select-keys profile [:fullname :username :email]) + (cond-> language (assoc :language language))))) + (def profile-ref - (-> (l/key :profile) + (-> (comp (l/key :profile) + (l/lens profile->form)) (l/derive st/state))) (s/def ::fullname ::fm/non-empty-string) (s/def ::username ::fm/non-empty-string) (s/def ::email ::fm/email) +(s/def ::language #{"en" "fr"}) (s/def ::profile-form (s/keys :req-un [::fullname ::username + ::language ::email])) (defn- on-error @@ -61,18 +70,13 @@ :mixins [mf/memo mf/reactive mf/sync-render (fm/clear-mixin st/store :profile)] :render (fn [own props] - (let [data (merge {:theme "light"} + (let [data (merge {:language @i18n/locale} (mf/react profile-ref) (mf/react form-data)) errors (mf/react form-errors) valid? (fm/valid? ::profile-form data) - theme (:theme data) on-success #(st/emit! (clear-form)) - on-submit #(st/emit! (udu/update-profile data on-success on-error)) - on-lang-change (fn [event] - (let [lang (read-string (dom/event->value event))] - (prn "on-lang-change" lang) - (i18n/set-current-locale! lang)))] + on-submit #(st/emit! (udu/update-profile data on-success on-error))] [:form.profile-form [:span.user-settings-label (tr "settings.profile.section-basic-data")] [:input.input-text @@ -94,10 +98,10 @@ (fm/input-error errors :email) [:span.user-settings-label (tr "settings.profile.section-i18n-data")] - [:select.input-select {:value (pr-str (mf/deref i18n/locale)) - :on-change on-lang-change} - [:option {:value ":en"} "English"] - [:option {:value ":fr"} "Français"]] + [:select.input-select {:value (:language data) + :on-change #(on-field-change % :language)} + [:option {:value "en"} "English"] + [:option {:value "fr"} "Français"]] [:input.btn-primary {:type "button" diff --git a/frontend/src/uxbox/util/i18n.cljs b/frontend/src/uxbox/util/i18n.cljs index 6b4793d26..e1e91839b 100644 --- a/frontend/src/uxbox/util/i18n.cljs +++ b/frontend/src/uxbox/util/i18n.cljs @@ -8,11 +8,16 @@ (ns uxbox.util.i18n "A i18n foundation." (:require [cuerdas.core :as str] - [uxbox.util.storage :refer (storage)])) + [uxbox.config :as cfg] + [uxbox.util.storage :refer [storage]])) -(defonce locale (atom (get storage ::locale :en))) +(defonce locale (atom (get storage ::locale cfg/default-language))) (defonce state (atom {})) +(defn set-default-locale! + [] + (set-current-locale! cfg/default-language)) + (defn update-locales! [callback] (swap! state callback)) diff --git a/frontend/src/uxbox/util/storage.cljs b/frontend/src/uxbox/util/storage.cljs index 264a68ba3..890f36d52 100644 --- a/frontend/src/uxbox/util/storage.cljs +++ b/frontend/src/uxbox/util/storage.cljs @@ -30,6 +30,10 @@ (when (not= *target* "nodejs") (add-watch data :sub #(persist alias %4))) (reify + Object + (toString [_] + (str "Storage" (pr-str @data))) + ICounted (-count [_] (count @data)) @@ -40,7 +44,7 @@ IReset (-reset! [self newval] - (-reset! data newval)) + (reset! data newval)) ISwap (-swap! [self f]