mirror of
https://github.com/penpot/penpot.git
synced 2025-06-06 23:11:39 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
60530a80d9
30 changed files with 191 additions and 182 deletions
|
@ -67,6 +67,7 @@ is a number of cores)
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
- Fix menu shadow color [Taiga #10102](https://tree.taiga.io/project/penpot/issue/10102)
|
- Fix menu shadow color [Taiga #10102](https://tree.taiga.io/project/penpot/issue/10102)
|
||||||
|
- Fix missing state refresh on notifications update [Taiga #10253](https://tree.taiga.io/project/penpot/issue/10253)
|
||||||
- Fix icon visualization on select component [Taiga #8889](https://tree.taiga.io/project/penpot/issue/8889)
|
- Fix icon visualization on select component [Taiga #8889](https://tree.taiga.io/project/penpot/issue/8889)
|
||||||
- Fix typo on integration tests docs [Taiga #10112](https://tree.taiga.io/project/penpot/issue/10112)
|
- Fix typo on integration tests docs [Taiga #10112](https://tree.taiga.io/project/penpot/issue/10112)
|
||||||
- Fix problem with alt key measures being stuck [Taiga #9348](https://tree.taiga.io/project/penpot/issue/9348)
|
- Fix problem with alt key measures being stuck [Taiga #9348](https://tree.taiga.io/project/penpot/issue/9348)
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
binfile format implementations and management rpc methods."
|
binfile format implementations and management rpc methods."
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.features :as cfeat]
|
[app.common.features :as cfeat]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
|
@ -219,10 +218,8 @@
|
||||||
"Given a set of file-id's, return all matching relations with the libraries"
|
"Given a set of file-id's, return all matching relations with the libraries"
|
||||||
[cfg ids]
|
[cfg ids]
|
||||||
|
|
||||||
(dm/assert!
|
(assert (set? ids) "expected a set of uuids")
|
||||||
"expected a set of uuids"
|
(assert (every? uuid? ids) "expected a set of uuids")
|
||||||
(and (set? ids)
|
|
||||||
(every? uuid? ids)))
|
|
||||||
|
|
||||||
(db/run! cfg (fn [{:keys [::db/conn]}]
|
(db/run! cfg (fn [{:keys [::db/conn]}]
|
||||||
(let [ids (db/create-array conn "uuid" ids)
|
(let [ids (db/create-array conn "uuid" ids)
|
||||||
|
@ -503,9 +500,7 @@
|
||||||
specific, should not be used outside of binfile domain"
|
specific, should not be used outside of binfile domain"
|
||||||
[{:keys [::timestamp] :as cfg} file & {:as opts}]
|
[{:keys [::timestamp] :as cfg} file & {:as opts}]
|
||||||
|
|
||||||
(dm/assert!
|
(assert (dt/instant? timestamp) "expected valid timestamp")
|
||||||
"expected valid timestamp"
|
|
||||||
(dt/instant? timestamp))
|
|
||||||
|
|
||||||
(let [file (-> file
|
(let [file (-> file
|
||||||
(assoc :created-at timestamp)
|
(assoc :created-at timestamp)
|
||||||
|
@ -513,12 +508,11 @@
|
||||||
(assoc :ignore-sync-until (dt/plus timestamp (dt/duration {:seconds 5})))
|
(assoc :ignore-sync-until (dt/plus timestamp (dt/duration {:seconds 5})))
|
||||||
(update :features
|
(update :features
|
||||||
(fn [features]
|
(fn [features]
|
||||||
(let [features (cfeat/check-supported-features! features)]
|
|
||||||
(-> (::features cfg #{})
|
(-> (::features cfg #{})
|
||||||
(set/union features)
|
(set/union features)
|
||||||
;; We never want to store
|
;; We never want to store
|
||||||
;; frontend-only features on file
|
;; frontend-only features on file
|
||||||
(set/difference cfeat/frontend-only-features))))))]
|
(set/difference cfeat/frontend-only-features)))))]
|
||||||
|
|
||||||
(when (contains? cf/flags :file-schema-validation)
|
(when (contains? cf/flags :file-schema-validation)
|
||||||
(fval/validate-file-schema! file))
|
(fval/validate-file-schema! file))
|
||||||
|
@ -542,7 +536,6 @@
|
||||||
|
|
||||||
file)
|
file)
|
||||||
|
|
||||||
|
|
||||||
(defn apply-pending-migrations!
|
(defn apply-pending-migrations!
|
||||||
"Apply alredy registered pending migrations to files"
|
"Apply alredy registered pending migrations to files"
|
||||||
[cfg]
|
[cfg]
|
||||||
|
|
|
@ -875,14 +875,17 @@
|
||||||
:manifest manifest))
|
:manifest manifest))
|
||||||
|
|
||||||
;; Check if all files referenced on manifest are present
|
;; Check if all files referenced on manifest are present
|
||||||
(doseq [{file-id :id} (:files manifest)]
|
(doseq [{file-id :id features :features} (:files manifest)]
|
||||||
(let [path (str "files/" file-id ".json")]
|
(let [path (str "files/" file-id ".json")]
|
||||||
|
|
||||||
(when-not (get-zip-entry input path)
|
(when-not (get-zip-entry input path)
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :invalid-binfile-v3
|
:code :invalid-binfile-v3
|
||||||
:hint "some files referenced on manifest not found"
|
:hint "some files referenced on manifest not found"
|
||||||
:path path
|
:path path
|
||||||
:file-id file-id))))
|
:file-id file-id))
|
||||||
|
|
||||||
|
(cfeat/check-supported-features! features)))
|
||||||
|
|
||||||
(events/tap :progress {:section :manifest})
|
(events/tap :progress {:section :manifest})
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[app.binfile.v3 :as bf.v3]
|
[app.binfile.v3 :as bf.v3]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
|
[app.common.features :as cfeat]
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
[app.common.pprint :as pp]
|
[app.common.pprint :as pp]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
[app.rpc.commands.auth :as auth]
|
[app.rpc.commands.auth :as auth]
|
||||||
[app.rpc.commands.files-create :refer [create-file]]
|
[app.rpc.commands.files-create :refer [create-file]]
|
||||||
[app.rpc.commands.profile :as profile]
|
[app.rpc.commands.profile :as profile]
|
||||||
|
[app.rpc.commands.teams :as teams]
|
||||||
[app.setup :as-alias setup]
|
[app.setup :as-alias setup]
|
||||||
[app.srepl.helpers :as srepl]
|
[app.srepl.helpers :as srepl]
|
||||||
[app.storage :as-alias sto]
|
[app.storage :as-alias sto]
|
||||||
|
@ -317,7 +319,10 @@
|
||||||
:hint "missing upload file"))
|
:hint "missing upload file"))
|
||||||
|
|
||||||
(let [profile (profile/get-profile pool profile-id)
|
(let [profile (profile/get-profile pool profile-id)
|
||||||
project-id (:default-project-id profile)]
|
project-id (:default-project-id profile)
|
||||||
|
team (teams/get-team pool
|
||||||
|
:profile-id profile-id
|
||||||
|
:project-id project-id)]
|
||||||
|
|
||||||
(when-not project-id
|
(when-not project-id
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
|
@ -329,7 +334,8 @@
|
||||||
cfg (assoc cfg
|
cfg (assoc cfg
|
||||||
::bfc/profile-id profile-id
|
::bfc/profile-id profile-id
|
||||||
::bfc/project-id project-id
|
::bfc/project-id project-id
|
||||||
::bfc/input path)]
|
::bfc/input path
|
||||||
|
::bfc/features (cfeat/get-team-enabled-features cf/flags team))]
|
||||||
|
|
||||||
(if (= format :binfile-v3)
|
(if (= format :binfile-v3)
|
||||||
(bf.v3/import-files! cfg)
|
(bf.v3/import-files! cfg)
|
||||||
|
|
|
@ -10,8 +10,10 @@
|
||||||
[app.binfile.common :as bfc]
|
[app.binfile.common :as bfc]
|
||||||
[app.binfile.v1 :as bf.v1]
|
[app.binfile.v1 :as bf.v1]
|
||||||
[app.binfile.v3 :as bf.v3]
|
[app.binfile.v3 :as bf.v3]
|
||||||
|
[app.common.features :as cfeat]
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
|
[app.config :as cf]
|
||||||
[app.db :as db]
|
[app.db :as db]
|
||||||
[app.http.sse :as sse]
|
[app.http.sse :as sse]
|
||||||
[app.loggers.audit :as-alias audit]
|
[app.loggers.audit :as-alias audit]
|
||||||
|
@ -20,6 +22,7 @@
|
||||||
[app.rpc :as-alias rpc]
|
[app.rpc :as-alias rpc]
|
||||||
[app.rpc.commands.files :as files]
|
[app.rpc.commands.files :as files]
|
||||||
[app.rpc.commands.projects :as projects]
|
[app.rpc.commands.projects :as projects]
|
||||||
|
[app.rpc.commands.teams :as teams]
|
||||||
[app.rpc.doc :as-alias doc]
|
[app.rpc.doc :as-alias doc]
|
||||||
[app.tasks.file-gc]
|
[app.tasks.file-gc]
|
||||||
[app.util.services :as sv]
|
[app.util.services :as sv]
|
||||||
|
@ -91,41 +94,30 @@
|
||||||
|
|
||||||
;; --- Command: import-binfile
|
;; --- Command: import-binfile
|
||||||
|
|
||||||
(defn- import-binfile-v1
|
|
||||||
[{:keys [::wrk/executor] :as cfg} {:keys [project-id profile-id name file]}]
|
|
||||||
(let [cfg (-> cfg
|
|
||||||
(assoc ::bfc/project-id project-id)
|
|
||||||
(assoc ::bfc/profile-id profile-id)
|
|
||||||
(assoc ::bfc/name name)
|
|
||||||
(assoc ::bfc/input (:path file)))]
|
|
||||||
|
|
||||||
;; NOTE: the importation process performs some operations that are
|
|
||||||
;; not very friendly with virtual threads, and for avoid
|
|
||||||
;; unexpected blocking of other concurrent operations we dispatch
|
|
||||||
;; that operation to a dedicated executor.
|
|
||||||
(px/invoke! executor (partial bf.v1/import-files! cfg))))
|
|
||||||
|
|
||||||
(defn- import-binfile-v3
|
|
||||||
[{:keys [::wrk/executor] :as cfg} {:keys [project-id profile-id name file]}]
|
|
||||||
(let [cfg (-> cfg
|
|
||||||
(assoc ::bfc/project-id project-id)
|
|
||||||
(assoc ::bfc/profile-id profile-id)
|
|
||||||
(assoc ::bfc/name name)
|
|
||||||
(assoc ::bfc/input (:path file)))]
|
|
||||||
;; NOTE: the importation process performs some operations that are
|
|
||||||
;; not very friendly with virtual threads, and for avoid
|
|
||||||
;; unexpected blocking of other concurrent operations we dispatch
|
|
||||||
;; that operation to a dedicated executor.
|
|
||||||
(px/invoke! executor (partial bf.v3/import-files! cfg))))
|
|
||||||
|
|
||||||
(defn- import-binfile
|
(defn- import-binfile
|
||||||
[{:keys [::db/pool] :as cfg} {:keys [project-id version] :as params}]
|
[{:keys [::db/pool ::wrk/executor] :as cfg} {:keys [profile-id project-id version name file]}]
|
||||||
(let [result (case (int version)
|
(let [team (teams/get-team pool
|
||||||
1 (import-binfile-v1 cfg params)
|
:profile-id profile-id
|
||||||
3 (import-binfile-v3 cfg params))]
|
:project-id project-id)
|
||||||
|
cfg (-> cfg
|
||||||
|
(assoc ::bfc/features (cfeat/get-team-enabled-features cf/flags team))
|
||||||
|
(assoc ::bfc/project-id project-id)
|
||||||
|
(assoc ::bfc/profile-id profile-id)
|
||||||
|
(assoc ::bfc/name name)
|
||||||
|
(assoc ::bfc/input (:path file)))
|
||||||
|
|
||||||
|
;; NOTE: the importation process performs some operations that are
|
||||||
|
;; not very friendly with virtual threads, and for avoid
|
||||||
|
;; unexpected blocking of other concurrent operations we dispatch
|
||||||
|
;; that operation to a dedicated executor.
|
||||||
|
result (case (int version)
|
||||||
|
1 (px/invoke! executor (partial bf.v1/import-files! cfg))
|
||||||
|
3 (px/invoke! executor (partial bf.v3/import-files! cfg)))]
|
||||||
|
|
||||||
(db/update! pool :project
|
(db/update! pool :project
|
||||||
{:modified-at (dt/now)}
|
{:modified-at (dt/now)}
|
||||||
{:id project-id})
|
{:id project-id})
|
||||||
|
|
||||||
result))
|
result))
|
||||||
|
|
||||||
(def ^:private schema:import-binfile
|
(def ^:private schema:import-binfile
|
||||||
|
|
|
@ -406,12 +406,16 @@
|
||||||
:prefix "penpot.template."
|
:prefix "penpot.template."
|
||||||
:suffix ""
|
:suffix ""
|
||||||
:min-age "30m")
|
:min-age "30m")
|
||||||
format (bfc/parse-file-format template)
|
|
||||||
|
|
||||||
|
format (bfc/parse-file-format template)
|
||||||
|
team (teams/get-team conn
|
||||||
|
:profile-id profile-id
|
||||||
|
:project-id project-id)
|
||||||
cfg (-> cfg
|
cfg (-> cfg
|
||||||
(assoc ::bfc/project-id project-id)
|
(assoc ::bfc/project-id project-id)
|
||||||
(assoc ::bfc/profile-id profile-id)
|
(assoc ::bfc/profile-id profile-id)
|
||||||
(assoc ::bfc/input template))
|
(assoc ::bfc/input template)
|
||||||
|
(assoc ::bfc/features (cfeat/get-team-enabled-features cf/flags team)))
|
||||||
|
|
||||||
result (if (= format :binfile-v3)
|
result (if (= format :binfile-v3)
|
||||||
(px/invoke! executor (partial bf.v3/import-files! cfg))
|
(px/invoke! executor (partial bf.v3/import-files! cfg))
|
||||||
|
|
|
@ -14,11 +14,12 @@
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.media :as di]
|
[app.main.data.media :as di]
|
||||||
|
[app.main.data.notifications :as ntf]
|
||||||
[app.main.data.team :as-alias dtm]
|
[app.main.data.team :as-alias dtm]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.router :as rt]
|
[app.main.router :as rt]
|
||||||
[app.plugins.register :as plugins.register]
|
[app.plugins.register :as plugins.register]
|
||||||
[app.util.i18n :as i18n]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.storage :as storage]
|
[app.util.storage :as storage]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -239,25 +240,24 @@
|
||||||
[:email-comments [::sm/one-of #{:all :partial :none}]]
|
[:email-comments [::sm/one-of #{:all :partial :none}]]
|
||||||
[:email-invites [::sm/one-of #{:all :none}]]])
|
[:email-invites [::sm/one-of #{:all :none}]]])
|
||||||
|
|
||||||
|
(def ^:private check-update-notifications-params
|
||||||
|
(sm/check-fn schema:update-notifications))
|
||||||
|
|
||||||
(defn update-notifications
|
(defn update-notifications
|
||||||
[data]
|
[data]
|
||||||
(dm/assert!
|
(assert (check-update-notifications-params data))
|
||||||
"expected valid parameters"
|
|
||||||
(sm/check schema:update-notifications data))
|
|
||||||
|
|
||||||
(ptk/reify ::update-notifications
|
(ptk/reify ::update-notifications
|
||||||
ev/Event
|
ev/Event
|
||||||
(-data [_] {})
|
(-data [_] {})
|
||||||
|
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update-in state [:profile :props] assoc :notifications data))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(let [{:keys [on-error on-success]
|
|
||||||
:or {on-error identity
|
|
||||||
on-success identity}} (meta data)]
|
|
||||||
(->> (rp/cmd! :update-profile-notifications data)
|
(->> (rp/cmd! :update-profile-notifications data)
|
||||||
(rx/tap on-success)
|
(rx/map #(ntf/success (tr "dashboard.notifications.notifications-saved")))))))
|
||||||
(rx/catch #(do (on-error %) (rx/empty)))
|
|
||||||
(rx/ignore))))))
|
|
||||||
|
|
||||||
(defn update-profile-props
|
(defn update-profile-props
|
||||||
[props]
|
[props]
|
||||||
|
|
|
@ -168,11 +168,13 @@
|
||||||
(assoc file :data (d/removem (comp t/pointer? val) data))))))))))
|
(assoc file :data (d/removem (comp t/pointer? val) data))))))))))
|
||||||
|
|
||||||
(defn- libraries-fetched
|
(defn- libraries-fetched
|
||||||
[libraries]
|
[file-id libraries]
|
||||||
(ptk/reify ::libraries-fetched
|
(ptk/reify ::libraries-fetched
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [libraries (d/index-by :id libraries)]
|
(let [libraries (->> libraries
|
||||||
|
(map (fn [l] (assoc l :library-of file-id)))
|
||||||
|
(d/index-by :id))]
|
||||||
(update state :files merge libraries)))
|
(update state :files merge libraries)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
@ -208,7 +210,7 @@
|
||||||
(rx/map #(assoc % :synced-at synced-at)))))
|
(rx/map #(assoc % :synced-at synced-at)))))
|
||||||
(rx/merge-map resolve-file)
|
(rx/merge-map resolve-file)
|
||||||
(rx/reduce conj [])
|
(rx/reduce conj [])
|
||||||
(rx/map libraries-fetched))
|
(rx/map (partial libraries-fetched file-id)))
|
||||||
(->> (rx/from libraries)
|
(->> (rx/from libraries)
|
||||||
(rx/map :id)
|
(rx/map :id)
|
||||||
(rx/mapcat (fn [file-id]
|
(rx/mapcat (fn [file-id]
|
||||||
|
|
|
@ -1203,7 +1203,7 @@
|
||||||
(vals (get state :files)))
|
(vals (get state :files)))
|
||||||
|
|
||||||
do-more-info
|
do-more-info
|
||||||
#(modal/show! :libraries-dialog {:starting-tab "updates"})
|
#(modal/show! :libraries-dialog {:starting-tab "updates" :file-id file-id})
|
||||||
|
|
||||||
do-update
|
do-update
|
||||||
#(do (apply st/emit! (map (fn [library]
|
#(do (apply st/emit! (map (fn [library]
|
||||||
|
@ -1390,7 +1390,10 @@
|
||||||
(let [libraries (:workspace-shared-files state)
|
(let [libraries (:workspace-shared-files state)
|
||||||
library (d/seek #(= (:id %) library-id) libraries)]
|
library (d/seek #(= (:id %) library-id) libraries)]
|
||||||
(if library
|
(if library
|
||||||
(update state :files assoc library-id (dissoc library :library-summary))
|
(update state :files assoc library-id
|
||||||
|
(-> library
|
||||||
|
(dissoc :library-summary)
|
||||||
|
(assoc :library-of file-id)))
|
||||||
state)))
|
state)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
@ -1403,6 +1406,8 @@
|
||||||
(->> (rp/cmd! :get-file {:id library-id :features features})
|
(->> (rp/cmd! :get-file {:id library-id :features features})
|
||||||
(rx/merge-map fpmap/resolve-file)
|
(rx/merge-map fpmap/resolve-file)
|
||||||
;; FIXME: this should call the libraries-fetched event instead of ad-hoc assoc event
|
;; FIXME: this should call the libraries-fetched event instead of ad-hoc assoc event
|
||||||
|
(rx/map (fn [file]
|
||||||
|
(assoc file :library-of file-id)))
|
||||||
(rx/map (fn [file]
|
(rx/map (fn [file]
|
||||||
(fn [state]
|
(fn [state]
|
||||||
(assoc-in state [:files library-id] file)))))
|
(assoc-in state [:files library-id] file)))))
|
||||||
|
|
|
@ -83,10 +83,32 @@
|
||||||
files (without the content, only summary)"
|
files (without the content, only summary)"
|
||||||
(l/derived :shared-files st/state))
|
(l/derived :shared-files st/state))
|
||||||
|
|
||||||
|
(defn select-libraries
|
||||||
|
[files file-id]
|
||||||
|
(persistent!
|
||||||
|
(reduce-kv (fn [result id file]
|
||||||
|
(if (or (= id file-id)
|
||||||
|
(= (:library-of file) file-id))
|
||||||
|
(assoc! result id file)
|
||||||
|
result))
|
||||||
|
(transient {})
|
||||||
|
files)))
|
||||||
|
|
||||||
|
;; NOTE: for performance reasons, prefer derefing refs/files and then
|
||||||
|
;; use with-memo mechanism with `select-libraries` this will avoid
|
||||||
|
;; executing the select-libraries reduce-kv on each state change and
|
||||||
|
;; only execute it when files are changed. This ref exists for
|
||||||
|
;; backward compatibility with the code, but it is considered
|
||||||
|
;; DEPRECATED and all new code should not use it and old code should
|
||||||
|
;; be gradually migrated to more efficient approach
|
||||||
(def libraries
|
(def libraries
|
||||||
"A derived state that contanins the currently loaded shared libraries
|
"A derived state that contanins the currently loaded shared
|
||||||
with all its content; including the current file"
|
libraries with all its content; including the current file"
|
||||||
(l/derived :files st/state))
|
(l/derived (fn [state]
|
||||||
|
(let [files (get state :files)
|
||||||
|
file-id (get state :current-file-id)]
|
||||||
|
(select-libraries files file-id)))
|
||||||
|
st/state))
|
||||||
|
|
||||||
(defn extract-selected-files
|
(defn extract-selected-files
|
||||||
[files selected]
|
[files selected]
|
||||||
|
|
|
@ -56,10 +56,12 @@
|
||||||
(make-typographies-library-ref (:typography-ref-file style)))
|
(make-typographies-library-ref (:typography-ref-file style)))
|
||||||
|
|
||||||
typography-library (mf/deref typography-library-ref)
|
typography-library (mf/deref typography-library-ref)
|
||||||
|
|
||||||
|
;; FIXME: too many duplicate operations
|
||||||
file-typographies-viewer (mf/deref file-typographies-ref)
|
file-typographies-viewer (mf/deref file-typographies-ref)
|
||||||
file-typographies-workspace (mf/deref refs/workspace-file-typography)
|
file-typographies-workspace (mf/deref refs/workspace-file-typography)
|
||||||
|
|
||||||
file-library-workspace (get (mf/deref refs/libraries) (:typography-ref-file style))
|
file-library-workspace (get (mf/deref refs/files) (:typography-ref-file style))
|
||||||
typography-external-lib (get-in file-library-workspace [:data :typographies (:typography-ref-id style)])
|
typography-external-lib (get-in file-library-workspace [:data :typographies (:typography-ref-id style)])
|
||||||
|
|
||||||
color-format (mf/use-state :hex)
|
color-format (mf/use-state :hex)
|
||||||
|
|
|
@ -26,12 +26,7 @@
|
||||||
"Retrieve all libraries, including the local file, on workspace or viewer"
|
"Retrieve all libraries, including the local file, on workspace or viewer"
|
||||||
[from]
|
[from]
|
||||||
(if (= from :workspace)
|
(if (= from :workspace)
|
||||||
(let [workspace-data (deref refs/workspace-data)
|
(deref refs/libraries)
|
||||||
{:keys [id] :as local} workspace-data
|
|
||||||
libraries (deref refs/libraries)]
|
|
||||||
(-> libraries
|
|
||||||
(assoc id {:id id
|
|
||||||
:data local})))
|
|
||||||
(let [viewer-data (deref refs/viewer-data)
|
(let [viewer-data (deref refs/viewer-data)
|
||||||
local (get-in viewer-data [:file :data])
|
local (get-in viewer-data [:file :data])
|
||||||
id (get local :id)
|
id (get local :id)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
[app.main.ui.settings.change-email]
|
[app.main.ui.settings.change-email]
|
||||||
[app.main.ui.settings.delete-account]
|
[app.main.ui.settings.delete-account]
|
||||||
[app.main.ui.settings.feedback :refer [feedback-page]]
|
[app.main.ui.settings.feedback :refer [feedback-page]]
|
||||||
[app.main.ui.settings.notifications :refer [notifications-page]]
|
[app.main.ui.settings.notifications :refer [notifications-page*]]
|
||||||
[app.main.ui.settings.options :refer [options-page]]
|
[app.main.ui.settings.options :refer [options-page]]
|
||||||
[app.main.ui.settings.password :refer [password-page]]
|
[app.main.ui.settings.password :refer [password-page]]
|
||||||
[app.main.ui.settings.profile :refer [profile-page]]
|
[app.main.ui.settings.profile :refer [profile-page]]
|
||||||
|
@ -71,4 +71,4 @@
|
||||||
[:& access-tokens-page]
|
[:& access-tokens-page]
|
||||||
|
|
||||||
:settings-notifications
|
:settings-notifications
|
||||||
[:& notifications-page])]]]]))
|
[:& notifications-page* {:profile profile}])]]]]))
|
||||||
|
|
|
@ -9,14 +9,11 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.main.data.notifications :as ntf]
|
|
||||||
[app.main.data.profile :as dp]
|
[app.main.data.profile :as dp]
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.forms :as fm]
|
[app.main.ui.components.forms :as fm]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[okulary.core :as l]
|
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def default-notification-settings
|
(def default-notification-settings
|
||||||
|
@ -24,29 +21,9 @@
|
||||||
:email-comments :partial
|
:email-comments :partial
|
||||||
:email-invites :all})
|
:email-invites :all})
|
||||||
|
|
||||||
(def notification-settings-ref
|
|
||||||
(l/derived
|
|
||||||
(fn [profile]
|
|
||||||
(-> (merge default-notification-settings
|
|
||||||
(-> profile :props :notifications))
|
|
||||||
(d/update-vals d/name)))
|
|
||||||
refs/profile))
|
|
||||||
|
|
||||||
(defn- on-error
|
|
||||||
[form _]
|
|
||||||
(reset! form nil)
|
|
||||||
(st/emit! (ntf/error (tr "generic.error"))))
|
|
||||||
|
|
||||||
(defn- on-success
|
|
||||||
[_]
|
|
||||||
(st/emit! (ntf/success (tr "dashboard.notifications.notifications-saved"))))
|
|
||||||
|
|
||||||
(defn- on-submit
|
(defn- on-submit
|
||||||
[form event]
|
[form _event]
|
||||||
(dom/prevent-default event)
|
(let [params (:clean-data @form)]
|
||||||
(let [params (with-meta (:clean-data @form)
|
|
||||||
{:on-success (partial on-success form)
|
|
||||||
:on-error (partial on-error form)})]
|
|
||||||
(st/emit! (dp/update-notifications params))))
|
(st/emit! (dp/update-notifications params))))
|
||||||
|
|
||||||
(def ^:private schema:notifications-form
|
(def ^:private schema:notifications-form
|
||||||
|
@ -55,11 +32,15 @@
|
||||||
[:email-comments [::sm/one-of #{:all :partial :none}]]
|
[:email-comments [::sm/one-of #{:all :partial :none}]]
|
||||||
[:email-invites [::sm/one-of #{:all :partial :none}]]])
|
[:email-invites [::sm/one-of #{:all :partial :none}]]])
|
||||||
|
|
||||||
(mf/defc notifications-page
|
(mf/defc notifications-page*
|
||||||
[]
|
[{:keys [profile]}]
|
||||||
(let [settings (mf/deref notification-settings-ref)
|
(let [settings (mf/with-memo [profile]
|
||||||
|
(-> (merge default-notification-settings
|
||||||
|
(-> profile :props :notifications))
|
||||||
|
(update-vals d/name)))
|
||||||
form (fm/use-form :schema schema:notifications-form
|
form (fm/use-form :schema schema:notifications-form
|
||||||
:initial settings)]
|
:initial settings)]
|
||||||
|
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(dom/set-html-title (tr "title.settings.notifications")))
|
(dom/set-html-title (tr "title.settings.notifications")))
|
||||||
|
|
||||||
|
|
|
@ -166,9 +166,9 @@
|
||||||
|
|
||||||
(defn- make-library-colors-ref
|
(defn- make-library-colors-ref
|
||||||
[file-id]
|
[file-id]
|
||||||
(l/derived (fn [libraries]
|
(l/derived (fn [files]
|
||||||
(dm/get-in libraries [file-id :data :colors]))
|
(dm/get-in files [file-id :data :colors]))
|
||||||
refs/libraries))
|
refs/files))
|
||||||
|
|
||||||
(mf/defc file-color-palette*
|
(mf/defc file-color-palette*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
{:value "file" :label (tr "workspace.libraries.colors.file-library")}])
|
{:value "file" :label (tr "workspace.libraries.colors.file-library")}])
|
||||||
|
|
||||||
options
|
options
|
||||||
(mf/with-memo [library-options file-id]
|
(mf/with-memo [library-options libraries file-id]
|
||||||
(into library-options
|
(into library-options
|
||||||
(comp
|
(comp
|
||||||
(map val)
|
(map val)
|
||||||
|
|
|
@ -248,10 +248,12 @@
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps file-id)
|
(mf/deps file-id)
|
||||||
#(st/emit! (dwl/set-file-shared file-id false)
|
#(st/emit! (dwl/set-file-shared file-id false)
|
||||||
(modal/show :libraries-dialog {})))
|
(modal/show :libraries-dialog {:file-id file-id})))
|
||||||
|
|
||||||
on-delete-cancel
|
on-delete-cancel
|
||||||
(mf/use-fn #(st/emit! (modal/show :libraries-dialog {})))
|
(mf/use-fn
|
||||||
|
(mf/deps file-id)
|
||||||
|
#(st/emit! (modal/show :libraries-dialog {:file-id file-id})))
|
||||||
|
|
||||||
publish
|
publish
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -259,7 +261,7 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [input-node (dom/get-target event)
|
(let [input-node (dom/get-target event)
|
||||||
publish-library #(st/emit! (dwl/set-file-shared file-id true))
|
publish-library #(st/emit! (dwl/set-file-shared file-id true))
|
||||||
cancel-publish #(st/emit! (modal/show :libraries-dialog {}))]
|
cancel-publish #(st/emit! (modal/show :libraries-dialog {:file-id file-id}))]
|
||||||
(if empty-library?
|
(if empty-library?
|
||||||
(st/emit! (modal/show
|
(st/emit! (modal/show
|
||||||
{:type :confirm
|
{:type :confirm
|
||||||
|
@ -563,17 +565,15 @@
|
||||||
(mf/defc libraries-dialog
|
(mf/defc libraries-dialog
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
::mf/register-as :libraries-dialog}
|
::mf/register-as :libraries-dialog}
|
||||||
[{:keys [starting-tab] :as props :or {starting-tab :libraries}}]
|
[{:keys [starting-tab file-id] :as props :or {starting-tab :libraries}}]
|
||||||
(let [;; NOTE: we don't want to react on file changes, we just want
|
(let [files (mf/deref refs/files)
|
||||||
;; a snapshot of file on the momento of open the dialog
|
file (get files file-id)
|
||||||
file (deref refs/file)
|
|
||||||
|
|
||||||
file-id (:id file)
|
|
||||||
team-id (:team-id file)
|
team-id (:team-id file)
|
||||||
shared? (:is-shared file)
|
shared? (:is-shared file)
|
||||||
|
|
||||||
linked-libraries
|
linked-libraries
|
||||||
(mf/deref refs/files)
|
(mf/with-memo [files file-id]
|
||||||
|
(refs/select-libraries files file-id))
|
||||||
|
|
||||||
linked-libraries
|
linked-libraries
|
||||||
(mf/with-memo [linked-libraries file-id]
|
(mf/with-memo [linked-libraries file-id]
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
[{:keys [layout file page-id] :as props}]
|
[{:keys [layout file page-id] :as props}]
|
||||||
(let [options-mode (mf/deref refs/options-mode-global)
|
(let [options-mode (mf/deref refs/options-mode-global)
|
||||||
project (mf/deref refs/project)
|
project (mf/deref refs/project)
|
||||||
|
file-id (get file :id)
|
||||||
|
|
||||||
design-tokens? (features/use-feature "design-tokens/v1")
|
design-tokens? (features/use-feature "design-tokens/v1")
|
||||||
mode-inspect? (= options-mode :inspect)
|
mode-inspect? (= options-mode :inspect)
|
||||||
|
@ -116,7 +117,7 @@
|
||||||
|
|
||||||
|
|
||||||
assets-tab
|
assets-tab
|
||||||
(mf/html [:& assets-toolbox {:size (- size 58) :file-id file}])
|
(mf/html [:& assets-toolbox {:size (- size 58) :file-id file-id}])
|
||||||
|
|
||||||
tokens-tab
|
tokens-tab
|
||||||
(when design-tokens?
|
(when design-tokens?
|
||||||
|
|
|
@ -33,10 +33,10 @@
|
||||||
::mf/private true}
|
::mf/private true}
|
||||||
[{:keys [filters]}]
|
[{:keys [filters]}]
|
||||||
(let [file-id (mf/use-ctx ctx/current-file-id)
|
(let [file-id (mf/use-ctx ctx/current-file-id)
|
||||||
|
files (mf/deref refs/files)
|
||||||
libraries (mf/deref refs/libraries)
|
libraries (mf/with-memo [files file-id]
|
||||||
libraries (mf/with-memo [libraries file-id]
|
(->> (refs/select-libraries files file-id)
|
||||||
(->> (vals libraries)
|
(vals)
|
||||||
(remove :is-indirect)
|
(remove :is-indirect)
|
||||||
(remove #(= file-id (:id %)))
|
(remove #(= file-id (:id %)))
|
||||||
(map (fn [file]
|
(map (fn [file]
|
||||||
|
@ -129,8 +129,9 @@
|
||||||
|
|
||||||
show-libraries-dialog
|
show-libraries-dialog
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
(mf/deps file-id)
|
||||||
(fn []
|
(fn []
|
||||||
(modal/show! :libraries-dialog {})
|
(modal/show! :libraries-dialog {:file-id file-id})
|
||||||
(modal/allow-click-outside!)))
|
(modal/allow-click-outside!)))
|
||||||
|
|
||||||
on-open-menu
|
on-open-menu
|
||||||
|
|
|
@ -323,7 +323,7 @@
|
||||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||||
current-page-id (mf/use-ctx ctx/current-page-id)
|
current-page-id (mf/use-ctx ctx/current-page-id)
|
||||||
|
|
||||||
libraries (deref refs/libraries)
|
libraries (deref refs/files)
|
||||||
current-file (get libraries current-file-id)
|
current-file (get libraries current-file-id)
|
||||||
|
|
||||||
objects (-> (dsh/get-page (:data current-file) current-page-id)
|
objects (-> (dsh/get-page (:data current-file) current-page-id)
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
(defn- get-component-root-and-container
|
(defn- get-component-root-and-container
|
||||||
[file-id component]
|
[file-id component]
|
||||||
(let [data (dm/get-in @refs/libraries [file-id :data])
|
(let [data (dm/get-in @refs/files [file-id :data])
|
||||||
root-shape (ctf/get-component-root data component)
|
root-shape (ctf/get-component-root data component)
|
||||||
container (ctf/get-component-page data component)]
|
container (ctf/get-component-page data component)]
|
||||||
[root-shape container]))
|
[root-shape container]))
|
||||||
|
@ -453,7 +453,7 @@
|
||||||
(fn [component event]
|
(fn [component event]
|
||||||
|
|
||||||
(let [file-data
|
(let [file-data
|
||||||
(dm/get-in @refs/libraries [file-id :data])
|
(dm/get-in @refs/files [file-id :data])
|
||||||
|
|
||||||
shape-main
|
shape-main
|
||||||
(ctf/get-component-root file-data component)]
|
(ctf/get-component-root file-data component)]
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
(mf/defc shape-options*
|
(mf/defc shape-options*
|
||||||
{::mf/wrap [#(mf/throttle % 60)]}
|
{::mf/wrap [#(mf/throttle % 60)]}
|
||||||
[{:keys [shape shapes-with-children page-id file-id shared-libs] :as props}]
|
[{:keys [shape shapes-with-children page-id file-id libraries] :as props}]
|
||||||
(let [shape-type (dm/get-prop shape :type)
|
(let [shape-type (dm/get-prop shape :type)
|
||||||
shape-id (dm/get-prop shape :id)
|
shape-id (dm/get-prop shape :id)
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@
|
||||||
[:*
|
[:*
|
||||||
(case shape-type
|
(case shape-type
|
||||||
:frame [:> frame/options* props]
|
:frame [:> frame/options* props]
|
||||||
:group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}]
|
:group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :libraries libraries}]
|
||||||
:text [:& text/options {:shape shape :file-id file-id :shared-libs shared-libs}]
|
:text [:& text/options {:shape shape :file-id file-id :libraries libraries}]
|
||||||
:rect [:& rect/options {:shape shape}]
|
:rect [:& rect/options {:shape shape}]
|
||||||
:circle [:& circle/options {:shape shape}]
|
:circle [:& circle/options {:shape shape}]
|
||||||
:path [:& path/options {:shape shape}]
|
:path [:& path/options {:shape shape}]
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
[{:keys [selected objects page-id file-id selected-shapes shapes-with-children]}]
|
[{:keys [selected objects page-id file-id selected-shapes shapes-with-children]}]
|
||||||
(let [sp-panel (mf/deref refs/specialized-panel)
|
(let [sp-panel (mf/deref refs/specialized-panel)
|
||||||
drawing (mf/deref refs/workspace-drawing)
|
drawing (mf/deref refs/workspace-drawing)
|
||||||
shared-libs (mf/deref refs/libraries)
|
libraries (mf/deref refs/libraries)
|
||||||
edition (mf/deref refs/selected-edition)
|
edition (mf/deref refs/selected-edition)
|
||||||
edit-grid? (ctl/grid-layout? objects edition)
|
edit-grid? (ctl/grid-layout? objects edition)
|
||||||
grid-edition (mf/deref refs/workspace-grid-edition)
|
grid-edition (mf/deref refs/workspace-grid-edition)
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
{:shape (:object drawing)
|
{:shape (:object drawing)
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
:shared-libs shared-libs}]
|
:libraries libraries}]
|
||||||
|
|
||||||
(= 0 (count selected))
|
(= 0 (count selected))
|
||||||
[:> page/options*]
|
[:> page/options*]
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
{:shape (first selected-shapes)
|
{:shape (first selected-shapes)
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
:shared-libs shared-libs
|
:libraries libraries
|
||||||
:shapes-with-children shapes-with-children}]
|
:shapes-with-children shapes-with-children}]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
:shapes selected-shapes
|
:shapes selected-shapes
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
:shared-libs shared-libs}])]))
|
:libraries libraries}])]))
|
||||||
|
|
||||||
(mf/defc options-content*
|
(mf/defc options-content*
|
||||||
{::mf/memo true
|
{::mf/memo true
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(defn- prepare-colors
|
(defn- prepare-colors
|
||||||
[shapes file-id shared-libs]
|
[shapes file-id libraries]
|
||||||
(let [data (into [] (remove nil? (ctc/extract-all-colors shapes file-id shared-libs)))
|
(let [data (into [] (remove nil? (ctc/extract-all-colors shapes file-id libraries)))
|
||||||
groups (d/group-by :attrs #(dissoc % :attrs) data)
|
groups (d/group-by :attrs #(dissoc % :attrs) data)
|
||||||
all-colors (distinct (mapv :attrs data))
|
all-colors (distinct (mapv :attrs data))
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,8 @@
|
||||||
(let [single? (= 1 (count shapes))
|
(let [single? (= 1 (count shapes))
|
||||||
shape (first shapes)
|
shape (first shapes)
|
||||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||||
libraries (mf/deref refs/files)
|
|
||||||
|
libraries (mf/deref refs/libraries)
|
||||||
objects (mf/deref refs/workspace-page-objects)
|
objects (mf/deref refs/workspace-page-objects)
|
||||||
|
|
||||||
^boolean
|
^boolean
|
||||||
|
@ -594,9 +595,9 @@
|
||||||
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
||||||
current-page-id (mf/use-ctx ctx/current-page-id)
|
current-page-id (mf/use-ctx ctx/current-page-id)
|
||||||
|
|
||||||
libraries (deref refs/libraries)
|
libraries (deref refs/files)
|
||||||
current-file (get libraries current-file-id)
|
current-file (get libraries current-file-id)
|
||||||
data (get-in libraries [current-file-id :data])
|
data (get current-file :data)
|
||||||
|
|
||||||
state* (mf/use-state
|
state* (mf/use-state
|
||||||
#(do {:show-content true
|
#(do {:show-content true
|
||||||
|
|
|
@ -184,7 +184,7 @@
|
||||||
|
|
||||||
(let [file-id (mf/use-ctx ctx/current-file-id)
|
(let [file-id (mf/use-ctx ctx/current-file-id)
|
||||||
typographies (mf/deref refs/workspace-file-typography)
|
typographies (mf/deref refs/workspace-file-typography)
|
||||||
shared-libs (mf/deref refs/libraries)
|
libraries (mf/deref refs/files)
|
||||||
label (case type
|
label (case type
|
||||||
:multiple (tr "workspace.options.text-options.title-selection")
|
:multiple (tr "workspace.options.text-options.title-selection")
|
||||||
:group (tr "workspace.options.text-options.title-group")
|
:group (tr "workspace.options.text-options.title-group")
|
||||||
|
@ -224,21 +224,19 @@
|
||||||
(emit-update! ids attrs)))
|
(emit-update! ids attrs)))
|
||||||
|
|
||||||
typography
|
typography
|
||||||
(mf/use-memo
|
(mf/with-memo [values file-id libraries]
|
||||||
(mf/deps values file-id shared-libs)
|
|
||||||
(fn []
|
|
||||||
(cond
|
(cond
|
||||||
(and typography-id
|
(and typography-id
|
||||||
(not= typography-id :multiple)
|
(not= typography-id :multiple)
|
||||||
(not= typography-file-id file-id))
|
(not= typography-file-id file-id))
|
||||||
(-> shared-libs
|
(-> libraries
|
||||||
(get-in [typography-file-id :data :typographies typography-id])
|
(get-in [typography-file-id :data :typographies typography-id])
|
||||||
(assoc :file-id typography-file-id))
|
(assoc :file-id typography-file-id))
|
||||||
|
|
||||||
(and typography-id
|
(and typography-id
|
||||||
(not= typography-id :multiple)
|
(not= typography-id :multiple)
|
||||||
(= typography-file-id file-id))
|
(= typography-file-id file-id))
|
||||||
(get typographies typography-id))))
|
(get typographies typography-id)))
|
||||||
|
|
||||||
on-convert-to-typography
|
on-convert-to-typography
|
||||||
(fn [_]
|
(fn [_]
|
||||||
|
|
|
@ -48,13 +48,13 @@
|
||||||
[{:keys [index color disable-gradient disable-opacity disable-image disable-picker hidden
|
[{:keys [index color disable-gradient disable-opacity disable-image disable-picker hidden
|
||||||
on-change on-reorder on-detach on-open on-close on-remove
|
on-change on-reorder on-detach on-open on-close on-remove
|
||||||
disable-drag on-focus on-blur select-only select-on-focus]}]
|
disable-drag on-focus on-blur select-only select-on-focus]}]
|
||||||
(let [shared-libs (mf/deref refs/libraries)
|
(let [libraries (mf/deref refs/files)
|
||||||
hover-detach (mf/use-state false)
|
hover-detach (mf/use-state false)
|
||||||
on-change (h/use-ref-callback on-change)
|
on-change (h/use-ref-callback on-change)
|
||||||
|
|
||||||
file-id (or (:ref-file color) (:file-id color))
|
file-id (or (:ref-file color) (:file-id color))
|
||||||
color-id (or (:ref-id color) (:id color))
|
color-id (or (:ref-id color) (:id color))
|
||||||
src-colors (dm/get-in shared-libs [file-id :data :colors])
|
src-colors (dm/get-in libraries [file-id :data :colors])
|
||||||
color-name (dm/get-in src-colors [color-id :name])
|
color-name (dm/get-in src-colors [color-id :name])
|
||||||
|
|
||||||
multiple-colors? (uc/multiple? color)
|
multiple-colors? (uc/multiple? color)
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
[props]
|
[props]
|
||||||
(let [shape (unchecked-get props "shape")
|
(let [shape (unchecked-get props "shape")
|
||||||
shape-with-children (unchecked-get props "shape-with-children")
|
shape-with-children (unchecked-get props "shape-with-children")
|
||||||
shared-libs (unchecked-get props "shared-libs")
|
libraries (unchecked-get props "libraries")
|
||||||
objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
|
objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
|
||||||
file-id (unchecked-get props "file-id")
|
file-id (unchecked-get props "file-id")
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
{:type type
|
{:type type
|
||||||
:shapes (vals objects)
|
:shapes (vals objects)
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
:libraries shared-libs}]
|
:libraries libraries}]
|
||||||
|
|
||||||
(when-not (empty? shadow-ids)
|
(when-not (empty? shadow-ids)
|
||||||
[:> shadow-menu* {:ids ids :values (get shape :shadow) :type type}])
|
[:> shadow-menu* {:ids ids :values (get shape :shadow) :type type}])
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc options
|
(mf/defc options
|
||||||
[{:keys [shape file-id] :as props}]
|
[{:keys [shape file-id libraries] :as props}]
|
||||||
(let [ids [(:id shape)]
|
(let [ids [(:id shape)]
|
||||||
type (:type shape)
|
type (:type shape)
|
||||||
|
|
||||||
|
@ -53,8 +53,6 @@
|
||||||
(mf/deref refs/workspace-v2-editor-state)
|
(mf/deref refs/workspace-v2-editor-state)
|
||||||
(mf/deref refs/workspace-editor-state))
|
(mf/deref refs/workspace-editor-state))
|
||||||
|
|
||||||
shared-libs (mf/deref refs/libraries)
|
|
||||||
|
|
||||||
editor-state (when (not (features/active-feature? @st/state "text-editor/v2"))
|
editor-state (when (not (features/active-feature? @st/state "text-editor/v2"))
|
||||||
(get state-map (:id shape)))
|
(get state-map (:id shape)))
|
||||||
|
|
||||||
|
@ -150,7 +148,7 @@
|
||||||
{:type type
|
{:type type
|
||||||
:shapes [shape]
|
:shapes [shape]
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
:libraries shared-libs}])
|
:libraries libraries}])
|
||||||
|
|
||||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
(str (:font-size typography) "px | " (:name variant-data))]])]))
|
(str (:font-size typography) "px | " (:name variant-data))]])]))
|
||||||
|
|
||||||
(mf/defc palette
|
(mf/defc palette
|
||||||
[{:keys [selected selected-ids current-file-id file-typographies shared-libs size width]}]
|
[{:keys [selected selected-ids current-file-id file-typographies libraries size width]}]
|
||||||
(let [file-id
|
(let [file-id
|
||||||
(case selected
|
(case selected
|
||||||
:recent nil
|
:recent nil
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
(case selected
|
(case selected
|
||||||
:recent []
|
:recent []
|
||||||
:file (sort-by #(str/lower (:name %)) (vals file-typographies))
|
:file (sort-by #(str/lower (:name %)) (vals file-typographies))
|
||||||
(sort-by #(str/lower (:name %)) (vals (get-in shared-libs [selected :data :typographies]))))
|
(sort-by #(str/lower (:name %)) (vals (get-in libraries [selected :data :typographies]))))
|
||||||
state (mf/use-state {:offset 0})
|
state (mf/use-state {:offset 0})
|
||||||
offset-step 144
|
offset-step 144
|
||||||
buttons-size (cond
|
buttons-size (cond
|
||||||
|
@ -182,13 +182,17 @@
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [size width selected] :as props}]
|
[{:keys [size width selected] :as props}]
|
||||||
(let [selected-ids (mf/deref refs/selected-shapes)
|
(let [selected-ids (mf/deref refs/selected-shapes)
|
||||||
|
|
||||||
|
;; FIXME: we have duplicate operations, if we already have the
|
||||||
|
;; libraries, so we already have file-typographies so we don't
|
||||||
|
;; need two separate lens/refs for that
|
||||||
file-typographies (mf/deref refs/workspace-file-typography)
|
file-typographies (mf/deref refs/workspace-file-typography)
|
||||||
shared-libs (mf/deref refs/libraries)
|
libraries (mf/deref refs/files)
|
||||||
current-file-id (mf/use-ctx ctx/current-file-id)]
|
current-file-id (mf/use-ctx ctx/current-file-id)]
|
||||||
[:& palette {:current-file-id current-file-id
|
[:& palette {:current-file-id current-file-id
|
||||||
:selected-ids selected-ids
|
:selected-ids selected-ids
|
||||||
:file-typographies file-typographies
|
:file-typographies file-typographies
|
||||||
:shared-libs shared-libs
|
:libraries libraries
|
||||||
:width width
|
:width width
|
||||||
:selected selected
|
:selected selected
|
||||||
:size size}]))
|
:size size}]))
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
(mf/defc text-palette-ctx-menu
|
(mf/defc text-palette-ctx-menu
|
||||||
[{:keys [show-menu? close-menu on-select-palette selected]}]
|
[{:keys [show-menu? close-menu on-select-palette selected]}]
|
||||||
(let [typographies (mf/deref refs/workspace-file-typography)
|
(let [typographies (mf/deref refs/workspace-file-typography)
|
||||||
shared-libs (mf/deref refs/libraries)]
|
libraries (mf/deref refs/libraries)]
|
||||||
[:& dropdown {:show show-menu?
|
[:& dropdown {:show show-menu?
|
||||||
:on-close close-menu}
|
:on-close close-menu}
|
||||||
[:ul {:class (stl/css :text-context-menu)}
|
[:ul {:class (stl/css :text-context-menu)}
|
||||||
(for [[idx cur-library] (map-indexed vector (vals shared-libs))]
|
(for [[idx cur-library] (map-indexed vector (vals libraries))]
|
||||||
(let [typographies (-> cur-library (get-in [:data :typographies]) vals)]
|
(let [typographies (-> cur-library (get-in [:data :typographies]) vals)]
|
||||||
[:li
|
[:li
|
||||||
{:class (stl/css-case :palette-library true
|
{:class (stl/css-case :palette-library true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue