mirror of
https://github.com/penpot/penpot.git
synced 2025-05-21 22:56:10 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
f76f4615cf
24 changed files with 177 additions and 56 deletions
11
CHANGES.md
11
CHANGES.md
|
@ -99,6 +99,17 @@
|
||||||
- Fix assets right click button for multiple selection [Taiga #5545](https://tree.taiga.io/project/penpot/issue/5545)
|
- Fix assets right click button for multiple selection [Taiga #5545](https://tree.taiga.io/project/penpot/issue/5545)
|
||||||
- Fix problem with precision in resizes [Taiga #5623](https://tree.taiga.io/project/penpot/issue/5623)
|
- Fix problem with precision in resizes [Taiga #5623](https://tree.taiga.io/project/penpot/issue/5623)
|
||||||
- Fix absolute positioned layouts not showing flex properties [Taiga #5630](https://tree.taiga.io/project/penpot/issue/5630)
|
- Fix absolute positioned layouts not showing flex properties [Taiga #5630](https://tree.taiga.io/project/penpot/issue/5630)
|
||||||
|
- Fix text gradient handlers [Taiga #4047](https://tree.taiga.io/project/penpot/issue/4047)
|
||||||
|
- Fix when user deletes one file during import it is impossible to finish importing of second file [Taiga #5656](https://tree.taiga.io/project/penpot/issue/5656)
|
||||||
|
- Fix export multiple images when only one of them has export settings [Taiga #5649](https://tree.taiga.io/project/penpot/issue/5649)
|
||||||
|
- Fix error when a user different than the thread creator edits a comment [Taiga #5647](https://tree.taiga.io/project/penpot/issue/5647)
|
||||||
|
- Fix unnecessary button [Taiga #3312](https://tree.taiga.io/project/penpot/issue/3312)
|
||||||
|
- Fix copy color information in several formats [Taiga #4723](https://tree.taiga.io/project/penpot/issue/4723)
|
||||||
|
- Fix dropdown width [Taiga #5541](https://tree.taiga.io/project/penpot/issue/5541)
|
||||||
|
- Fix enable comment mode and insert image keeps on comment mode [Taiga #5678](https://tree.taiga.io/project/penpot/issue/5678)
|
||||||
|
- Fix enable undo just after using pencil [Taiga #5674](https://tree.taiga.io/project/penpot/issue/5674)
|
||||||
|
- Fix 400 error when user changes password [Taiga #5643](https://tree.taiga.io/project/penpot/issue/5643)
|
||||||
|
- Fix cannot undo layer styles [Taiga #5676](https://tree.taiga.io/project/penpot/issue/5676)
|
||||||
|
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
|
|
||||||
|
|
|
@ -468,8 +468,8 @@
|
||||||
{::doc/added "1.15"}
|
{::doc/added "1.15"}
|
||||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at id share-id content] :as params}]
|
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at id share-id content] :as params}]
|
||||||
(db/with-atomic [conn pool]
|
(db/with-atomic [conn pool]
|
||||||
(let [{:keys [thread-id] :as comment} (get-comment conn id ::db/for-update? true)
|
(let [{:keys [thread-id owner-id] :as comment} (get-comment conn id ::db/for-update? true)
|
||||||
{:keys [file-id page-id owner-id] :as thread} (get-comment-thread conn thread-id ::db/for-update? true)]
|
{:keys [file-id page-id] :as thread} (get-comment-thread conn thread-id ::db/for-update? true)]
|
||||||
|
|
||||||
(files/check-comment-permissions! conn profile-id file-id share-id)
|
(files/check-comment-permissions! conn profile-id file-id share-id)
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,8 @@
|
||||||
(def schema:update-profile-password
|
(def schema:update-profile-password
|
||||||
[:map {:title "update-profile-password"}
|
[:map {:title "update-profile-password"}
|
||||||
[:password [::sm/word-string {:max 500}]]
|
[:password [::sm/word-string {:max 500}]]
|
||||||
[:old-password [::sm/word-string {:max 500}]]])
|
;; Social registered users don't have old-password
|
||||||
|
[:old-password {:optional true} [:maybe [::sm/word-string {:max 500}]]]])
|
||||||
|
|
||||||
(sv/defmethod ::update-profile-password
|
(sv/defmethod ::update-profile-password
|
||||||
{:doc/added "1.0"
|
{:doc/added "1.0"
|
||||||
|
|
|
@ -776,6 +776,12 @@
|
||||||
[key (delay (generator-fn key))]))
|
[key (delay (generator-fn key))]))
|
||||||
keys))
|
keys))
|
||||||
|
|
||||||
|
(defn opacity-to-hex [opacity]
|
||||||
|
(let [opacity (* opacity 255)
|
||||||
|
value (mth/round opacity)]
|
||||||
|
(.. value
|
||||||
|
(toString 16)
|
||||||
|
(padStart 2 "0"))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; String Functions
|
;; String Functions
|
||||||
|
|
|
@ -316,6 +316,22 @@
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid $color-gray-20;
|
border: 1px solid $color-gray-20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.no-check {
|
||||||
|
.custom-select-dropdown {
|
||||||
|
width: 100%;
|
||||||
|
min-width: unset;
|
||||||
|
.check-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
li.checked-element {
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
&.is-selected {
|
||||||
|
background-color: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.opened {
|
.opened {
|
||||||
border: 1px solid $color-primary;
|
border: 1px solid $color-primary;
|
||||||
|
|
|
@ -416,6 +416,12 @@ span.element-name {
|
||||||
.page-name {
|
.page-name {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
color: #e3e3e3;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
max-width: 90%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.icon-search {
|
.icon-search {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
|
|
@ -60,6 +60,15 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.pages-title {
|
||||||
|
color: #e3e3e3;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
span.tool-badge {
|
span.tool-badge {
|
||||||
border: 1px solid $color-primary;
|
border: 1px solid $color-primary;
|
||||||
border-radius: $br2;
|
border-radius: $br2;
|
||||||
|
|
|
@ -322,7 +322,7 @@
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (partial fetched-comments comments))
|
(rx/of (partial fetched-comments comments))
|
||||||
|
|
||||||
(->> (rx/from (map :file-id comments))
|
(->> (rx/from (into #{} (map :file-id) comments))
|
||||||
(rx/merge-map #(rp/cmd! :get-profiles-for-file-comments {:file-id %}))
|
(rx/merge-map #(rp/cmd! :get-profiles-for-file-comments {:file-id %}))
|
||||||
(rx/reduce #(merge %1 (d/index-by :id %2)) {})
|
(rx/reduce #(merge %1 (d/index-by :id %2)) {})
|
||||||
(rx/map #(partial fetched-users %))))))
|
(rx/map #(partial fetched-users %))))))
|
||||||
|
|
|
@ -337,7 +337,8 @@
|
||||||
[:map {:closed true}
|
[:map {:closed true}
|
||||||
[:password-1 :string]
|
[:password-1 :string]
|
||||||
[:password-2 :string]
|
[:password-2 :string]
|
||||||
[:password-old :string]])
|
;; Social registered users don't have old-password
|
||||||
|
[:password-old {:optional true} [:maybe :string]]])
|
||||||
|
|
||||||
(defn update-password
|
(defn update-password
|
||||||
[data]
|
[data]
|
||||||
|
|
|
@ -129,7 +129,7 @@
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (wsh/lookup-page-objects state)
|
||||||
edition (get-in state [:workspace-local :edition])
|
edition (get-in state [:workspace-local :edition])
|
||||||
drawing (get state :workspace-drawing)]
|
drawing (get state :workspace-drawing)]
|
||||||
(when-not (and (or (some? edition) (not-empty drawing))
|
(when-not (and (or (some? edition) (some? (:object drawing)))
|
||||||
(not (ctl/grid-layout? objects edition)))
|
(not (ctl/grid-layout? objects edition)))
|
||||||
(let [undo (:workspace-undo state)
|
(let [undo (:workspace-undo state)
|
||||||
items (:items undo)
|
items (:items undo)
|
||||||
|
|
|
@ -182,11 +182,19 @@
|
||||||
|
|
||||||
(rx/of (shapes-changes-persisted-finished))))))
|
(rx/of (shapes-changes-persisted-finished))))))
|
||||||
(rx/catch (fn [cause]
|
(rx/catch (fn [cause]
|
||||||
|
(cond
|
||||||
|
(= :authentication (:type cause))
|
||||||
|
(rx/throw cause)
|
||||||
|
|
||||||
|
(instance? js/TypeError cause)
|
||||||
|
(->> (rx/timer 2000)
|
||||||
|
(rx/map (fn [_]
|
||||||
|
(persist-changes file-id file-revn changes pending-commits))))
|
||||||
|
|
||||||
|
:else
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(if (= :authentication (:type cause))
|
(rx/of (rt/assign-exception cause))
|
||||||
(rx/empty)
|
(rx/throw cause))))))))))
|
||||||
(rx/of (rt/assign-exception cause)))
|
|
||||||
(rx/throw cause)))))))))
|
|
||||||
|
|
||||||
;; Event to be thrown after the changes have been persisted
|
;; Event to be thrown after the changes have been persisted
|
||||||
(defn shapes-changes-persisted-finished
|
(defn shapes-changes-persisted-finished
|
||||||
|
|
|
@ -66,7 +66,8 @@
|
||||||
|
|
||||||
(defmethod ptk/handle-error :default
|
(defmethod ptk/handle-error :default
|
||||||
[error]
|
[error]
|
||||||
(ts/schedule #(st/emit! (rt/assign-exception (::instance error))))
|
(when-let [cause (::instance error)]
|
||||||
|
(ts/schedule #(st/emit! (rt/assign-exception cause))))
|
||||||
(print-group! "Unhandled Error"
|
(print-group! "Unhandled Error"
|
||||||
(fn []
|
(fn []
|
||||||
(print-trace! error)
|
(print-trace! error)
|
||||||
|
|
|
@ -145,6 +145,7 @@
|
||||||
|
|
||||||
(mf/with-effect [theme]
|
(mf/with-effect [theme]
|
||||||
(dom/set-html-theme-color theme))
|
(dom/set-html-theme-color theme))
|
||||||
|
|
||||||
[:& (mf/provider ctx/current-route) {:value route}
|
[:& (mf/provider ctx/current-route) {:value route}
|
||||||
[:& (mf/provider ctx/current-profile) {:value profile}
|
[:& (mf/provider ctx/current-profile) {:value profile}
|
||||||
(if edata
|
(if edata
|
||||||
|
|
|
@ -214,7 +214,11 @@
|
||||||
:select-on-focus true
|
:select-on-focus true
|
||||||
:on-change on-change}]
|
:on-change on-change}]
|
||||||
[:div.buttons
|
[:div.buttons
|
||||||
[:input.btn-primary {:type "button" :value "Post" :on-click on-submit*}]
|
[:input.btn-primary {:type "button"
|
||||||
|
:value "Post"
|
||||||
|
:on-click on-submit*
|
||||||
|
:disabled (or (fm/all-spaces? @content)
|
||||||
|
(str/empty-or-nil? @content))}]
|
||||||
[:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]]]))
|
[:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]]]))
|
||||||
|
|
||||||
(mf/defc comment-item
|
(mf/defc comment-item
|
||||||
|
|
|
@ -481,3 +481,13 @@
|
||||||
(cond-> errors
|
(cond-> errors
|
||||||
(all-spaces? (get data field))
|
(all-spaces? (get data field))
|
||||||
(assoc field {:message error-msg}))))
|
(assoc field {:message error-msg}))))
|
||||||
|
|
||||||
|
(defn validate-not-all-spaces
|
||||||
|
[field error-msg]
|
||||||
|
(fn [errors data]
|
||||||
|
(let [value (get data field)]
|
||||||
|
(cond-> errors
|
||||||
|
(and
|
||||||
|
(all-spaces? value)
|
||||||
|
(> (count value) 0))
|
||||||
|
(assoc field {:message error-msg})))))
|
||||||
|
|
|
@ -22,17 +22,12 @@
|
||||||
|
|
||||||
(mf/defc comments-section
|
(mf/defc comments-section
|
||||||
[{:keys [profile team]}]
|
[{:keys [profile team]}]
|
||||||
|
|
||||||
(mf/use-effect
|
|
||||||
(mf/deps team)
|
|
||||||
(fn []
|
|
||||||
(st/emit! (dcm/retrieve-unread-comment-threads (:id team)))))
|
|
||||||
|
|
||||||
(let [show-dropdown? (mf/use-state false)
|
(let [show-dropdown? (mf/use-state false)
|
||||||
show-dropdown (mf/use-fn #(reset! show-dropdown? true))
|
show-dropdown (mf/use-fn #(reset! show-dropdown? true))
|
||||||
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
|
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
|
||||||
threads-map (mf/deref refs/comment-threads)
|
threads-map (mf/deref refs/comment-threads)
|
||||||
users (mf/deref refs/current-team-comments-users)
|
users (mf/deref refs/current-team-comments-users)
|
||||||
|
team-id (:id team)
|
||||||
|
|
||||||
tgroups (->> (vals threads-map)
|
tgroups (->> (vals threads-map)
|
||||||
(sort-by :modified-at)
|
(sort-by :modified-at)
|
||||||
|
@ -46,6 +41,11 @@
|
||||||
(st/emit! (-> (dwcm/navigate thread)
|
(st/emit! (-> (dwcm/navigate thread)
|
||||||
(with-meta {::ev/origin "dashboard"})))))]
|
(with-meta {::ev/origin "dashboard"})))))]
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps team-id)
|
||||||
|
(fn []
|
||||||
|
(st/emit! (dcm/retrieve-unread-comment-threads team-id))))
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps @show-dropdown?)
|
(mf/deps @show-dropdown?)
|
||||||
(fn []
|
(fn []
|
||||||
|
|
|
@ -337,18 +337,18 @@
|
||||||
(st/emit! (modal/hide))
|
(st/emit! (modal/hide))
|
||||||
(when on-finish-import (on-finish-import))))
|
(when on-finish-import (on-finish-import))))
|
||||||
|
|
||||||
|
files (->> (:files @state) (filterv (comp not :deleted?)))
|
||||||
|
|
||||||
num-importing (+
|
num-importing (+
|
||||||
(->> @state :files (filter #(= (:status %) :importing)) count)
|
(->> files (filter #(= (:status %) :importing)) count)
|
||||||
(:importing-templates @state))
|
(:importing-templates @state))
|
||||||
|
|
||||||
|
|
||||||
warning-files (->> @state :files (filter #(and (= (:status %) :import-finish) (d/not-empty? (:errors %)))) count)
|
warning-files (->> files (filter #(and (= (:status %) :import-finish) (d/not-empty? (:errors %)))) count)
|
||||||
success-files (->> @state :files (filter #(and (= (:status %) :import-finish) (empty? (:errors %)))) count)
|
success-files (->> files (filter #(and (= (:status %) :import-finish) (empty? (:errors %)))) count)
|
||||||
pending-analysis? (> (->> @state :files (filter #(= (:status %) :analyzing)) count) 0)
|
pending-analysis? (> (->> files (filter #(= (:status %) :analyzing)) count) 0)
|
||||||
pending-import? (> num-importing 0)
|
pending-import? (> num-importing 0)
|
||||||
files (->> (:files @state) (filterv (comp not :deleted?)))
|
|
||||||
;; pending-import? (> (->> @state :files (filter #(= (:status %) :importing)) count) 0)
|
|
||||||
;; files (->> (:files @state) (filterv (comp not :deleted?)))
|
|
||||||
valid-files? (or (some? template)
|
valid-files? (or (some? template)
|
||||||
(> (+ (->> files (filterv (fn [x] (not= (:status x) :analyze-error))) count)) 0))]
|
(> (+ (->> files (filterv (fn [x] (not= (:status x) :analyze-error))) count)) 0))]
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@
|
||||||
|
|
||||||
[:div.modal-footer
|
[:div.modal-footer
|
||||||
[:div.action-buttons
|
[:div.action-buttons
|
||||||
(when (or (= :analyzing (:status @state)) pending-import?)
|
(when (= :analyzing (:status @state))
|
||||||
[:input.cancel-button
|
[:input.cancel-button
|
||||||
{:type "button"
|
{:type "button"
|
||||||
:value (tr "labels.cancel")
|
:value (tr "labels.cancel")
|
||||||
|
|
|
@ -71,7 +71,8 @@
|
||||||
[{:keys [locale] :as props}]
|
[{:keys [locale] :as props}]
|
||||||
(let [initial (mf/use-memo (constantly {:password-old nil}))
|
(let [initial (mf/use-memo (constantly {:password-old nil}))
|
||||||
form (fm/use-form :spec ::password-form
|
form (fm/use-form :spec ::password-form
|
||||||
:validators [(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
|
:validators [(fm/validate-not-all-spaces :password-old (tr "auth.password-not-empty"))
|
||||||
|
(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
|
||||||
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))
|
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))
|
||||||
password-equality]
|
password-equality]
|
||||||
:initial initial)]
|
:initial initial)]
|
||||||
|
|
|
@ -28,19 +28,25 @@
|
||||||
(seq (:fills shape)))))
|
(seq (:fills shape)))))
|
||||||
|
|
||||||
(mf/defc fill-block
|
(mf/defc fill-block
|
||||||
|
{::mf/wrap-props false}
|
||||||
[{:keys [objects shape]}]
|
[{:keys [objects shape]}]
|
||||||
(let [color-format (mf/use-state :hex)
|
(let [format* (mf/use-state :hex)
|
||||||
color (shape->color shape)]
|
format (deref format*)
|
||||||
|
|
||||||
|
color (shape->color shape)
|
||||||
|
on-change (mf/use-fn #(reset! format* %))]
|
||||||
|
|
||||||
[:div.attributes-fill-block
|
[:div.attributes-fill-block
|
||||||
[:& color-row {:color color
|
[:& color-row
|
||||||
:format @color-format
|
{:color color
|
||||||
:on-change-format #(reset! color-format %)
|
:format format
|
||||||
|
:on-change-format on-change
|
||||||
:copy-data (css/get-shape-properties-css objects {:fills [shape]} properties)}]]))
|
:copy-data (css/get-shape-properties-css objects {:fills [shape]} properties)}]]))
|
||||||
|
|
||||||
(mf/defc fill-panel
|
(mf/defc fill-panel
|
||||||
|
{::mf/wrap-props false}
|
||||||
[{:keys [shapes]}]
|
[{:keys [shapes]}]
|
||||||
(let [shapes (->> shapes (filter has-fill?))]
|
(let [shapes (filter has-fill? shapes)]
|
||||||
(when (seq shapes)
|
(when (seq shapes)
|
||||||
[:div.attributes-block
|
[:div.attributes-block
|
||||||
[:div.attributes-block-title
|
[:div.attributes-block-title
|
||||||
|
|
|
@ -31,7 +31,10 @@
|
||||||
file-id (mf/use-ctx ctx/current-file-id)
|
file-id (mf/use-ctx ctx/current-file-id)
|
||||||
|
|
||||||
on-click
|
on-click
|
||||||
(mf/use-fn #(dom/click (mf/ref-val ref)))
|
(mf/use-fn
|
||||||
|
(fn []
|
||||||
|
(st/emit! :interrupt dw/clear-edition-mode)
|
||||||
|
(dom/click (mf/ref-val ref))))
|
||||||
|
|
||||||
on-selected
|
on-selected
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|
|
@ -31,9 +31,11 @@
|
||||||
state (mf/deref refs/export)
|
state (mf/deref refs/export)
|
||||||
in-progress? (:in-progress state)
|
in-progress? (:in-progress state)
|
||||||
|
|
||||||
|
shapes-with-exports (->> (wsh/lookup-shapes @st/state ids)
|
||||||
|
(filter #(pos? (count (:exports %)))))
|
||||||
|
|
||||||
sname (when (seqable? exports)
|
sname (when (seqable? exports)
|
||||||
(let [shapes (wsh/lookup-shapes @st/state ids)
|
(let [sname (-> shapes-with-exports first :name)
|
||||||
sname (-> shapes first :name)
|
|
||||||
suffix (-> exports first :suffix)]
|
suffix (-> exports first :suffix)]
|
||||||
(cond-> sname
|
(cond-> sname
|
||||||
(and (= 1 (count exports)) (some? suffix))
|
(and (= 1 (count exports)) (some? suffix))
|
||||||
|
@ -50,7 +52,22 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(if (= :multiple type)
|
(if (= :multiple type)
|
||||||
(st/emit! (de/show-workspace-export-dialog {:selected (reverse ids)}))
|
;; I can select multiple shapes all of them with no export settings and one of them with only one
|
||||||
|
;; In that situation we must export it directly
|
||||||
|
(if (and (= 1 (count shapes-with-exports)) (= 1 (-> shapes-with-exports first :exports count)))
|
||||||
|
(let [shape (-> shapes-with-exports first)
|
||||||
|
export (-> shape :exports first)
|
||||||
|
sname (:name shape)
|
||||||
|
suffix (:suffix export)
|
||||||
|
defaults {:page-id page-id
|
||||||
|
:file-id file-id
|
||||||
|
:name sname
|
||||||
|
:object-id (:id (first shapes-with-exports))}]
|
||||||
|
(cond-> sname
|
||||||
|
(some? suffix)
|
||||||
|
(str suffix))
|
||||||
|
(st/emit! (de/request-simple-export {:export (merge export defaults)})))
|
||||||
|
(st/emit! (de/show-workspace-export-dialog {:selected (reverse ids)})))
|
||||||
|
|
||||||
;; In other all cases we only allowed to have a single
|
;; In other all cases we only allowed to have a single
|
||||||
;; shape-id because multiple shape-ids are handled
|
;; shape-id because multiple shape-ids are handled
|
||||||
|
@ -182,4 +199,4 @@
|
||||||
:disabled in-progress?}
|
:disabled in-progress?}
|
||||||
(if in-progress?
|
(if in-progress?
|
||||||
(tr "workspace.options.exporting-object")
|
(tr "workspace.options.exporting-object")
|
||||||
(tr "workspace.options.export-object" (c (count ids))))])]))
|
(tr "workspace.options.export-object" (c (count shapes-with-exports))))])]))
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
:selected-blend-mode value
|
:selected-blend-mode value
|
||||||
:option-highlighted? false
|
:option-highlighted? false
|
||||||
:preview-complete? true)
|
:preview-complete? true)
|
||||||
|
(st/emit! (dw/unset-preview-blend-mode ids))
|
||||||
(on-change :blend-mode value)))
|
(on-change :blend-mode value)))
|
||||||
|
|
||||||
handle-blend-mode-enter
|
handle-blend-mode-enter
|
||||||
|
@ -152,7 +153,7 @@
|
||||||
[:div.element-set-content
|
[:div.element-set-content
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:& select
|
[:& select
|
||||||
{:class "flex-grow"
|
{:class "flex-grow no-check"
|
||||||
:default-value selected-blend-mode
|
:default-value selected-blend-mode
|
||||||
:options options
|
:options options
|
||||||
:on-change handle-change-blend-mode
|
:on-change handle-change-blend-mode
|
||||||
|
|
|
@ -269,7 +269,7 @@
|
||||||
[:div#sitemap.tool-window {:ref parent-ref
|
[:div#sitemap.tool-window {:ref parent-ref
|
||||||
:style #js {"--height" (str size "px")}}
|
:style #js {"--height" (str size "px")}}
|
||||||
[:div.tool-window-bar
|
[:div.tool-window-bar
|
||||||
[:span (tr "workspace.sidebar.sitemap")]
|
[:span.pages-title (tr "workspace.sidebar.sitemap")]
|
||||||
(if workspace-read-only?
|
(if workspace-read-only?
|
||||||
[:div.view-only-mode (tr "labels.view-only")]
|
[:div.view-only-mode (tr "labels.view-only")]
|
||||||
[:div.add-page {:on-click create} i/close])
|
[:div.add-page {:on-click create} i/close])
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.util.color
|
(ns app.util.color
|
||||||
"Color conversion utils."
|
"Color conversion utils."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.strings :as ust]
|
[app.util.strings :as ust]
|
||||||
|
@ -150,6 +151,24 @@
|
||||||
|
|
||||||
:else "transparent")))
|
:else "transparent")))
|
||||||
|
|
||||||
|
(defn color->format->background [{:keys [color opacity gradient]} format]
|
||||||
|
(let [opacity (or opacity 1)]
|
||||||
|
(cond
|
||||||
|
(and gradient (not= :multiple gradient))
|
||||||
|
(gradient->css gradient)
|
||||||
|
|
||||||
|
(not= color :multiple)
|
||||||
|
(case format
|
||||||
|
:rgba (let [[r g b] (hex->rgb color)]
|
||||||
|
(str/fmt "rgba(%s, %s, %s, %s)" r g b opacity))
|
||||||
|
|
||||||
|
:hsla (let [[h s l] (hex->hsl color)]
|
||||||
|
(str/fmt "hsla(%s, %s, %s, %s)" h (* 100 s) (* 100 l) opacity))
|
||||||
|
|
||||||
|
:hex (str color (str/upper (d/opacity-to-hex opacity))))
|
||||||
|
|
||||||
|
:else "transparent")))
|
||||||
|
|
||||||
(defn multiple? [{:keys [id file-id value color gradient]}]
|
(defn multiple? [{:keys [id file-id value color gradient]}]
|
||||||
(or (= value :multiple)
|
(or (= value :multiple)
|
||||||
(= color :multiple)
|
(= color :multiple)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue