mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 10:46:38 +02:00
Refactor settings pages and add tha ability to change current locale.
This commit is contained in:
parent
76726b6cd2
commit
14d97511e6
12 changed files with 182 additions and 169 deletions
|
@ -22,8 +22,6 @@
|
||||||
[uxbox.util.router :as rt]
|
[uxbox.util.router :as rt]
|
||||||
[uxbox.util.timers :as ts]))
|
[uxbox.util.timers :as ts]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; --- i18n
|
;; --- i18n
|
||||||
|
|
||||||
(declare reinit)
|
(declare reinit)
|
||||||
|
|
|
@ -119,7 +119,8 @@
|
||||||
"settings.exit" "EXIT"
|
"settings.exit" "EXIT"
|
||||||
|
|
||||||
"settings.profile.profile-saved" "Profile saved successfully!"
|
"settings.profile.profile-saved" "Profile saved successfully!"
|
||||||
"settings.profile.profile.profile-saved" "Name, username and email"
|
"settings.profile.section-basic-data" "Name, username and email"
|
||||||
|
"settings.profile.section-i18n-data" "Default language"
|
||||||
"settings.profile.your-name" "Your name"
|
"settings.profile.your-name" "Your name"
|
||||||
"settings.profile.your-username" "Your username"
|
"settings.profile.your-username" "Your username"
|
||||||
"settings.profile.your-email" "Your email"
|
"settings.profile.your-email" "Your email"
|
||||||
|
|
|
@ -119,7 +119,9 @@
|
||||||
"settings.exit" "QUITTER"
|
"settings.exit" "QUITTER"
|
||||||
|
|
||||||
"settings.profile.profile-saved" "Profil enregistré avec succès !"
|
"settings.profile.profile-saved" "Profil enregistré avec succès !"
|
||||||
"settings.profile.profile.profile-saved" "Nom, nom d'utilisateur et adresse email"
|
"settings.profile.section-basic-data" "Nom, nom d'utilisateur et adresse email"
|
||||||
|
"settings.profile.section-i18n-data" nil ;; TODO
|
||||||
|
|
||||||
"settings.profile.your-name" "Votre nom complet"
|
"settings.profile.your-name" "Votre nom complet"
|
||||||
"settings.profile.your-username" "Votre nom d'utilisateur"
|
"settings.profile.your-username" "Votre nom d'utilisateur"
|
||||||
"settings.profile.your-email" "Votre adresse email"
|
"settings.profile.your-email" "Votre adresse email"
|
||||||
|
|
|
@ -91,9 +91,9 @@
|
||||||
(uuid-str? id) (uuid id)
|
(uuid-str? id) (uuid id)
|
||||||
:else nil)
|
:else nil)
|
||||||
type (when (str/alpha? type) (keyword type))]
|
type (when (str/alpha? type) (keyword type))]
|
||||||
{:section section
|
#js {:section section
|
||||||
:id id
|
:id id
|
||||||
:type type}))
|
:type type}))
|
||||||
|
|
||||||
|
|
||||||
(mf/def app
|
(mf/def app
|
||||||
|
@ -105,9 +105,10 @@
|
||||||
|
|
||||||
:render
|
:render
|
||||||
(fn [own props]
|
(fn [own props]
|
||||||
(let [route (mx/react (::route-ref own))]
|
(let [route (mx/react (::route-ref own))
|
||||||
(case (get-in route [:data :name])
|
route-id (get-in route [:data :name])]
|
||||||
:auth/login (mf/element auth/login-page)
|
(case route-id
|
||||||
|
:auth/login (mf/elem auth/login-page)
|
||||||
:auth/register (auth/register-page)
|
:auth/register (auth/register-page)
|
||||||
:auth/recovery-request (auth/recovery-request-page)
|
:auth/recovery-request (auth/recovery-request-page)
|
||||||
|
|
||||||
|
@ -115,17 +116,22 @@
|
||||||
(let [token (get-in route [:params :path :token])]
|
(let [token (get-in route [:params :path :token])]
|
||||||
(auth/recovery-page token))
|
(auth/recovery-page token))
|
||||||
|
|
||||||
:settings/profile (mf/element settings/profile-page)
|
(:settings/profile
|
||||||
:settings/password (settings/password-page)
|
:settings/password
|
||||||
:settings/notifications (settings/notifications-page)
|
:settings/notifications)
|
||||||
|
(mf/elem settings/settings {:route route})
|
||||||
|
|
||||||
:dashboard/projects (dashboard/dashboard {:section :projects})
|
;; :settings/profile (mf/elem settings/settings {:section :profile})
|
||||||
:dashboard/icons (-> (parse-dashboard-params route :icons)
|
;; :settings/password (mf/elem settings/settings {:section :password})
|
||||||
(dashboard/dashboard))
|
;; :settings/notifications (mf/elem settings/notifications-page)
|
||||||
:dashboard/images (-> (parse-dashboard-params route :images)
|
|
||||||
(dashboard/dashboard))
|
:dashboard/projects (mf/elem dashboard/dashboard {:section :projects})
|
||||||
:dashboard/colors (-> (parse-dashboard-params route :colors)
|
:dashboard/icons (->> (parse-dashboard-params route :icons)
|
||||||
(dashboard/dashboard))
|
(mf/element dashboard/dashboard))
|
||||||
|
:dashboard/images (->> (parse-dashboard-params route :images)
|
||||||
|
(mf/element dashboard/dashboard))
|
||||||
|
:dashboard/colors (->> (parse-dashboard-params route :colors)
|
||||||
|
(mf/element dashboard/dashboard))
|
||||||
:workspace/page
|
:workspace/page
|
||||||
(let [project (uuid (get-in route [:params :path :project]))
|
(let [project (uuid (get-in route [:params :path :project]))
|
||||||
page (uuid (get-in route [:params :path :page]))]
|
page (uuid (get-in route [:params :path :page]))]
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
" the projects will be periodicaly wiped."]])
|
" the projects will be periodicaly wiped."]])
|
||||||
|
|
||||||
(mf/defc login-form
|
(mf/defc login-form
|
||||||
{:wrap [mf/reactive]}
|
{:wrap [mf/reactive*]}
|
||||||
[]
|
[]
|
||||||
(let [data (mf/react form-data)
|
(let [data (mf/react form-data)
|
||||||
valid? (fm/valid? ::login-form data)]
|
valid? (fm/valid? ::login-form data)]
|
||||||
|
|
|
@ -6,17 +6,29 @@
|
||||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
(ns uxbox.main.ui.settings
|
(ns uxbox.main.ui.settings
|
||||||
(:require [cuerdas.core :as str]
|
(:require
|
||||||
[potok.core :as ptk]
|
[cuerdas.core :as str]
|
||||||
[rumext.core :as mx :include-macros true]
|
[potok.core :as ptk]
|
||||||
[uxbox.builtins.icons :as i]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.util.router :as r]
|
[uxbox.main.ui.messages :refer [messages-widget]]
|
||||||
[uxbox.main.ui.settings.profile :as profile]
|
[uxbox.main.ui.settings.header :refer [header]]
|
||||||
[uxbox.main.ui.settings.password :as password]
|
[uxbox.main.ui.settings.notifications :as notifications]
|
||||||
[uxbox.main.ui.settings.notifications :as notifications]
|
[uxbox.main.ui.settings.password :as password]
|
||||||
[uxbox.main.ui.dashboard.header :refer (header)]))
|
[uxbox.main.ui.settings.profile :as profile]))
|
||||||
|
|
||||||
|
(mf/defc settings
|
||||||
|
{:wrap [mf/memo*]}
|
||||||
|
[{:keys [route] :as props}]
|
||||||
|
(let [section (get-in route [:data :name])]
|
||||||
|
[:main.dashboard-main
|
||||||
|
(messages-widget)
|
||||||
|
[:& header {:section section}]
|
||||||
|
(case section
|
||||||
|
:settings/profile (mf/elem profile/profile-page)
|
||||||
|
:settings/password (mf/elem password/password-page)
|
||||||
|
:settings/notifications (mf/elem notifications/notifications-page))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(def profile-page profile/profile-page)
|
|
||||||
(def password-page password/password-page)
|
|
||||||
(def notifications-page notifications/notifications-page)
|
|
||||||
|
|
|
@ -18,39 +18,33 @@
|
||||||
[uxbox.util.i18n :refer [tr]]
|
[uxbox.util.i18n :refer [tr]]
|
||||||
[uxbox.util.router :as rt]))
|
[uxbox.util.router :as rt]))
|
||||||
|
|
||||||
(def ^:private section-ref
|
|
||||||
(-> (l/in [:route :id])
|
|
||||||
(l/derive st/state)))
|
|
||||||
|
|
||||||
(mf/defc header-link
|
(mf/defc header-link
|
||||||
[{:keys [section content] :as props}]
|
[{:keys [section content] :as props}]
|
||||||
(let [on-click #(st/emit! (rt/nav section))]
|
(let [on-click #(st/emit! (rt/nav section))]
|
||||||
[:a {:on-click on-click} content]))
|
[:a {:on-click on-click} content]))
|
||||||
|
|
||||||
(mf/def header
|
(mf/defc header
|
||||||
:mixins [mf/static mf/reactive]
|
{:wrap [mf/memo*]}
|
||||||
:render
|
[{:keys [section] :as props}]
|
||||||
(fn [own props]
|
(let [profile? (= section :settings/profile)
|
||||||
(let [section (mf/react section-ref)
|
password? (= section :settings/password)
|
||||||
profile? (= section :settings/profile)
|
notifications? (= section :settings/notifications)]
|
||||||
password? (= section :settings/password)
|
[:header#main-bar.main-bar
|
||||||
notifications? (= section :settings/notifications)]
|
[:div.main-logo
|
||||||
[:header#main-bar.main-bar
|
[:& header-link {:section :dashboard/projects
|
||||||
[:div.main-logo
|
:content i/logo}]]
|
||||||
[:& header-link {:section :dashboard/projects
|
[:ul.main-nav
|
||||||
:content i/logo}]]
|
[:li {:class (when profile? "current")}
|
||||||
[:ul.main-nav
|
[:& header-link {:section :settings/profile
|
||||||
[:li {:class (when profile? "current")}
|
:content (tr "settings.profile")}]]
|
||||||
[:& header-link {:setion :settings/profile
|
[:li {:class (when password? "current")}
|
||||||
:content (tr "settings.profile")}]]
|
[:& header-link {:section :settings/password
|
||||||
[:li {:class (when password? "current")}
|
:content (tr "settings.password")}]]
|
||||||
[:& header-link {:section :settings/password
|
[:li {:class (when notifications? "current")}
|
||||||
:content (tr "settings.password")}]]
|
[:& header-link {:section :settings/notifications
|
||||||
[:li {:class (when notifications? "current")}
|
:content (tr "settings.notifications")}]]
|
||||||
[:& header-link {:section :settings/notifications
|
#_[:li {:on-click #(st/emit! (da/logout))}
|
||||||
:content (tr "settings.notifications")}]]
|
[:& header-link {:section :auth/login
|
||||||
[:li {:on-click #(st/emit! (da/logout))}
|
:content (tr "settings.exit")}]]]
|
||||||
[:& header-link {:section :auth/login
|
[:& user]]))
|
||||||
:content (tr "settings.exit")}]]]
|
|
||||||
(user)])))
|
|
||||||
|
|
||||||
|
|
|
@ -6,45 +6,38 @@
|
||||||
;; Copyright (c) 2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
(ns uxbox.main.ui.settings.notifications
|
(ns uxbox.main.ui.settings.notifications
|
||||||
(:require [cuerdas.core :as str]
|
(:require
|
||||||
[uxbox.util.router :as r]
|
[cuerdas.core :as str]
|
||||||
[potok.core :as ptk]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.util.i18n :refer [tr]]))
|
||||||
[rumext.core :as mx :include-macros true]
|
|
||||||
[uxbox.util.i18n :refer [tr]]
|
|
||||||
[uxbox.util.dom :as dom]
|
|
||||||
[uxbox.main.ui.settings.header :refer (header)]))
|
|
||||||
|
|
||||||
(mx/defc notifications-page
|
(mf/defc notifications-page
|
||||||
{:mixins [mx/static]}
|
[]
|
||||||
[own]
|
[:section.dashboard-content.user-settings
|
||||||
[:main.dashboard-main
|
[:section.user-settings-content
|
||||||
(header)
|
[:span.user-settings-label (tr "settings.notifications.notifications-saved")]
|
||||||
[:section.dashboard-content.user-settings
|
[:p (tr "settings.notifications.description")]
|
||||||
[:section.user-settings-content
|
[:div.input-radio.radio-primary
|
||||||
[:span.user-settings-label (tr "settings.notifications.notifications-saved")]
|
[:input {:type "radio"
|
||||||
[:p (tr "settings.notifications.description")]
|
:id "notification-1"
|
||||||
[:div.input-radio.radio-primary
|
:name "notification"
|
||||||
[:input {:type "radio"
|
:value "none"}]
|
||||||
:id "notification-1"
|
[:label {:for "notification-1"
|
||||||
:name "notification"
|
:value (tr "settings.notifications.none")} (tr "settings.notifications.none")]
|
||||||
:value "none"}]
|
[:input {:type "radio"
|
||||||
[:label {:for "notification-1"
|
:id "notification-2"
|
||||||
:value (tr "settings.notifications.none")} (tr "settings.notifications.none")]
|
:name "notification"
|
||||||
[:input {:type "radio"
|
:value "every-hour"}]
|
||||||
:id "notification-2"
|
[:label {:for "notification-2"
|
||||||
:name "notification"
|
:value (tr "settings.notifications.every-hour")} (tr "settings.notifications.every-hour")]
|
||||||
:value "every-hour"}]
|
[:input {:type "radio"
|
||||||
[:label {:for "notification-2"
|
:id "notification-3"
|
||||||
:value (tr "settings.notifications.every-hour")} (tr "settings.notifications.every-hour")]
|
:name "notification"
|
||||||
[:input {:type "radio"
|
:value "every-day"}]
|
||||||
:id "notification-3"
|
[:label {:for "notification-3"
|
||||||
:name "notification"
|
:value (tr "settings.notifications.every-day")} (tr "settings.notifications.every-day")]]
|
||||||
:value "every-day"}]
|
[:input.btn-primary {:type "submit"
|
||||||
[:label {:for "notification-3"
|
:class "btn-disabled"
|
||||||
:value (tr "settings.notifications.every-day")} (tr "settings.notifications.every-day")]]
|
:disabled true
|
||||||
[:input.btn-primary {:type "submit"
|
:value (tr "settings.update-settings")}]
|
||||||
:class "btn-disabled"
|
]])
|
||||||
:disabled true
|
|
||||||
:value (tr "settings.update-settings")}]
|
|
||||||
]]])
|
|
||||||
|
|
|
@ -94,11 +94,7 @@
|
||||||
;; --- Password Page
|
;; --- Password Page
|
||||||
|
|
||||||
(mx/defc password-page
|
(mx/defc password-page
|
||||||
{:mixins [mx/static]}
|
|
||||||
[]
|
[]
|
||||||
[:main.dashboard-main
|
[:section.dashboard-content.user-settings
|
||||||
(messages-widget)
|
[:section.user-settings-content
|
||||||
(header)
|
(password-form)]])
|
||||||
[:section.dashboard-content.user-settings
|
|
||||||
[:section.user-settings-content
|
|
||||||
(password-form)]]])
|
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.ui.messages :refer [messages-widget]]
|
||||||
[uxbox.main.ui.settings.header :refer [header]]
|
[uxbox.main.ui.settings.header :refer [header]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.util.data :refer [read-string]]
|
||||||
[uxbox.util.forms :as fm]
|
[uxbox.util.forms :as fm]
|
||||||
[uxbox.util.i18n :refer [tr]]
|
[uxbox.util.i18n :as i18n :refer [tr]]
|
||||||
[uxbox.util.interop :refer [iterable->seq]]
|
[uxbox.util.interop :refer [iterable->seq]]
|
||||||
[uxbox.util.router :as r]
|
[uxbox.util.router :as r]))
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
(def form-data (fm/focus-data :profile st/state))
|
(def form-data (fm/focus-data :profile st/state))
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
|
|
||||||
;; --- Profile Form
|
;; --- Profile Form
|
||||||
(mf/def profile-form
|
(mf/def profile-form
|
||||||
:mixins [mf/static mf/reactive mf/sync-render (fm/clear-mixin st/store :profile)]
|
:mixins [mf/memo mf/reactive mf/sync-render (fm/clear-mixin st/store :profile)]
|
||||||
:render
|
:render
|
||||||
(fn [own props]
|
(fn [own props]
|
||||||
(let [data (merge {:theme "light"}
|
(let [data (merge {:theme "light"}
|
||||||
|
@ -73,9 +73,13 @@
|
||||||
valid? (fm/valid? ::profile-form data)
|
valid? (fm/valid? ::profile-form data)
|
||||||
theme (:theme data)
|
theme (:theme data)
|
||||||
on-success #(st/emit! (clear-form))
|
on-success #(st/emit! (clear-form))
|
||||||
on-submit #(st/emit! (udu/update-profile data on-success on-error))]
|
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)))]
|
||||||
[:form.profile-form
|
[:form.profile-form
|
||||||
[:span.user-settings-label (tr "settings.profile.profile.profile-saved")]
|
[:span.user-settings-label (tr "settings.profile.section-basic-data")]
|
||||||
[:input.input-text
|
[:input.input-text
|
||||||
{:type "text"
|
{:type "text"
|
||||||
:on-change #(on-field-change % :fullname)
|
:on-change #(on-field-change % :fullname)
|
||||||
|
@ -87,7 +91,6 @@
|
||||||
:value (:username data "")
|
:value (:username data "")
|
||||||
:placeholder (tr "settings.profile.your-username")}]
|
:placeholder (tr "settings.profile.your-username")}]
|
||||||
(fm/input-error errors :username)
|
(fm/input-error errors :username)
|
||||||
|
|
||||||
[:input.input-text
|
[:input.input-text
|
||||||
{:type "email"
|
{:type "email"
|
||||||
:on-change #(on-field-change % :email)
|
:on-change #(on-field-change % :email)
|
||||||
|
@ -95,6 +98,12 @@
|
||||||
:placeholder (tr "settings.profile.your-email")}]
|
:placeholder (tr "settings.profile.your-email")}]
|
||||||
(fm/input-error errors :email)
|
(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"]]
|
||||||
|
|
||||||
[:input.btn-primary
|
[:input.btn-primary
|
||||||
{:type "button"
|
{:type "button"
|
||||||
:class (when-not valid? "btn-disabled")
|
:class (when-not valid? "btn-disabled")
|
||||||
|
@ -105,7 +114,7 @@
|
||||||
;; --- Profile Photo Form
|
;; --- Profile Photo Form
|
||||||
|
|
||||||
(mf/defc profile-photo-form
|
(mf/defc profile-photo-form
|
||||||
{:wrap [mf/reactive]}
|
{:wrap [mf/reactive*]}
|
||||||
[]
|
[]
|
||||||
(letfn [(on-change [event]
|
(letfn [(on-change [event]
|
||||||
(let [target (dom/get-target event)
|
(let [target (dom/get-target event)
|
||||||
|
@ -128,11 +137,8 @@
|
||||||
|
|
||||||
(mf/defc profile-page
|
(mf/defc profile-page
|
||||||
[]
|
[]
|
||||||
[:main.dashboard-main
|
[:section.dashboard-content.user-settings
|
||||||
(messages-widget)
|
[:section.user-settings-content
|
||||||
(header)
|
[:span.user-settings-label (tr "settings.profile.your-avatar")]
|
||||||
[:section.dashboard-content.user-settings
|
[:& profile-photo-form]
|
||||||
[:section.user-settings-content
|
(profile-form)]])
|
||||||
[:span.user-settings-label (tr "settings.profile.your-avatar")]
|
|
||||||
[:& profile-photo-form]
|
|
||||||
(profile-form)]]])
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
[uxbox.main.data.lightbox :as udl]
|
[uxbox.main.data.lightbox :as udl]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.navigation :as nav]
|
[uxbox.main.ui.navigation :as nav]
|
||||||
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.i18n :refer (tr)]
|
[uxbox.util.i18n :refer (tr)]
|
||||||
[uxbox.util.router :as rt]))
|
[uxbox.util.router :as rt]))
|
||||||
|
|
||||||
|
@ -22,19 +23,24 @@
|
||||||
|
|
||||||
(mf/defc user-menu
|
(mf/defc user-menu
|
||||||
[props]
|
[props]
|
||||||
[:ul.dropdown #_{:class (when-not open? "hide")}
|
(letfn [(on-click [event section]
|
||||||
[:li {:on-click #(st/emit! (rt/nav :settings/profile))}
|
(dom/stop-propagation event)
|
||||||
i/user
|
(if (keyword? section)
|
||||||
[:span (tr "ds.user.profile")]]
|
(st/emit! (rt/nav section))
|
||||||
[:li {:on-click #(st/emit! (rt/nav :settings/password))}
|
(st/emit! section)))]
|
||||||
i/lock
|
[:ul.dropdown
|
||||||
[:span (tr "ds.user.password")]]
|
[:li {:on-click #(on-click % :settings/profile)}
|
||||||
[:li {:on-click #(st/emit! (rt/nav :settings/notifications))}
|
i/user
|
||||||
i/mail
|
[:span (tr "ds.user.profile")]]
|
||||||
[:span (tr "ds.user.notifications")]]
|
[:li {:on-click #(on-click % :settings/password)}
|
||||||
[:li {:on-click #(st/emit! (da/logout))}
|
i/lock
|
||||||
i/exit
|
[:span (tr "ds.user.password")]]
|
||||||
[:span (tr "ds.user.exit")]]])
|
[:li {:on-click #(on-click % :settings/notifications)}
|
||||||
|
i/mail
|
||||||
|
[:span (tr "ds.user.notifications")]]
|
||||||
|
[:li {:on-click #(on-click % (da/logout))}
|
||||||
|
i/exit
|
||||||
|
[:span (tr "ds.user.exit")]]]))
|
||||||
|
|
||||||
;; --- User Widget
|
;; --- User Widget
|
||||||
|
|
||||||
|
@ -42,19 +48,18 @@
|
||||||
(-> (l/key :profile)
|
(-> (l/key :profile)
|
||||||
(l/derive st/state)))
|
(l/derive st/state)))
|
||||||
|
|
||||||
(mf/def user
|
(mf/defc user
|
||||||
:mixins [mf/static mf/reactive (mf/local false)]
|
{:wrap [mf/reactive*]}
|
||||||
|
[_]
|
||||||
:render
|
(let [open (mf/use-state false)
|
||||||
(fn [{:keys [::mf/local] :as own} props]
|
profile (mf/react profile-ref)
|
||||||
(let [profile (mf/react profile-ref)
|
photo (if (str/empty? (:photo profile ""))
|
||||||
photo (if (str/empty? (:photo profile ""))
|
"/images/avatar.jpg"
|
||||||
"/images/avatar.jpg"
|
(:photo profile))]
|
||||||
(:photo profile))]
|
[:div.user-zone {:on-click #(st/emit! (rt/navigate :settings/profile))
|
||||||
[:div.user-zone {:on-click #(st/emit! (rt/navigate :settings/profile))
|
:on-mouse-enter #(reset! open true)
|
||||||
:on-mouse-enter #(reset! local true)
|
:on-mouse-leave #(reset! open false)}
|
||||||
:on-mouse-leave #(reset! local false)}
|
[:span (:fullname profile)]
|
||||||
[:span (:fullname profile)]
|
[:img {:src photo}]
|
||||||
[:img {:src photo}]
|
(when @open
|
||||||
(when @local
|
[:& user-menu])]))
|
||||||
[:& user-menu])])))
|
|
||||||
|
|
|
@ -10,24 +10,23 @@
|
||||||
(:require [cuerdas.core :as str]
|
(:require [cuerdas.core :as str]
|
||||||
[uxbox.util.storage :refer (storage)]))
|
[uxbox.util.storage :refer (storage)]))
|
||||||
|
|
||||||
(defonce state (atom {:current-locale (get storage ::locale :en)}))
|
(defonce locale (atom (get storage ::locale :en)))
|
||||||
|
(defonce state (atom {}))
|
||||||
|
|
||||||
(defn update-locales!
|
(defn update-locales!
|
||||||
[callback]
|
[callback]
|
||||||
(swap! state callback))
|
(swap! state callback))
|
||||||
|
|
||||||
(defn set-current-locale!
|
(defn set-current-locale!
|
||||||
[locale]
|
[v]
|
||||||
(swap! storage assoc ::locale locale)
|
(swap! storage assoc ::locale v)
|
||||||
(swap! state assoc :current-locale locale))
|
(reset! locale v))
|
||||||
|
|
||||||
(defn on-locale-change!
|
(defn on-locale-change!
|
||||||
[callback]
|
[callback]
|
||||||
(add-watch state ::main (fn [_ _ old new]
|
(add-watch locale ::main (fn [_ _ old-locale new-locale]
|
||||||
(let [old-locale (:current-locale old)
|
(when (not= old-locale new-locale)
|
||||||
new-locale (:current-locale new)]
|
(callback new-locale old-locale)))))
|
||||||
(when (not= old-locale new-locale)
|
|
||||||
(callback new-locale old-locale))))))
|
|
||||||
|
|
||||||
;; A marker type that is used just for mark
|
;; A marker type that is used just for mark
|
||||||
;; a parameter that reprsentes the counter.
|
;; a parameter that reprsentes the counter.
|
||||||
|
@ -50,13 +49,14 @@
|
||||||
"Translate the string."
|
"Translate the string."
|
||||||
([t]
|
([t]
|
||||||
(let [default (name t)
|
(let [default (name t)
|
||||||
locale (get @state :current-locale)
|
locale (deref locale)
|
||||||
value (get-in @state [locale t] default)]
|
value (or (get-in @state [locale t])
|
||||||
|
default)]
|
||||||
(if (vector? value)
|
(if (vector? value)
|
||||||
(or (second value) default)
|
(or (second value) default)
|
||||||
value)))
|
value)))
|
||||||
([t & args]
|
([t & args]
|
||||||
(let [locale (get @state :current-locale)
|
(let [locale (deref locale)
|
||||||
value (get-in @state [locale t] (name t))
|
value (get-in @state [locale t] (name t))
|
||||||
plural (first (filter c? args))
|
plural (first (filter c? args))
|
||||||
args (mapv #(if (c? %) @% %) args)
|
args (mapv #(if (c? %) @% %) args)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue