mirror of
https://github.com/penpot/penpot.git
synced 2025-06-06 17:21:38 +02:00
♻️ Refactor messages component.
This commit is contained in:
parent
a0b70b7bbd
commit
02170a156e
24 changed files with 298 additions and 374 deletions
|
@ -956,112 +956,6 @@ input[type=range]:focus::-ms-fill-upper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Messages
|
|
||||||
.message {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0px;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 12;
|
|
||||||
@include animation(0, 1s, fadeInDown);
|
|
||||||
|
|
||||||
.message-body {
|
|
||||||
align-items: center;
|
|
||||||
border-radius: $br-small;
|
|
||||||
border-bottom: 3px solid transparent;
|
|
||||||
color: $color-white;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: $medium $big;
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: $fs18;
|
|
||||||
max-width: 60%;
|
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close {
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
right: 10px;
|
|
||||||
opacity: .3;
|
|
||||||
width: 18px;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
fill: $color-black;
|
|
||||||
height: 18px;
|
|
||||||
width: 18px;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: .8;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-action {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
margin-top: $medium;
|
|
||||||
max-width: 60%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&.error {
|
|
||||||
|
|
||||||
.message-body {
|
|
||||||
background-color: $color-danger;
|
|
||||||
border-color: $color-danger-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&.success {
|
|
||||||
|
|
||||||
.message-body {
|
|
||||||
background-color: $color-success;
|
|
||||||
border-color: $color-success-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&.info {
|
|
||||||
|
|
||||||
.message-body {
|
|
||||||
background-color: $color-info;
|
|
||||||
border-color: $color-info-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&.quick {
|
|
||||||
|
|
||||||
.message-body {
|
|
||||||
|
|
||||||
.close {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&.hide-message {
|
|
||||||
@include animation(0, .6s, fadeOutUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-version {
|
.message-version {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: rgba(27, 170, 214, .6);
|
background-color: rgba(27, 170, 214, .6);
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
@import "main/partials/viewer-header";
|
@import "main/partials/viewer-header";
|
||||||
@import "main/partials/viewer-thumbnails";
|
@import "main/partials/viewer-thumbnails";
|
||||||
@import "main/partials/viewer";
|
@import "main/partials/viewer";
|
||||||
|
@import "main/partials/messages";
|
||||||
|
|
||||||
//#################################################
|
//#################################################
|
||||||
// Resources
|
// Resources
|
||||||
|
|
74
frontend/resources/styles/main/partials/messages.scss
Normal file
74
frontend/resources/styles/main/partials/messages.scss
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Messages
|
||||||
|
|
||||||
|
.message {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
z-index: 13;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
top: 0px;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: $color-black;
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
color: $color-white;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: $fs18;
|
||||||
|
max-width: 60%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
background-color: $color-danger;
|
||||||
|
border-color: $color-danger-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
background-color: $color-success;
|
||||||
|
border-color: $color-success-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.info {
|
||||||
|
background-color: $color-info;
|
||||||
|
border-color: $color-info-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.quick {
|
||||||
|
.close-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hide-message {
|
||||||
|
@include animation(0, .6s, fadeOutUp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.html.history :as html-history]
|
[uxbox.util.html.history :as html-history]
|
||||||
[uxbox.util.i18n :as i18n]
|
[uxbox.util.i18n :as i18n]
|
||||||
[uxbox.util.messages :as uum]
|
|
||||||
[uxbox.util.router :as rt]
|
[uxbox.util.router :as rt]
|
||||||
[uxbox.util.storage :refer [storage]]
|
[uxbox.util.storage :refer [storage]]
|
||||||
[uxbox.util.timers :as ts]))
|
[uxbox.util.timers :as ts]))
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
[uxbox.main.repo :as rp]
|
[uxbox.main.repo :as rp]
|
||||||
[uxbox.main.store :refer [initial-state]]
|
[uxbox.main.store :refer [initial-state]]
|
||||||
[uxbox.main.data.users :as du]
|
[uxbox.main.data.users :as du]
|
||||||
[uxbox.util.messages :as um]
|
[uxbox.main.data.messages :as dm]
|
||||||
[uxbox.util.router :as rt]
|
[uxbox.util.router :as rt]
|
||||||
[uxbox.util.i18n :as i18n :refer [tr]]
|
[uxbox.util.i18n :as i18n :refer [tr]]
|
||||||
[uxbox.util.storage :refer [storage]]))
|
[uxbox.util.storage :refer [storage]]))
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
(let [params {:email email
|
(let [params {:email email
|
||||||
:password password
|
:password password
|
||||||
:scope "webapp"}
|
:scope "webapp"}
|
||||||
on-error #(rx/of (um/error (tr "errors.auth.unauthorized")))]
|
on-error #(rx/of (dm/error (tr "errors.auth.unauthorized")))]
|
||||||
(->> (rp/mutation :login params)
|
(->> (rp/mutation :login params)
|
||||||
(rx/map logged-in)
|
(rx/map logged-in)
|
||||||
(rx/catch rp/client-error? on-error))))))
|
(rx/catch rp/client-error? on-error))))))
|
||||||
|
|
50
frontend/src/uxbox/main/data/messages.cljs
Normal file
50
frontend/src/uxbox/main/data/messages.cljs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||||
|
;; defined by the Mozilla Public License, v. 2.0.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) 2020 UXBOX Labs SL
|
||||||
|
|
||||||
|
(ns uxbox.main.data.messages
|
||||||
|
(:require
|
||||||
|
[cljs.spec.alpha :as s]
|
||||||
|
[potok.core :as ptk]
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[uxbox.common.data :as d]
|
||||||
|
[uxbox.common.pages :as cp]
|
||||||
|
[uxbox.common.spec :as us]
|
||||||
|
[uxbox.common.exceptions :as ex]
|
||||||
|
[uxbox.config :as cfg]))
|
||||||
|
|
||||||
|
(declare hide)
|
||||||
|
(declare show)
|
||||||
|
|
||||||
|
(def +animation-timeout+ 600)
|
||||||
|
|
||||||
|
(defn show
|
||||||
|
[data]
|
||||||
|
(ptk/reify ::show
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [message (assoc data :status :visible)]
|
||||||
|
(assoc state :message message)))
|
||||||
|
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(let [stoper (rx/filter (ptk/type? ::show) stream)]
|
||||||
|
(->> (rx/of hide)
|
||||||
|
(rx/delay (:timeout data))
|
||||||
|
(rx/take-until stoper))))))
|
||||||
|
|
||||||
|
(def hide
|
||||||
|
(ptk/reify ::hide
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :message assoc :status :hide))
|
||||||
|
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(->> (rx/of #(dissoc % :message))
|
||||||
|
(rx/delay +animation-timeout+)))))
|
|
@ -13,7 +13,6 @@
|
||||||
[uxbox.common.spec :as us]
|
[uxbox.common.spec :as us]
|
||||||
[uxbox.main.repo :as rp]
|
[uxbox.main.repo :as rp]
|
||||||
[uxbox.util.i18n :as i18n :refer [tr]]
|
[uxbox.util.i18n :as i18n :refer [tr]]
|
||||||
[uxbox.util.messages :as uum]
|
|
||||||
[uxbox.util.storage :refer [storage]]))
|
[uxbox.util.storage :refer [storage]]))
|
||||||
|
|
||||||
;; --- Common Specs
|
;; --- Common Specs
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
[uxbox.common.exceptions :as ex]
|
[uxbox.common.exceptions :as ex]
|
||||||
[uxbox.common.data :as d]
|
[uxbox.common.data :as d]
|
||||||
[uxbox.main.data.auth :refer [logout]]
|
[uxbox.main.data.auth :refer [logout]]
|
||||||
|
[uxbox.main.data.messages :as dm]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.dashboard :refer [dashboard]]
|
[uxbox.main.ui.dashboard :refer [dashboard]]
|
||||||
|
@ -31,7 +32,6 @@
|
||||||
[uxbox.main.ui.shapes]
|
[uxbox.main.ui.shapes]
|
||||||
[uxbox.main.ui.workspace :as workspace]
|
[uxbox.main.ui.workspace :as workspace]
|
||||||
[uxbox.util.i18n :refer [tr]]
|
[uxbox.util.i18n :refer [tr]]
|
||||||
[uxbox.util.messages :as uum]
|
|
||||||
[uxbox.util.timers :as ts]))
|
[uxbox.util.timers :as ts]))
|
||||||
|
|
||||||
(def route-iref
|
(def route-iref
|
||||||
|
@ -171,12 +171,12 @@
|
||||||
(and (map? error)
|
(and (map? error)
|
||||||
(= :unexpected type)
|
(= :unexpected type)
|
||||||
(= :abort code))
|
(= :abort code))
|
||||||
(ts/schedule 100 #(st/emit! (uum/error (tr "errors.network"))))
|
(ts/schedule 100 #(st/emit! (dm/error (tr "errors.network"))))
|
||||||
|
|
||||||
;; Something else
|
;; Something else
|
||||||
:else
|
:else
|
||||||
(do
|
(do
|
||||||
(js/console.error error)
|
(js/console.error error)
|
||||||
(ts/schedule 100 #(st/emit! (uum/error (tr "errors.generic")))))))
|
(ts/schedule 100 #(st/emit! (dm/error (tr "errors.generic")))))))
|
||||||
|
|
||||||
(set! st/*on-error* on-error)
|
(set! st/*on-error* on-error)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
[uxbox.main.ui.dashboard.recent-files :refer [recent-files-page]]
|
[uxbox.main.ui.dashboard.recent-files :refer [recent-files-page]]
|
||||||
[uxbox.main.ui.dashboard.library :refer [library-page]]
|
[uxbox.main.ui.dashboard.library :refer [library-page]]
|
||||||
[uxbox.main.ui.dashboard.profile :refer [profile-section]]
|
[uxbox.main.ui.dashboard.profile :refer [profile-section]]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]))
|
[uxbox.main.ui.messages :refer [messages]]))
|
||||||
|
|
||||||
(defn ^boolean uuid-str?
|
(defn ^boolean uuid-str?
|
||||||
[s]
|
[s]
|
||||||
|
@ -64,8 +64,8 @@
|
||||||
page (get-in route [:data :name])
|
page (get-in route [:data :name])
|
||||||
{:keys [search-term team-id project-id library-id library-section] :as params}
|
{:keys [search-term team-id project-id library-id library-section] :as params}
|
||||||
(parse-params route profile)]
|
(parse-params route profile)]
|
||||||
[:main.dashboard-main
|
[:*
|
||||||
[:& messages-widget]
|
[:& messages]
|
||||||
[:section.dashboard-layout
|
[:section.dashboard-layout
|
||||||
[:div.main-logo i/logo-icon]
|
[:div.main-logo i/logo-icon]
|
||||||
[:& profile-section {:profile profile}]
|
[:& profile-section {:profile profile}]
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
[uxbox.main.ui.keyboard :as kbd]
|
[uxbox.main.ui.keyboard :as kbd]
|
||||||
[uxbox.main.ui.confirm :refer [confirm-dialog]]
|
[uxbox.main.ui.confirm :refer [confirm-dialog]]
|
||||||
[uxbox.main.ui.dashboard.common :as common]
|
[uxbox.main.ui.dashboard.common :as common]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.i18n :as i18n :refer [t tr]]
|
[uxbox.util.i18n :as i18n :refer [t tr]]
|
||||||
[uxbox.util.router :as rt]
|
[uxbox.util.router :as rt]
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
[uxbox.config :as cfg]
|
[uxbox.config :as cfg]
|
||||||
[uxbox.main.data.auth :as da]
|
[uxbox.main.data.auth :as da]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.forms :as fm]
|
[uxbox.util.forms :as fm]
|
||||||
[uxbox.util.i18n :refer [tr]]
|
[uxbox.util.i18n :refer [tr]]
|
||||||
|
@ -94,6 +94,6 @@
|
||||||
[]
|
[]
|
||||||
[:div.login
|
[:div.login
|
||||||
[:div.login-body
|
[:div.login-body
|
||||||
[:& messages-widget]
|
[:& messages]
|
||||||
[:a i/logo]
|
[:a i/logo]
|
||||||
[:& login-form]]])
|
[:& login-form]]])
|
||||||
|
|
|
@ -2,16 +2,56 @@
|
||||||
(:require
|
(:require
|
||||||
[lentes.core :as l]
|
[lentes.core :as l]
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
|
[uxbox.builtins.icons :as i]
|
||||||
|
[uxbox.main.data.messages :as dm]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.util.messages :as um]))
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.util.timers :as ts]
|
||||||
|
[uxbox.util.i18n :as i18n :refer [t]]
|
||||||
|
[uxbox.util.data :refer [classnames]]))
|
||||||
|
|
||||||
|
;; --- Main Component (entry point)
|
||||||
|
|
||||||
|
(declare notification)
|
||||||
|
|
||||||
(def ^:private message-iref
|
(def ^:private message-iref
|
||||||
(-> (l/key :message)
|
(-> (l/key :message)
|
||||||
(l/derive st/state)))
|
(l/derive st/state)))
|
||||||
|
|
||||||
|
(mf/defc messages
|
||||||
|
[]
|
||||||
|
(let [message (mf/deref message-iref)
|
||||||
|
;; message {:type :error
|
||||||
|
;; :content "Hello world!"}
|
||||||
|
]
|
||||||
|
(when message
|
||||||
|
[:& notification {:type (:type message)
|
||||||
|
:status (:status message)
|
||||||
|
:content (:content message)}])))
|
||||||
|
|
||||||
(mf/defc messages-widget
|
(mf/defc messages-widget
|
||||||
[]
|
[]
|
||||||
(let [message (mf/deref message-iref)
|
(let [message (mf/deref message-iref)
|
||||||
on-close #(st/emit! (um/hide))]
|
message {:type :error
|
||||||
[:& um/messages-widget {:message message
|
:content "Hello world!"}]
|
||||||
:on-close on-close}]))
|
|
||||||
|
[:& notification {:type (:type message)
|
||||||
|
:status (:status message)
|
||||||
|
:content (:content message)}]))
|
||||||
|
|
||||||
|
;; --- Notification Component
|
||||||
|
|
||||||
|
(mf/defc notification
|
||||||
|
[{:keys [type status content] :as props}]
|
||||||
|
(let [on-close #(st/emit! dm/hide)
|
||||||
|
klass (classnames
|
||||||
|
:error (= type :error)
|
||||||
|
:info (= type :info)
|
||||||
|
:hide-message (= status :hide)
|
||||||
|
:success (= type :success)
|
||||||
|
:quick false)]
|
||||||
|
[:div.message {:class klass}
|
||||||
|
[:a.close-button {:on-click on-close} i/close]
|
||||||
|
[:div.message-content
|
||||||
|
[:span content]]]))
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.common.spec :as us]
|
[uxbox.common.spec :as us]
|
||||||
[uxbox.main.data.auth :as uda]
|
[uxbox.main.data.auth :as uda]
|
||||||
|
[uxbox.main.data.messages :as dm]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.main.ui.navigation :as nav]
|
[uxbox.main.ui.navigation :as nav]
|
||||||
[uxbox.util.messages :as um]
|
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.forms :as fm]
|
[uxbox.util.forms :as fm]
|
||||||
[uxbox.util.i18n :as i18n :refer [t]]
|
[uxbox.util.i18n :as i18n :refer [t]]
|
||||||
|
@ -37,12 +37,12 @@
|
||||||
|
|
||||||
on-success
|
on-success
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (um/info (t locale "profile.recovery.password-changed"))
|
(st/emit! (dm/info (t locale "profile.recovery.password-changed"))
|
||||||
(rt/nav :login)))
|
(rt/nav :login)))
|
||||||
|
|
||||||
on-error
|
on-error
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (um/error (t locale "profile.recovery.invalid-token"))))
|
(st/emit! (dm/error (t locale "profile.recovery.invalid-token"))))
|
||||||
|
|
||||||
on-submit
|
on-submit
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
@ -86,6 +86,6 @@
|
||||||
[]
|
[]
|
||||||
[:div.login
|
[:div.login
|
||||||
[:div.login-body
|
[:div.login-body
|
||||||
[:& messages-widget]
|
[:& messages]
|
||||||
[:a i/logo]
|
[:a i/logo]
|
||||||
[:& recovery-form]]])
|
[:& recovery-form]]])
|
||||||
|
|
|
@ -17,10 +17,10 @@
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.common.spec :as us]
|
[uxbox.common.spec :as us]
|
||||||
[uxbox.main.data.auth :as uda]
|
[uxbox.main.data.auth :as uda]
|
||||||
|
[uxbox.main.data.messages :as dm]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.main.ui.navigation :as nav]
|
[uxbox.main.ui.navigation :as nav]
|
||||||
[uxbox.util.messages :as um]
|
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.forms :as fm]
|
[uxbox.util.forms :as fm]
|
||||||
[uxbox.util.i18n :as i18n :refer [t]]
|
[uxbox.util.i18n :as i18n :refer [t]]
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
on-success
|
on-success
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (um/info (t locale "profile.recovery.recovery-token-sent"))
|
(st/emit! (dm/info (t locale "profile.recovery.recovery-token-sent"))
|
||||||
(rt/nav :profile-recovery)))
|
(rt/nav :profile-recovery)))
|
||||||
|
|
||||||
on-submit
|
on-submit
|
||||||
|
@ -70,6 +70,6 @@
|
||||||
[]
|
[]
|
||||||
[:div.login
|
[:div.login
|
||||||
[:div.login-body
|
[:div.login-body
|
||||||
[:& messages-widget]
|
[:& messages]
|
||||||
[:a i/logo]
|
[:a i/logo]
|
||||||
[:& recovery-form]]])
|
[:& recovery-form]]])
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.data.auth :as uda]
|
[uxbox.main.data.auth :as uda]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.main.ui.navigation :as nav]
|
[uxbox.main.ui.navigation :as nav]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.forms :as fm]
|
[uxbox.util.forms :as fm]
|
||||||
|
@ -115,6 +115,6 @@
|
||||||
[props]
|
[props]
|
||||||
[:div.login
|
[:div.login
|
||||||
[:div.login-body
|
[:div.login-body
|
||||||
[:& messages-widget]
|
[:& messages]
|
||||||
[:a i/logo]
|
[:a i/logo]
|
||||||
[:& register-form]]])
|
[:& register-form]]])
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.util.router :as rt]
|
[uxbox.util.router :as rt]
|
||||||
[uxbox.main.ui.dashboard.profile :refer [profile-section]]
|
[uxbox.main.ui.dashboard.profile :refer [profile-section]]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.main.ui.settings.header :refer [header]]
|
[uxbox.main.ui.settings.header :refer [header]]
|
||||||
[uxbox.main.ui.settings.password :refer [password-page]]
|
[uxbox.main.ui.settings.password :refer [password-page]]
|
||||||
[uxbox.main.ui.settings.profile :refer [profile-page]]))
|
[uxbox.main.ui.settings.profile :refer [profile-page]]))
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
(let [section (get-in route [:data :name])
|
(let [section (get-in route [:data :name])
|
||||||
profile (mf/deref refs/profile)]
|
profile (mf/deref refs/profile)]
|
||||||
[:main.settings-main
|
[:main.settings-main
|
||||||
[:& messages-widget]
|
[:& messages]
|
||||||
[:div.settings-content
|
[:div.settings-content
|
||||||
[:& header {:section section}]
|
[:& header {:section section}]
|
||||||
(case section
|
(case section
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
[cljs.spec.alpha :as s]
|
[cljs.spec.alpha :as s]
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.data.users :as udu]
|
[uxbox.main.data.users :as udu]
|
||||||
|
[uxbox.main.data.messages :as dm]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.forms :as fm]
|
[uxbox.util.forms :as fm]
|
||||||
[uxbox.util.i18n :refer [tr]]
|
[uxbox.util.i18n :refer [tr]]))
|
||||||
[uxbox.util.messages :as um]))
|
|
||||||
|
|
||||||
(defn- on-error
|
(defn- on-error
|
||||||
[form error]
|
[form error]
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
[event form]
|
[event form]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(let [data (:clean-data form)
|
(let [data (:clean-data form)
|
||||||
mdata {:on-success #(st/emit! (um/info (tr "settings.password.password-saved")))
|
mdata {:on-success #(st/emit! (dm/info (tr "settings.password.password-saved")))
|
||||||
:on-error #(on-error form %)}]
|
:on-error #(on-error form %)}]
|
||||||
(st/emit! (udu/update-password (with-meta data mdata)))))
|
(st/emit! (udu/update-password (with-meta data mdata)))))
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,12 @@
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.data.users :as udu]
|
[uxbox.main.data.users :as udu]
|
||||||
|
[uxbox.main.data.messages :as dm]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.util.data :refer [read-string]]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.forms :as fm]
|
[uxbox.util.forms :as fm]
|
||||||
[uxbox.util.i18n :as i18n :refer [tr t]]
|
[uxbox.util.i18n :as i18n :refer [tr t]]))
|
||||||
[uxbox.util.messages :as um]))
|
|
||||||
|
|
||||||
(def ^:private profile-iref
|
|
||||||
(-> (l/key :profile)
|
|
||||||
(l/derive st/state)))
|
|
||||||
|
|
||||||
(s/def ::fullname ::fm/not-empty-string)
|
(s/def ::fullname ::fm/not-empty-string)
|
||||||
(s/def ::lang (s/nilable ::fm/not-empty-string))
|
(s/def ::lang (s/nilable ::fm/not-empty-string))
|
||||||
|
@ -48,7 +44,7 @@
|
||||||
[event form]
|
[event form]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(let [data (:clean-data form)
|
(let [data (:clean-data form)
|
||||||
on-success #(st/emit! (um/info (tr "settings.profile.profile-saved")))
|
on-success #(st/emit! (dm/info (tr "settings.profile.profile-saved")))
|
||||||
on-error #(on-error % form)]
|
on-error #(on-error % form)]
|
||||||
(st/emit! (udu/update-profile (with-meta data
|
(st/emit! (udu/update-profile (with-meta data
|
||||||
{:on-success on-success
|
{:on-success on-success
|
||||||
|
@ -59,7 +55,7 @@
|
||||||
(mf/defc profile-form
|
(mf/defc profile-form
|
||||||
[props]
|
[props]
|
||||||
(let [locale (i18n/use-locale)
|
(let [locale (i18n/use-locale)
|
||||||
form (fm/use-form ::profile-form #(deref profile-iref))
|
form (fm/use-form ::profile-form #(deref refs/profile))
|
||||||
data (:data form)]
|
data (:data form)]
|
||||||
(prn "data" form)
|
(prn "data" form)
|
||||||
[:form.profile-form {:on-submit #(on-submit % form)}
|
[:form.profile-form {:on-submit #(on-submit % form)}
|
||||||
|
@ -108,7 +104,7 @@
|
||||||
|
|
||||||
(mf/defc profile-photo-form
|
(mf/defc profile-photo-form
|
||||||
[props]
|
[props]
|
||||||
(let [profile (mf/deref profile-iref)
|
(let [profile (mf/deref refs/profile)
|
||||||
photo (:photo-uri profile)
|
photo (:photo-uri profile)
|
||||||
photo (if (or (str/empty? photo) (nil? photo))
|
photo (if (or (str/empty? photo) (nil? photo))
|
||||||
"images/avatar.jpg"
|
"images/avatar.jpg"
|
||||||
|
|
|
@ -15,19 +15,18 @@
|
||||||
[lentes.core :as l]
|
[lentes.core :as l]
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.store :as st]
|
|
||||||
[uxbox.common.exceptions :as ex]
|
[uxbox.common.exceptions :as ex]
|
||||||
[uxbox.main.ui.keyboard :as kbd]
|
|
||||||
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
|
||||||
[uxbox.main.data.viewer :as dv]
|
[uxbox.main.data.viewer :as dv]
|
||||||
|
[uxbox.main.store :as st]
|
||||||
|
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
||||||
|
[uxbox.main.ui.hooks :as hooks]
|
||||||
|
[uxbox.main.ui.keyboard :as kbd]
|
||||||
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.main.ui.viewer.header :refer [header]]
|
[uxbox.main.ui.viewer.header :refer [header]]
|
||||||
[uxbox.main.ui.viewer.thumbnails :refer [thumbnails-panel frame-svg]]
|
[uxbox.main.ui.viewer.thumbnails :refer [thumbnails-panel frame-svg]]
|
||||||
[uxbox.util.dom :as dom]
|
|
||||||
[uxbox.main.ui.hooks :as hooks]
|
|
||||||
[uxbox.util.data :refer [classnames]]
|
[uxbox.util.data :refer [classnames]]
|
||||||
[uxbox.util.i18n :as i18n :refer [t tr]]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.math :as mth]
|
[uxbox.util.i18n :as i18n :refer [t tr]])
|
||||||
[uxbox.util.router :as rt])
|
|
||||||
(:import goog.events.EventType
|
(:import goog.events.EventType
|
||||||
goog.events.KeyCodes))
|
goog.events.KeyCodes))
|
||||||
|
|
||||||
|
@ -68,6 +67,8 @@
|
||||||
(mf/use-effect on-mount)
|
(mf/use-effect on-mount)
|
||||||
(hooks/use-shortcuts dv/shortcuts)
|
(hooks/use-shortcuts dv/shortcuts)
|
||||||
|
|
||||||
|
[:*
|
||||||
|
[:& messages]
|
||||||
[:div.viewer-layout {:class (classnames :fullscreen fullscreen?)
|
[:div.viewer-layout {:class (classnames :fullscreen fullscreen?)
|
||||||
:ref container}
|
:ref container}
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@
|
||||||
:data data}])
|
:data data}])
|
||||||
[:& main-panel {:data data
|
[:& main-panel {:data data
|
||||||
:zoom (:zoom local)
|
:zoom (:zoom local)
|
||||||
:index index}]]]))
|
:index index}]]]]))
|
||||||
|
|
||||||
|
|
||||||
;; --- Component: Viewer Page
|
;; --- Component: Viewer Page
|
||||||
|
|
|
@ -9,25 +9,20 @@
|
||||||
|
|
||||||
(ns uxbox.main.ui.viewer.header
|
(ns uxbox.main.ui.viewer.header
|
||||||
(:require
|
(:require
|
||||||
[beicon.core :as rx]
|
|
||||||
[goog.events :as events]
|
|
||||||
[goog.object :as gobj]
|
|
||||||
[lentes.core :as l]
|
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
|
[uxbox.main.data.messages :as dm]
|
||||||
|
[uxbox.main.data.viewer :as dv]
|
||||||
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
||||||
[uxbox.main.ui.workspace.header :refer [zoom-widget]]
|
[uxbox.main.ui.workspace.header :refer [zoom-widget]]
|
||||||
[uxbox.main.data.viewer :as dv]
|
|
||||||
[uxbox.main.refs :as refs]
|
|
||||||
[uxbox.util.data :refer [classnames]]
|
[uxbox.util.data :refer [classnames]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.util.i18n :as i18n :refer [t]]
|
||||||
|
[uxbox.util.router :as rt]
|
||||||
[uxbox.util.uuid :as uuid]
|
[uxbox.util.uuid :as uuid]
|
||||||
[uxbox.util.i18n :as i18n :refer [t tr]]
|
[uxbox.util.webapi :as wapi]))
|
||||||
[uxbox.util.math :as mth]
|
|
||||||
[uxbox.util.router :as rt])
|
|
||||||
(:import goog.events.EventType
|
|
||||||
goog.events.KeyCodes))
|
|
||||||
|
|
||||||
|
|
||||||
(mf/defc share-link
|
(mf/defc share-link
|
||||||
|
@ -36,30 +31,45 @@
|
||||||
dropdown-ref (mf/use-ref)
|
dropdown-ref (mf/use-ref)
|
||||||
token (:share-token page)
|
token (:share-token page)
|
||||||
|
|
||||||
|
locale (i18n/use-locale)
|
||||||
|
|
||||||
create #(st/emit! dv/create-share-link)
|
create #(st/emit! dv/create-share-link)
|
||||||
delete #(st/emit! dv/delete-share-link)
|
delete #(st/emit! dv/delete-share-link)
|
||||||
href (.-href js/location)]
|
|
||||||
|
href (.-href js/location)
|
||||||
|
link (str href "&token=" token)
|
||||||
|
|
||||||
|
copy-link
|
||||||
|
(fn [event]
|
||||||
|
(wapi/write-to-clipboard link)
|
||||||
|
(st/emit! (dm/show {:type :info
|
||||||
|
:content "Link copied successfuly!"
|
||||||
|
:timeout 2000})))]
|
||||||
[:*
|
[:*
|
||||||
[:span.btn-primary.btn-small
|
[:span.btn-primary.btn-small
|
||||||
{:alt "Share link"
|
{:alt (t locale "viewer.header.share.title")
|
||||||
:on-click #(swap! show-dropdown? not)}
|
:on-click #(swap! show-dropdown? not)}
|
||||||
"Share link"]
|
(t locale "viewer.header.share.title")]
|
||||||
|
|
||||||
[:& dropdown {:show @show-dropdown?
|
[:& dropdown {:show @show-dropdown?
|
||||||
:on-close #(swap! show-dropdown? not)
|
:on-close #(swap! show-dropdown? not)
|
||||||
:container dropdown-ref}
|
:container dropdown-ref}
|
||||||
[:div.share-link-dropdown {:ref dropdown-ref}
|
[:div.share-link-dropdown {:ref dropdown-ref}
|
||||||
[:span.share-link-title "Share link"]
|
[:span.share-link-title (t locale "viewer.header.share.title")]
|
||||||
[:div.share-link-input
|
[:div.share-link-input
|
||||||
(if (string? token)
|
(if (string? token)
|
||||||
[:span.link (str href "&token=" token)]
|
[:span.link link]
|
||||||
[:span.link-placeholder "Share link will apear here"])
|
[:span.link-placeholder (t locale "viewer.header.share.placeholder")])
|
||||||
[:span.link-button "Copy link"]]
|
[:span.link-button {:on-click copy-link}
|
||||||
[:span.share-link-subtitle "Anyone with the link will have access"]
|
(t locale "viewer.header.share.copy-link")]]
|
||||||
|
|
||||||
|
[:span.share-link-subtitle (t locale "viewer.header.share.subtitle")]
|
||||||
[:div.share-link-buttons
|
[:div.share-link-buttons
|
||||||
(if (string? token)
|
(if (string? token)
|
||||||
[:button.btn-delete {:on-click delete} "Remove link"]
|
[:button.btn-delete {:on-click delete}
|
||||||
[:button.btn-primary {:on-click create} "Create link"])]]]]))
|
(t locale "viewer.header.share.remove-link")]
|
||||||
|
[:button.btn-primary {:on-click create}
|
||||||
|
(t locale "viewer.header.share.create-link")])]]]]))
|
||||||
|
|
||||||
(mf/defc header
|
(mf/defc header
|
||||||
[{:keys [data index local fullscreen? toggle-fullscreen] :as props}]
|
[{:keys [data index local fullscreen? toggle-fullscreen] :as props}]
|
||||||
|
@ -67,6 +77,8 @@
|
||||||
total (count frames)
|
total (count frames)
|
||||||
on-click #(st/emit! dv/toggle-thumbnails-panel)
|
on-click #(st/emit! dv/toggle-thumbnails-panel)
|
||||||
|
|
||||||
|
locale (i18n/use-locale)
|
||||||
|
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
anonymous? (= uuid/zero (:id profile))
|
anonymous? (= uuid/zero (:id profile))
|
||||||
|
|
||||||
|
@ -82,7 +94,7 @@
|
||||||
[:div.main-icon
|
[:div.main-icon
|
||||||
[:a {:on-click on-edit} i/logo-icon]]
|
[:a {:on-click on-edit} i/logo-icon]]
|
||||||
|
|
||||||
[:div.sitemap-zone {:alt (tr "header.sitemap")
|
[:div.sitemap-zone {:alt (t locale "viewer.header.sitemap")
|
||||||
:on-click on-click}
|
:on-click on-click}
|
||||||
[:span.project-name (:name project)]
|
[:span.project-name (:name project)]
|
||||||
[:span "/"]
|
[:span "/"]
|
||||||
|
@ -96,7 +108,8 @@
|
||||||
(when-not anonymous?
|
(when-not anonymous?
|
||||||
[:& share-link {:page (:page data)}])
|
[:& share-link {:page (:page data)}])
|
||||||
(when-not anonymous?
|
(when-not anonymous?
|
||||||
[:a {:on-click on-edit} "Edit page"])
|
[:a {:on-click on-edit}
|
||||||
|
(t locale "viewer.header.edit-page")])
|
||||||
|
|
||||||
[:& zoom-widget
|
[:& zoom-widget
|
||||||
{:zoom (:zoom local)
|
{:zoom (:zoom local)
|
||||||
|
@ -107,7 +120,7 @@
|
||||||
:on-zoom-to-200 #(st/emit! dv/zoom-to-200)}]
|
:on-zoom-to-200 #(st/emit! dv/zoom-to-200)}]
|
||||||
|
|
||||||
[:span.btn-fullscreen.tooltip.tooltip-bottom
|
[:span.btn-fullscreen.tooltip.tooltip-bottom
|
||||||
{:alt "Full Screen"
|
{:alt (t locale "viewer.header.fullscreen")
|
||||||
:on-click toggle-fullscreen}
|
:on-click toggle-fullscreen}
|
||||||
(if fullscreen?
|
(if fullscreen?
|
||||||
i/full-screen-off
|
i/full-screen-off
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
[uxbox.main.ui.confirm]
|
[uxbox.main.ui.confirm]
|
||||||
[uxbox.main.ui.keyboard :as kbd]
|
[uxbox.main.ui.keyboard :as kbd]
|
||||||
[uxbox.main.ui.hooks :as hooks]
|
[uxbox.main.ui.hooks :as hooks]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.main.ui.workspace.viewport :refer [viewport]]
|
[uxbox.main.ui.workspace.viewport :refer [viewport]]
|
||||||
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
||||||
[uxbox.main.ui.workspace.context-menu :refer [context-menu]]
|
[uxbox.main.ui.workspace.context-menu :refer [context-menu]]
|
||||||
|
@ -68,8 +68,9 @@
|
||||||
(when (:colorpalette layout)
|
(when (:colorpalette layout)
|
||||||
[:& colorpalette {:left-sidebar? left-sidebar?}])
|
[:& colorpalette {:left-sidebar? left-sidebar?}])
|
||||||
|
|
||||||
[:main.main-content
|
[:& messages]
|
||||||
[:& context-menu {}]
|
[:& context-menu {}]
|
||||||
|
|
||||||
[:section.workspace-content
|
[:section.workspace-content
|
||||||
{:class classes
|
{:class classes
|
||||||
:on-scroll on-scroll
|
:on-scroll on-scroll
|
||||||
|
@ -94,7 +95,7 @@
|
||||||
(when left-sidebar?
|
(when left-sidebar?
|
||||||
[:& left-sidebar {:file file :page page :layout layout}])
|
[:& left-sidebar {:file file :page page :layout layout}])
|
||||||
(when right-sidebar?
|
(when right-sidebar?
|
||||||
[:& right-sidebar {:page page :layout layout}])]]))
|
[:& right-sidebar {:page page :layout layout}])]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc workspace
|
(mf/defc workspace
|
||||||
|
@ -121,7 +122,6 @@
|
||||||
project (mf/deref refs/workspace-project)
|
project (mf/deref refs/workspace-project)
|
||||||
layout (mf/deref refs/workspace-layout)]
|
layout (mf/deref refs/workspace-layout)]
|
||||||
[:> rdnd/provider {:backend rdnd/html5}
|
[:> rdnd/provider {:backend rdnd/html5}
|
||||||
[:& messages-widget]
|
|
||||||
[:& header {:page page
|
[:& header {:page page
|
||||||
:file file
|
:file file
|
||||||
:project project
|
:project project
|
||||||
|
|
|
@ -178,5 +178,6 @@
|
||||||
|
|
||||||
[:a.preview-button
|
[:a.preview-button
|
||||||
{;; :target "__blank"
|
{;; :target "__blank"
|
||||||
|
:alt (t locale "workspace.header.viewer")
|
||||||
:href (str "#" view-url)} i/play]]]))
|
:href (str "#" view-url)} i/play]]]))
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.modal :as modal]
|
[uxbox.main.ui.modal :as modal]
|
||||||
[uxbox.main.ui.workspace.images :refer [import-image-modal]]
|
[uxbox.main.ui.workspace.images :refer [import-image-modal]]
|
||||||
|
[uxbox.util.i18n :as i18n :refer [t]]
|
||||||
[uxbox.builtins.icons :as i]))
|
[uxbox.builtins.icons :as i]))
|
||||||
|
|
||||||
;; --- Component: Left toolbar
|
;; --- Component: Left toolbar
|
||||||
|
@ -25,41 +26,42 @@
|
||||||
(let [selected-drawtool (mf/deref refs/selected-drawing-tool)
|
(let [selected-drawtool (mf/deref refs/selected-drawing-tool)
|
||||||
select-drawtool #(st/emit! :interrupt
|
select-drawtool #(st/emit! :interrupt
|
||||||
(dw/select-for-drawing %))
|
(dw/select-for-drawing %))
|
||||||
|
locale (i18n/use-locale)
|
||||||
on-image #(modal/show! import-image-modal {})]
|
on-image #(modal/show! import-image-modal {})]
|
||||||
[:div.left-toolbar
|
[:aside.left-toolbar
|
||||||
[:div.left-toolbar-inside
|
[:div.left-toolbar-inside
|
||||||
[:ul.left-toolbar-options
|
[:ul.left-toolbar-options
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Artboard"
|
{:alt (t locale "workspace.toolbar.frame")
|
||||||
:class (when (= selected-drawtool :frame) "selected")
|
:class (when (= selected-drawtool :frame) "selected")
|
||||||
:on-click (partial select-drawtool :frame)}
|
:on-click (partial select-drawtool :frame)}
|
||||||
i/artboard]
|
i/artboard]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Box"
|
{:alt (t locale "workspace.toolbar.rect")
|
||||||
:class (when (= selected-drawtool :rect) "selected")
|
:class (when (= selected-drawtool :rect) "selected")
|
||||||
:on-click (partial select-drawtool :rect)}
|
:on-click (partial select-drawtool :rect)}
|
||||||
i/box]
|
i/box]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Circle"
|
{:alt (t locale "workspace.toolbar.circle")
|
||||||
:class (when (= selected-drawtool :circle) "selected")
|
:class (when (= selected-drawtool :circle) "selected")
|
||||||
:on-click (partial select-drawtool :circle)}
|
:on-click (partial select-drawtool :circle)}
|
||||||
i/circle]
|
i/circle]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Text"
|
{:alt (t locale "workspace.toolbar.text")
|
||||||
:class (when (= selected-drawtool :text) "selected")
|
:class (when (= selected-drawtool :text) "selected")
|
||||||
:on-click (partial select-drawtool :text)}
|
:on-click (partial select-drawtool :text)}
|
||||||
i/text]
|
i/text]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Insert image"
|
{:alt (t locale "workspace.toolbar.image")
|
||||||
:on-click on-image}
|
:on-click on-image}
|
||||||
i/image]
|
i/image]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Pencil tool"
|
{:alt (t locale "workspace.toolbar.curve")
|
||||||
:class (when (= selected-drawtool :curve) "selected")
|
:class (when (= selected-drawtool :curve) "selected")
|
||||||
:on-click (partial select-drawtool :curve)}
|
:on-click (partial select-drawtool :curve)}
|
||||||
i/pencil]
|
i/pencil]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Curves tool"
|
{:alt (t locale "workspace.toolbar.path")
|
||||||
:class (when (= selected-drawtool :path) "selected")
|
:class (when (= selected-drawtool :path) "selected")
|
||||||
:on-click (partial select-drawtool :path)}
|
:on-click (partial select-drawtool :path)}
|
||||||
i/curve]]
|
i/curve]]
|
||||||
|
@ -71,7 +73,7 @@
|
||||||
:on-click #(st/emit! (dw/toggle-layout-flag :layers))}
|
:on-click #(st/emit! (dw/toggle-layout-flag :layers))}
|
||||||
i/layers]
|
i/layers]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Libraries"
|
{:alt (t locale "workspace.toolbar.libraries")
|
||||||
:class (when (contains? layout :libraries) "selected")
|
:class (when (contains? layout :libraries) "selected")
|
||||||
:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
||||||
i/icon-set]
|
i/icon-set]
|
||||||
|
@ -79,7 +81,7 @@
|
||||||
{:alt "History"}
|
{:alt "History"}
|
||||||
i/undo-history]
|
i/undo-history]
|
||||||
[:li.tooltip.tooltip-right
|
[:li.tooltip.tooltip-right
|
||||||
{:alt "Palette"
|
{:alt (t locale "workspace.toolbar.color-palette")
|
||||||
:class (when (contains? layout :colorpalette) "selected")
|
:class (when (contains? layout :colorpalette) "selected")
|
||||||
:on-click #(st/emit! (dw/toggle-layout-flag :colorpalette))}
|
:on-click #(st/emit! (dw/toggle-layout-flag :colorpalette))}
|
||||||
i/palette]]]]))
|
i/palette]]]]))
|
||||||
|
|
|
@ -1,145 +0,0 @@
|
||||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
;;
|
|
||||||
;; Copyright (c) 2016-2017 Andrey Antukh <niwi@niwi.nz>
|
|
||||||
|
|
||||||
(ns uxbox.util.messages
|
|
||||||
"Messages notifications."
|
|
||||||
(:require
|
|
||||||
[beicon.core :as rx]
|
|
||||||
[cuerdas.core :as str]
|
|
||||||
[lentes.core :as l]
|
|
||||||
[potok.core :as ptk]
|
|
||||||
[rumext.alpha :as mf]
|
|
||||||
[uxbox.builtins.icons :as i]
|
|
||||||
[uxbox.util.data :refer [classnames]]
|
|
||||||
[uxbox.util.dom :as dom]
|
|
||||||
[uxbox.util.timers :as ts]
|
|
||||||
[uxbox.util.i18n :refer [tr]]))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Data Events
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;; --- Constants
|
|
||||||
|
|
||||||
(def +animation-timeout+ 600)
|
|
||||||
|
|
||||||
;; --- Main API
|
|
||||||
|
|
||||||
(declare hide)
|
|
||||||
(declare show)
|
|
||||||
(declare show?)
|
|
||||||
|
|
||||||
(defn error
|
|
||||||
[message & {:keys [timeout] :or {timeout 3000}}]
|
|
||||||
(show {:content message
|
|
||||||
:type :error
|
|
||||||
:timeout timeout}))
|
|
||||||
|
|
||||||
(defn info
|
|
||||||
[message & {:keys [timeout] :or {timeout 3000}}]
|
|
||||||
(show {:content message
|
|
||||||
:type :info
|
|
||||||
:timeout timeout}))
|
|
||||||
|
|
||||||
(defn dialog
|
|
||||||
[message & {:keys [on-accept on-cancel]}]
|
|
||||||
(show {:content message
|
|
||||||
:on-accept on-accept
|
|
||||||
:on-cancel on-cancel
|
|
||||||
:timeout js/Number.MAX_SAFE_INTEGER
|
|
||||||
:type :dialog}))
|
|
||||||
|
|
||||||
;; --- Show Event
|
|
||||||
|
|
||||||
(defn show
|
|
||||||
[data]
|
|
||||||
(ptk/reify ::show
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [message (assoc data :state :visible)]
|
|
||||||
(assoc state :message message)))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state s]
|
|
||||||
(let [stoper (->> (rx/filter show? s)
|
|
||||||
(rx/take 1))]
|
|
||||||
(->> (rx/of (hide))
|
|
||||||
(rx/delay (:timeout data))
|
|
||||||
(rx/take-until stoper))))))
|
|
||||||
|
|
||||||
(defn show?
|
|
||||||
[v]
|
|
||||||
(= ::show (ptk/type v)))
|
|
||||||
|
|
||||||
;; --- Hide Event
|
|
||||||
|
|
||||||
(defn hide
|
|
||||||
[]
|
|
||||||
(reify
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(update state :message assoc :state :hide))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state stream]
|
|
||||||
(->> (rx/of #(dissoc % :message))
|
|
||||||
(rx/delay +animation-timeout+)))))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; UI Components
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;; --- Notification Component
|
|
||||||
|
|
||||||
(mf/defc notification-box
|
|
||||||
[{:keys [message on-close] :as message}]
|
|
||||||
(let [type (:type message)
|
|
||||||
classes (classnames :error (= type :error)
|
|
||||||
:info (= type :info)
|
|
||||||
:hide-message (= (:state message) :hide)
|
|
||||||
:quick true)]
|
|
||||||
[:div.message {:class classes}
|
|
||||||
[:div.message-body
|
|
||||||
[:span.close {:on-click on-close} i/close]
|
|
||||||
[:span (:content message)]]]))
|
|
||||||
|
|
||||||
;; --- Dialog Component
|
|
||||||
|
|
||||||
(mf/defc dialog-box
|
|
||||||
[{:keys [on-accept on-cancel on-close message] :as props}]
|
|
||||||
(let [classes (classnames :info true
|
|
||||||
:hide-message (= (:state message) :hide))]
|
|
||||||
(letfn [(accept [event]
|
|
||||||
(dom/prevent-default event)
|
|
||||||
(on-accept)
|
|
||||||
(ts/schedule 0 on-close))
|
|
||||||
|
|
||||||
(cancel [event]
|
|
||||||
(dom/prevent-default event)
|
|
||||||
(when on-cancel
|
|
||||||
(on-cancel))
|
|
||||||
(ts/schedule 0 on-close))]
|
|
||||||
[:div.message {:class classes}
|
|
||||||
[:div.message-body
|
|
||||||
[:span.close {:on-click cancel} i/close]
|
|
||||||
[:span (:content message)]
|
|
||||||
[:div.message-action
|
|
||||||
[:a.btn-transparent.btn-small
|
|
||||||
{:on-click accept}
|
|
||||||
(tr "ds.accept")]
|
|
||||||
[:a.btn-transparent.btn-small
|
|
||||||
{:on-click cancel}
|
|
||||||
(tr "ds.cancel")]]]])))
|
|
||||||
|
|
||||||
;; --- Main Component (entry point)
|
|
||||||
|
|
||||||
(mf/defc messages-widget
|
|
||||||
[{:keys [message] :as props}]
|
|
||||||
(case (:type message)
|
|
||||||
:error (mf/element notification-box props)
|
|
||||||
:info (mf/element notification-box props)
|
|
||||||
:dialog (mf/element dialog-box props)
|
|
||||||
nil))
|
|
Loading…
Add table
Add a link
Reference in a new issue