mirror of
https://github.com/penpot/penpot.git
synced 2025-05-24 15:26:12 +02:00
♻️ Refactor state locality
The main purpose of this refactor is reduce a custom state from different pages and unify them under common access patterns
This commit is contained in:
parent
f62aecb383
commit
85746e7cb2
110 changed files with 2254 additions and 2125 deletions
|
@ -47,31 +47,28 @@
|
||||||
(str/join "")))
|
(str/join "")))
|
||||||
|
|
||||||
(defn- format-comment-url
|
(defn- format-comment-url
|
||||||
[thread {:keys [team-id file-id page-id]}]
|
[thread file]
|
||||||
(str/ffmt "%/#/workspace?%"
|
(str/ffmt "%/#/workspace?%"
|
||||||
(cf/get :public-uri)
|
(cf/get :public-uri)
|
||||||
(uri/map->query-string
|
(uri/map->query-string
|
||||||
{:file-id file-id
|
{:file-id (:id file)
|
||||||
:page-id page-id
|
:page-id (:page-id file)
|
||||||
:team-id team-id
|
:team-id (:team-id file)
|
||||||
:comment-id (:id thread)})))
|
:comment-id (:id thread)})))
|
||||||
|
|
||||||
(defn- format-comment-ref
|
(defn- format-comment-ref
|
||||||
[{:keys [seqn]} {:keys [file-name page-name]}]
|
[thread file]
|
||||||
(str/ffmt "#%, %, %" seqn file-name page-name))
|
(str/ffmt "#%, %, %"
|
||||||
|
(:seqn thread)
|
||||||
|
(:name file)
|
||||||
|
(:page-name file)))
|
||||||
|
|
||||||
(defn get-team-users
|
(defn- get-team-users
|
||||||
[conn team-id]
|
[conn team-id]
|
||||||
(->> (teams/get-users+props conn team-id)
|
(->> (teams/get-users+props conn team-id)
|
||||||
(map profile/decode-row)
|
(map profile/decode-row)
|
||||||
(d/index-by :id)))
|
(d/index-by :id)))
|
||||||
|
|
||||||
(defn- resolve-profile-name
|
|
||||||
[conn profile-id]
|
|
||||||
(-> (db/get conn :profile {:id profile-id}
|
|
||||||
{::sql/columns [:fullname]})
|
|
||||||
(get :fullname)))
|
|
||||||
|
|
||||||
(defn- notification-email?
|
(defn- notification-email?
|
||||||
[profile-id owner-id props]
|
[profile-id owner-id props]
|
||||||
(if (= profile-id owner-id)
|
(if (= profile-id owner-id)
|
||||||
|
@ -83,24 +80,22 @@
|
||||||
(not= :none (-> props :notifications :email-comments)))
|
(not= :none (-> props :notifications :email-comments)))
|
||||||
|
|
||||||
(defn send-comment-emails!
|
(defn send-comment-emails!
|
||||||
[conn {:keys [profile-id team-id] :as params} comment thread]
|
[conn profile comment thread file]
|
||||||
|
(let [team-users (get-team-users conn (:team-id file))
|
||||||
(let [team-users (get-team-users conn team-id)
|
comment-reference (format-comment-ref thread file)
|
||||||
source-user (resolve-profile-name conn profile-id)
|
|
||||||
|
|
||||||
comment-reference (format-comment-ref thread params)
|
|
||||||
comment-content (format-comment comment)
|
comment-content (format-comment comment)
|
||||||
comment-url (format-comment-url thread params)
|
comment-url (format-comment-url thread file)
|
||||||
|
profile-id (get profile :id)
|
||||||
|
|
||||||
;; Users mentioned in this comment
|
;; Users mentioned in this comment
|
||||||
comment-mentions
|
comment-mentions
|
||||||
(-> (:mentions comment)
|
(-> (:mentions comment)
|
||||||
(set/difference #{profile-id}))
|
(disj profile-id))
|
||||||
|
|
||||||
;; Users mentioned in this thread
|
;; Users mentioned in this thread
|
||||||
thread-mentions
|
thread-mentions
|
||||||
(-> (:mentions thread)
|
(-> (:mentions thread)
|
||||||
;; Remove the mentions in the thread because we're already sending a
|
;; Remove the mentions in the comment because we're already sending a
|
||||||
;; notification
|
;; notification
|
||||||
(set/difference comment-mentions)
|
(set/difference comment-mentions)
|
||||||
(disj profile-id))
|
(disj profile-id))
|
||||||
|
@ -118,9 +113,10 @@
|
||||||
(eml/send!
|
(eml/send!
|
||||||
{::eml/conn conn
|
{::eml/conn conn
|
||||||
::eml/factory eml/comment-mention
|
::eml/factory eml/comment-mention
|
||||||
|
:public-uri (cf/get :public-uri)
|
||||||
:to email
|
:to email
|
||||||
:name fullname
|
:name fullname
|
||||||
:source-user source-user
|
:source-user (:fullname profile)
|
||||||
:comment-reference comment-reference
|
:comment-reference comment-reference
|
||||||
:comment-content comment-content
|
:comment-content comment-content
|
||||||
:comment-url comment-url}))))
|
:comment-url comment-url}))))
|
||||||
|
@ -132,9 +128,10 @@
|
||||||
(eml/send!
|
(eml/send!
|
||||||
{::eml/conn conn
|
{::eml/conn conn
|
||||||
::eml/factory eml/comment-thread
|
::eml/factory eml/comment-thread
|
||||||
|
:public-uri (cf/get :public-uri)
|
||||||
:to email
|
:to email
|
||||||
:name fullname
|
:name fullname
|
||||||
:source-user source-user
|
:source-user (:fullname profile)
|
||||||
:comment-reference comment-reference
|
:comment-reference comment-reference
|
||||||
:comment-content comment-content
|
:comment-content comment-content
|
||||||
:comment-url comment-url}))))
|
:comment-url comment-url}))))
|
||||||
|
@ -146,9 +143,10 @@
|
||||||
(eml/send!
|
(eml/send!
|
||||||
{::eml/conn conn
|
{::eml/conn conn
|
||||||
::eml/factory eml/comment-notification
|
::eml/factory eml/comment-notification
|
||||||
|
:public-uri (cf/get :public-uri)
|
||||||
:to email
|
:to email
|
||||||
:name fullname
|
:name fullname
|
||||||
:source-user source-user
|
:source-user (:fullname profile)
|
||||||
:comment-reference comment-reference
|
:comment-reference comment-reference
|
||||||
:comment-content comment-content
|
:comment-content comment-content
|
||||||
:comment-url comment-url}))))))
|
:comment-url comment-url}))))))
|
||||||
|
@ -165,12 +163,13 @@
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
sql:get-file
|
sql:get-file
|
||||||
"select f.id, f.modified_at, f.revn, f.features, f.name,
|
"SELECT f.id, f.modified_at, f.revn, f.features, f.name,
|
||||||
f.project_id, p.team_id, f.data
|
f.project_id, p.team_id, f.data,
|
||||||
from file as f
|
f.data_ref_id, f.data_backend
|
||||||
join project as p on (p.id = f.project_id)
|
FROM file as f
|
||||||
where f.id = ?
|
INNER JOIN project as p on (p.id = f.project_id)
|
||||||
and f.deleted_at is null")
|
WHERE f.id = ?
|
||||||
|
AND (f.deleted_at IS NULL OR f.deleted_at > now())")
|
||||||
|
|
||||||
(defn- get-file
|
(defn- get-file
|
||||||
"A specialized version of get-file for comments module."
|
"A specialized version of get-file for comments module."
|
||||||
|
@ -182,12 +181,16 @@
|
||||||
:hint "file not found"))
|
:hint "file not found"))
|
||||||
|
|
||||||
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg file-id)]
|
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg file-id)]
|
||||||
(let [{:keys [data] :as file} (files/decode-row file)]
|
(let [file (->> file
|
||||||
|
(files/decode-row)
|
||||||
|
(feat.fdata/resolve-file-data cfg))
|
||||||
|
data (get file :data)]
|
||||||
(-> file
|
(-> file
|
||||||
(assoc :page-name (dm/get-in data [:pages-index page-id :name]))
|
(assoc :page-name (dm/get-in data [:pages-index page-id :name]))
|
||||||
(assoc :page-id page-id)
|
(assoc :page-id page-id)
|
||||||
(dissoc :data))))))
|
(dissoc :data))))))
|
||||||
|
|
||||||
|
;; FIXME: rename
|
||||||
(defn- get-comment-thread
|
(defn- get-comment-thread
|
||||||
[conn thread-id & {:as opts}]
|
[conn thread-id & {:as opts}]
|
||||||
(-> (db/get-by-id conn :comment-thread thread-id opts)
|
(-> (db/get-by-id conn :comment-thread thread-id opts)
|
||||||
|
@ -249,6 +252,9 @@
|
||||||
(def ^:private sql:comment-threads
|
(def ^:private sql:comment-threads
|
||||||
"SELECT DISTINCT ON (ct.id)
|
"SELECT DISTINCT ON (ct.id)
|
||||||
ct.*,
|
ct.*,
|
||||||
|
pf.fullname AS owner_fullname,
|
||||||
|
pf.email AS owner_email,
|
||||||
|
pf.photo_id AS owner_photo_id,
|
||||||
p.team_id AS team_id,
|
p.team_id AS team_id,
|
||||||
f.name AS file_name,
|
f.name AS file_name,
|
||||||
f.project_id AS project_id,
|
f.project_id AS project_id,
|
||||||
|
@ -265,6 +271,7 @@
|
||||||
INNER JOIN file AS f ON (f.id = ct.file_id)
|
INNER JOIN file AS f ON (f.id = ct.file_id)
|
||||||
INNER JOIN project AS p ON (p.id = f.project_id)
|
INNER JOIN project AS p ON (p.id = f.project_id)
|
||||||
LEFT JOIN comment_thread_status AS cts ON (cts.thread_id = ct.id AND cts.profile_id = ?)
|
LEFT JOIN comment_thread_status AS cts ON (cts.thread_id = ct.id AND cts.profile_id = ?)
|
||||||
|
LEFT JOIN profile AS pf ON (ct.owner_id = pf.id)
|
||||||
WINDOW w AS (PARTITION BY c.thread_id ORDER BY c.created_at ASC)")
|
WINDOW w AS (PARTITION BY c.thread_id ORDER BY c.created_at ASC)")
|
||||||
|
|
||||||
(def ^:private sql:comment-threads-by-file-id
|
(def ^:private sql:comment-threads-by-file-id
|
||||||
|
@ -360,15 +367,25 @@
|
||||||
::sm/params schema:get-comments}
|
::sm/params schema:get-comments}
|
||||||
[cfg {:keys [::rpc/profile-id thread-id share-id]}]
|
[cfg {:keys [::rpc/profile-id thread-id share-id]}]
|
||||||
(db/run! cfg (fn [{:keys [::db/conn]}]
|
(db/run! cfg (fn [{:keys [::db/conn]}]
|
||||||
(let [{:keys [file-id] :as thread} (get-comment-thread conn thread-id)]
|
(let [{:keys [file-id]} (get-comment-thread conn thread-id)]
|
||||||
(files/check-comment-permissions! conn profile-id file-id share-id)
|
(files/check-comment-permissions! conn profile-id file-id share-id)
|
||||||
(get-comments conn thread-id)))))
|
(get-comments conn thread-id)))))
|
||||||
|
|
||||||
|
(def sql:get-comments
|
||||||
|
"SELECT c.*,
|
||||||
|
ct.file_id AS file_id,
|
||||||
|
pf.fullname AS owner_fullname,
|
||||||
|
pf.email AS owner_email,
|
||||||
|
pf.photo_id AS owner_photo_id
|
||||||
|
FROM comment AS c
|
||||||
|
INNER JOIN comment_thread AS ct ON (ct.id = c.thread_id)
|
||||||
|
LEFT JOIN profile AS pf ON (c.owner_id = pf.id)
|
||||||
|
WHERE c.thread_id = ?
|
||||||
|
ORDER BY c.created_at ASC")
|
||||||
|
|
||||||
(defn- get-comments
|
(defn- get-comments
|
||||||
[conn thread-id]
|
[conn thread-id]
|
||||||
(->> (db/query conn :comment
|
(->> (db/exec! conn [sql:get-comments thread-id])
|
||||||
{:thread-id thread-id}
|
|
||||||
{:order-by [[:created-at :asc]]})
|
|
||||||
(into [] xf-decode-row)))
|
(into [] xf-decode-row)))
|
||||||
|
|
||||||
;; --- COMMAND: Get file comments users
|
;; --- COMMAND: Get file comments users
|
||||||
|
@ -429,7 +446,21 @@
|
||||||
[:page-id ::sm/uuid]
|
[:page-id ::sm/uuid]
|
||||||
[:frame-id ::sm/uuid]
|
[:frame-id ::sm/uuid]
|
||||||
[:share-id {:optional true} [:maybe ::sm/uuid]]
|
[:share-id {:optional true} [:maybe ::sm/uuid]]
|
||||||
[:mentions {:optional true} [:vector ::sm/uuid]]])
|
[:mentions {:optional true} [::sm/set ::sm/uuid]]])
|
||||||
|
|
||||||
|
(defn- update-thread-seqn
|
||||||
|
[conn file-id seqn]
|
||||||
|
(db/update! conn :file
|
||||||
|
{:comment-thread-seqn seqn}
|
||||||
|
{:id file-id}
|
||||||
|
{::db/return-keys false}))
|
||||||
|
|
||||||
|
(defn add-owner
|
||||||
|
[thread-or-comment profile]
|
||||||
|
(-> thread-or-comment
|
||||||
|
(assoc :owner-fullname (:fullname profile))
|
||||||
|
(assoc :owner-email (:email profile))
|
||||||
|
(assoc :owner-photo-id (:photo-id profile))))
|
||||||
|
|
||||||
(sv/defmethod ::create-comment-thread
|
(sv/defmethod ::create-comment-thread
|
||||||
{::doc/added "1.15"
|
{::doc/added "1.15"
|
||||||
|
@ -437,10 +468,10 @@
|
||||||
::rtry/enabled true
|
::rtry/enabled true
|
||||||
::rtry/when rtry/conflict-exception?
|
::rtry/when rtry/conflict-exception?
|
||||||
::sm/params schema:create-comment-thread}
|
::sm/params schema:create-comment-thread}
|
||||||
[cfg {:keys [::rpc/profile-id ::rpc/request-at file-id page-id share-id mentions position content frame-id]}]
|
[cfg {:keys [::rpc/profile-id file-id page-id share-id] :as params}]
|
||||||
(files/check-comment-permissions! cfg profile-id file-id share-id)
|
(files/check-comment-permissions! cfg profile-id file-id share-id)
|
||||||
|
|
||||||
(let [{:keys [team-id project-id page-name name]} (get-file cfg file-id page-id)]
|
(let [{:keys [team-id project-id] :as file} (get-file cfg file-id page-id)]
|
||||||
(-> cfg
|
(-> cfg
|
||||||
(assoc ::quotes/profile-id profile-id)
|
(assoc ::quotes/profile-id profile-id)
|
||||||
(assoc ::quotes/team-id team-id)
|
(assoc ::quotes/team-id team-id)
|
||||||
|
@ -449,26 +480,14 @@
|
||||||
(quotes/check! {::quotes/id ::quotes/comment-threads-per-file}
|
(quotes/check! {::quotes/id ::quotes/comment-threads-per-file}
|
||||||
{::quotes/id ::quotes/comments-per-file}))
|
{::quotes/id ::quotes/comments-per-file}))
|
||||||
|
|
||||||
(let [params {:created-at request-at
|
(let [params (assoc params ::file file)
|
||||||
:profile-id profile-id
|
thread (db/tx-run! cfg create-comment-thread params)]
|
||||||
:file-id file-id
|
|
||||||
:file-name name
|
|
||||||
:page-id page-id
|
|
||||||
:page-name page-name
|
|
||||||
:position position
|
|
||||||
:content content
|
|
||||||
:frame-id frame-id
|
|
||||||
:team-id team-id
|
|
||||||
:project-id project-id
|
|
||||||
:mentions mentions}
|
|
||||||
thread (-> (db/tx-run! cfg create-comment-thread params)
|
|
||||||
(decode-row))]
|
|
||||||
|
|
||||||
(vary-meta thread assoc ::audit/props thread))))
|
(vary-meta thread assoc ::audit/props thread))))
|
||||||
|
|
||||||
(defn- create-comment-thread
|
(defn- create-comment-thread
|
||||||
[{:keys [::db/conn] :as cfg}
|
[{:keys [::db/conn] :as cfg}
|
||||||
{:keys [profile-id file-id page-id page-name created-at position content mentions frame-id] :as params}]
|
{:keys [::rpc/profile-id ::rpc/request-at ::file position content mentions frame-id] :as params}]
|
||||||
|
|
||||||
(let [;; NOTE: we take the next seq number from a separate query
|
(let [;; NOTE: we take the next seq number from a separate query
|
||||||
;; because we need to lock the file for avoid race conditions
|
;; because we need to lock the file for avoid race conditions
|
||||||
|
@ -479,46 +498,47 @@
|
||||||
;; different storage (example: redis) for alivate the update
|
;; different storage (example: redis) for alivate the update
|
||||||
;; pression on the file table
|
;; pression on the file table
|
||||||
|
|
||||||
seqn (get-next-seqn conn file-id)
|
profile (profile/get-profile conn profile-id)
|
||||||
|
seqn (get-next-seqn conn (:id file))
|
||||||
|
|
||||||
|
file-id (get file :id)
|
||||||
thread-id (uuid/next)
|
thread-id (uuid/next)
|
||||||
|
|
||||||
thread (-> (db/insert! conn :comment-thread
|
thread (-> (db/insert! conn :comment-thread
|
||||||
{:id thread-id
|
{:id thread-id
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
|
:page-name (:page-name file)
|
||||||
|
:page-id (:page-id file)
|
||||||
:owner-id profile-id
|
:owner-id profile-id
|
||||||
:participants (db/tjson #{profile-id})
|
:participants (db/tjson #{profile-id})
|
||||||
:page-name page-name
|
:created-at request-at
|
||||||
:page-id page-id
|
:modified-at request-at
|
||||||
:created-at created-at
|
|
||||||
:modified-at created-at
|
|
||||||
:seqn seqn
|
:seqn seqn
|
||||||
:position (db/pgpoint position)
|
|
||||||
:frame-id frame-id
|
:frame-id frame-id
|
||||||
|
:position (db/pgpoint position)
|
||||||
:mentions (db/encode-pgarray mentions conn "uuid")})
|
:mentions (db/encode-pgarray mentions conn "uuid")})
|
||||||
(decode-row))
|
(decode-row))
|
||||||
comment (-> (db/insert! conn :comment
|
comment (-> (db/insert! conn :comment
|
||||||
{:id (uuid/next)
|
{:id (uuid/next)
|
||||||
:thread-id thread-id
|
:thread-id thread-id
|
||||||
:owner-id profile-id
|
:owner-id profile-id
|
||||||
:created-at created-at
|
:created-at request-at
|
||||||
:modified-at created-at
|
:modified-at request-at
|
||||||
:mentions (db/encode-pgarray mentions conn "uuid")
|
:mentions (db/encode-pgarray mentions conn "uuid")
|
||||||
:content content})
|
:content content})
|
||||||
(decode-row))]
|
(decode-row))]
|
||||||
|
|
||||||
;; Make the current thread as read.
|
;; Make the current thread as read.
|
||||||
(upsert-comment-thread-status! conn profile-id thread-id created-at)
|
(upsert-comment-thread-status! conn profile-id thread-id request-at)
|
||||||
|
|
||||||
;; Optimistic update of current seq number on file.
|
;; Optimistic update of current seq number on file.
|
||||||
(db/update! conn :file
|
(update-thread-seqn conn file-id seqn)
|
||||||
{:comment-thread-seqn seqn}
|
|
||||||
{:id file-id}
|
|
||||||
{::db/return-keys false})
|
|
||||||
|
|
||||||
;; Send mentions emails
|
;; Send mentions emails
|
||||||
(send-comment-emails! conn params comment thread)
|
(send-comment-emails! conn profile comment thread file)
|
||||||
|
|
||||||
(-> thread
|
(-> thread
|
||||||
(select-keys [:id :file-id :page-id :mentions])
|
(add-owner profile)
|
||||||
(assoc :comment-id (:id comment)))))
|
(assoc :comment-id (:id comment)))))
|
||||||
|
|
||||||
;; --- COMMAND: Update Comment Thread Status
|
;; --- COMMAND: Update Comment Thread Status
|
||||||
|
@ -534,7 +554,7 @@
|
||||||
::sm/params schema:update-comment-thread-status
|
::sm/params schema:update-comment-thread-status
|
||||||
::db/transaction true}
|
::db/transaction true}
|
||||||
[{:keys [::db/conn]} {:keys [::rpc/profile-id id share-id]}]
|
[{:keys [::db/conn]} {:keys [::rpc/profile-id id share-id]}]
|
||||||
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
|
(let [{:keys [file-id]} (get-comment-thread conn id ::sql/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)
|
||||||
(upsert-comment-thread-status! conn profile-id id)))
|
(upsert-comment-thread-status! conn profile-id id)))
|
||||||
|
|
||||||
|
@ -552,7 +572,7 @@
|
||||||
::sm/params schema:update-comment-thread
|
::sm/params schema:update-comment-thread
|
||||||
::db/transaction true}
|
::db/transaction true}
|
||||||
[{:keys [::db/conn]} {:keys [::rpc/profile-id id is-resolved share-id]}]
|
[{:keys [::db/conn]} {:keys [::rpc/profile-id id is-resolved share-id]}]
|
||||||
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
|
(let [{:keys [file-id]} (get-comment-thread conn id ::sql/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)
|
||||||
(db/update! conn :comment-thread
|
(db/update! conn :comment-thread
|
||||||
{:is-resolved is-resolved}
|
{:is-resolved is-resolved}
|
||||||
|
@ -561,15 +581,13 @@
|
||||||
|
|
||||||
;; --- COMMAND: Add Comment
|
;; --- COMMAND: Add Comment
|
||||||
|
|
||||||
(declare ^:private get-comment-thread)
|
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
schema:create-comment
|
schema:create-comment
|
||||||
[:map {:title "create-comment"}
|
[:map {:title "create-comment"}
|
||||||
[:thread-id ::sm/uuid]
|
[:thread-id ::sm/uuid]
|
||||||
[:content [:string {:max 250}]]
|
[:content [:string {:max 250}]]
|
||||||
[:share-id {:optional true} [:maybe ::sm/uuid]]
|
[:share-id {:optional true} [:maybe ::sm/uuid]]
|
||||||
[:mentions {:optional true} [:vector ::sm/uuid]]])
|
[:mentions {:optional true} [::sm/set ::sm/uuid]]])
|
||||||
|
|
||||||
(sv/defmethod ::create-comment
|
(sv/defmethod ::create-comment
|
||||||
{::doc/added "1.15"
|
{::doc/added "1.15"
|
||||||
|
@ -577,65 +595,58 @@
|
||||||
::sm/params schema:create-comment
|
::sm/params schema:create-comment
|
||||||
::db/transaction true}
|
::db/transaction true}
|
||||||
[{:keys [::db/conn] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at thread-id share-id content mentions]}]
|
[{:keys [::db/conn] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at thread-id share-id content mentions]}]
|
||||||
(let [{:keys [file-id page-id] :as thread} (get-comment-thread conn thread-id ::sql/for-update true)
|
(let [{:keys [file-id page-id] :as thread}
|
||||||
{file-name :name :keys [team-id project-id page-name] :as file} (get-file cfg file-id page-id)]
|
(get-comment-thread conn thread-id ::sql/for-update true)
|
||||||
|
|
||||||
|
{:keys [team-id project-id] :as file}
|
||||||
|
(get-file cfg file-id page-id)]
|
||||||
|
|
||||||
(files/check-comment-permissions! conn profile-id file-id share-id)
|
(files/check-comment-permissions! conn profile-id file-id share-id)
|
||||||
|
|
||||||
(quotes/check! cfg {::quotes/id ::quotes/comments-per-file
|
(quotes/check! cfg {::quotes/id ::quotes/comments-per-file
|
||||||
::quotes/profile-id profile-id
|
::quotes/profile-id profile-id
|
||||||
::quotes/team-id team-id
|
::quotes/team-id team-id
|
||||||
::quotes/project-id project-id
|
::quotes/project-id project-id
|
||||||
::quotes/file-id file-id})
|
::quotes/file-id file-id})
|
||||||
|
|
||||||
;; Update the page-name cached attribute on comment thread table.
|
(let [profile (profile/get-profile conn profile-id)
|
||||||
(when (not= page-name (:page-name thread))
|
mentions (into #{} mentions)
|
||||||
(db/update! conn :comment-thread
|
params {:id (uuid/next)
|
||||||
{:page-name page-name}
|
:created-at request-at
|
||||||
{:id thread-id}))
|
:modified-at request-at
|
||||||
|
:thread-id thread-id
|
||||||
|
:owner-id profile-id
|
||||||
|
:content content
|
||||||
|
:mentions (db/encode-pgarray mentions conn "uuid")}
|
||||||
|
|
||||||
(let [comment (-> (db/insert!
|
comment (-> (db/insert! conn :comment params)
|
||||||
conn :comment
|
(decode-row)
|
||||||
{:id (uuid/next)
|
(add-owner profile))]
|
||||||
:created-at request-at
|
|
||||||
:modified-at request-at
|
|
||||||
:thread-id thread-id
|
|
||||||
:owner-id profile-id
|
|
||||||
:content content
|
|
||||||
:mentions
|
|
||||||
(-> mentions
|
|
||||||
(set)
|
|
||||||
(db/encode-pgarray conn "uuid"))})
|
|
||||||
(decode-row))
|
|
||||||
props {:file-id file-id
|
|
||||||
:share-id nil}]
|
|
||||||
|
|
||||||
;; Update thread modified-at attribute and assoc the current
|
;; Update thread modified-at attribute and assoc the current
|
||||||
;; profile to the participant set.
|
;; profile to the participant set.
|
||||||
(db/update! conn :comment-thread
|
(let [mentions (into (:mentions thread) mentions)
|
||||||
{:modified-at request-at
|
participants (-> (:participants thread #{})
|
||||||
:participants (-> (:participants thread #{})
|
(conj profile-id))
|
||||||
(conj profile-id)
|
params {:modified-at request-at
|
||||||
(db/tjson))
|
:participants (db/tjson participants)
|
||||||
:mentions (-> (:mentions thread)
|
:mentions (db/encode-pgarray mentions conn "uuid")}
|
||||||
(set)
|
|
||||||
(into mentions)
|
|
||||||
(db/encode-pgarray conn "uuid"))}
|
|
||||||
{:id thread-id})
|
|
||||||
|
|
||||||
;; Update the current profile status in relation to the
|
;; Update the page-name cached attribute on comment thread table.
|
||||||
;; current thread.
|
params (cond-> params
|
||||||
|
(not= (:page-name file) (:page-name thread))
|
||||||
|
(assoc :page-name (:page-name file)))]
|
||||||
|
|
||||||
|
(db/update! conn :comment-thread params
|
||||||
|
{:id thread-id}
|
||||||
|
{::db/return-keys false}))
|
||||||
|
|
||||||
|
;; Update the current profile status in relation to the current thread
|
||||||
(upsert-comment-thread-status! conn profile-id thread-id)
|
(upsert-comment-thread-status! conn profile-id thread-id)
|
||||||
|
|
||||||
(let [params {:project-id project-id
|
(send-comment-emails! conn profile comment thread file)
|
||||||
:profile-id profile-id
|
|
||||||
:team-id team-id
|
|
||||||
:file-id (:file-id thread)
|
|
||||||
:page-id (:page-id thread)
|
|
||||||
:file-name file-name
|
|
||||||
:page-name page-name}]
|
|
||||||
(send-comment-emails! conn params comment thread))
|
|
||||||
|
|
||||||
(vary-meta comment assoc ::audit/props props))))
|
(vary-meta comment assoc ::audit/props comment))))
|
||||||
|
|
||||||
;; --- COMMAND: Update Comment
|
;; --- COMMAND: Update Comment
|
||||||
|
|
||||||
|
@ -645,16 +656,20 @@
|
||||||
[:id ::sm/uuid]
|
[:id ::sm/uuid]
|
||||||
[:content [:string {:max 250}]]
|
[:content [:string {:max 250}]]
|
||||||
[:share-id {:optional true} [:maybe ::sm/uuid]]
|
[:share-id {:optional true} [:maybe ::sm/uuid]]
|
||||||
[:mentions {:optional true} [:vector ::sm/uuid]]])
|
[:mentions {:optional true} [::sm/set ::sm/uuid]]])
|
||||||
|
|
||||||
|
;; TODO: Check if there are new mentions, if there are send the new emails.
|
||||||
|
|
||||||
;; TODO Check if there are new mentions, if there are send the new emails.
|
|
||||||
(sv/defmethod ::update-comment
|
(sv/defmethod ::update-comment
|
||||||
{::doc/added "1.15"
|
{::doc/added "1.15"
|
||||||
::sm/params schema:update-comment
|
::sm/params schema:update-comment
|
||||||
::db/transaction true}
|
::db/transaction true}
|
||||||
[{:keys [::db/conn] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at id share-id content mentions]}]
|
[{:keys [::db/conn] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at id share-id content mentions]}]
|
||||||
(let [{:keys [thread-id owner-id] :as comment} (get-comment conn id ::sql/for-update true)
|
(let [{:keys [thread-id owner-id] :as comment}
|
||||||
{:keys [file-id page-id] :as thread} (get-comment-thread conn thread-id ::sql/for-update true)]
|
(get-comment conn id ::sql/for-update true)
|
||||||
|
|
||||||
|
{:keys [file-id page-id] :as thread}
|
||||||
|
(get-comment-thread conn thread-id ::sql/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)
|
||||||
|
|
||||||
|
@ -675,10 +690,10 @@
|
||||||
:page-name page-name
|
:page-name page-name
|
||||||
:mentions
|
:mentions
|
||||||
(-> (:mentions thread)
|
(-> (:mentions thread)
|
||||||
(set)
|
|
||||||
(into mentions)
|
(into mentions)
|
||||||
(db/encode-pgarray conn "uuid"))}
|
(db/encode-pgarray conn "uuid"))}
|
||||||
{:id thread-id})
|
{:id thread-id}
|
||||||
|
{::db/return-keys false})
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
;; --- COMMAND: Delete Comment Thread
|
;; --- COMMAND: Delete Comment Thread
|
||||||
|
@ -700,7 +715,8 @@
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :not-allowed))
|
:code :not-allowed))
|
||||||
|
|
||||||
(db/delete! conn :comment-thread {:id id})
|
(db/delete! conn :comment-thread {:id id}
|
||||||
|
{::db/return-keys false})
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
;; --- COMMAND: Delete comment
|
;; --- COMMAND: Delete comment
|
||||||
|
@ -716,13 +732,19 @@
|
||||||
::sm/params schema:delete-comment
|
::sm/params schema:delete-comment
|
||||||
::db/transaction true}
|
::db/transaction true}
|
||||||
[{:keys [::db/conn]} {:keys [::rpc/profile-id id share-id]}]
|
[{:keys [::db/conn]} {:keys [::rpc/profile-id id share-id]}]
|
||||||
(let [{:keys [owner-id thread-id] :as comment} (get-comment conn id ::sql/for-update true)
|
(let [{:keys [owner-id thread-id] :as comment}
|
||||||
{:keys [file-id] :as thread} (get-comment-thread conn thread-id)]
|
(get-comment conn id ::sql/for-update true)
|
||||||
|
|
||||||
|
{:keys [file-id]}
|
||||||
|
(get-comment-thread conn thread-id)]
|
||||||
|
|
||||||
(files/check-comment-permissions! conn profile-id file-id share-id)
|
(files/check-comment-permissions! conn profile-id file-id share-id)
|
||||||
(when-not (= owner-id profile-id)
|
(when-not (= owner-id profile-id)
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :not-allowed))
|
:code :not-allowed))
|
||||||
(db/delete! conn :comment {:id id})
|
|
||||||
|
(db/delete! conn :comment {:id id}
|
||||||
|
{::db/return-keys false})
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
;; --- COMMAND: Update comment thread position
|
;; --- COMMAND: Update comment thread position
|
||||||
|
@ -740,13 +762,14 @@
|
||||||
::sm/params schema:update-comment-thread-position
|
::sm/params schema:update-comment-thread-position
|
||||||
::db/transaction true}
|
::db/transaction true}
|
||||||
[{:keys [::db/conn]} {:keys [::rpc/profile-id ::rpc/request-at id position frame-id share-id]}]
|
[{:keys [::db/conn]} {:keys [::rpc/profile-id ::rpc/request-at id position frame-id share-id]}]
|
||||||
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
|
(let [{:keys [file-id]} (get-comment-thread conn id ::sql/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)
|
||||||
(db/update! conn :comment-thread
|
(db/update! conn :comment-thread
|
||||||
{:modified-at request-at
|
{:modified-at request-at
|
||||||
:position (db/pgpoint position)
|
:position (db/pgpoint position)
|
||||||
:frame-id frame-id}
|
:frame-id frame-id}
|
||||||
{:id (:id thread)})
|
{:id id}
|
||||||
|
{::db/return-keys false})
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
;; --- COMMAND: Update comment frame
|
;; --- COMMAND: Update comment frame
|
||||||
|
@ -763,10 +786,11 @@
|
||||||
::sm/params schema:update-comment-thread-frame
|
::sm/params schema:update-comment-thread-frame
|
||||||
::db/transaction true}
|
::db/transaction true}
|
||||||
[{:keys [::db/conn]} {:keys [::rpc/profile-id ::rpc/request-at id frame-id share-id]}]
|
[{:keys [::db/conn]} {:keys [::rpc/profile-id ::rpc/request-at id frame-id share-id]}]
|
||||||
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
|
(let [{:keys [file-id]} (get-comment-thread conn id ::sql/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)
|
||||||
(db/update! conn :comment-thread
|
(db/update! conn :comment-thread
|
||||||
{:modified-at request-at
|
{:modified-at request-at
|
||||||
:frame-id frame-id}
|
:frame-id frame-id}
|
||||||
{:id id})
|
{:id id}
|
||||||
|
{::db/return-keys false})
|
||||||
nil))
|
nil))
|
||||||
|
|
|
@ -614,7 +614,8 @@
|
||||||
l.name,
|
l.name,
|
||||||
l.revn,
|
l.revn,
|
||||||
l.vern,
|
l.vern,
|
||||||
l.synced_at
|
l.synced_at,
|
||||||
|
l.is_shared
|
||||||
FROM libs AS l
|
FROM libs AS l
|
||||||
WHERE l.deleted_at IS NULL OR l.deleted_at > now();")
|
WHERE l.deleted_at IS NULL OR l.deleted_at > now();")
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
:deleted-at nil})]
|
:deleted-at nil})]
|
||||||
|
|
||||||
{:users members
|
{:users members
|
||||||
|
:profiles members
|
||||||
:fonts fonts
|
:fonts fonts
|
||||||
:project project
|
:project project
|
||||||
:share-links links
|
:share-links links
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
[app.common.types.color :as ctc]
|
[app.common.types.color :as ctc]
|
||||||
[app.common.types.colors-list :as ctcl]
|
[app.common.types.colors-list :as ctcl]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.file :as ctf]
|
|
||||||
[app.common.types.pages-list :as ctpl]
|
[app.common.types.pages-list :as ctpl]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
|
@ -43,25 +42,25 @@
|
||||||
frame-id (if (cfh/frame-shape? parent)
|
frame-id (if (cfh/frame-shape? parent)
|
||||||
(:id parent)
|
(:id parent)
|
||||||
(:frame-id parent))]
|
(:frame-id parent))]
|
||||||
(ctf/update-file-data
|
(update file :data
|
||||||
file
|
(fn [file-data]
|
||||||
(fn [file-data]
|
(ctpl/update-page file-data
|
||||||
(ctpl/update-page file-data
|
(:id page)
|
||||||
(:id page)
|
#(ctst/add-shape (:id shape)
|
||||||
#(ctst/add-shape (:id shape)
|
shape
|
||||||
shape
|
%
|
||||||
%
|
frame-id
|
||||||
frame-id
|
parent-id
|
||||||
parent-id
|
nil
|
||||||
nil
|
true))))))
|
||||||
true))))))
|
|
||||||
|
|
||||||
(defn get-shape
|
(defn get-shape
|
||||||
[file label & {:keys [page-label]}]
|
[file label & {:keys [page-label]}]
|
||||||
(let [page (if page-label
|
(let [page (if page-label
|
||||||
(thf/get-page file page-label)
|
(thf/get-page file page-label)
|
||||||
(thf/current-page file))]
|
(thf/current-page file))
|
||||||
(ctst/get-shape page (thi/id label))))
|
shape-id (thi/id label)]
|
||||||
|
(ctst/get-shape page shape-id)))
|
||||||
|
|
||||||
(defn get-shape-by-id
|
(defn get-shape-by-id
|
||||||
[file id & {:keys [page-label]}]
|
[file id & {:keys [page-label]}]
|
||||||
|
@ -76,12 +75,11 @@
|
||||||
(thf/get-page file page-label)
|
(thf/get-page file page-label)
|
||||||
(thf/current-page file))
|
(thf/current-page file))
|
||||||
shape (ctst/get-shape page (thi/id shape-label))]
|
shape (ctst/get-shape page (thi/id shape-label))]
|
||||||
(ctf/update-file-data
|
(update file :data
|
||||||
file
|
(fn [file-data]
|
||||||
(fn [file-data]
|
(ctpl/update-page file-data
|
||||||
(ctpl/update-page file-data
|
(:id page)
|
||||||
(:id page)
|
#(ctst/set-shape % (ctn/set-shape-attr shape attr val)))))))
|
||||||
#(ctst/set-shape % (ctn/set-shape-attr shape attr val)))))))
|
|
||||||
|
|
||||||
(defn sample-color
|
(defn sample-color
|
||||||
[label & {:keys [] :as params}]
|
[label & {:keys [] :as params}]
|
||||||
|
@ -104,7 +102,7 @@
|
||||||
(defn add-sample-library-color
|
(defn add-sample-library-color
|
||||||
[file label & {:keys [] :as params}]
|
[file label & {:keys [] :as params}]
|
||||||
(let [color (sample-color label params)]
|
(let [color (sample-color label params)]
|
||||||
(ctf/update-file-data file #(ctcl/add-color % color))))
|
(update file :data ctcl/add-color color)))
|
||||||
|
|
||||||
(defn sample-typography
|
(defn sample-typography
|
||||||
[label & {:keys [] :as params}]
|
[label & {:keys [] :as params}]
|
||||||
|
@ -113,7 +111,7 @@
|
||||||
(defn add-sample-typography
|
(defn add-sample-typography
|
||||||
[file label & {:keys [] :as params}]
|
[file label & {:keys [] :as params}]
|
||||||
(let [typography (sample-typography label params)]
|
(let [typography (sample-typography label params)]
|
||||||
(ctf/update-file-data file #(cttl/add-typography % typography))))
|
(update file :data cttl/add-typography typography)))
|
||||||
|
|
||||||
(defn add-interaction
|
(defn add-interaction
|
||||||
[file origin-label dest-label]
|
[file origin-label dest-label]
|
||||||
|
@ -124,9 +122,8 @@
|
||||||
(ctsi/set-destination (:id dest))
|
(ctsi/set-destination (:id dest))
|
||||||
(assoc :position-relative-to (:id origin)))
|
(assoc :position-relative-to (:id origin)))
|
||||||
interactions (ctsi/add-interaction (:interactions origin) interaction)]
|
interactions (ctsi/add-interaction (:interactions origin) interaction)]
|
||||||
(ctf/update-file-data
|
(update file :data
|
||||||
file
|
(fn [file-data]
|
||||||
(fn [file-data]
|
(ctpl/update-page file-data
|
||||||
(ctpl/update-page file-data
|
(:id page)
|
||||||
(:id page)
|
#(ctst/set-shape % (assoc origin :interactions interactions)))))))
|
||||||
#(ctst/set-shape % (assoc origin :interactions interactions)))))))
|
|
||||||
|
|
|
@ -143,6 +143,7 @@
|
||||||
|
|
||||||
;; --- fill
|
;; --- fill
|
||||||
|
|
||||||
|
;; FIXME: revisit, this generates invalid colors
|
||||||
(defn fill->shape-color
|
(defn fill->shape-color
|
||||||
[fill]
|
[fill]
|
||||||
(d/without-nils
|
(d/without-nils
|
||||||
|
@ -153,6 +154,16 @@
|
||||||
:ref-id (:fill-color-ref-id fill)
|
:ref-id (:fill-color-ref-id fill)
|
||||||
:ref-file (:fill-color-ref-file fill)}))
|
:ref-file (:fill-color-ref-file fill)}))
|
||||||
|
|
||||||
|
(defn fill->color
|
||||||
|
[fill]
|
||||||
|
(d/without-nils
|
||||||
|
{:color (:fill-color fill)
|
||||||
|
:opacity (:fill-opacity fill)
|
||||||
|
:gradient (:fill-color-gradient fill)
|
||||||
|
:image (:fill-image fill)
|
||||||
|
:id (:fill-color-ref-id fill)
|
||||||
|
:file-id (:fill-color-ref-file fill)}))
|
||||||
|
|
||||||
(defn set-fill-color
|
(defn set-fill-color
|
||||||
[shape position color opacity gradient image]
|
[shape position color opacity gradient image]
|
||||||
(update-in shape [:fills position]
|
(update-in shape [:fills position]
|
||||||
|
|
|
@ -103,4 +103,3 @@
|
||||||
(txt/transform-nodes #(not= (:typography-ref-file %) file-id)
|
(txt/transform-nodes #(not= (:typography-ref-file %) file-id)
|
||||||
remove-ref-file
|
remove-ref-file
|
||||||
content)))))
|
content)))))
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.worker :as uw]
|
[app.main.worker :as uw]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
|
@ -76,32 +77,30 @@
|
||||||
(ptk/reify ::apply-changes-localy
|
(ptk/reify ::apply-changes-localy
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [current-file-id (get state :current-file-id)
|
(let [undo-changes
|
||||||
path (if (= file-id current-file-id)
|
(if pending
|
||||||
[:workspace-data]
|
(->> pending
|
||||||
[:libraries file-id :data])
|
(map :undo-changes)
|
||||||
|
(reverse)
|
||||||
|
(mapcat identity)
|
||||||
|
(vec))
|
||||||
|
nil)
|
||||||
|
|
||||||
undo-changes (if pending
|
redo-changes
|
||||||
(->> pending
|
(if pending
|
||||||
(map :undo-changes)
|
(into redo-changes
|
||||||
(reverse)
|
(mapcat :redo-changes)
|
||||||
(mapcat identity)
|
pending)
|
||||||
(vec))
|
redo-changes)
|
||||||
nil)
|
|
||||||
|
|
||||||
redo-changes (if pending
|
apply-changes
|
||||||
(into redo-changes
|
(fn [fdata]
|
||||||
(mapcat :redo-changes)
|
(let [fdata (cpc/process-changes fdata undo-changes false)
|
||||||
pending)
|
fdata (cpc/process-changes fdata redo-changes false)
|
||||||
redo-changes)]
|
pids (into #{} xf:map-page-id redo-changes)]
|
||||||
|
(reduce #(ctst/update-object-indices %1 %2) fdata pids)))]
|
||||||
(d/update-in-when state path
|
|
||||||
(fn [file]
|
|
||||||
(let [file (cpc/process-changes file undo-changes false)
|
|
||||||
file (cpc/process-changes file redo-changes false)
|
|
||||||
pids (into #{} xf:map-page-id redo-changes)]
|
|
||||||
(reduce #(ctst/update-object-indices %1 %2) file pids))))))))
|
|
||||||
|
|
||||||
|
(update-in state [:files file-id :data] apply-changes)))))
|
||||||
|
|
||||||
(defn commit
|
(defn commit
|
||||||
"Create a commit event instance"
|
"Create a commit event instance"
|
||||||
|
@ -156,17 +155,11 @@
|
||||||
|
|
||||||
(defn- resolve-file-revn
|
(defn- resolve-file-revn
|
||||||
[state file-id]
|
[state file-id]
|
||||||
(let [file (:workspace-file state)]
|
(:revn (dsh/lookup-file state file-id)))
|
||||||
(if (= (:id file) file-id)
|
|
||||||
(:revn file)
|
|
||||||
(dm/get-in state [:libraries file-id :revn]))))
|
|
||||||
|
|
||||||
(defn- resolve-file-vern
|
(defn- resolve-file-vern
|
||||||
[state file-id]
|
[state file-id]
|
||||||
(let [file (:workspace-file state)]
|
(:vern (dsh/lookup-file state file-id)))
|
||||||
(if (= (:id file) file-id)
|
|
||||||
(:vern file)
|
|
||||||
(dm/get-in state [:libraries file-id :vern]))))
|
|
||||||
|
|
||||||
(defn commit-changes
|
(defn commit-changes
|
||||||
"Schedules a list of changes to execute now, and add the corresponding undo changes to
|
"Schedules a list of changes to execute now, and add the corresponding undo changes to
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
|
[app.main.data.team :as dtm]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -25,8 +26,10 @@
|
||||||
[:file-id ::sm/uuid]
|
[:file-id ::sm/uuid]
|
||||||
[:project-id ::sm/uuid]
|
[:project-id ::sm/uuid]
|
||||||
[:owner-id ::sm/uuid]
|
[:owner-id ::sm/uuid]
|
||||||
[:page-name {:optional true} :string]
|
[:owner-fullname {:optional true} ::sm/text]
|
||||||
[:file-name :string]
|
[:owner-email {:optional true} ::sm/email]
|
||||||
|
[:page-name {:optional true} ::sm/text]
|
||||||
|
[:file-name ::sm/text]
|
||||||
[:seqn :int]
|
[:seqn :int]
|
||||||
[:content :string]
|
[:content :string]
|
||||||
[:participants ::sm/set-of-uuid]
|
[:participants ::sm/set-of-uuid]
|
||||||
|
@ -40,7 +43,10 @@
|
||||||
[:map {:title "Comment"}
|
[:map {:title "Comment"}
|
||||||
[:id ::sm/uuid]
|
[:id ::sm/uuid]
|
||||||
[:thread-id ::sm/uuid]
|
[:thread-id ::sm/uuid]
|
||||||
|
[:file-id ::sm/uuid]
|
||||||
[:owner-id ::sm/uuid]
|
[:owner-id ::sm/uuid]
|
||||||
|
[:owner-fullname {:optional true} ::sm/text]
|
||||||
|
[:owner-email {:optional true} ::sm/email]
|
||||||
[:created-at ::sm/inst]
|
[:created-at ::sm/inst]
|
||||||
[:modified-at ::sm/inst]
|
[:modified-at ::sm/inst]
|
||||||
[:content :string]])
|
[:content :string]])
|
||||||
|
@ -75,10 +81,11 @@
|
||||||
(ptk/reify ::created-thread-on-workspace
|
(ptk/reify ::created-thread-on-workspace
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [position (select-keys thread [:position :frame-id])]
|
(let [position (select-keys thread [:position :frame-id])
|
||||||
|
page-id (or page-id (:current-page-id state))]
|
||||||
(-> state
|
(-> state
|
||||||
(update :comment-threads assoc id (dissoc thread :comment))
|
(update :comment-threads assoc id (dissoc thread :comment))
|
||||||
(update-in [:workspace-data :pages-index page-id :comment-thread-positions] assoc id position)
|
(dsh/update-page page-id #(update % :comment-thread-positions assoc id position))
|
||||||
(cond-> open?
|
(cond-> open?
|
||||||
(update :comments-local assoc :open id))
|
(update :comments-local assoc :open id))
|
||||||
(update :comments-local assoc :options nil)
|
(update :comments-local assoc :options nil)
|
||||||
|
@ -94,8 +101,6 @@
|
||||||
:id id
|
:id id
|
||||||
:content-size (count (:content comment))}))))))
|
:content-size (count (:content comment))}))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
schema:create-thread-on-workspace
|
schema:create-thread-on-workspace
|
||||||
[:map {:title "created-thread-on-workspace"}
|
[:map {:title "created-thread-on-workspace"}
|
||||||
|
@ -114,7 +119,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
frame-id (ctst/get-frame-id-by-position objects (:position params))
|
frame-id (ctst/get-frame-id-by-position objects (:position params))
|
||||||
params (-> params
|
params (-> params
|
||||||
(update-mentions)
|
(update-mentions)
|
||||||
|
@ -263,7 +268,7 @@
|
||||||
(rx/of (refresh-comment-thread thread)))))))
|
(rx/of (refresh-comment-thread thread)))))))
|
||||||
|
|
||||||
(defn update-comment
|
(defn update-comment
|
||||||
[{:keys [id content thread-id] :as comment}]
|
[{:keys [id content thread-id file-id] :as comment}]
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected valid comment"
|
"expected valid comment"
|
||||||
(check-comment! comment))
|
(check-comment! comment))
|
||||||
|
@ -277,15 +282,13 @@
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(d/update-in-when state [:comments thread-id id] assoc :content content))
|
||||||
(d/update-in-when [:comments thread-id id] assoc :content content)))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-id (:current-file-id state)
|
(let [share-id (-> state :viewer-local :share-id)
|
||||||
share-id (-> state :viewer-local :share-id)
|
params {:id id :content content :share-id share-id}
|
||||||
params (-> {:id id :content content :share-id share-id}
|
params (update-mentions params)]
|
||||||
(update-mentions))]
|
|
||||||
(->> (rp/cmd! :update-comment params)
|
(->> (rp/cmd! :update-comment params)
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))
|
(rx/catch #(rx/throw {:type :comment-error}))
|
||||||
(rx/map #(retrieve-comment-threads file-id)))))))
|
(rx/map #(retrieve-comment-threads file-id)))))))
|
||||||
|
@ -299,11 +302,10 @@
|
||||||
(ptk/reify ::delete-comment-thread-on-workspace
|
(ptk/reify ::delete-comment-thread-on-workspace
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [page-id (:current-page-id state)]
|
(-> state
|
||||||
(-> state
|
(dsh/update-page #(update % :comment-thread-positions dissoc id))
|
||||||
(update-in [:workspace-data :pages-index page-id :comment-thread-positions] dissoc id)
|
(update :comments dissoc id)
|
||||||
(update :comments dissoc id)
|
(update :comment-threads dissoc id)))
|
||||||
(update :comment-threads dissoc id))))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
|
@ -380,35 +382,37 @@
|
||||||
(rx/map #(partial fetched %))
|
(rx/map #(partial fetched %))
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- comment-threads-fetched
|
||||||
|
[threads]
|
||||||
|
(ptk/reify ::comment-threads-fetched
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(reduce (fn [state {:keys [id file-id page-id] :as thread}]
|
||||||
|
(-> state
|
||||||
|
(update :comment-threads assoc id thread)
|
||||||
|
(dsh/update-page file-id page-id
|
||||||
|
(fn [page]
|
||||||
|
(update-in page [:comment-thread-positions id]
|
||||||
|
(fn [state]
|
||||||
|
(-> state
|
||||||
|
(assoc :position (:position thread))
|
||||||
|
(assoc :frame-id (:frame-id thread)))))))))
|
||||||
|
state
|
||||||
|
threads))))
|
||||||
|
|
||||||
(defn retrieve-comment-threads
|
(defn retrieve-comment-threads
|
||||||
[file-id]
|
[file-id]
|
||||||
(dm/assert! (uuid? file-id))
|
(ptk/reify ::retrieve-comment-threads
|
||||||
(letfn [(set-comment-threds [state comment-thread]
|
ptk/WatchEvent
|
||||||
(let [path [:workspace-data :pages-index (:page-id comment-thread) :comment-thread-positions (:id comment-thread)]
|
(watch [_ state _]
|
||||||
thread-position (get-in state path)]
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(cond-> state
|
(rx/merge
|
||||||
(nil? thread-position)
|
(->> (rp/cmd! :get-comment-threads {:file-id file-id :share-id share-id})
|
||||||
(->
|
(rx/map comment-threads-fetched))
|
||||||
(assoc-in (conj path :position) (:position comment-thread))
|
|
||||||
(assoc-in (conj path :frame-id) (:frame-id comment-thread))))))
|
|
||||||
(fetched [[users comments] state]
|
|
||||||
(let [pages (-> (get-in state [:workspace-data :pages])
|
|
||||||
set)
|
|
||||||
comments (filter #(contains? pages (:page-id %)) comments)
|
|
||||||
state (-> state
|
|
||||||
(assoc :comment-threads (d/index-by :id comments))
|
|
||||||
(update :current-file-comments-users merge (d/index-by :id users)))]
|
|
||||||
(reduce set-comment-threds state comments)))]
|
|
||||||
|
|
||||||
(ptk/reify ::retrieve-comment-threads
|
;; Refresh team members
|
||||||
ptk/WatchEvent
|
(rx/of (dtm/fetch-members)))))))
|
||||||
(watch [_ state _]
|
|
||||||
(let [share-id (-> state :viewer-local :share-id)]
|
|
||||||
(->> (rx/zip (rp/cmd! :get-team-users {:file-id file-id})
|
|
||||||
(rp/cmd! :get-comment-threads {:file-id file-id :share-id share-id}))
|
|
||||||
(rx/take 1)
|
|
||||||
(rx/map #(partial fetched %))
|
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
|
||||||
|
|
||||||
(defn retrieve-comments
|
(defn retrieve-comments
|
||||||
[thread-id]
|
[thread-id]
|
||||||
|
@ -423,6 +427,8 @@
|
||||||
(rx/map #(partial fetched %))
|
(rx/map #(partial fetched %))
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
||||||
|
|
||||||
|
|
||||||
|
;; FIXME: revisit
|
||||||
(defn retrieve-unread-comment-threads
|
(defn retrieve-unread-comment-threads
|
||||||
"A event used mainly in dashboard for retrieve all unread threads of a team."
|
"A event used mainly in dashboard for retrieve all unread threads of a team."
|
||||||
[team-id]
|
[team-id]
|
||||||
|
@ -544,6 +550,13 @@
|
||||||
;; Helpers
|
;; Helpers
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn get-owner
|
||||||
|
[thread-or-comment]
|
||||||
|
{:id (:owner-id thread-or-comment)
|
||||||
|
:fullname (:owner-fullname thread-or-comment)
|
||||||
|
:email (:owner-email thread-or-comment)
|
||||||
|
:photo-id (:owner-photo-id thread-or-comment)})
|
||||||
|
|
||||||
(defn group-threads-by-page
|
(defn group-threads-by-page
|
||||||
[threads]
|
[threads]
|
||||||
(letfn [(group-by-page [result thread]
|
(letfn [(group-by-page [result thread]
|
||||||
|
@ -621,7 +634,7 @@
|
||||||
(ptk/reify ::detach-comment-thread
|
(ptk/reify ::detach-comment-thread
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
||||||
frame-ids? (into #{} (filter is-frame?) ids)]
|
frame-ids? (into #{} (filter is-frame?) ids)]
|
||||||
|
|
||||||
|
@ -635,7 +648,7 @@
|
||||||
(defn fetch-profiles
|
(defn fetch-profiles
|
||||||
"Fetch or refresh all profile data for comments of the current file"
|
"Fetch or refresh all profile data for comments of the current file"
|
||||||
[]
|
[]
|
||||||
(ptk/reify ::fetch-comments-profiles
|
(ptk/reify ::fetch-profiles
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.types.components-list :as ctkl]
|
[app.common.types.components-list :as ctkl]
|
||||||
[app.common.types.team :as ctt]
|
[app.common.types.team :as ctt]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.notifications :as ntf]
|
[app.main.data.notifications :as ntf]
|
||||||
[app.main.data.persistence :as-alias dps]
|
[app.main.data.persistence :as-alias dps]
|
||||||
|
@ -111,8 +112,9 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [features (features/get-team-enabled-features state)
|
(let [features (features/get-team-enabled-features state)
|
||||||
data (:workspace-data state)
|
file (dsh/lookup-file state)
|
||||||
file (:workspace-file state)]
|
data (get file :data)]
|
||||||
|
|
||||||
(->> (if (and data file)
|
(->> (if (and data file)
|
||||||
(rx/of {:name (:name file)
|
(rx/of {:name (:name file)
|
||||||
:components-count (count (ctkl/components-seq data))
|
:components-count (count (ctkl/components-seq data))
|
||||||
|
@ -368,7 +370,9 @@
|
||||||
(let [team-id (or team-id (:current-team-id state))
|
(let [team-id (or team-id (:current-team-id state))
|
||||||
file-id (or file-id (:current-file-id state))
|
file-id (or file-id (:current-file-id state))
|
||||||
page-id (or page-id (:current-page-id state)
|
page-id (or page-id (:current-page-id state)
|
||||||
(dm/get-in state [:workspace-data :pages 0]))
|
(-> (dsh/lookup-file-data state file-id)
|
||||||
|
(get :pages)
|
||||||
|
(first)))
|
||||||
|
|
||||||
params (-> (rt/get-params state)
|
params (-> (rt/get-params state)
|
||||||
(assoc :team-id team-id)
|
(assoc :team-id team-id)
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.persistence :as dwp]
|
[app.main.data.persistence :as dwp]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -56,11 +56,11 @@
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
selected (or selected (wsh/lookup-selected state page-id {}))
|
selected (or selected (dsh/lookup-selected state page-id {}))
|
||||||
|
|
||||||
shapes (if (seq selected)
|
shapes (if (seq selected)
|
||||||
(wsh/lookup-shapes state selected)
|
(dsh/lookup-shapes state selected)
|
||||||
(reverse (wsh/filter-shapes state #(pos? (count (:exports %))))))
|
(reverse (dsh/filter-shapes state #(pos? (count (:exports %))))))
|
||||||
|
|
||||||
exports (for [shape shapes
|
exports (for [shape shapes
|
||||||
export (:exports shape)]
|
export (:exports shape)]
|
||||||
|
|
|
@ -327,27 +327,23 @@
|
||||||
;; Workspace related events
|
;; Workspace related events
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn- update-recent-font
|
||||||
|
"Moves the font/font to the top of the list of recents and then truncates up to 4"
|
||||||
|
[state file-id font]
|
||||||
|
(let [xform (comp
|
||||||
|
(remove #(= font %))
|
||||||
|
(take 3))]
|
||||||
|
(update state file-id #(into [font] xform %))))
|
||||||
|
|
||||||
(defn add-recent-font
|
(defn add-recent-font
|
||||||
[font]
|
[font]
|
||||||
(ptk/reify ::add-recent-font
|
(ptk/reify ::add-recent-font
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [recent-fonts (get-in state [:workspace-data :recent-fonts])
|
(let [file-id (:current-file-id state)]
|
||||||
most-recent-fonts (into [font] (comp (remove #(= font %)) (take 3)) recent-fonts)]
|
(update state :recent-fonts update-recent-font file-id font)))
|
||||||
(assoc-in state [:workspace-data :recent-fonts] most-recent-fonts)))
|
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ state _]
|
(effect [_ state _]
|
||||||
(let [most-recent-fonts (get-in state [:workspace-data :recent-fonts])]
|
(let [recent-fonts (:recent-fonts state)]
|
||||||
;; FIXME: this should be prefixed by team
|
(swap! storage/user assoc :recent-fonts recent-fonts)))))
|
||||||
(swap! storage/user assoc ::recent-fonts most-recent-fonts)))))
|
|
||||||
|
|
||||||
(defn load-recent-fonts
|
|
||||||
[fonts]
|
|
||||||
(ptk/reify ::load-recent-fonts
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [fonts-map (d/index-by :id fonts)
|
|
||||||
saved-recent-fonts (->> (::recent-fonts storage/user)
|
|
||||||
(keep #(get fonts-map (:id %)))
|
|
||||||
(into #{}))]
|
|
||||||
(assoc-in state [:workspace-data :recent-fonts] saved-recent-fonts)))))
|
|
||||||
|
|
170
frontend/src/app/main/data/helpers.cljs
Normal file
170
frontend/src/app/main/data/helpers.cljs
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
;; 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) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.data.helpers
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.helpers :as cfh]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.svg.path.command :as upc]))
|
||||||
|
|
||||||
|
(defn lookup-profile
|
||||||
|
([state]
|
||||||
|
(:profile state))
|
||||||
|
([state profile-id]
|
||||||
|
(dm/get-in state [:profiles profile-id])))
|
||||||
|
|
||||||
|
(defn lookup-libraries
|
||||||
|
"Retrieve all libraries, including the local file."
|
||||||
|
[state]
|
||||||
|
(:files state))
|
||||||
|
|
||||||
|
(defn lookup-file
|
||||||
|
([state]
|
||||||
|
(lookup-file state (:current-file-id state)))
|
||||||
|
([state file-id]
|
||||||
|
(dm/get-in state [:files file-id])))
|
||||||
|
|
||||||
|
(defn lookup-file-data
|
||||||
|
([state]
|
||||||
|
(lookup-file-data state (:current-file-id state)))
|
||||||
|
([state file-id]
|
||||||
|
(dm/get-in state [:files file-id :data])))
|
||||||
|
|
||||||
|
(defn get-page
|
||||||
|
[fdata page-id]
|
||||||
|
(dm/get-in fdata [:pages-index page-id]))
|
||||||
|
|
||||||
|
(defn lookup-page
|
||||||
|
([state]
|
||||||
|
(let [file-id (:current-file-id state)
|
||||||
|
page-id (:current-page-id state)]
|
||||||
|
(lookup-page state file-id page-id)))
|
||||||
|
([state page-id]
|
||||||
|
(let [file-id (:current-file-id state)]
|
||||||
|
(lookup-page state file-id page-id)))
|
||||||
|
([state file-id page-id]
|
||||||
|
(dm/get-in state [:files file-id :data :pages-index page-id])))
|
||||||
|
|
||||||
|
(defn lookup-page-objects
|
||||||
|
([state]
|
||||||
|
(lookup-page-objects state
|
||||||
|
(:current-file-id state)
|
||||||
|
(:current-page-id state)))
|
||||||
|
([state page-id]
|
||||||
|
(lookup-page-objects state
|
||||||
|
(:current-file-id state)
|
||||||
|
page-id))
|
||||||
|
([state file-id page-id]
|
||||||
|
(-> (lookup-page state file-id page-id)
|
||||||
|
(get :objects))))
|
||||||
|
|
||||||
|
(defn process-selected-shapes
|
||||||
|
([objects selected]
|
||||||
|
(process-selected-shapes objects selected nil))
|
||||||
|
|
||||||
|
([objects selected {:keys [omit-blocked?] :or {omit-blocked? false}}]
|
||||||
|
(letfn [(selectable? [id]
|
||||||
|
(and (contains? objects id)
|
||||||
|
(or (not omit-blocked?)
|
||||||
|
(not (get-in objects [id :blocked] false)))))]
|
||||||
|
(let [selected (->> selected (cfh/clean-loops objects))]
|
||||||
|
(into (d/ordered-set)
|
||||||
|
(filter selectable?)
|
||||||
|
selected)))))
|
||||||
|
|
||||||
|
;; DEPRECATED
|
||||||
|
(defn lookup-selected-raw
|
||||||
|
[state]
|
||||||
|
(dm/get-in state [:workspace-local :selected]))
|
||||||
|
|
||||||
|
(defn get-selected-ids
|
||||||
|
[state]
|
||||||
|
(dm/get-in state [:workspace-local :selected]))
|
||||||
|
|
||||||
|
(defn lookup-selected
|
||||||
|
([state]
|
||||||
|
(lookup-selected state (:current-page-id state) nil))
|
||||||
|
([state options]
|
||||||
|
(lookup-selected state (:current-page-id state) options))
|
||||||
|
([state page-id options]
|
||||||
|
(let [objects (lookup-page-objects state page-id)
|
||||||
|
selected (dm/get-in state [:workspace-local :selected])]
|
||||||
|
(process-selected-shapes objects selected options))))
|
||||||
|
|
||||||
|
(defn lookup-shape
|
||||||
|
([state id]
|
||||||
|
(lookup-shape state (:current-page-id state) id))
|
||||||
|
|
||||||
|
([state page-id id]
|
||||||
|
(let [objects (lookup-page-objects state page-id)]
|
||||||
|
(get objects id))))
|
||||||
|
|
||||||
|
(defn lookup-shapes
|
||||||
|
([state ids]
|
||||||
|
(lookup-shapes state (:current-page-id state) ids))
|
||||||
|
([state page-id ids]
|
||||||
|
(let [objects (lookup-page-objects state page-id)]
|
||||||
|
(into [] (keep (d/getf objects)) ids))))
|
||||||
|
|
||||||
|
(defn update-file
|
||||||
|
([state f]
|
||||||
|
(update-file state (:current-file-id state) f))
|
||||||
|
([state file-id f]
|
||||||
|
(d/update-in-when state [:files file-id] f)))
|
||||||
|
|
||||||
|
(defn update-page
|
||||||
|
([state f]
|
||||||
|
(update-page state
|
||||||
|
(:current-file-id state)
|
||||||
|
(:current-page-id state)
|
||||||
|
f))
|
||||||
|
([state page-id f]
|
||||||
|
(update-page state
|
||||||
|
(:current-file-id state)
|
||||||
|
page-id
|
||||||
|
f))
|
||||||
|
([state file-id page-id f]
|
||||||
|
(d/update-in-when state [:files file-id :data :pages-index page-id] f)))
|
||||||
|
|
||||||
|
(defn filter-shapes
|
||||||
|
([state filter-fn]
|
||||||
|
(filter-shapes state (:current-page-id state) filter-fn))
|
||||||
|
([state page-id filter-fn]
|
||||||
|
(let [objects (lookup-page-objects state page-id)]
|
||||||
|
(into [] (filter filter-fn) (vals objects)))))
|
||||||
|
|
||||||
|
(defn select-bool-children
|
||||||
|
[state parent-id]
|
||||||
|
(let [objects (lookup-page-objects state)
|
||||||
|
|
||||||
|
shape-modifiers
|
||||||
|
(:workspace-modifiers state)
|
||||||
|
|
||||||
|
content-modifiers
|
||||||
|
(dm/get-in state [:workspace-local :edit-path])]
|
||||||
|
|
||||||
|
(reduce (fn [result id]
|
||||||
|
(if-let [shape (get objects id)]
|
||||||
|
(let [modifiers (dm/get-in shape-modifiers [id :modifiers])
|
||||||
|
shape (if (some? modifiers)
|
||||||
|
(gsh/transform-shape shape modifiers)
|
||||||
|
shape)
|
||||||
|
modifiers (dm/get-in content-modifiers [id :content-modifiers])
|
||||||
|
shape (if (some? modifiers)
|
||||||
|
(update shape :content upc/apply-content-modifiers modifiers)
|
||||||
|
shape)]
|
||||||
|
(assoc result id shape))
|
||||||
|
result))
|
||||||
|
{}
|
||||||
|
(cfh/get-children-ids objects parent-id))))
|
||||||
|
|
||||||
|
(defn get-viewport-center
|
||||||
|
[state]
|
||||||
|
(when-let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])]
|
||||||
|
(gpt/point (+ x (/ width 2)) (+ y (/ height 2)))))
|
|
@ -11,6 +11,7 @@
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -49,11 +50,7 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(log/dbg :hint "update-file-revn" :file-id (dm/str file-id) :revn revn)
|
(log/dbg :hint "update-file-revn" :file-id (dm/str file-id) :revn revn)
|
||||||
(if-let [current-file-id (:current-file-id state)]
|
(dsh/update-file state file-id #(update % :revn max revn)))
|
||||||
(if (= file-id current-file-id)
|
|
||||||
(update-in state [:workspace-file :revn] max revn)
|
|
||||||
(d/update-in-when state [:libraries file-id :revn] max revn))
|
|
||||||
state))
|
|
||||||
|
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ _ _]
|
(effect [_ _ _]
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.util.code-beautify :as cb]
|
[app.util.code-beautify :as cb]
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
(ptk/reify ::update-preview
|
(ptk/reify ::update-preview
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ state _]
|
(effect [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects shape-id)
|
shape (get objects shape-id)
|
||||||
|
|
||||||
all-children
|
all-children
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
(ptk/reify ::open-preview-selected
|
(ptk/reify ::open-preview-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [shape-id (first (wsh/lookup-selected state))
|
(let [shape-id (first (dsh/lookup-selected state))
|
||||||
closed-preview (rx/subject)
|
closed-preview (rx/subject)
|
||||||
preview (.open js/window "/#/frame-preview")
|
preview (.open js/window "/#/frame-preview")
|
||||||
listener-fn #(rx/push! closed-preview true)]
|
listener-fn #(rx/push! closed-preview true)]
|
||||||
|
|
|
@ -330,19 +330,6 @@
|
||||||
(rx/map (constantly (refresh-profile)))
|
(rx/map (constantly (refresh-profile)))
|
||||||
(rx/catch on-error))))))
|
(rx/catch on-error))))))
|
||||||
|
|
||||||
(defn fetch-users
|
|
||||||
[]
|
|
||||||
(letfn [(fetched [users state]
|
|
||||||
(->> users
|
|
||||||
(d/index-by :id)
|
|
||||||
(assoc state :users)))]
|
|
||||||
(ptk/reify ::fetch-team-users
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state _]
|
|
||||||
(let [team-id (:current-team-id state)]
|
|
||||||
(->> (rp/cmd! :get-team-users {:team-id team-id})
|
|
||||||
(rx/map #(partial fetched %))))))))
|
|
||||||
|
|
||||||
(defn fetch-file-comments-users
|
(defn fetch-file-comments-users
|
||||||
[{:keys [team-id]}]
|
[{:keys [team-id]}]
|
||||||
(dm/assert! (uuid? team-id))
|
(dm/assert! (uuid? team-id))
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.main.ui.workspace.tokens.token-set :as wtts]
|
[app.main.ui.workspace.tokens.token-set :as wtts]
|
||||||
[app.main.ui.workspace.tokens.update :as wtu]
|
[app.main.ui.workspace.tokens.update :as wtu]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
|
@ -42,18 +42,15 @@
|
||||||
;; TOKENS Getters
|
;; TOKENS Getters
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn get-tokens-lib [state]
|
(defn get-tokens-lib
|
||||||
(get-in state [:workspace-data :tokens-lib]))
|
[state]
|
||||||
|
(-> (dsh/lookup-file-data state)
|
||||||
|
(get :tokens-lib)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; TOKENS Actions
|
;; TOKENS Actions
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn get-token-data-from-token-id
|
|
||||||
[id]
|
|
||||||
(let [workspace-data (deref refs/workspace-data)]
|
|
||||||
(get (:tokens workspace-data) id)))
|
|
||||||
|
|
||||||
(defn set-selected-token-set-path
|
(defn set-selected-token-set-path
|
||||||
[full-path]
|
[full-path]
|
||||||
(ptk/reify ::set-selected-token-set-path
|
(ptk/reify ::set-selected-token-set-path
|
||||||
|
@ -112,7 +109,8 @@
|
||||||
(ptk/reify ::delete-token-theme
|
(ptk/reify ::delete-token-theme
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
|
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-token-theme group name))]
|
(pcb/delete-token-theme group name))]
|
||||||
|
@ -178,7 +176,7 @@
|
||||||
(ptk/reify ::import-tokens-lib
|
(ptk/reify ::import-tokens-lib
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
update-token-set-change (some-> lib
|
update-token-set-change (some-> lib
|
||||||
(ctob/get-sets)
|
(ctob/get-sets)
|
||||||
(first)
|
(first)
|
||||||
|
@ -196,7 +194,7 @@
|
||||||
(ptk/reify ::delete-token-set-path
|
(ptk/reify ::delete-token-set-path
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-token-set-path prefixed-full-set-path))]
|
(pcb/delete-token-set-path prefixed-full-set-path))]
|
||||||
|
@ -259,7 +257,7 @@
|
||||||
(ptk/reify ::delete-token
|
(ptk/reify ::delete-token
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-token set-name token-name))]
|
(pcb/delete-token set-name token-name))]
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.fonts :as df]
|
[app.main.data.fonts :as df]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.notifications :as ntf]
|
[app.main.data.notifications :as ntf]
|
||||||
[app.main.data.plugins :as dp]
|
[app.main.data.plugins :as dp]
|
||||||
|
@ -67,7 +68,6 @@
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.texts :as dwtxt]
|
[app.main.data.workspace.texts :as dwtxt]
|
||||||
[app.main.data.workspace.thumbnails :as dwth]
|
[app.main.data.workspace.thumbnails :as dwth]
|
||||||
[app.main.data.workspace.transforms :as dwt]
|
[app.main.data.workspace.transforms :as dwt]
|
||||||
|
@ -174,16 +174,21 @@
|
||||||
(ptk/reify ::libraries-fetched
|
(ptk/reify ::libraries-fetched
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc state :libraries (d/index-by :id libraries)))
|
(let [libraries (d/index-by :id libraries)]
|
||||||
|
(update state :files merge libraries)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-id (dm/get-in state [:workspace-file :id])
|
(let [file (dsh/lookup-file state)
|
||||||
ignore-until (dm/get-in state [:workspace-file :ignore-sync-until])
|
file-id (get file :id)
|
||||||
needs-check? (some #(and (> (:modified-at %) (:synced-at %))
|
ignore-until (get file :ignore-sync-until)
|
||||||
(or (not ignore-until)
|
|
||||||
(> (:modified-at %) ignore-until)))
|
needs-check?
|
||||||
libraries)]
|
(some #(and (> (:modified-at %) (:synced-at %))
|
||||||
|
(or (not ignore-until)
|
||||||
|
(> (:modified-at %) ignore-until)))
|
||||||
|
libraries)]
|
||||||
|
|
||||||
(when needs-check?
|
(when needs-check?
|
||||||
(rx/concat (rx/timer 1000)
|
(rx/concat (rx/timer 1000)
|
||||||
(rx/of (dwl/notify-sync-file file-id))))))))
|
(rx/of (dwl/notify-sync-file file-id))))))))
|
||||||
|
@ -213,23 +218,19 @@
|
||||||
(rx/map dwl/library-thumbnails-fetched))))))))))
|
(rx/map dwl/library-thumbnails-fetched))))))))))
|
||||||
|
|
||||||
(defn- workspace-initialized
|
(defn- workspace-initialized
|
||||||
[]
|
[file-id]
|
||||||
(ptk/reify ::workspace-initialized
|
(ptk/reify ::workspace-initialized
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc :workspace-undo {})
|
(assoc :workspace-undo {})
|
||||||
(assoc :workspace-ready true)))
|
(assoc :workspace-ready file-id)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ _ _]
|
||||||
(rx/of
|
(rx/of (dp/check-open-plugin)
|
||||||
(when (and (not (boolean (-> state :profile :props :v2-info-shown)))
|
(fdf/fix-deleted-fonts)
|
||||||
(features/active-feature? state "components/v2"))
|
(fbs/fix-broken-shapes)))))
|
||||||
(modal/show :v2-info {}))
|
|
||||||
(dp/check-open-plugin)
|
|
||||||
(fdf/fix-deleted-fonts)
|
|
||||||
(fbs/fix-broken-shapes)))))
|
|
||||||
|
|
||||||
(defn- bundle-fetched
|
(defn- bundle-fetched
|
||||||
[{:keys [features file thumbnails]}]
|
[{:keys [features file thumbnails]}]
|
||||||
|
@ -242,10 +243,10 @@
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(let [file-id (:id file)]
|
||||||
(assoc :thumbnails thumbnails)
|
(-> state
|
||||||
(assoc :workspace-file (dissoc file :data))
|
(assoc :thumbnails thumbnails)
|
||||||
(assoc :workspace-data (:data file))))
|
(update :files assoc file-id file))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -317,11 +318,13 @@
|
||||||
(ptk/reify ::initialize-workspace
|
(ptk/reify ::initialize-workspace
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc state
|
(-> state
|
||||||
:recent-colors (:recent-colors storage/user)
|
(dissoc :files)
|
||||||
:workspace-ready false
|
(dissoc :workspace-ready)
|
||||||
:current-file-id file-id
|
(assoc :recent-colors (:recent-colors storage/user))
|
||||||
:workspace-presence {}))
|
(assoc :recent-fonts (:recent-fonts storage/user))
|
||||||
|
(assoc :current-file-id file-id)
|
||||||
|
(assoc :workspace-presence {})))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
|
@ -341,7 +344,7 @@
|
||||||
(rx/map deref)
|
(rx/map deref)
|
||||||
(rx/mapcat (fn [{:keys [file]}]
|
(rx/mapcat (fn [{:keys [file]}]
|
||||||
(rx/of (dpj/initialize-project (:project-id file))
|
(rx/of (dpj/initialize-project (:project-id file))
|
||||||
(-> (workspace-initialized)
|
(-> (workspace-initialized file-id)
|
||||||
(with-meta {:file-id file-id}))))))
|
(with-meta {:file-id file-id}))))))
|
||||||
|
|
||||||
(when-let [component-id (some-> rparams :component-id parse-uuid)]
|
(when-let [component-id (some-> rparams :component-id parse-uuid)]
|
||||||
|
@ -388,12 +391,11 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
|
;; FIXME: revisit
|
||||||
(dissoc
|
(dissoc
|
||||||
:current-file-id
|
:current-file-id
|
||||||
:workspace-data
|
|
||||||
:workspace-editor-state
|
:workspace-editor-state
|
||||||
:workspace-file
|
:files
|
||||||
:libraries
|
|
||||||
:workspace-media-objects
|
:workspace-media-objects
|
||||||
:workspace-persistence
|
:workspace-persistence
|
||||||
:workspace-presence
|
:workspace-presence
|
||||||
|
@ -431,7 +433,7 @@
|
||||||
(ptk/reify ::initialize-page
|
(ptk/reify ::initialize-page
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if-let [{:keys [id] :as page} (dm/get-in state [:workspace-data :pages-index page-id])]
|
(if-let [{:keys [id] :as page} (dsh/lookup-page state page-id)]
|
||||||
;; we maintain a cache of page state for user convenience with the exception of the
|
;; we maintain a cache of page state for user convenience with the exception of the
|
||||||
;; selection; when user abandon the current page, the selection is lost
|
;; selection; when user abandon the current page, the selection is lost
|
||||||
(let [local (dm/get-in state [:workspace-cache id] default-workspace-local)]
|
(let [local (dm/get-in state [:workspace-cache id] default-workspace-local)]
|
||||||
|
@ -483,7 +485,7 @@
|
||||||
(cond
|
(cond
|
||||||
(some? metadata) (cf/resolve-file-media metadata)
|
(some? metadata) (cf/resolve-file-media metadata)
|
||||||
(some? fill-image) (cf/resolve-file-media fill-image)))))
|
(some? fill-image) (cf/resolve-file-media fill-image)))))
|
||||||
uris (into #{} xform (wsh/lookup-page-objects state page-id))]
|
uris (into #{} xform (dsh/lookup-page-objects state page-id))]
|
||||||
|
|
||||||
(->> (rx/from uris)
|
(->> (rx/from uris)
|
||||||
(rx/subs! #(http/fetch-data-uri % false)))))))
|
(rx/subs! #(http/fetch-data-uri % false)))))))
|
||||||
|
@ -503,7 +505,9 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [pages (get-in state [:workspace-data :pages-index])
|
(let [pages (-> (dsh/lookup-file-data state)
|
||||||
|
(get :pages-index))
|
||||||
|
|
||||||
unames (cfh/get-used-names pages)
|
unames (cfh/get-used-names pages)
|
||||||
name (cfh/generate-unique-name unames "Page 1")
|
name (cfh/generate-unique-name unames "Page 1")
|
||||||
|
|
||||||
|
@ -518,14 +522,14 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [id (uuid/next)
|
(let [id (uuid/next)
|
||||||
pages (get-in state [:workspace-data :pages-index])
|
fdata (dsh/lookup-file-data state)
|
||||||
|
pages (get fdata :pages-index)
|
||||||
|
page (get pages page-id)
|
||||||
|
|
||||||
unames (cfh/get-used-names pages)
|
unames (cfh/get-used-names pages)
|
||||||
page (get-in state [:workspace-data :pages-index page-id])
|
|
||||||
name (cfh/generate-unique-name unames (:name page))
|
name (cfh/generate-unique-name unames (:name page))
|
||||||
fdata (:workspace-data state)
|
objects (update-vals (:objects page) #(dissoc % :use-for-thumbnail))
|
||||||
components-v2 (dm/get-in fdata [:options :components-v2])
|
|
||||||
objects (->> (:objects page)
|
|
||||||
(d/mapm (fn [_ val] (dissoc val :use-for-thumbnail))))
|
|
||||||
main-instances-ids (set (keep #(when (ctk/main-instance? (val %)) (key %)) objects))
|
main-instances-ids (set (keep #(when (ctk/main-instance? (val %)) (key %)) objects))
|
||||||
ids-to-remove (set (apply concat (map #(cfh/get-children-ids objects %) main-instances-ids)))
|
ids-to-remove (set (apply concat (map #(cfh/get-children-ids objects %) main-instances-ids)))
|
||||||
|
|
||||||
|
@ -537,7 +541,7 @@
|
||||||
component
|
component
|
||||||
fdata
|
fdata
|
||||||
(gpt/point (:x shape) (:y shape))
|
(gpt/point (:x shape) (:y shape))
|
||||||
components-v2
|
true
|
||||||
{:keep-ids? true})
|
{:keep-ids? true})
|
||||||
children (into {} (map (fn [shape] [(:id shape) shape]) new-shapes))
|
children (into {} (map (fn [shape] [(:id shape) shape]) new-shapes))
|
||||||
objs (assoc objs id new-shape)]
|
objs (assoc objs id new-shape)]
|
||||||
|
@ -576,10 +580,9 @@
|
||||||
(ptk/reify ::rename-page
|
(ptk/reify ::rename-page
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (get-in state [:workspace-data :pages-index id])
|
(let [page (dsh/lookup-page state id)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/mod-page page {:name name}))]
|
(pcb/mod-page page {:name name}))]
|
||||||
|
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
||||||
(defn set-plugin-data
|
(defn set-plugin-data
|
||||||
|
@ -599,20 +602,14 @@
|
||||||
(ptk/reify ::set-file-plugin-data
|
(ptk/reify ::set-file-plugin-data
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file-data
|
(let [file-data (dm/get-in state [:files file-id :data])
|
||||||
(if (= file-id (:current-file-id state))
|
changes (-> (pcb/empty-changes it)
|
||||||
(:workspace-data state)
|
(pcb/with-file-data file-data)
|
||||||
(get-in state [:libraries file-id :data]))
|
(assoc :file-id file-id)
|
||||||
|
(pcb/set-plugin-data type id page-id namespace key value))]
|
||||||
changes
|
|
||||||
(-> (pcb/empty-changes it)
|
|
||||||
(pcb/with-file-data file-data)
|
|
||||||
(assoc :file-id file-id)
|
|
||||||
(pcb/set-plugin-data type id page-id namespace key value))]
|
|
||||||
(rx/of (dch/commit-changes changes)))))))
|
(rx/of (dch/commit-changes changes)))))))
|
||||||
|
|
||||||
(declare purge-page)
|
(declare purge-page)
|
||||||
(declare go-to-file)
|
|
||||||
|
|
||||||
(defn- delete-page-components
|
(defn- delete-page-components
|
||||||
[changes page]
|
[changes page]
|
||||||
|
@ -633,30 +630,29 @@
|
||||||
(ptk/reify ::delete-page
|
(ptk/reify ::delete-page
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [components-v2 (features/active-feature? state "components/v2")
|
(let [file-id (:current-file-id state)
|
||||||
file-id (:current-file-id state)
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
file (wsh/get-file state file-id)
|
pindex (:pages-index fdata)
|
||||||
pages (get-in state [:workspace-data :pages])
|
pages (:pages fdata)
|
||||||
index (d/index-of pages id)
|
|
||||||
page (get-in state [:workspace-data :pages-index id])
|
|
||||||
page (assoc page :index index)
|
|
||||||
|
|
||||||
changes (cond-> (pcb/empty-changes it)
|
index (d/index-of pages id)
|
||||||
components-v2
|
page (get pindex id)
|
||||||
(pcb/with-library-data file)
|
page (assoc page :index index)
|
||||||
components-v2
|
|
||||||
(delete-page-components page)
|
changes (-> (pcb/empty-changes it)
|
||||||
:always
|
(pcb/with-library-data fdata)
|
||||||
(pcb/del-page page))]
|
(delete-page-components page)
|
||||||
|
(pcb/del-page page))]
|
||||||
|
|
||||||
(rx/of (dch/commit-changes changes)
|
(rx/of (dch/commit-changes changes)
|
||||||
(when (= id (:current-page-id state))
|
(when (= id (:current-page-id state))
|
||||||
(go-to-file)))))))
|
(dcm/go-to-workspace)))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; WORKSPACE File Actions
|
;; WORKSPACE File Actions
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; FIXME: move to common
|
||||||
(defn rename-file
|
(defn rename-file
|
||||||
[id name]
|
[id name]
|
||||||
{:pre [(uuid? id) (string? name)]}
|
{:pre [(uuid? id) (string? name)]}
|
||||||
|
@ -668,7 +664,8 @@
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc-in state [:workspace-file :name] name))
|
(let [file-id (:current-file-id state)]
|
||||||
|
(assoc-in state [:files file-id :name] name)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
|
@ -752,7 +749,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(when-let [shape-id (d/nilv shape-id (dm/get-in state [:workspace-local :shape-for-rename]))]
|
(when-let [shape-id (d/nilv shape-id (dm/get-in state [:workspace-local :shape-for-rename]))]
|
||||||
(let [shape (wsh/lookup-shape state shape-id)
|
(let [shape (dsh/lookup-shape state shape-id)
|
||||||
name (str/trim name)
|
name (str/trim name)
|
||||||
clean-name (cfh/clean-path name)
|
clean-name (cfh/clean-path name)
|
||||||
valid? (and (not (str/ends-with? name "/"))
|
valid? (and (not (str/ends-with? name "/"))
|
||||||
|
@ -782,7 +779,7 @@
|
||||||
(ptk/reify ::update-selected-shapes
|
(ptk/reify ::update-selected-shapes
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/from (map #(update-shape % attrs) selected))))))
|
(rx/from (map #(update-shape % attrs) selected))))))
|
||||||
|
|
||||||
;; --- Delete Selected
|
;; --- Delete Selected
|
||||||
|
@ -793,7 +790,7 @@
|
||||||
(ptk/reify ::delete-selected
|
(ptk/reify ::delete-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
hover-guides (get-in state [:workspace-guides :hover])]
|
hover-guides (get-in state [:workspace-guides :hover])]
|
||||||
(cond
|
(cond
|
||||||
(d/not-empty? selected)
|
(d/not-empty? selected)
|
||||||
|
@ -812,7 +809,7 @@
|
||||||
(ptk/reify ::start-rename-selected
|
(ptk/reify ::start-rename-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
id (first selected)]
|
id (first selected)]
|
||||||
(when (= (count selected) 1)
|
(when (= (count selected) 1)
|
||||||
(rx/of (dcm/go-to-workspace :layout :layers)
|
(rx/of (dcm/go-to-workspace :layout :layers)
|
||||||
|
@ -832,8 +829,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected-ids (wsh/lookup-selected state)
|
selected-ids (dsh/lookup-selected state)
|
||||||
selected-shapes (map (d/getf objects) selected-ids)
|
selected-shapes (map (d/getf objects) selected-ids)
|
||||||
undo-id (js/Symbol)
|
undo-id (js/Symbol)
|
||||||
|
|
||||||
|
@ -876,7 +873,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
|
|
||||||
;; Ignore any shape whose parent is also intended to be moved
|
;; Ignore any shape whose parent is also intended to be moved
|
||||||
ids (cfh/clean-loops objects ids)
|
ids (cfh/clean-loops objects ids)
|
||||||
|
@ -906,7 +903,7 @@
|
||||||
(ptk/reify ::relocate-selected-shapes
|
(ptk/reify ::relocate-selected-shapes
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/of (relocate-shapes selected parent-id to-index))))))
|
(rx/of (relocate-shapes selected parent-id to-index))))))
|
||||||
|
|
||||||
(defn start-editing-selected
|
(defn start-editing-selected
|
||||||
|
@ -914,8 +911,8 @@
|
||||||
(ptk/reify ::start-editing-selected
|
(ptk/reify ::start-editing-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
objects (wsh/lookup-page-objects state)]
|
objects (dsh/lookup-page-objects state)]
|
||||||
|
|
||||||
(if (> (count selected) 1)
|
(if (> (count selected) 1)
|
||||||
(let [shapes-to-select
|
(let [shapes-to-select
|
||||||
|
@ -950,8 +947,8 @@
|
||||||
(ptk/reify ::select-parent-layer
|
(ptk/reify ::select-parent-layer
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
shapes-to-select
|
shapes-to-select
|
||||||
(->> selected
|
(->> selected
|
||||||
(reduce
|
(reduce
|
||||||
|
@ -970,7 +967,8 @@
|
||||||
(ptk/reify ::relocate-page
|
(ptk/reify ::relocate-page
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [prev-index (-> (get-in state [:workspace-data :pages])
|
(let [prev-index (-> (dsh/lookup-file-data state)
|
||||||
|
(get :pages)
|
||||||
(d/index-of id))
|
(d/index-of id))
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/move-page id index prev-index))]
|
(pcb/move-page id index prev-index))]
|
||||||
|
@ -1009,8 +1007,8 @@
|
||||||
(ptk/reify ::align-objects
|
(ptk/reify ::align-objects
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (or selected (wsh/lookup-selected state))
|
selected (or selected (dsh/lookup-selected state))
|
||||||
moved (if (= 1 (count selected))
|
moved (if (= 1 (count selected))
|
||||||
(align-object-to-parent objects (first selected) axis)
|
(align-object-to-parent objects (first selected) axis)
|
||||||
(align-objects-list objects selected axis))
|
(align-objects-list objects selected axis))
|
||||||
|
@ -1039,8 +1037,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (or ids (wsh/lookup-selected state))
|
selected (or ids (dsh/lookup-selected state))
|
||||||
moved (-> (map #(get objects %) selected)
|
moved (-> (map #(get objects %) selected)
|
||||||
(gal/distribute-space axis))
|
(gal/distribute-space axis))
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
@ -1070,8 +1068,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
selected-obj (-> (map #(get objects %) selected))
|
selected-obj (-> (map #(get objects %) selected))
|
||||||
multi (attrs/get-attrs-multi selected-obj [:proportion-lock])
|
multi (attrs/get-attrs-multi selected-obj [:proportion-lock])
|
||||||
multi? (= :multiple (:proportion-lock multi))]
|
multi? (= :multiple (:proportion-lock multi))]
|
||||||
|
@ -1157,9 +1155,12 @@
|
||||||
(ptk/reify ::show-component-in-assets
|
(ptk/reify ::show-component-in-assets
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [component-path (cfh/split-path (get-in state [:workspace-data :components component-id :path]))
|
(let [file-id (:current-file-id state)
|
||||||
paths (map (fn [i] (cfh/join-path (take (inc i) component-path))) (range (count component-path)))
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
file-id (:current-file-id state)]
|
cpath (dm/get-in fdata [:components component-id :path])
|
||||||
|
cpath (cfh/split-path cpath)
|
||||||
|
paths (map (fn [i] (cfh/join-path (take (inc i) cpath)))
|
||||||
|
(range (count cpath)))]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/from (map #(set-assets-group-open file-id :components % true) paths))
|
(rx/from (map #(set-assets-group-open file-id :components % true) paths))
|
||||||
(rx/of (dcm/go-to-workspace :layout :assets)
|
(rx/of (dcm/go-to-workspace :layout :assets)
|
||||||
|
@ -1189,8 +1190,8 @@
|
||||||
(ptk/reify ::show-shape-context-menu
|
(ptk/reify ::show-shape-context-menu
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
all-selected (into [] (mapcat #(cfh/get-children-with-self objects %)) selected)
|
all-selected (into [] (mapcat #(cfh/get-children-with-self objects %)) selected)
|
||||||
head (get objects (first selected))
|
head (get objects (first selected))
|
||||||
|
|
||||||
|
@ -1236,7 +1237,7 @@
|
||||||
(ptk/reify ::show-grid-cell-context-menu
|
(ptk/reify ::show-grid-cell-context-menu
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
grid (get objects grid-id)
|
grid (get objects grid-id)
|
||||||
cells (->> (get-in state [:workspace-grid-edition grid-id :selected])
|
cells (->> (get-in state [:workspace-grid-edition grid-id :selected])
|
||||||
(map #(get-in grid [:layout-grid-cells %])))]
|
(map #(get-in grid [:layout-grid-cells %])))]
|
||||||
|
@ -1260,8 +1261,8 @@
|
||||||
(defn copy-selected
|
(defn copy-selected
|
||||||
[]
|
[]
|
||||||
(letfn [(sort-selected [state data]
|
(letfn [(sort-selected [state data]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
;; Narrow the objects map so it contains only relevant data for
|
;; Narrow the objects map so it contains only relevant data for
|
||||||
;; selected and its parents
|
;; selected and its parents
|
||||||
|
@ -1325,9 +1326,10 @@
|
||||||
;; When copying an instance that is nested inside another one, we need to
|
;; When copying an instance that is nested inside another one, we need to
|
||||||
;; advance the shape refs to one or more levels of remote mains.
|
;; advance the shape refs to one or more levels of remote mains.
|
||||||
(advance-copies [state selected data]
|
(advance-copies [state selected data]
|
||||||
(let [file (wsh/get-local-file-full state)
|
(let [file (dsh/lookup-file state)
|
||||||
libraries (wsh/get-libraries state)
|
libraries (:files state)
|
||||||
page (wsh/lookup-page state)
|
;; FIXME
|
||||||
|
page (dsh/lookup-page state)
|
||||||
heads (mapcat #(ctn/get-child-heads (:objects data) %) selected)]
|
heads (mapcat #(ctn/get-child-heads (:objects data) %) selected)]
|
||||||
(update data :objects
|
(update data :objects
|
||||||
#(reduce (partial advance-copy file libraries page)
|
#(reduce (partial advance-copy file libraries page)
|
||||||
|
@ -1364,15 +1366,16 @@
|
||||||
(catch :default e
|
(catch :default e
|
||||||
(on-copy-error e)))
|
(on-copy-error e)))
|
||||||
|
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (->> (wsh/lookup-selected state)
|
selected (->> (dsh/lookup-selected state)
|
||||||
(cfh/clean-loops objects))
|
(cfh/clean-loops objects))
|
||||||
features (-> (features/get-team-enabled-features state)
|
features (-> (features/get-team-enabled-features state)
|
||||||
(set/difference cfeat/frontend-only-features))
|
(set/difference cfeat/frontend-only-features))
|
||||||
|
|
||||||
file-id (:current-file-id state)
|
file-id (:current-file-id state)
|
||||||
frame-id (cfh/common-parent-frame objects selected)
|
frame-id (cfh/common-parent-frame objects selected)
|
||||||
version (dm/get-in state [:workspace-file :version])
|
file (dsh/lookup-file state file-id)
|
||||||
|
version (get file :version)
|
||||||
|
|
||||||
initial {:type :copied-shapes
|
initial {:type :copied-shapes
|
||||||
:features features
|
:features features
|
||||||
|
@ -1478,7 +1481,7 @@
|
||||||
(ptk/reify ::paste-from-event
|
(ptk/reify ::paste-from-event
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
edit-id (dm/get-in state [:workspace-local :edition])
|
edit-id (dm/get-in state [:workspace-local :edition])
|
||||||
is-editing? (and edit-id (= :text (get-in objects [edit-id :type])))]
|
is-editing? (and edit-id (= :text (get-in objects [edit-id :type])))]
|
||||||
|
|
||||||
|
@ -1516,8 +1519,8 @@
|
||||||
(ptk/reify ::copy-selected-css
|
(ptk/reify ::copy-selected-css
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ state _]
|
(effect [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (->> (wsh/lookup-selected state) (mapv (d/getf objects)))
|
selected (->> (dsh/lookup-selected state) (mapv (d/getf objects)))
|
||||||
css (css/generate-style objects selected selected {:with-prelude? false})]
|
css (css/generate-style objects selected selected {:with-prelude? false})]
|
||||||
(wapi/write-to-clipboard css)))))
|
(wapi/write-to-clipboard css)))))
|
||||||
|
|
||||||
|
@ -1526,8 +1529,8 @@
|
||||||
(ptk/reify ::copy-selected-css-nested
|
(ptk/reify ::copy-selected-css-nested
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ state _]
|
(effect [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (->> (wsh/lookup-selected state)
|
selected (->> (dsh/lookup-selected state)
|
||||||
(cfh/selected-with-children objects)
|
(cfh/selected-with-children objects)
|
||||||
(mapv (d/getf objects)))
|
(mapv (d/getf objects)))
|
||||||
css (css/generate-style objects selected selected {:with-prelude? false})]
|
css (css/generate-style objects selected selected {:with-prelude? false})]
|
||||||
|
@ -1564,14 +1567,14 @@
|
||||||
(js/console.error "clipboard blocked:" error)
|
(js/console.error "clipboard blocked:" error)
|
||||||
(rx/empty))]
|
(rx/empty))]
|
||||||
|
|
||||||
(let [selected (->> (wsh/lookup-selected state) first)
|
(let [selected (->> (dsh/lookup-selected state) first)
|
||||||
objects (wsh/lookup-page-objects state)]
|
objects (dsh/lookup-page-objects state)]
|
||||||
|
|
||||||
(when-let [shape (get objects selected)]
|
(when-let [shape (get objects selected)]
|
||||||
(let [props (cts/extract-props shape)
|
(let [props (cts/extract-props shape)
|
||||||
features (-> (features/get-team-enabled-features state)
|
features (-> (features/get-team-enabled-features state)
|
||||||
(set/difference cfeat/frontend-only-features))
|
(set/difference cfeat/frontend-only-features))
|
||||||
version (dm/get-in state [:workspace-file :version])
|
version (-> (dsh/lookup-file state) :version)
|
||||||
|
|
||||||
copy-data {:type :copied-props
|
copy-data {:type :copied-props
|
||||||
:features features
|
:features features
|
||||||
|
@ -1628,8 +1631,8 @@
|
||||||
(rx/catch on-error))))))
|
(rx/catch on-error))))))
|
||||||
|
|
||||||
(defn selected-frame? [state]
|
(defn selected-frame? [state]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
objects (wsh/lookup-page-objects state)]
|
objects (dsh/lookup-page-objects state)]
|
||||||
|
|
||||||
(and (= 1 (count selected))
|
(and (= 1 (count selected))
|
||||||
(= :frame (get-in objects [(first selected) :type])))))
|
(= :frame (get-in objects [(first selected) :type])))))
|
||||||
|
@ -1643,7 +1646,7 @@
|
||||||
(filter #(contains? parent-ids %)))))
|
(filter #(contains? parent-ids %)))))
|
||||||
|
|
||||||
(defn any-same-frame-from-selected? [state frame-ids]
|
(defn any-same-frame-from-selected? [state frame-ids]
|
||||||
(let [selected (first (wsh/lookup-selected state))]
|
(let [selected (first (dsh/lookup-selected state))]
|
||||||
(< 0 (count (filter #(= % selected) frame-ids)))))
|
(< 0 (count (filter #(= % selected) frame-ids)))))
|
||||||
|
|
||||||
(defn frame-same-size?
|
(defn frame-same-size?
|
||||||
|
@ -1777,7 +1780,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [features (features/get-team-enabled-features state)
|
(let [features (features/get-team-enabled-features state)
|
||||||
selected (wsh/lookup-selected state)]
|
selected (dsh/lookup-selected state)]
|
||||||
|
|
||||||
(when (paste-data-valid? pdata)
|
(when (paste-data-valid? pdata)
|
||||||
(cfeat/check-paste-features! features (:features pdata))
|
(cfeat/check-paste-features! features (:features pdata))
|
||||||
|
@ -1841,10 +1844,10 @@
|
||||||
change)))
|
change)))
|
||||||
|
|
||||||
(calculate-paste-position [state pobjects selected position]
|
(calculate-paste-position [state pobjects selected position]
|
||||||
(let [page-objects (wsh/lookup-page-objects state)
|
(let [page-objects (dsh/lookup-page-objects state)
|
||||||
selected-objs (map (d/getf pobjects) selected)
|
selected-objs (map (d/getf pobjects) selected)
|
||||||
first-selected-obj (first selected-objs)
|
first-selected-obj (first selected-objs)
|
||||||
page-selected (wsh/lookup-selected state)
|
page-selected (dsh/lookup-selected state)
|
||||||
wrapper (gsh/shapes->rect selected-objs)
|
wrapper (gsh/shapes->rect selected-objs)
|
||||||
orig-pos (gpt/point (:x1 wrapper) (:y1 wrapper))
|
orig-pos (gpt/point (:x1 wrapper) (:y1 wrapper))
|
||||||
frame-id (first page-selected)
|
frame-id (first page-selected)
|
||||||
|
@ -1954,7 +1957,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
page (wsh/lookup-page state)
|
page (dsh/lookup-page state)
|
||||||
|
|
||||||
media-idx (->> (:images pdata)
|
media-idx (->> (:images pdata)
|
||||||
(d/index-by :prev-id))
|
(d/index-by :prev-id))
|
||||||
|
@ -1972,10 +1975,12 @@
|
||||||
|
|
||||||
page-objects (:objects page)
|
page-objects (:objects page)
|
||||||
|
|
||||||
libraries (wsh/get-libraries state)
|
libraries (dsh/lookup-libraries state)
|
||||||
ldata (wsh/get-local-file state)
|
ldata (dsh/lookup-file-data state file-id)
|
||||||
|
|
||||||
full-libs (assoc-in libraries [(:id ldata) :data] ldata)
|
;; full-libs (assoc-in libraries [(:id ldata) :data] ldata)
|
||||||
|
|
||||||
|
full-libs libraries
|
||||||
|
|
||||||
[parent-id
|
[parent-id
|
||||||
frame-id] (ctn/find-valid-parent-and-frame-ids candidate-parent-id page-objects (vals objects) true full-libs)
|
frame-id] (ctn/find-valid-parent-and-frame-ids candidate-parent-id page-objects (vals objects) true full-libs)
|
||||||
|
@ -2053,8 +2058,8 @@
|
||||||
(cond
|
(cond
|
||||||
;; Pasting inside a frame
|
;; Pasting inside a frame
|
||||||
(selected-frame? state)
|
(selected-frame? state)
|
||||||
(let [page-selected (wsh/lookup-selected state)
|
(let [page-selected (dsh/lookup-selected state)
|
||||||
page-objects (wsh/lookup-page-objects state)
|
page-objects (dsh/lookup-page-objects state)
|
||||||
frame-id (first page-selected)
|
frame-id (first page-selected)
|
||||||
frame-object (get page-objects frame-id)]
|
frame-object (get page-objects frame-id)]
|
||||||
(gsh/shape->center frame-object))
|
(gsh/shape->center frame-object))
|
||||||
|
@ -2133,7 +2138,7 @@
|
||||||
(ptk/reify ::paste-image
|
(ptk/reify ::paste-image
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-id (dm/get-in state [:workspace-file :id])
|
(let [file-id (:current-file-id state)
|
||||||
position (calculate-paste-position state)
|
position (calculate-paste-position state)
|
||||||
params {:file-id file-id
|
params {:file-id file-id
|
||||||
:blobs [image]
|
:blobs [image]
|
||||||
|
@ -2177,7 +2182,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (or page-id (:current-page-id state))
|
(let [page-id (or page-id (:current-page-id state))
|
||||||
page (wsh/lookup-page state page-id)
|
page (dsh/lookup-page state page-id)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-page page)
|
(pcb/with-page page)
|
||||||
(pcb/mod-page {:background (:color color)}))]
|
(pcb/mod-page {:background (:color color)}))]
|
||||||
|
@ -2214,12 +2219,24 @@
|
||||||
;; Orphan Shapes
|
;; Orphan Shapes
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn- find-orphan-shapes
|
||||||
|
([state]
|
||||||
|
(find-orphan-shapes state (:current-page-id state)))
|
||||||
|
([state page-id]
|
||||||
|
(let [objects (dsh/lookup-page-objects state page-id)
|
||||||
|
objects (filter (fn [item]
|
||||||
|
(and
|
||||||
|
(not= (key item) uuid/zero)
|
||||||
|
(not (contains? objects (:parent-id (val item))))))
|
||||||
|
objects)]
|
||||||
|
objects)))
|
||||||
|
|
||||||
(defn fix-orphan-shapes
|
(defn fix-orphan-shapes
|
||||||
[]
|
[]
|
||||||
(ptk/reify ::fix-orphan-shapes
|
(ptk/reify ::fix-orphan-shapes
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [orphans (set (into [] (keys (wsh/find-orphan-shapes state))))]
|
(let [orphans (set (into [] (keys (find-orphan-shapes state))))]
|
||||||
(rx/of (relocate-shapes orphans uuid/zero 0 true))))))
|
(rx/of (relocate-shapes orphans uuid/zero 0 true))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -2254,7 +2271,9 @@
|
||||||
(ptk/reify ::update-component-annotation
|
(ptk/reify ::update-component-annotation
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data
|
||||||
|
(dsh/lookup-file-data state)
|
||||||
|
|
||||||
update-fn
|
update-fn
|
||||||
(fn [component]
|
(fn [component]
|
||||||
;; NOTE: we need to ensure the component exists,
|
;; NOTE: we need to ensure the component exists,
|
||||||
|
@ -2265,9 +2284,10 @@
|
||||||
(dissoc component :annotation)
|
(dissoc component :annotation)
|
||||||
(assoc component :annotation annotation))))
|
(assoc component :annotation annotation))))
|
||||||
|
|
||||||
changes (-> (pcb/empty-changes it)
|
changes
|
||||||
(pcb/with-library-data data)
|
(-> (pcb/empty-changes it)
|
||||||
(pcb/update-component id update-fn))]
|
(pcb/with-library-data data)
|
||||||
|
(pcb/update-component id update-fn))]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (dch/commit-changes changes))
|
(rx/of (dch/commit-changes changes))
|
||||||
|
@ -2323,7 +2343,7 @@
|
||||||
(ptk/reify ::find-components-norefs
|
(ptk/reify ::find-components-norefs
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
copies (->> objects
|
copies (->> objects
|
||||||
vals
|
vals
|
||||||
(filter #(and (ctk/instance-head? %) (not (ctk/main-instance? %)))))
|
(filter #(and (ctk/instance-head? %) (not (ctk/main-instance? %)))))
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(defn selected-shapes-idx
|
(defn selected-shapes-idx
|
||||||
[state]
|
[state]
|
||||||
(let [objects (wsh/lookup-page-objects state)]
|
(let [objects (dsh/lookup-page-objects state)]
|
||||||
(->> (wsh/lookup-selected state)
|
(->> (dsh/lookup-selected state)
|
||||||
(cph/clean-loops objects))))
|
(cph/clean-loops objects))))
|
||||||
|
|
||||||
(defn create-bool-data
|
(defn create-bool-data
|
||||||
|
@ -91,9 +91,9 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
name (-> bool-type d/name str/capital)
|
name (-> bool-type d/name str/capital)
|
||||||
ids (->> (or ids (wsh/lookup-selected state))
|
ids (->> (or ids (dsh/lookup-selected state))
|
||||||
(cph/clean-loops objects))
|
(cph/clean-loops objects))
|
||||||
ordered-indexes (cph/order-by-indexed-shapes objects ids)
|
ordered-indexes (cph/order-by-indexed-shapes objects ids)
|
||||||
shapes (->> ordered-indexes
|
shapes (->> ordered-indexes
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
(ptk/reify ::group-to-bool
|
(ptk/reify ::group-to-bool
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
change-to-bool
|
change-to-bool
|
||||||
(fn [shape] (group->bool shape bool-type objects))]
|
(fn [shape] (group->bool shape bool-type objects))]
|
||||||
(when-not (ctn/has-any-copy-parent? objects (get objects shape-id))
|
(when-not (ctn/has-any-copy-parent? objects (get objects shape-id))
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
(ptk/reify ::bool-to-group
|
(ptk/reify ::bool-to-group
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
change-to-group
|
change-to-group
|
||||||
(fn [shape] (bool->group shape objects))]
|
(fn [shape] (bool->group shape objects))]
|
||||||
(when-not (ctn/has-any-copy-parent? objects (get objects shape-id))
|
(when-not (ctn/has-any-copy-parent? objects (get objects shape-id))
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
(ptk/reify ::change-bool-type
|
(ptk/reify ::change-bool-type
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
change-type
|
change-type
|
||||||
(fn [shape] (assoc shape :bool-type bool-type))]
|
(fn [shape] (assoc shape :bool-type bool-type))]
|
||||||
(when-not (ctn/has-any-copy-parent? objects (get objects shape-id))
|
(when-not (ctn/has-any-copy-parent? objects (get objects shape-id))
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
[app.common.types.shape.shadow :refer [check-shadow!]]
|
[app.common.types.shape.shadow :refer [check-shadow!]]
|
||||||
[app.main.broadcast :as mbc]
|
[app.main.broadcast :as mbc]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as md]
|
[app.main.data.modal :as md]
|
||||||
[app.main.data.workspace.layout :as layout]
|
[app.main.data.workspace.layout :as layout]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.util.storage :as storage]
|
[app.util.storage :as storage]
|
||||||
|
@ -84,8 +84,7 @@
|
||||||
(defn transform-fill
|
(defn transform-fill
|
||||||
([state ids color transform] (transform-fill state ids color transform nil))
|
([state ids color transform] (transform-fill state ids color transform nil))
|
||||||
([state ids color transform options]
|
([state ids color transform options]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
is-text? #(= :text (:type (get objects %)))
|
is-text? #(= :text (:type (get objects %)))
|
||||||
text-ids (filter is-text? ids)
|
text-ids (filter is-text? ids)
|
||||||
shape-ids (remove is-text? ids)
|
shape-ids (remove is-text? ids)
|
||||||
|
@ -135,7 +134,7 @@
|
||||||
(ptk/reify ::reorder-fills
|
(ptk/reify ::reorder-fills
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
is-text? #(= :text (:type (get objects %)))
|
is-text? #(= :text (:type (get objects %)))
|
||||||
text-ids (filter is-text? ids)
|
text-ids (filter is-text? ids)
|
||||||
|
@ -234,7 +233,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
is-text? #(= :text (:type (get objects %)))
|
is-text? #(= :text (:type (get objects %)))
|
||||||
shape-ids (filter (complement is-text?) ids)
|
shape-ids (filter (complement is-text?) ids)
|
||||||
attrs {:hide-fill-on-export hide-fill-on-export}]
|
attrs {:hide-fill-on-export hide-fill-on-export}]
|
||||||
|
@ -436,7 +435,7 @@
|
||||||
(ptk/reify ::picker-for-selected-shape
|
(ptk/reify ::picker-for-selected-shape
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [ids (wsh/lookup-selected state)
|
(let [ids (dsh/lookup-selected state)
|
||||||
stop? (rx/filter (ptk/type? ::stop-picker) stream)
|
stop? (rx/filter (ptk/type? ::stop-picker) stream)
|
||||||
|
|
||||||
update-events
|
update-events
|
||||||
|
@ -541,8 +540,8 @@
|
||||||
(ptk/reify ::apply-color-from-palette
|
(ptk/reify ::apply-color-from-palette
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (->> (wsh/lookup-selected state)
|
selected (->> (dsh/lookup-selected state)
|
||||||
(cfh/clean-loops objects))
|
(cfh/clean-loops objects))
|
||||||
|
|
||||||
ids
|
ids
|
||||||
|
@ -716,7 +715,7 @@
|
||||||
(ptk/reify ::update-colorpicker
|
(ptk/reify ::update-colorpicker
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [shape-id (-> state wsh/lookup-selected first)]
|
(let [shape-id (-> state dsh/lookup-selected first)]
|
||||||
(update state :colorpicker
|
(update state :colorpicker
|
||||||
(fn [state]
|
(fn [state]
|
||||||
(let [current-color (:current-color state)]
|
(let [current-color (:current-color state)]
|
||||||
|
@ -978,8 +977,8 @@
|
||||||
(ptk/reify ::select-color
|
(ptk/reify ::select-color
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
shapes (wsh/lookup-shapes state selected)
|
shapes (dsh/lookup-shapes state selected)
|
||||||
shape (first shapes)
|
shape (first shapes)
|
||||||
fills (if (cfh/text-shape? shape)
|
fills (if (cfh/text-shape? shape)
|
||||||
(:fills (dwt/current-text-values
|
(:fills (dwt/current-text-values
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
[app.main.data.comments :as dcmt]
|
[app.main.data.comments :as dcmt]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.common :as dwco]
|
[app.main.data.workspace.common :as dwco]
|
||||||
[app.main.data.workspace.drawing :as dwd]
|
[app.main.data.workspace.drawing :as dwd]
|
||||||
[app.main.data.workspace.edition :as dwe]
|
[app.main.data.workspace.edition :as dwe]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.viewport :as dwv]
|
[app.main.data.workspace.viewport :as dwv]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.router :as rt]
|
[app.main.router :as rt]
|
||||||
|
@ -35,26 +35,25 @@
|
||||||
|
|
||||||
(defn initialize-comments
|
(defn initialize-comments
|
||||||
[file-id]
|
[file-id]
|
||||||
(dm/assert! (uuid? file-id))
|
|
||||||
(ptk/reify ::initialize-comments
|
(ptk/reify ::initialize-comments
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ stream]
|
(watch [_ _ stream]
|
||||||
(let [stopper (rx/filter #(= ::finalize %) stream)]
|
(let [stopper-s (rx/filter #(= ::finalize %) stream)]
|
||||||
(rx/merge
|
(->> (rx/merge
|
||||||
(rx/of (dcmt/retrieve-comment-threads file-id))
|
(rx/of (dcmt/retrieve-comment-threads file-id))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter mse/mouse-event?)
|
(rx/filter mse/mouse-event?)
|
||||||
(rx/filter mse/mouse-click-event?)
|
(rx/filter mse/mouse-click-event?)
|
||||||
(rx/switch-map #(rx/take 1 ms/mouse-position))
|
(rx/switch-map #(rx/take 1 ms/mouse-position))
|
||||||
(rx/with-latest-from ms/keyboard-space)
|
(rx/with-latest-from ms/keyboard-space)
|
||||||
(rx/filter (fn [[_ space]] (not space)))
|
(rx/filter (fn [[_ space]] (not space)))
|
||||||
(rx/map first)
|
(rx/map first)
|
||||||
(rx/map handle-comment-layer-click)
|
(rx/map handle-comment-layer-click))
|
||||||
(rx/take-until stopper))
|
(->> stream
|
||||||
(->> stream
|
(rx/filter dwco/interrupt?)
|
||||||
(rx/filter dwco/interrupt?)
|
(rx/map handle-interrupt)))
|
||||||
(rx/map handle-interrupt)
|
|
||||||
(rx/take-until stopper)))))))
|
(rx/take-until stopper-s))))))
|
||||||
|
|
||||||
(defn- handle-interrupt
|
(defn- handle-interrupt
|
||||||
[]
|
[]
|
||||||
|
@ -65,10 +64,8 @@
|
||||||
(cond
|
(cond
|
||||||
(:draft local) (rx/of (dcmt/close-thread))
|
(:draft local) (rx/of (dcmt/close-thread))
|
||||||
(:open local) (rx/of (dcmt/close-thread))
|
(:open local) (rx/of (dcmt/close-thread))
|
||||||
|
:else (rx/of (dwe/clear-edition-mode)
|
||||||
:else
|
(dws/deselect-all true)))))))
|
||||||
(rx/of (dwe/clear-edition-mode)
|
|
||||||
(dws/deselect-all true)))))))
|
|
||||||
|
|
||||||
;; Event responsible of the what should be executed when user clicked
|
;; Event responsible of the what should be executed when user clicked
|
||||||
;; on the comments layer. An option can be create a new draft thread,
|
;; on the comments layer. An option can be create a new draft thread,
|
||||||
|
@ -139,9 +136,9 @@
|
||||||
(ptk/reify ::update-comment-thread-position
|
(ptk/reify ::update-comment-thread-position
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (wsh/lookup-page state)
|
(let [page (dsh/lookup-page state)
|
||||||
page-id (:id page)
|
page-id (:id page)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
frame-id (if (nil? frame-id)
|
frame-id (if (nil? frame-id)
|
||||||
(ctst/get-frame-id-by-position objects (gpt/point new-x new-y))
|
(ctst/get-frame-id-by-position objects (gpt/point new-x new-y))
|
||||||
(:frame-id thread))
|
(:frame-id thread))
|
||||||
|
@ -172,7 +169,7 @@
|
||||||
(ptk/reify ::move-frame-comment-threads
|
(ptk/reify ::move-frame-comment-threads
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page (wsh/lookup-page state)
|
(let [page (dsh/lookup-page state)
|
||||||
objects (get page :objects)
|
objects (get page :objects)
|
||||||
|
|
||||||
is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.constants :refer [zoom-half-pixel-precision]]
|
[app.main.constants :refer [zoom-half-pixel-precision]]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.drawing.common :as common]
|
[app.main.data.workspace.drawing.common :as common]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.array :as array]
|
[app.util.array :as array]
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
initial (cond-> @ms/mouse-position snap-pixel? (gpt/round-step snap-prec))
|
initial (cond-> @ms/mouse-position snap-pixel? (gpt/round-step snap-prec))
|
||||||
|
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
focus (:workspace-focus-selected state)
|
focus (:workspace-focus-selected state)
|
||||||
|
|
||||||
fid (->> (ctst/top-nested-frame objects initial)
|
fid (->> (ctst/top-nested-frame objects initial)
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.types.modifiers :as ctm]
|
[app.common.types.modifiers :as ctm]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.worker :as uw]
|
[app.main.worker :as uw]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [tool (dm/get-in state [:workspace-drawing :tool])
|
(let [tool (dm/get-in state [:workspace-drawing :tool])
|
||||||
shape (dm/get-in state [:workspace-drawing :object])
|
shape (dm/get-in state [:workspace-drawing :object])
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
page-id (:current-page-id state)]
|
page-id (:current-page-id state)]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.drawing.common :as common]
|
[app.main.data.workspace.drawing.common :as common]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
[app.util.path.simplify-curve :as ups]
|
[app.util.path.simplify-curve :as ups]
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
(ptk/reify ::setup-frame
|
(ptk/reify ::setup-frame
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
content (dm/get-in state [:workspace-drawing :object :content] [])
|
content (dm/get-in state [:workspace-drawing :object :content] [])
|
||||||
start (dm/get-in content [0 :params] nil)
|
start (dm/get-in content [0 :params] nil)
|
||||||
position (when start (gpt/point start))
|
position (when start (gpt/point start))
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
(ns app.main.data.workspace.edition
|
(ns app.main.data.workspace.edition
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.path.common :as dwpc]
|
[app.main.data.workspace.path.common :as dwpc]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
(ptk/reify ::start-edition-mode
|
(ptk/reify ::start-edition-mode
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)]
|
(let [objects (dsh/lookup-page-objects state)]
|
||||||
;; Can only edit objects that exist
|
;; Can only edit objects that exist
|
||||||
(if (contains? objects id)
|
(if (contains? objects id)
|
||||||
(-> state
|
(-> state
|
||||||
|
@ -38,7 +38,10 @@
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/map clear-edition-mode)))))
|
(rx/map clear-edition-mode)))))
|
||||||
|
|
||||||
;; If these event change modules review /src/app/main/data/workspace/path/undo.cljs
|
;; IMPORTANT: If this event is moved from this namespace to other,
|
||||||
|
;; update namespace reference in the
|
||||||
|
;; app/main/data/workspace/path/undo.cljs file.
|
||||||
|
|
||||||
(defn clear-edition-mode
|
(defn clear-edition-mode
|
||||||
[]
|
[]
|
||||||
(ptk/reify ::clear-edition-mode
|
(ptk/reify ::clear-edition-mode
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.main.data.workspace.fix-broken-shapes
|
(ns app.main.data.workspace.fix-broken-shapes
|
||||||
(:require
|
(:require
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -39,12 +40,12 @@
|
||||||
(ptk/reify ::fix-broken-shapes
|
(ptk/reify ::fix-broken-shapes
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [fdata (dsh/lookup-file-data state)
|
||||||
changes (concat
|
changes (concat
|
||||||
(mapcat (partial generate-broken-link-changes :page-id)
|
(mapcat (partial generate-broken-link-changes :page-id)
|
||||||
(vals (:pages-index data)))
|
(vals (:pages-index fdata)))
|
||||||
(mapcat (partial generate-broken-link-changes :component-id)
|
(mapcat (partial generate-broken-link-changes :component-id)
|
||||||
(vals (:components data))))]
|
(vals (:components fdata))))]
|
||||||
|
|
||||||
(if (seq changes)
|
(if (seq changes)
|
||||||
(rx/of (dch/commit-changes
|
(rx/of (dch/commit-changes
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
[app.main.data.changes :as dwc]
|
[app.main.data.changes :as dwc]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
objects))
|
objects))
|
||||||
|
|
||||||
(defn- generate-deleted-font-components-changes
|
(defn- generate-deleted-font-components-changes
|
||||||
[state]
|
[fdata]
|
||||||
(sequence
|
(sequence
|
||||||
(comp (map val)
|
(comp (map val)
|
||||||
(filter should-fix-deleted-font-component?)
|
(filter should-fix-deleted-font-component?)
|
||||||
|
@ -99,27 +99,29 @@
|
||||||
{:type :mod-component
|
{:type :mod-component
|
||||||
:id (:id component)
|
:id (:id component)
|
||||||
:objects (-> (fix-deleted-font-component component) :objects)})))
|
:objects (-> (fix-deleted-font-component component) :objects)})))
|
||||||
(wsh/lookup-local-components state)))
|
(:components fdata)))
|
||||||
|
|
||||||
(defn- generate-deleted-font-typography-changes
|
(defn- generate-deleted-font-typography-changes
|
||||||
[state]
|
[fdata]
|
||||||
(sequence
|
(sequence
|
||||||
(comp (map val)
|
(comp (map val)
|
||||||
(filter has-invalid-font-family?)
|
(filter has-invalid-font-family?)
|
||||||
(map (fn [typography]
|
(map (fn [typography]
|
||||||
{:type :mod-typography
|
{:type :mod-typography
|
||||||
:typography (fix-deleted-font-typography typography)})))
|
:typography (fix-deleted-font-typography typography)})))
|
||||||
(get-in state [:workspace-data :typographies])))
|
(:typographies fdata)))
|
||||||
|
|
||||||
(defn fix-deleted-fonts
|
(defn fix-deleted-fonts
|
||||||
[]
|
[]
|
||||||
(ptk/reify ::fix-deleted-fonts
|
(ptk/reify ::fix-deleted-fonts
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [fdata (dsh/lookup-file-data state)
|
||||||
shape-changes (mapcat generate-deleted-font-shape-changes (vals (:pages-index data)))
|
pages (:pages-index fdata)
|
||||||
components-changes (generate-deleted-font-components-changes state)
|
|
||||||
typography-changes (generate-deleted-font-typography-changes state)
|
shape-changes (mapcat generate-deleted-font-shape-changes (vals pages))
|
||||||
|
components-changes (generate-deleted-font-components-changes fdata)
|
||||||
|
typography-changes (generate-deleted-font-typography-changes fdata)
|
||||||
changes (concat shape-changes
|
changes (concat shape-changes
|
||||||
components-changes
|
components-changes
|
||||||
typography-changes)]
|
typography-changes)]
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
[app.common.files.changes-builder :as pcb]
|
[app.common.files.changes-builder :as pcb]
|
||||||
[app.common.types.grid :as ctg]
|
[app.common.types.grid :as ctg]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -26,8 +26,7 @@
|
||||||
(ptk/reify ::add-frame-grid
|
(ptk/reify ::add-frame-grid
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page (dsh/lookup-page state)
|
||||||
page (dm/get-in state [:workspace-data :pages-index page-id])
|
|
||||||
params (or (dm/get-in page [:default-grids :square])
|
params (or (dm/get-in page [:default-grids :square])
|
||||||
(:square ctg/default-grid-params))
|
(:square ctg/default-grid-params))
|
||||||
grid {:type :square
|
grid {:type :square
|
||||||
|
@ -56,7 +55,7 @@
|
||||||
(ptk/reify ::set-default-grid
|
(ptk/reify ::set-default-grid
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (wsh/lookup-page state)]
|
(let [page (dsh/lookup-page state)]
|
||||||
(rx/of (dch/commit-changes
|
(rx/of (dch/commit-changes
|
||||||
(-> (pcb/empty-changes it)
|
(-> (pcb/empty-changes it)
|
||||||
(pcb/with-page page)
|
(pcb/with-page page)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.rect :as grc]
|
[app.common.geom.rect :as grc]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(defn hover-grid-cell
|
(defn hover-grid-cell
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if shift?
|
(if shift?
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
grid (get objects grid-id)
|
grid (get objects grid-id)
|
||||||
selected (or (dm/get-in state [:workspace-grid-edition grid-id :selected]) #{})
|
selected (or (dm/get-in state [:workspace-grid-edition grid-id :selected]) #{})
|
||||||
selected (into selected [cell-id])
|
selected (into selected [cell-id])
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
(ptk/reify ::clean-selection
|
(ptk/reify ::clean-selection
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects grid-id)]
|
shape (get objects grid-id)]
|
||||||
(update-in state [:workspace-grid-edition grid-id :selected]
|
(update-in state [:workspace-grid-edition grid-id :selected]
|
||||||
(fn [selected]
|
(fn [selected]
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
(ptk/reify ::locate-board
|
(ptk/reify ::locate-board
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
srect (get-in objects [grid-id :selrect])]
|
srect (get-in objects [grid-id :selrect])]
|
||||||
(-> state
|
(-> state
|
||||||
(update :workspace-local
|
(update :workspace-local
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
(ptk/reify ::select-track-cells
|
(ptk/reify ::select-track-cells
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
parent (get objects grid-id)
|
parent (get objects grid-id)
|
||||||
|
|
||||||
cells
|
cells
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -182,7 +182,7 @@
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [id (d/nilv id (uuid/next))
|
(let [id (d/nilv id (uuid/next))
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
|
|
||||||
shapes
|
shapes
|
||||||
(->> ids
|
(->> ids
|
||||||
|
@ -203,7 +203,7 @@
|
||||||
(ptk/reify ::group-selected
|
(ptk/reify ::group-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/of (group-shapes nil selected :change-selection? true))))))
|
(rx/of (group-shapes nil selected :change-selection? true))))))
|
||||||
|
|
||||||
(defn ungroup-shapes
|
(defn ungroup-shapes
|
||||||
|
@ -212,7 +212,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
|
|
||||||
prepare
|
prepare
|
||||||
(fn [shape-id]
|
(fn [shape-id]
|
||||||
|
@ -264,7 +264,7 @@
|
||||||
(ptk/reify ::ungroup-selected
|
(ptk/reify ::ungroup-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/of (ungroup-shapes selected :change-selection? true))))))
|
(rx/of (ungroup-shapes selected :change-selection? true))))))
|
||||||
|
|
||||||
(defn mask-group
|
(defn mask-group
|
||||||
|
@ -275,8 +275,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (->> (or ids (wsh/lookup-selected state))
|
selected (->> (or ids (dsh/lookup-selected state))
|
||||||
(cfh/clean-loops objects)
|
(cfh/clean-loops objects)
|
||||||
(remove #(ctn/has-any-copy-parent? objects (get objects %))))
|
(remove #(ctn/has-any-copy-parent? objects (get objects %))))
|
||||||
shapes (shapes-for-grouping objects selected)
|
shapes (shapes-for-grouping objects selected)
|
||||||
|
@ -323,9 +323,9 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
|
|
||||||
masked-groups (->> (d/nilv ids (wsh/lookup-selected state))
|
masked-groups (->> (d/nilv ids (dsh/lookup-selected state))
|
||||||
(map #(get objects %))
|
(map #(get objects %))
|
||||||
(filter #(or (= :bool (:type %)) (= :group (:type %)))))
|
(filter #(or (= :bool (:type %)) (= :group (:type %)))))
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
[app.common.types.page :as ctp]
|
[app.common.types.page :as ctp]
|
||||||
[app.main.data.changes :as dwc]
|
[app.main.data.changes :as dwc]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (wsh/lookup-page state)
|
(let [page (dsh/lookup-page state)
|
||||||
changes
|
changes
|
||||||
(-> (pcb/empty-changes it)
|
(-> (pcb/empty-changes it)
|
||||||
(pcb/with-page page)
|
(pcb/with-page page)
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (wsh/lookup-page state)
|
(let [page (dsh/lookup-page state)
|
||||||
changes
|
changes
|
||||||
(-> (pcb/empty-changes it)
|
(-> (pcb/empty-changes it)
|
||||||
(pcb/with-page page)
|
(pcb/with-page page)
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
(ptk/reify ::remove-guides
|
(ptk/reify ::remove-guides
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [{:keys [guides] :as page} (wsh/lookup-page state)
|
(let [{:keys [guides] :as page} (dsh/lookup-page state)
|
||||||
guides (-> (select-keys guides ids) (vals))]
|
guides (-> (select-keys guides ids) (vals))]
|
||||||
(rx/from (mapv remove-guide guides))))))
|
(rx/from (mapv remove-guide guides))))))
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
(let [ids (:ids args)
|
(let [ids (:ids args)
|
||||||
object-modifiers (:modifiers args)
|
object-modifiers (:modifiers args)
|
||||||
|
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
||||||
frame-ids? (into #{} (filter is-frame?) ids)
|
frame-ids? (into #{} (filter is-frame?) ids)
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
guide (update guide :position + (get moved (:axis guide)))]
|
guide (update guide :position + (get moved (:axis guide)))]
|
||||||
(update-guides guide)))
|
(update-guides guide)))
|
||||||
|
|
||||||
guides (-> state wsh/lookup-page :guides vals)]
|
guides (-> state dsh/lookup-page :guides vals)]
|
||||||
|
|
||||||
(->> guides
|
(->> guides
|
||||||
(filter (comp frame-ids? :frame-id))
|
(filter (comp frame-ids? :frame-id))
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (if page-id
|
(let [page (if page-id
|
||||||
(wsh/lookup-page state page-id)
|
(dsh/lookup-page state page-id)
|
||||||
(wsh/lookup-page state))
|
(dsh/lookup-page state))
|
||||||
|
|
||||||
flows (get page :flows)
|
flows (get page :flows)
|
||||||
unames (cfh/get-used-names (vals flows))
|
unames (cfh/get-used-names (vals flows))
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
(ptk/reify ::add-flow-selected-frame
|
(ptk/reify ::add-flow-selected-frame
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/of (add-flow (first selected)))))))
|
(rx/of (add-flow (first selected)))))))
|
||||||
|
|
||||||
(defn remove-flow
|
(defn remove-flow
|
||||||
|
@ -77,8 +77,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (if page-id
|
(let [page (if page-id
|
||||||
(wsh/lookup-page state page-id)
|
(dsh/lookup-page state page-id)
|
||||||
(wsh/lookup-page state))]
|
(dsh/lookup-page state))]
|
||||||
(rx/of (dch/commit-changes
|
(rx/of (dch/commit-changes
|
||||||
(-> (pcb/empty-changes it)
|
(-> (pcb/empty-changes it)
|
||||||
(pcb/with-page page)
|
(pcb/with-page page)
|
||||||
|
@ -94,8 +94,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (if page-id
|
(let [page (if page-id
|
||||||
(wsh/lookup-page state page-id)
|
(dsh/lookup-page state page-id)
|
||||||
(wsh/lookup-page state))
|
(dsh/lookup-page state))
|
||||||
flow (dm/get-in page [:flows flow-id])
|
flow (dm/get-in page [:flows flow-id])
|
||||||
flow (some-> flow update-fn)]
|
flow (some-> flow update-fn)]
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
(ptk/reify ::rename-flow
|
(ptk/reify ::rename-flow
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page (wsh/lookup-page state)]
|
(let [page (dsh/lookup-page state)]
|
||||||
(rx/of (update-flow (:id page) flow-id #(assoc % :name name)))))))
|
(rx/of (update-flow (:id page) flow-id #(assoc % :name name)))))))
|
||||||
|
|
||||||
(defn start-rename-flow
|
(defn start-rename-flow
|
||||||
|
@ -165,7 +165,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
page (wsh/lookup-page state page-id)
|
page (dsh/lookup-page state page-id)
|
||||||
objects (get page :objects)
|
objects (get page :objects)
|
||||||
frame (cfh/get-root-frame objects (:id shape))
|
frame (cfh/get-root-frame objects (:id shape))
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
|
|
||||||
remove-interactions-shape
|
remove-interactions-shape
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
|
@ -258,7 +258,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [initial-pos @ms/mouse-position
|
(let [initial-pos @ms/mouse-position
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
stopper (mse/drag-stopper stream)]
|
stopper (mse/drag-stopper stream)]
|
||||||
(when (= 1 (count selected))
|
(when (= 1 (count selected))
|
||||||
(rx/concat
|
(rx/concat
|
||||||
|
@ -270,9 +270,9 @@
|
||||||
(defn- get-target-frame
|
(defn- get-target-frame
|
||||||
[state position]
|
[state position]
|
||||||
|
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
from-id (-> state wsh/lookup-selected first)
|
from-id (-> state dsh/lookup-selected first)
|
||||||
from-shape (wsh/lookup-shape state from-id)
|
from-shape (dsh/lookup-shape state from-id)
|
||||||
|
|
||||||
from-frame-id (if (cfh/frame-shape? from-shape)
|
from-frame-id (if (cfh/frame-shape? from-shape)
|
||||||
from-id (:frame-id from-shape))
|
from-id (:frame-id from-shape))
|
||||||
|
@ -309,8 +309,8 @@
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [position @ms/mouse-position
|
(let [position @ms/mouse-position
|
||||||
target-frame (get-target-frame state position)
|
target-frame (get-target-frame state position)
|
||||||
shape-id (-> state wsh/lookup-selected first)
|
shape-id (-> state dsh/lookup-selected first)
|
||||||
shape (wsh/lookup-shape state shape-id)
|
shape (dsh/lookup-shape state shape-id)
|
||||||
|
|
||||||
change-interaction
|
change-interaction
|
||||||
(fn [interaction]
|
(fn [interaction]
|
||||||
|
@ -368,13 +368,13 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [initial-pos @ms/mouse-position
|
(let [initial-pos @ms/mouse-position
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
stopper (mse/drag-stopper stream)]
|
stopper (mse/drag-stopper stream)]
|
||||||
(when (= 1 (count selected))
|
(when (= 1 (count selected))
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shape (->> state
|
shape (->> state
|
||||||
wsh/lookup-selected
|
dsh/lookup-selected
|
||||||
first
|
first
|
||||||
(get objects))
|
(get objects))
|
||||||
overlay-pos (-> shape
|
overlay-pos (-> shape
|
||||||
|
@ -418,9 +418,9 @@
|
||||||
(gpt/subtract offset))
|
(gpt/subtract offset))
|
||||||
|
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shape (->> state
|
shape (->> state
|
||||||
wsh/lookup-selected
|
dsh/lookup-selected
|
||||||
first
|
first
|
||||||
(get objects))
|
(get objects))
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -43,8 +43,8 @@
|
||||||
(ptk/reify ::set-opacity
|
(ptk/reify ::set-opacity
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
selected (dsh/lookup-selected state {:omit-blocked? true})
|
||||||
shapes (map #(get objects %) selected)
|
shapes (map #(get objects %) selected)
|
||||||
shapes-ids (->> shapes
|
shapes-ids (->> shapes
|
||||||
(map :id))]
|
(map :id))]
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
[app.main.data.comments :as dc]
|
[app.main.data.comments :as dc]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.notifications :as ntf]
|
[app.main.data.notifications :as ntf]
|
||||||
[app.main.data.workspace :as-alias dw]
|
[app.main.data.workspace :as-alias dw]
|
||||||
|
@ -37,7 +38,6 @@
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.specialized-panel :as dwsp]
|
[app.main.data.workspace.specialized-panel :as dwsp]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.thumbnails :as dwt]
|
[app.main.data.workspace.thumbnails :as dwt]
|
||||||
[app.main.data.workspace.transforms :as dwtr]
|
[app.main.data.workspace.transforms :as dwtr]
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
[file-id state]
|
[file-id state]
|
||||||
(if (= file-id (:current-file-id state))
|
(if (= file-id (:current-file-id state))
|
||||||
"<local>"
|
"<local>"
|
||||||
(str "<" (get-in state [:libraries file-id :name]) ">")))
|
(str "<" (get-in state [:files file-id :name]) ">")))
|
||||||
|
|
||||||
(defn- log-changes
|
(defn- log-changes
|
||||||
[changes file]
|
[changes file]
|
||||||
|
@ -164,16 +164,16 @@
|
||||||
|
|
||||||
(defn- update-color*
|
(defn- update-color*
|
||||||
[it state color file-id]
|
[it state color file-id]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
[path name] (cfh/parse-path-name (:name color))
|
[path name] (cfh/parse-path-name (:name color))
|
||||||
color (assoc color :path path :name name)
|
color (assoc color :path path :name name)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/update-color color))
|
(pcb/update-color color))
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
(rx/of (dwu/start-undo-transaction undo-id)
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
(dch/commit-changes changes)
|
(dch/commit-changes changes)
|
||||||
(sync-file (:current-file-id state) file-id :colors (:id color))
|
(sync-file (:id data) file-id :colors (:id color))
|
||||||
(dwu/commit-undo-transaction undo-id))))
|
(dwu/commit-undo-transaction undo-id))))
|
||||||
|
|
||||||
(defn update-color
|
(defn update-color
|
||||||
|
@ -212,6 +212,7 @@
|
||||||
(let [color (assoc color :name (dm/str (:path color) "/" (:name color)))]
|
(let [color (assoc color :name (dm/str (:path color) "/" (:name color)))]
|
||||||
(update-color* it state color file-id))))))
|
(update-color* it state color file-id))))))
|
||||||
|
|
||||||
|
;; FIXME: revisit why file-id is passed on the event
|
||||||
(defn rename-color
|
(defn rename-color
|
||||||
[file-id id new-name]
|
[file-id id new-name]
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
|
@ -232,7 +233,7 @@
|
||||||
(let [new-name (str/trim new-name)]
|
(let [new-name (str/trim new-name)]
|
||||||
(if (str/empty? new-name)
|
(if (str/empty? new-name)
|
||||||
(rx/empty)
|
(rx/empty)
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
color (get-in data [:colors id])
|
color (get-in data [:colors id])
|
||||||
color (assoc color :name new-name)
|
color (assoc color :name new-name)
|
||||||
color (d/without-nils color)]
|
color (d/without-nils color)]
|
||||||
|
@ -247,7 +248,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-color id))]
|
(pcb/delete-color id))]
|
||||||
|
@ -288,7 +289,7 @@
|
||||||
(if (str/empty? new-name)
|
(if (str/empty? new-name)
|
||||||
(rx/empty)
|
(rx/empty)
|
||||||
(let [[path name] (cfh/parse-path-name new-name)
|
(let [[path name] (cfh/parse-path-name new-name)
|
||||||
data (get state :workspace-data)
|
data (dsh/lookup-file-data state)
|
||||||
object (get-in data [:media id])
|
object (get-in data [:media id])
|
||||||
new-object (assoc object :path path :name name)
|
new-object (assoc object :path path :name name)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
|
@ -308,7 +309,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-media id))]
|
(pcb/delete-media id))]
|
||||||
|
@ -337,7 +338,7 @@
|
||||||
|
|
||||||
(defn- do-update-tipography
|
(defn- do-update-tipography
|
||||||
[it state typography file-id]
|
[it state typography file-id]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
typography (extract-path-if-missing typography)
|
typography (extract-path-if-missing typography)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
|
@ -373,7 +374,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(when (and (some? new-name) (not= "" new-name))
|
(when (and (some? new-name) (not= "" new-name))
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
[path name] (cfh/parse-path-name new-name)
|
[path name] (cfh/parse-path-name new-name)
|
||||||
object (get-in data [:typographies id])
|
object (get-in data [:typographies id])
|
||||||
new-object (assoc object :path path :name name)]
|
new-object (assoc object :path path :name name)]
|
||||||
|
@ -388,7 +389,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-typography id))]
|
(pcb/delete-typography id))]
|
||||||
|
@ -409,7 +410,7 @@
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shapes (dwg/shapes-for-grouping objects selected)
|
shapes (dwg/shapes-for-grouping objects selected)
|
||||||
parents (into #{} (map :parent-id) shapes)]
|
parents (into #{} (map :parent-id) shapes)]
|
||||||
(when-not (empty? shapes)
|
(when-not (empty? shapes)
|
||||||
|
@ -436,8 +437,8 @@
|
||||||
(ptk/reify ::add-component
|
(ptk/reify ::add-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (->> (d/nilv ids (wsh/lookup-selected state))
|
selected (->> (d/nilv ids (dsh/lookup-selected state))
|
||||||
(cfh/clean-loops objects))
|
(cfh/clean-loops objects))
|
||||||
selected-objects (map #(get objects %) selected)
|
selected-objects (map #(get objects %) selected)
|
||||||
components-v2 (features/active-feature? state "components/v2")
|
components-v2 (features/active-feature? state "components/v2")
|
||||||
|
@ -454,8 +455,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [components-v2 (features/active-feature? state "components/v2")
|
(let [components-v2 (features/active-feature? state "components/v2")
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
selected (->> (wsh/lookup-selected state)
|
selected (->> (dsh/lookup-selected state)
|
||||||
(cfh/clean-loops objects))
|
(cfh/clean-loops objects))
|
||||||
selected-objects (map #(get objects %) selected)
|
selected-objects (map #(get objects %) selected)
|
||||||
;; We don't want to change the structure of component copies
|
;; We don't want to change the structure of component copies
|
||||||
|
@ -488,11 +489,9 @@
|
||||||
(let [new-name (str/trim new-name)]
|
(let [new-name (str/trim new-name)]
|
||||||
(if (str/empty? new-name)
|
(if (str/empty? new-name)
|
||||||
(rx/empty)
|
(rx/empty)
|
||||||
(let [library-data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
components-v2 (features/active-feature? state "components/v2")
|
changes (-> (pcb/empty-changes it)
|
||||||
changes (-> (pcb/empty-changes it)
|
(cll/generate-rename-component id new-name data true))]
|
||||||
(cll/generate-rename-component id new-name library-data components-v2))]
|
|
||||||
|
|
||||||
(rx/of (dch/commit-changes changes))))))))
|
(rx/of (dch/commit-changes changes))))))))
|
||||||
|
|
||||||
(defn rename-component-and-main-instance
|
(defn rename-component-and-main-instance
|
||||||
|
@ -505,14 +504,17 @@
|
||||||
valid? (and (not (str/ends-with? name "/"))
|
valid? (and (not (str/ends-with? name "/"))
|
||||||
(string? clean-name)
|
(string? clean-name)
|
||||||
(not (str/blank? clean-name)))
|
(not (str/blank? clean-name)))
|
||||||
component (dm/get-in state [:workspace-data :components component-id])]
|
data (dsh/lookup-file-data state)
|
||||||
|
component (dm/get-in data [:components component-id])]
|
||||||
|
|
||||||
(when (and valid? component)
|
(when (and valid? component)
|
||||||
(let [shape-id (:main-instance-id component)
|
(let [shape-id (:main-instance-id component)
|
||||||
page-id (:main-instance-page component)]
|
page-id (:main-instance-page component)]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (rename-component component-id clean-name))
|
(rx/of (rename-component component-id clean-name))
|
||||||
|
|
||||||
;; NOTE: only when components-v2 is enabled
|
;; NOTE: only when components-v2 is enabled
|
||||||
(when (and shape-id page-id)
|
(when (and shape-id page-id)
|
||||||
(rx/of (dwsh/update-shapes [shape-id] #(assoc % :name clean-name) {:page-id page-id :stack-undo? true}))))))))))
|
(rx/of (dwsh/update-shapes [shape-id] #(assoc % :name clean-name) {:page-id page-id :stack-undo? true}))))))))))
|
||||||
|
|
||||||
|
@ -522,7 +524,7 @@
|
||||||
(ptk/reify ::duplicate-component
|
(ptk/reify ::duplicate-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [libraries (wsh/get-libraries state)
|
(let [libraries (dsh/lookup-libraries state)
|
||||||
library (get libraries library-id)
|
library (get libraries library-id)
|
||||||
components-v2 (features/active-feature? state "components/v2")
|
components-v2 (features/active-feature? state "components/v2")
|
||||||
changes (-> (pcb/empty-changes it nil)
|
changes (-> (pcb/empty-changes it nil)
|
||||||
|
@ -540,37 +542,31 @@
|
||||||
(ptk/reify ::delete-component
|
(ptk/reify ::delete-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)]
|
(let [file-id (:current-file-id state)
|
||||||
(if (features/active-feature? state "components/v2")
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
(let [component (ctkl/get-component data id)
|
component (ctkl/get-component fdata id)
|
||||||
page-id (:main-instance-page component)
|
page-id (:main-instance-page component)
|
||||||
root-id (:main-instance-id component)
|
root-id (:main-instance-id component)
|
||||||
file-id (:current-file-id state)
|
|
||||||
file (wsh/get-file state file-id)
|
|
||||||
page (wsh/lookup-page state page-id)
|
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
|
||||||
components-v2 (features/active-feature? state "components/v2")
|
|
||||||
undo-group (uuid/next)
|
|
||||||
undo-id (js/Symbol)
|
|
||||||
[all-parents changes]
|
|
||||||
(-> (pcb/empty-changes it page-id)
|
|
||||||
;; Deleting main root triggers component delete
|
|
||||||
(cls/generate-delete-shapes file page objects #{root-id} {:components-v2 components-v2
|
|
||||||
:undo-group undo-group
|
|
||||||
:undo-id undo-id}))]
|
|
||||||
(rx/of
|
|
||||||
(dwu/start-undo-transaction undo-id)
|
|
||||||
(dwt/clear-thumbnail (:current-file-id state) page-id root-id "component")
|
|
||||||
(dc/detach-comment-thread #{root-id})
|
|
||||||
(dch/commit-changes changes)
|
|
||||||
(ptk/data-event :layout/update {:ids all-parents :undo-group undo-group})
|
|
||||||
(dwu/commit-undo-transaction undo-id)))
|
|
||||||
(let [page-id (:current-page-id state)
|
|
||||||
changes (-> (pcb/empty-changes it)
|
|
||||||
(pcb/with-library-data data)
|
|
||||||
(pcb/delete-component id page-id))]
|
|
||||||
(rx/of (dch/commit-changes changes))))))))
|
|
||||||
|
|
||||||
|
page (dsh/get-page fdata page-id)
|
||||||
|
objects (:objects page)
|
||||||
|
|
||||||
|
undo-group (uuid/next)
|
||||||
|
undo-id (js/Symbol)
|
||||||
|
|
||||||
|
[all-parents changes]
|
||||||
|
(-> (pcb/empty-changes it page-id)
|
||||||
|
;; Deleting main root triggers component delete
|
||||||
|
(cls/generate-delete-shapes fdata page objects #{root-id} {:components-v2 true
|
||||||
|
:undo-group undo-group
|
||||||
|
:undo-id undo-id}))]
|
||||||
|
(rx/of
|
||||||
|
(dwu/start-undo-transaction undo-id)
|
||||||
|
(dwt/clear-thumbnail (:current-file-id state) page-id root-id "component")
|
||||||
|
(dc/detach-comment-thread #{root-id})
|
||||||
|
(dch/commit-changes changes)
|
||||||
|
(ptk/data-event :layout/update {:ids all-parents :undo-group undo-group})
|
||||||
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
(defn restore-component
|
(defn restore-component
|
||||||
"Restore a deleted component, with the given id, in the given file library."
|
"Restore a deleted component, with the given id, in the given file library."
|
||||||
|
@ -580,12 +576,14 @@
|
||||||
(ptk/reify ::restore-component
|
(ptk/reify ::restore-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
current-page (dm/get-in state [:workspace-data :pages-index page-id])
|
page (dsh/lookup-page state page-id)
|
||||||
library-data (wsh/get-file state library-id)
|
objects (:objects page)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
|
||||||
changes (-> (pcb/empty-changes it)
|
ldata (dsh/lookup-file-data state library-id)
|
||||||
(cll/generate-restore-component library-data component-id library-id current-page objects))]
|
|
||||||
|
changes (-> (pcb/empty-changes it)
|
||||||
|
(cll/generate-restore-component ldata component-id library-id page objects))]
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -614,8 +612,8 @@
|
||||||
(ptk/reify ::instantiate-component
|
(ptk/reify ::instantiate-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (wsh/lookup-page state)
|
(let [page (dsh/lookup-page state)
|
||||||
libraries (wsh/get-libraries state)
|
libraries (dsh/lookup-libraries state)
|
||||||
|
|
||||||
objects (:objects page)
|
objects (:objects page)
|
||||||
changes (-> (pcb/empty-changes it (:id page))
|
changes (-> (pcb/empty-changes it (:id page))
|
||||||
|
@ -637,11 +635,10 @@
|
||||||
(when id-ref
|
(when id-ref
|
||||||
(reset! id-ref (:id new-shape)))
|
(reset! id-ref (:id new-shape)))
|
||||||
|
|
||||||
(rx/of (ptk/event
|
(rx/of (ptk/event ::ev/event
|
||||||
::ev/event
|
{::ev/name "use-library-component"
|
||||||
{::ev/name "use-library-component"
|
::ev/origin origin
|
||||||
::ev/origin origin
|
:external-library (not= file-id current-file-id)})
|
||||||
:external-library (not= file-id current-file-id)})
|
|
||||||
(dwu/start-undo-transaction undo-id)
|
(dwu/start-undo-transaction undo-id)
|
||||||
(dch/commit-changes changes)
|
(dch/commit-changes changes)
|
||||||
(ptk/data-event :layout/update {:ids [(:id new-shape)]})
|
(ptk/data-event :layout/update {:ids [(:id new-shape)]})
|
||||||
|
@ -658,12 +655,14 @@
|
||||||
(ptk/reify ::detach-component
|
(ptk/reify ::detach-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file (wsh/get-local-file state)
|
(let [page-id (:current-page-id state)
|
||||||
page-id (get state :current-page-id)
|
file-id (:current-file-id state)
|
||||||
libraries (wsh/get-libraries state)
|
|
||||||
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
|
libraries (dsh/lookup-libraries state)
|
||||||
|
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(cll/generate-detach-component id file page-id libraries))]
|
(cll/generate-detach-component id fdata page-id libraries))]
|
||||||
|
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
||||||
|
@ -685,20 +684,27 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
file-id (:current-file-id state)
|
||||||
file (wsh/get-local-file state)
|
|
||||||
libraries (wsh/get-libraries state)
|
;; FIXME: revisit, innefficient access
|
||||||
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
|
|
||||||
|
libraries (dsh/lookup-libraries state)
|
||||||
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
|
|
||||||
selected (->> state
|
selected (->> state
|
||||||
(wsh/lookup-selected)
|
(dsh/lookup-selected)
|
||||||
(cfh/clean-loops objects))
|
(cfh/clean-loops objects))
|
||||||
|
|
||||||
selected-objects (map #(get objects %) selected)
|
selected-objects (map #(get objects %) selected)
|
||||||
copies (filter ctk/in-component-copy? selected-objects)
|
copies (filter ctk/in-component-copy? selected-objects)
|
||||||
can-detach? (and (seq copies)
|
can-detach? (and (seq copies)
|
||||||
(every? #(not (ctn/has-any-copy-parent? objects %)) selected-objects))
|
(every? #(not (ctn/has-any-copy-parent? objects %)) selected-objects))
|
||||||
|
|
||||||
changes (when can-detach?
|
changes (when can-detach?
|
||||||
(reduce
|
(reduce
|
||||||
(fn [changes id]
|
(fn [changes id]
|
||||||
(cll/generate-detach-component changes id file page-id libraries))
|
(cll/generate-detach-component changes id fdata page-id libraries))
|
||||||
(pcb/empty-changes it)
|
(pcb/empty-changes it)
|
||||||
selected))]
|
selected))]
|
||||||
|
|
||||||
|
@ -725,6 +731,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [current-page-id (:current-page-id state)
|
(let [current-page-id (:current-page-id state)
|
||||||
|
data (dsh/lookup-file-data state)
|
||||||
|
|
||||||
select-and-zoom
|
select-and-zoom
|
||||||
(fn [shape-id]
|
(fn [shape-id]
|
||||||
|
@ -741,7 +748,7 @@
|
||||||
(rx/observe-on :async)
|
(rx/observe-on :async)
|
||||||
(rx/mapcat (fn [_] (select-and-zoom shape-id))))))]
|
(rx/mapcat (fn [_] (select-and-zoom shape-id))))))]
|
||||||
|
|
||||||
(when-let [component (dm/get-in state [:workspace-data :components id])]
|
(when-let [component (dm/get-in data [:components id])]
|
||||||
(let [page-id (:main-instance-page component)
|
(let [page-id (:main-instance-page component)
|
||||||
shape-id (:main-instance-id component)]
|
shape-id (:main-instance-id component)]
|
||||||
(when (some? page-id)
|
(when (some? page-id)
|
||||||
|
@ -779,9 +786,9 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
(update-in [:libraries library-id]
|
(update-in [:files library-id]
|
||||||
assoc :modified-at modified-at :revn revn)
|
assoc :modified-at modified-at :revn revn)
|
||||||
(d/update-in-when [:libraries library-id :data]
|
(d/update-in-when [:files library-id :data]
|
||||||
ch/process-changes changes)))
|
ch/process-changes changes)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
@ -805,30 +812,25 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(log/info :msg "RESET-COMPONENT of shape" :id (str id))
|
(log/info :msg "RESET-COMPONENT of shape" :id (str id))
|
||||||
(let [file (wsh/get-local-file state)
|
(let [libraries (:files state)
|
||||||
file-full (wsh/get-local-file-full state)
|
|
||||||
libraries (wsh/get-libraries state)
|
|
||||||
|
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
container (ctn/get-container file :page page-id)
|
|
||||||
|
|
||||||
components-v2
|
file (dsh/lookup-file state)
|
||||||
(features/active-feature? state "components/v2")
|
data (:data file)
|
||||||
|
|
||||||
|
container (ctn/get-container data :page page-id)
|
||||||
undo-id (js/Symbol)
|
undo-id (js/Symbol)
|
||||||
|
|
||||||
changes
|
changes
|
||||||
(-> (pcb/empty-changes it)
|
(-> (pcb/empty-changes it)
|
||||||
(cll/generate-reset-component file-full libraries container id components-v2))]
|
(cll/generate-reset-component file libraries container id true))]
|
||||||
|
|
||||||
(log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes
|
(log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes
|
||||||
(:redo-changes changes)
|
(:redo-changes changes)
|
||||||
file))
|
file))
|
||||||
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
(rx/of
|
(dch/commit-changes changes)
|
||||||
(dwu/start-undo-transaction undo-id)
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
(dch/commit-changes changes)
|
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
|
||||||
|
|
||||||
(defn reset-components
|
(defn reset-components
|
||||||
"Cancels all modifications in the shapes with the given ids"
|
"Cancels all modifications in the shapes with the given ids"
|
||||||
|
@ -859,24 +861,24 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(log/info :msg "UPDATE-COMPONENT of shape" :id (str id) :undo-group undo-group)
|
(log/info :msg "UPDATE-COMPONENT of shape" :id (str id) :undo-group undo-group)
|
||||||
(let [page-id (get state :current-page-id)
|
(let [page-id (:current-page-id state)
|
||||||
local-file (wsh/get-local-file state)
|
|
||||||
full-file (wsh/get-local-file-full state)
|
libraries (dsh/lookup-libraries state)
|
||||||
container (ctn/get-container local-file :page page-id)
|
file (dsh/lookup-file state)
|
||||||
shape (ctn/get-shape container id)
|
fdata (:data file)
|
||||||
components-v2 (features/active-feature? state "components/v2")]
|
|
||||||
|
container (ctn/get-container fdata :page page-id)
|
||||||
|
shape (ctn/get-shape container id)]
|
||||||
|
|
||||||
(when (ctk/instance-head? shape)
|
(when (ctk/instance-head? shape)
|
||||||
(let [libraries (wsh/get-libraries state)
|
(let [changes
|
||||||
|
|
||||||
changes
|
|
||||||
(-> (pcb/empty-changes it)
|
(-> (pcb/empty-changes it)
|
||||||
(pcb/set-undo-group undo-group)
|
(pcb/set-undo-group undo-group)
|
||||||
(pcb/with-container container)
|
(pcb/with-container container)
|
||||||
(cll/generate-sync-shape-inverse full-file libraries container id components-v2))
|
(cll/generate-sync-shape-inverse fdata libraries container id true))
|
||||||
|
|
||||||
file-id (:component-file shape)
|
ldata (->> (:component-file shape)
|
||||||
file (wsh/get-file state file-id)
|
(dsh/lookup-file-data state))
|
||||||
|
|
||||||
xf-filter (comp
|
xf-filter (comp
|
||||||
(filter :local-change?)
|
(filter :local-change?)
|
||||||
|
@ -897,29 +899,25 @@
|
||||||
(log/debug :msg "UPDATE-COMPONENT finished"
|
(log/debug :msg "UPDATE-COMPONENT finished"
|
||||||
:js/local-changes (log-changes
|
:js/local-changes (log-changes
|
||||||
(:redo-changes local-changes)
|
(:redo-changes local-changes)
|
||||||
file)
|
fdata)
|
||||||
:js/nonlocal-changes (log-changes
|
:js/nonlocal-changes (log-changes
|
||||||
(:redo-changes nonlocal-changes)
|
(:redo-changes nonlocal-changes)
|
||||||
file))
|
fdata))
|
||||||
|
|
||||||
(rx/of
|
(rx/of
|
||||||
(when (seq (:redo-changes local-changes))
|
(when (seq (:redo-changes local-changes))
|
||||||
(dch/commit-changes (assoc local-changes
|
(dch/commit-changes (assoc local-changes
|
||||||
:file-id (:id local-file))))
|
:file-id (:id file))))
|
||||||
(when (seq (:redo-changes nonlocal-changes))
|
(when (seq (:redo-changes nonlocal-changes))
|
||||||
(dch/commit-changes (assoc nonlocal-changes
|
(dch/commit-changes (assoc nonlocal-changes
|
||||||
:file-id file-id)))))))))))
|
:file-id (:id ldata))))))))))))
|
||||||
|
|
||||||
(defn- update-component-thumbnail-sync
|
(defn- update-component-thumbnail-sync
|
||||||
[state component-id file-id tag]
|
[state component-id file-id tag]
|
||||||
(let [current-file-id (:current-file-id state)
|
(let [data (dsh/lookup-file-data state file-id)
|
||||||
current-file? (= current-file-id file-id)
|
component (ctkl/get-component data component-id)
|
||||||
data (if current-file?
|
page-id (:main-instance-page component)
|
||||||
(get state :workspace-data)
|
root-id (:main-instance-id component)]
|
||||||
(get-in state [:libraries file-id :data]))
|
|
||||||
component (ctkl/get-component data component-id)
|
|
||||||
page-id (:main-instance-page component)
|
|
||||||
root-id (:main-instance-id component)]
|
|
||||||
(dwt/update-thumbnail file-id page-id root-id tag "update-component-thumbnail-sync")))
|
(dwt/update-thumbnail file-id page-id root-id tag "update-component-thumbnail-sync")))
|
||||||
|
|
||||||
(defn update-component-sync
|
(defn update-component-sync
|
||||||
|
@ -930,7 +928,8 @@
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [current-file-id (:current-file-id state)
|
(let [current-file-id (:current-file-id state)
|
||||||
current-file? (= current-file-id file-id)
|
current-file? (= current-file-id file-id)
|
||||||
page (wsh/lookup-page state)
|
|
||||||
|
page (dsh/lookup-page state)
|
||||||
shape (ctn/get-shape page shape-id)
|
shape (ctn/get-shape page shape-id)
|
||||||
component-id (:component-id shape)
|
component-id (:component-id shape)
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
@ -995,12 +994,13 @@
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
;; First delete shapes so we have space in the layout otherwise we can have problems
|
;; First delete shapes so we have space in the layout otherwise we can have problems
|
||||||
;; in the grid creating new rows/columns to make space
|
;; in the grid creating new rows/columns to make space
|
||||||
(let [file (wsh/get-file state file-id)
|
(let [libraries (dsh/lookup-libraries state)
|
||||||
libraries (wsh/get-libraries state)
|
page (dsh/lookup-page state)
|
||||||
page (wsh/lookup-page state)
|
objects (:objects page)
|
||||||
objects (wsh/lookup-page-objects state)
|
|
||||||
parent (get objects (:parent-id shape))
|
parent (get objects (:parent-id shape))
|
||||||
|
|
||||||
|
ldata (dsh/lookup-file-data state file-id)
|
||||||
|
|
||||||
;; If the target parent is a grid layout we need to pass the target cell
|
;; If the target parent is a grid layout we need to pass the target cell
|
||||||
target-cell (when (ctl/grid-layout? parent)
|
target-cell (when (ctl/grid-layout? parent)
|
||||||
(ctl/get-cell-by-shape-id parent (:id shape)))
|
(ctl/get-cell-by-shape-id parent (:id shape)))
|
||||||
|
@ -1016,7 +1016,7 @@
|
||||||
[new-shape all-parents changes]
|
[new-shape all-parents changes]
|
||||||
(-> (pcb/empty-changes it (:id page))
|
(-> (pcb/empty-changes it (:id page))
|
||||||
(pcb/set-undo-group undo-group)
|
(pcb/set-undo-group undo-group)
|
||||||
(cll/generate-component-swap objects shape file page libraries id-new-component index target-cell keep-props-values))]
|
(cll/generate-component-swap objects shape ldata page libraries id-new-component index target-cell keep-props-values))]
|
||||||
|
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwu/start-undo-transaction undo-id)
|
(dwu/start-undo-transaction undo-id)
|
||||||
|
@ -1086,7 +1086,7 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (and (not= library-id (:current-file-id state))
|
(if (and (not= library-id (:current-file-id state))
|
||||||
(nil? asset-id))
|
(nil? asset-id))
|
||||||
(d/assoc-in-when state [:libraries library-id :synced-at] (dt/now))
|
(d/assoc-in-when state [:files library-id :synced-at] (dt/now))
|
||||||
state))
|
state))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
@ -1098,8 +1098,8 @@
|
||||||
:asset-type asset-type
|
:asset-type asset-type
|
||||||
:asset-id asset-id
|
:asset-id asset-id
|
||||||
:undo-group undo-group)
|
:undo-group undo-group)
|
||||||
(let [file (wsh/get-file state file-id)
|
(let [ldata (dsh/lookup-file-data state file-id)
|
||||||
libraries (wsh/get-libraries state)
|
libraries (dsh/lookup-libraries state)
|
||||||
current-file-id (:current-file-id state)
|
current-file-id (:current-file-id state)
|
||||||
|
|
||||||
changes (cll/generate-sync-file-changes
|
changes (cll/generate-sync-file-changes
|
||||||
|
@ -1113,7 +1113,7 @@
|
||||||
current-file-id)
|
current-file-id)
|
||||||
|
|
||||||
find-frames (fn [change]
|
find-frames (fn [change]
|
||||||
(->> (ch/frames-changed file change)
|
(->> (ch/frames-changed ldata change)
|
||||||
(map #(assoc %1 :page-id (:page-id change)))))
|
(map #(assoc %1 :page-id (:page-id change)))))
|
||||||
|
|
||||||
updated-frames (->> changes
|
updated-frames (->> changes
|
||||||
|
@ -1123,7 +1123,7 @@
|
||||||
|
|
||||||
(log/debug :msg "SYNC-FILE finished" :js/rchanges (log-changes
|
(log/debug :msg "SYNC-FILE finished" :js/rchanges (log-changes
|
||||||
(:redo-changes changes)
|
(:redo-changes changes)
|
||||||
file))
|
ldata))
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (set-updating-library false)
|
(rx/of (set-updating-library false)
|
||||||
(ntf/hide {:tag :sync-dialog}))
|
(ntf/hide {:tag :sync-dialog}))
|
||||||
|
@ -1161,7 +1161,8 @@
|
||||||
(ptk/reify ::ignore-sync
|
(ptk/reify ::ignore-sync
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc-in state [:workspace-file :ignore-sync-until] (dt/now)))
|
(let [file-id (:current-file-id state)]
|
||||||
|
(assoc-in state [:files file-id :ignore-sync-until] (dt/now))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -1175,11 +1176,13 @@
|
||||||
"Get a lazy sequence of all the assets of each type in the library that have
|
"Get a lazy sequence of all the assets of each type in the library that have
|
||||||
been modified after the last sync of the library. The sync date may be
|
been modified after the last sync of the library. The sync date may be
|
||||||
overriden by providing a ignore-until parameter."
|
overriden by providing a ignore-until parameter."
|
||||||
([library file-data] (assets-need-sync library file-data nil))
|
([library file-data]
|
||||||
|
(assets-need-sync library file-data nil))
|
||||||
([library file-data ignore-until]
|
([library file-data ignore-until]
|
||||||
(let [sync-date (max (:synced-at library) (or ignore-until 0))]
|
(when (not= (:id library) (:id file-data))
|
||||||
(when (> (:modified-at library) sync-date)
|
(let [sync-date (max (:synced-at library) (or ignore-until 0))]
|
||||||
(ctf/used-assets-changed-since file-data library sync-date)))))
|
(when (> (:modified-at library) sync-date)
|
||||||
|
(ctf/used-assets-changed-since file-data library sync-date))))))
|
||||||
|
|
||||||
(defn notify-sync-file
|
(defn notify-sync-file
|
||||||
[file-id]
|
[file-id]
|
||||||
|
@ -1187,18 +1190,29 @@
|
||||||
(ptk/reify ::notify-sync-file
|
(ptk/reify ::notify-sync-file
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-data (:workspace-data state)
|
(let [file (dm/get-in state [:files file-id])
|
||||||
ignore-until (dm/get-in state [:workspace-file :ignore-sync-until])
|
file-data (get file :data)
|
||||||
libraries-need-sync (filter #(seq (assets-need-sync % file-data ignore-until))
|
ignore-until (get file :ignore-sync-until)
|
||||||
(vals (get state :libraries)))
|
|
||||||
do-more-info #(modal/show! :libraries-dialog {:starting-tab "updates"})
|
|
||||||
do-update #(do (apply st/emit! (map (fn [library]
|
;; FIXME: syntax of this can be improved
|
||||||
(sync-file (:current-file-id state)
|
libraries-need-sync
|
||||||
(:id library)))
|
(filter #(seq (assets-need-sync % file-data ignore-until))
|
||||||
libraries-need-sync))
|
(vals (get state :files)))
|
||||||
(st/emit! (ntf/hide)))
|
|
||||||
do-dismiss #(do (st/emit! ignore-sync)
|
do-more-info
|
||||||
(st/emit! (ntf/hide)))]
|
#(modal/show! :libraries-dialog {:starting-tab "updates"})
|
||||||
|
|
||||||
|
do-update
|
||||||
|
#(do (apply st/emit! (map (fn [library]
|
||||||
|
(sync-file (:current-file-id state)
|
||||||
|
(:id library)))
|
||||||
|
libraries-need-sync))
|
||||||
|
(st/emit! (ntf/hide)))
|
||||||
|
|
||||||
|
do-dismiss
|
||||||
|
#(do (st/emit! ignore-sync)
|
||||||
|
(st/emit! (ntf/hide)))]
|
||||||
|
|
||||||
(when (seq libraries-need-sync)
|
(when (seq libraries-need-sync)
|
||||||
(rx/of (ntf/dialog
|
(rx/of (ntf/dialog
|
||||||
|
@ -1227,7 +1241,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (dsh/lookup-file-data state)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/update-component id #(assoc % :modified-at (dt/now))))]
|
(pcb/update-component id #(assoc % :modified-at (dt/now))))]
|
||||||
|
@ -1351,7 +1365,7 @@
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc-in state [:workspace-file :is-shared] is-shared))
|
(update-in state [:files id] assoc :is-shared is-shared))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
|
@ -1377,7 +1391,7 @@
|
||||||
(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 :libraries assoc library-id (dissoc library :library-summary))
|
(update state :files assoc library-id (dissoc library :library-summary))
|
||||||
state)))
|
state)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
@ -1389,9 +1403,10 @@
|
||||||
(rx/ignore))
|
(rx/ignore))
|
||||||
(->> (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
|
||||||
(rx/map (fn [file]
|
(rx/map (fn [file]
|
||||||
(fn [state]
|
(fn [state]
|
||||||
(assoc-in state [:libraries library-id] file)))))
|
(assoc-in state [:files library-id] file)))))
|
||||||
(->> (rp/cmd! :get-file-object-thumbnails {:file-id library-id :tag "component"})
|
(->> (rp/cmd! :get-file-object-thumbnails {:file-id library-id :tag "component"})
|
||||||
(rx/map (fn [thumbnails]
|
(rx/map (fn [thumbnails]
|
||||||
(fn [state]
|
(fn [state]
|
||||||
|
@ -1409,7 +1424,7 @@
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(d/dissoc-in state [:libraries library-id]))
|
(update state :files dissoc library-id))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.media :as dmm]
|
[app.main.data.media :as dmm]
|
||||||
[app.main.data.notifications :as ntf]
|
[app.main.data.notifications :as ntf]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.svg-upload :as svg]
|
[app.main.data.workspace.svg-upload :as svg]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -266,9 +266,11 @@
|
||||||
(on-success image)
|
(on-success image)
|
||||||
(dmm/notify-finished-loading))
|
(dmm/notify-finished-loading))
|
||||||
|
|
||||||
|
file-id (:current-file-id state)
|
||||||
|
|
||||||
prepare
|
prepare
|
||||||
(fn [content]
|
(fn [content]
|
||||||
{:file-id (get-in state [:workspace-file :id])
|
{:file-id file-id
|
||||||
:name (if (dmm/file? content) (.-name content) (tr "media.image"))
|
:name (if (dmm/file? content) (.-name content) (tr "media.image"))
|
||||||
:is-local false
|
:is-local false
|
||||||
:content content})]
|
:content content})]
|
||||||
|
@ -399,22 +401,31 @@
|
||||||
(ptk/reify ::process-img-component
|
(ptk/reify ::process-img-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file-data (wsh/get-local-file state)
|
(let [file-id (:current-file-id state)
|
||||||
page (wsh/lookup-page state)
|
page-id (:current-page-id state)
|
||||||
pos (wsh/viewport-center state)]
|
|
||||||
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
|
page (dsh/get-page fdata page-id)
|
||||||
|
pos (dsh/get-viewport-center state)]
|
||||||
|
|
||||||
(->> (create-shapes-img pos media-obj)
|
(->> (create-shapes-img pos media-obj)
|
||||||
(rx/map (partial add-shapes-and-component it file-data page (:name media-obj))))))))
|
(rx/map (partial add-shapes-and-component it fdata page (:name media-obj))))))))
|
||||||
|
|
||||||
(defn- process-svg-component
|
(defn- process-svg-component
|
||||||
[svg-data]
|
[svg-data]
|
||||||
(ptk/reify ::process-svg-component
|
(ptk/reify ::process-svg-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file-data (wsh/get-local-file state)
|
|
||||||
page (wsh/lookup-page state)
|
(let [file-id (:current-file-id state)
|
||||||
pos (wsh/viewport-center state)]
|
page-id (:current-page-id state)
|
||||||
(->> (create-shapes-svg (:id file-data) (:objects page) pos svg-data)
|
|
||||||
(rx/map (partial add-shapes-and-component it file-data page (:name svg-data))))))))
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
|
page (dsh/get-page fdata page-id)
|
||||||
|
pos (dsh/get-viewport-center state)]
|
||||||
|
|
||||||
|
(->> (create-shapes-svg file-id (:objects page) pos svg-data)
|
||||||
|
(rx/map (partial add-shapes-and-component it fdata page (:name svg-data))))))))
|
||||||
|
|
||||||
(defn upload-media-components
|
(defn upload-media-components
|
||||||
[params]
|
[params]
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.constants :refer [zoom-half-pixel-precision]]
|
[app.main.constants :refer [zoom-half-pixel-precision]]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.comments :as-alias dwcm]
|
[app.main.data.workspace.comments :as-alias dwcm]
|
||||||
[app.main.data.workspace.guides :as-alias dwg]
|
[app.main.data.workspace.guides :as-alias dwg]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -335,7 +335,7 @@
|
||||||
|
|
||||||
([state ignore-constraints ignore-snap-pixel modif-tree params]
|
([state ignore-constraints ignore-snap-pixel modif-tree params]
|
||||||
(let [objects
|
(let [objects
|
||||||
(wsh/lookup-page-objects state)
|
(dsh/lookup-page-objects state)
|
||||||
|
|
||||||
snap-pixel?
|
snap-pixel?
|
||||||
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
|
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
|
||||||
|
@ -355,7 +355,7 @@
|
||||||
(defn- calculate-update-modifiers
|
(defn- calculate-update-modifiers
|
||||||
[old-modif-tree state ignore-constraints ignore-snap-pixel modif-tree]
|
[old-modif-tree state ignore-constraints ignore-snap-pixel modif-tree]
|
||||||
(let [objects
|
(let [objects
|
||||||
(wsh/lookup-page-objects state)
|
(dsh/lookup-page-objects state)
|
||||||
|
|
||||||
snap-pixel?
|
snap-pixel?
|
||||||
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
|
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
|
||||||
|
@ -421,7 +421,7 @@
|
||||||
(ptk/reify ::set-rotation-modifiers
|
(ptk/reify ::set-rotation-modifiers
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
ids (sequence xf-rotation-shape shapes)
|
ids (sequence xf-rotation-shape shapes)
|
||||||
|
|
||||||
get-modifier
|
get-modifier
|
||||||
|
@ -442,7 +442,7 @@
|
||||||
(ptk/reify ::set-delta-rotation-modifiers
|
(ptk/reify ::set-delta-rotation-modifiers
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
ids
|
ids
|
||||||
(->> shapes
|
(->> shapes
|
||||||
(remove #(get % :blocked false))
|
(remove #(get % :blocked false))
|
||||||
|
@ -473,7 +473,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [text-modifiers (get state :workspace-text-modifier)
|
(let [text-modifiers (get state :workspace-text-modifier)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
object-modifiers
|
object-modifiers
|
||||||
(if (some? modifiers)
|
(if (some? modifiers)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.common :as dc]
|
[app.main.data.common :as dc]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.plugins :as dpl]
|
[app.main.data.plugins :as dpl]
|
||||||
[app.main.data.websocket :as dws]
|
[app.main.data.websocket :as dws]
|
||||||
|
@ -273,7 +274,7 @@
|
||||||
[:file-id ::sm/uuid]
|
[:file-id ::sm/uuid]
|
||||||
[:vern :int]])
|
[:vern :int]])
|
||||||
|
|
||||||
(def ^:private check-file-restore-params!
|
(def ^:private check-file-restore-params
|
||||||
(sm/check-fn schema:handle-file-restore))
|
(sm/check-fn schema:handle-file-restore))
|
||||||
|
|
||||||
(defn handle-file-restore
|
(defn handle-file-restore
|
||||||
|
@ -281,15 +282,17 @@
|
||||||
|
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected valid parameters"
|
"expected valid parameters"
|
||||||
(check-file-restore-params! msg))
|
(check-file-restore-params msg))
|
||||||
|
|
||||||
(ptk/reify ::handle-file-restore
|
(ptk/reify ::handle-file-restore
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [curr-file-id (:current-file-id state)
|
(let [curr-file-id (:current-file-id state)
|
||||||
curr-vern (dm/get-in state [:workspace-file :vern])
|
file (dsh/lookup-file state curr-file-id)
|
||||||
reload? (and (= file-id curr-file-id) (not= vern curr-vern))]
|
curr-vern (:vern file)]
|
||||||
(when reload?
|
|
||||||
|
(when (and (= file-id curr-file-id)
|
||||||
|
(not= vern curr-vern))
|
||||||
(rx/of (ptk/event ::dw/reload-current-file)))))))
|
(rx/of (ptk/event ::dw/reload-current-file)))))))
|
||||||
|
|
||||||
(def ^:private schema:handle-library-change
|
(def ^:private schema:handle-library-change
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.changes-builder :as pcb]
|
[app.common.files.changes-builder :as pcb]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.path.common :refer [check-path-content!]]
|
[app.main.data.workspace.path.common :refer [check-path-content!]]
|
||||||
[app.main.data.workspace.path.helpers :as helpers]
|
[app.main.data.workspace.path.helpers :as helpers]
|
||||||
[app.main.data.workspace.path.state :as st]
|
[app.main.data.workspace.path.state :as st]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
id (get-in state [:workspace-local :edition])
|
id (get-in state [:workspace-local :edition])
|
||||||
old-content (get-in state [:workspace-local :edit-path id :old-content])
|
old-content (get-in state [:workspace-local :edit-path id :old-content])
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.drawing.common :as dwdc]
|
[app.main.data.workspace.drawing.common :as dwdc]
|
||||||
[app.main.data.workspace.edition :as dwe]
|
[app.main.data.workspace.edition :as dwe]
|
||||||
[app.main.data.workspace.path.changes :as changes]
|
[app.main.data.workspace.path.changes :as changes]
|
||||||
|
@ -24,7 +25,6 @@
|
||||||
[app.main.data.workspace.path.streams :as streams]
|
[app.main.data.workspace.path.streams :as streams]
|
||||||
[app.main.data.workspace.path.undo :as undo]
|
[app.main.data.workspace.path.undo :as undo]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -252,7 +252,7 @@
|
||||||
(ptk/reify ::setup-frame
|
(ptk/reify ::setup-frame
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
content (get-in state [:workspace-drawing :object :content] [])
|
content (get-in state [:workspace-drawing :object :content] [])
|
||||||
position (gpt/point (get-in content [0 :params] nil))
|
position (gpt/point (get-in content [0 :params] nil))
|
||||||
frame-id (->> (ctst/top-nested-frame objects position)
|
frame-id (->> (ctst/top-nested-frame objects position)
|
||||||
|
@ -321,11 +321,10 @@
|
||||||
(ptk/reify ::start-draw-mode
|
(ptk/reify ::start-draw-mode
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [id (get-in state [:workspace-local :edition])
|
(let [id (dm/get-in state [:workspace-local :edition])
|
||||||
page-id (:current-page-id state)
|
objects (dsh/lookup-page-objects state)
|
||||||
old-content (get-in state [:workspace-data :pages-index page-id :objects id :content])]
|
content (dm/get-in objects [id :content])]
|
||||||
(-> state
|
(update-in state [:workspace-local :edit-path id] assoc :old-content content)))
|
||||||
(assoc-in [:workspace-local :edit-path id :old-content] old-content))))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
[app.common.svg.path.shapes-to-path :as upsp]
|
[app.common.svg.path.shapes-to-path :as upsp]
|
||||||
[app.common.svg.path.subpath :as ups]
|
[app.common.svg.path.subpath :as ups]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.edition :as dwe]
|
[app.main.data.workspace.edition :as dwe]
|
||||||
[app.main.data.workspace.path.changes :as changes]
|
[app.main.data.workspace.path.changes :as changes]
|
||||||
[app.main.data.workspace.path.drawing :as drawing]
|
[app.main.data.workspace.path.drawing :as drawing]
|
||||||
|
@ -24,7 +25,6 @@
|
||||||
[app.main.data.workspace.path.streams :as streams]
|
[app.main.data.workspace.path.streams :as streams]
|
||||||
[app.main.data.workspace.path.undo :as undo]
|
[app.main.data.workspace.path.undo :as undo]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
[app.util.path.tools :as upt]
|
[app.util.path.tools :as upt]
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
(ptk/reify ::apply-content-modifiers
|
(ptk/reify ::apply-content-modifiers
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
id (st/get-path-id state)
|
id (st/get-path-id state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
|
@ -294,7 +294,7 @@
|
||||||
(ptk/reify ::start-path-edit
|
(ptk/reify ::start-path-edit
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
edit-path (dm/get-in state [:workspace-local :edit-path id])
|
edit-path (dm/get-in state [:workspace-local :edit-path id])
|
||||||
content (st/get-path state :content)
|
content (st/get-path state :content)
|
||||||
state (cond-> state
|
state (cond-> state
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
[app.common.svg.path.shapes-to-path :as upsp]
|
[app.common.svg.path.shapes-to-path :as upsp]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
selected (->> (or ids (wsh/lookup-selected state))
|
selected (->> (or ids (dsh/lookup-selected state))
|
||||||
(remove #(ctn/has-any-copy-parent? objects (get objects %))))
|
(remove #(ctn/has-any-copy-parent? objects (get objects %))))
|
||||||
|
|
||||||
children-ids
|
children-ids
|
||||||
|
|
|
@ -51,22 +51,20 @@
|
||||||
|
|
||||||
(defn get-path-location
|
(defn get-path-location
|
||||||
[state & ks]
|
[state & ks]
|
||||||
(let [edit-id (get-in state [:workspace-local :edition])
|
(if-let [edit-id (dm/get-in state [:workspace-local :edition])]
|
||||||
page-id (:current-page-id state)]
|
(let [page-id (:current-page-id state)
|
||||||
(into (if edit-id
|
file-id (:current-file-id state)]
|
||||||
[:workspace-data :pages-index page-id :objects edit-id]
|
(into [:files file-id :data :pages-index page-id :objects edit-id] ks))
|
||||||
[:workspace-drawing :object])
|
(into [:workspace-drawing :object] ks)))
|
||||||
ks)))
|
|
||||||
|
|
||||||
(defn get-path
|
(defn get-path
|
||||||
"Retrieves the location of the path object and additionally can pass
|
"Retrieves the location of the path object and additionally can pass
|
||||||
the arguments. This location can be used in get-in, assoc-in... functions"
|
the arguments. This location can be used in get-in, assoc-in... functions"
|
||||||
[state & ks]
|
[state & ks]
|
||||||
(let [path-loc (get-path-location state)
|
(let [path-loc (get-path-location state)
|
||||||
shape (-> (get-in state path-loc)
|
shape (-> (get-in state path-loc)
|
||||||
;; Empty map because we know the current shape will not have children
|
;; Empty map because we know the current shape will not have children
|
||||||
(upsp/convert-to-path {}))]
|
(upsp/convert-to-path {}))]
|
||||||
|
|
||||||
(if (empty? ks)
|
(if (empty? ks)
|
||||||
shape
|
shape
|
||||||
(get-in shape ks))))
|
(get-in shape ks))))
|
||||||
|
@ -74,5 +72,4 @@
|
||||||
(defn set-content
|
(defn set-content
|
||||||
[state content]
|
[state content]
|
||||||
(let [path-loc (get-path-location state :content)]
|
(let [path-loc (get-path-location state :content)]
|
||||||
(-> state
|
(assoc-in state path-loc content)))
|
||||||
(assoc-in path-loc content))))
|
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
[app.common.svg.path.shapes-to-path :as upsp]
|
[app.common.svg.path.shapes-to-path :as upsp]
|
||||||
[app.common.svg.path.subpath :as ups]
|
[app.common.svg.path.subpath :as ups]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.edition :as dwe]
|
[app.main.data.workspace.edition :as dwe]
|
||||||
[app.main.data.workspace.path.changes :as changes]
|
[app.main.data.workspace.path.changes :as changes]
|
||||||
[app.main.data.workspace.path.state :as st]
|
[app.main.data.workspace.path.state :as st]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.util.path.tools :as upt]
|
[app.util.path.tools :as upt]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
(ptk/reify ::process-path-tool
|
(ptk/reify ::process-path-tool
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
id (st/get-path-id state)
|
id (st/get-path-id state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
shape (st/get-path state)
|
shape (st/get-path state)
|
||||||
|
|
|
@ -132,8 +132,9 @@
|
||||||
dissoc :undo-lock :undo-stack)))))
|
dissoc :undo-lock :undo-stack)))))
|
||||||
|
|
||||||
(defn- stop-undo? [event]
|
(defn- stop-undo? [event]
|
||||||
(or (= :app.main.data.workspace.common/clear-edition-mode (ptk/type event))
|
(let [type (ptk/type event)]
|
||||||
(= :app.main.data.workspace/finalize-page (ptk/type event))))
|
(or (= :app.main.data.workspace.edition/clear-edition-mode type)
|
||||||
|
(= :app.main.data.workspace/finalize-page type))))
|
||||||
|
|
||||||
(def path-content-ref
|
(def path-content-ref
|
||||||
(letfn [(selector [state]
|
(letfn [(selector [state]
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as md]
|
[app.main.data.modal :as md]
|
||||||
[app.main.data.workspace.collapse :as dwc]
|
[app.main.data.workspace.collapse :as dwc]
|
||||||
[app.main.data.workspace.specialized-panel :as-alias dwsp]
|
[app.main.data.workspace.specialized-panel :as-alias dwsp]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.data.workspace.zoom :as dwz]
|
[app.main.data.workspace.zoom :as dwz]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
|
@ -140,9 +140,9 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected-id (wsh/lookup-selected state)
|
selected-id (dsh/lookup-selected state)
|
||||||
selected (wsh/lookup-shapes state selected-id)
|
selected (dsh/lookup-shapes state selected-id)
|
||||||
frame-ids (map (fn [item] (let [parent (cfh/get-frame objects (:id item))]
|
frame-ids (map (fn [item] (let [parent (cfh/get-frame objects (:id item))]
|
||||||
(:id parent))) selected)
|
(:id parent))) selected)
|
||||||
params-without-board (-> (rt/get-params state)
|
params-without-board (-> (rt/get-params state)
|
||||||
|
@ -162,11 +162,11 @@
|
||||||
(ptk/reify ::select-prev-shape
|
(ptk/reify ::select-prev-shape
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
count-selected (count selected)
|
count-selected (count selected)
|
||||||
first-selected (first selected)
|
first-selected (first selected)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
current (get objects first-selected)
|
current (get objects first-selected)
|
||||||
parent (get objects (:parent-id current))
|
parent (get objects (:parent-id current))
|
||||||
sibling-ids (:shapes parent)
|
sibling-ids (:shapes parent)
|
||||||
|
@ -187,11 +187,11 @@
|
||||||
(ptk/reify ::select-next-shape
|
(ptk/reify ::select-next-shape
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
count-selected (count selected)
|
count-selected (count selected)
|
||||||
first-selected (first selected)
|
first-selected (first selected)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
current (get objects first-selected)
|
current (get objects first-selected)
|
||||||
parent (get objects (:parent-id current))
|
parent (get objects (:parent-id current))
|
||||||
sibling-ids (:shapes parent)
|
sibling-ids (:shapes parent)
|
||||||
|
@ -230,10 +230,10 @@
|
||||||
(rx/of ::dwsp/interrupt))
|
(rx/of ::dwsp/interrupt))
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (or objects (wsh/lookup-page-objects state))
|
(let [objects (or objects (dsh/lookup-page-objects state))
|
||||||
append-to-selection (cfh/expand-region-selection objects (into #{} [(get-in state [:workspace-local :last-selected]) id]))
|
append-to-selection (cfh/expand-region-selection objects (into #{} [(get-in state [:workspace-local :last-selected]) id]))
|
||||||
selection (-> state
|
selection (-> state
|
||||||
wsh/lookup-selected
|
dsh/lookup-selected
|
||||||
(conj id))]
|
(conj id))]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc-in [:workspace-local :selected]
|
(assoc-in [:workspace-local :selected]
|
||||||
|
@ -250,7 +250,7 @@
|
||||||
(ptk/reify ::select-shapes
|
(ptk/reify ::select-shapes
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
focus (:workspace-focus-selected state)
|
focus (:workspace-focus-selected state)
|
||||||
ids (if (d/not-empty? focus)
|
ids (if (d/not-empty? focus)
|
||||||
(cpf/filter-not-focus objects focus ids)
|
(cpf/filter-not-focus objects focus ids)
|
||||||
|
@ -259,7 +259,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)]
|
(let [objects (dsh/lookup-page-objects state)]
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwc/expand-all-parents ids objects)
|
(dwc/expand-all-parents ids objects)
|
||||||
::dwsp/interrupt)))))
|
::dwsp/interrupt)))))
|
||||||
|
@ -273,11 +273,11 @@
|
||||||
;; case delimit the objects to the focused shapes if focus
|
;; case delimit the objects to the focused shapes if focus
|
||||||
;; mode is active
|
;; mode is active
|
||||||
focus (:workspace-focus-selected state)
|
focus (:workspace-focus-selected state)
|
||||||
objects (-> (wsh/lookup-page-objects state)
|
objects (-> (dsh/lookup-page-objects state)
|
||||||
(cpf/focus-objects focus))
|
(cpf/focus-objects focus))
|
||||||
|
|
||||||
lookup (d/getf objects)
|
lookup (d/getf objects)
|
||||||
parents (->> (wsh/lookup-selected state)
|
parents (->> (dsh/lookup-selected state)
|
||||||
(into #{} (comp (keep lookup) (map :parent-id))))
|
(into #{} (comp (keep lookup) (map :parent-id))))
|
||||||
|
|
||||||
;; If we have a only unique parent, then use it as main
|
;; If we have a only unique parent, then use it as main
|
||||||
|
@ -307,6 +307,7 @@
|
||||||
(dissoc :board-id))]
|
(dissoc :board-id))]
|
||||||
(rx/of ::dwsp/interrupt)
|
(rx/of ::dwsp/interrupt)
|
||||||
(rx/of (rt/nav :workspace params-without-board {::rt/replace true}))))
|
(rx/of (rt/nav :workspace params-without-board {::rt/replace true}))))
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
|
||||||
|
@ -329,8 +330,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
initial-set (if preserve?
|
initial-set (if preserve?
|
||||||
selected
|
selected
|
||||||
lks/empty-linked-set)
|
lks/empty-linked-set)
|
||||||
|
@ -363,7 +364,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
group (get objects group-id)
|
group (get objects group-id)
|
||||||
children (map #(get objects %) (:shapes group))
|
children (map #(get objects %) (:shapes group))
|
||||||
|
|
||||||
|
@ -435,7 +436,7 @@
|
||||||
(ptk/reify ::duplicate-shapes
|
(ptk/reify ::duplicate-shapes
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (wsh/lookup-page state)
|
(let [page (dsh/lookup-page state)
|
||||||
objects (:objects page)
|
objects (:objects page)
|
||||||
ids (into #{}
|
ids (into #{}
|
||||||
(comp (map (d/getf objects))
|
(comp (map (d/getf objects))
|
||||||
|
@ -449,8 +450,9 @@
|
||||||
(gpt/point 0 0))
|
(gpt/point 0 0))
|
||||||
|
|
||||||
file-id (:current-file-id state)
|
file-id (:current-file-id state)
|
||||||
libraries (wsh/get-libraries state)
|
|
||||||
library-data (wsh/get-file state file-id)
|
libraries (dsh/lookup-libraries state)
|
||||||
|
library-data (dsh/lookup-file-data state file-id)
|
||||||
|
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(cll/generate-duplicate-changes objects page ids delta libraries library-data file-id)
|
(cll/generate-duplicate-changes objects page ids delta libraries library-data file-id)
|
||||||
|
@ -504,7 +506,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(when (or (not move-delta?) (nil? (get-in state [:workspace-local :transform])))
|
(when (or (not move-delta?) (nil? (get-in state [:workspace-local :transform])))
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/of (duplicate-shapes selected
|
(rx/of (duplicate-shapes selected
|
||||||
:move-delta? move-delta?
|
:move-delta? move-delta?
|
||||||
:alt-duplication? alt-duplication?))))))))
|
:alt-duplication? alt-duplication?))))))))
|
||||||
|
@ -523,7 +525,7 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
focus (-> (:workspace-focus-selected state)
|
focus (-> (:workspace-focus-selected state)
|
||||||
(set/union added)
|
(set/union added)
|
||||||
|
@ -541,7 +543,7 @@
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(cond-> state
|
(cond-> state
|
||||||
(and (empty? (:workspace-focus-selected state))
|
(and (empty? (:workspace-focus-selected state))
|
||||||
(d/not-empty? selected))
|
(d/not-empty? selected))
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.colors :as cl]
|
[app.main.data.workspace.colors :as cl]
|
||||||
[app.main.data.workspace.grid-layout.editor :as dwge]
|
[app.main.data.workspace.grid-layout.editor :as dwge]
|
||||||
[app.main.data.workspace.modifiers :as dwm]
|
[app.main.data.workspace.modifiers :as dwm]
|
||||||
[app.main.data.workspace.selection :as dwse]
|
[app.main.data.workspace.selection :as dwse]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
(ptk/reify ::update-layout-positions
|
(ptk/reify ::update-layout-positions
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
ids (->> ids (filter #(contains? objects %)))]
|
ids (->> ids (filter #(contains? objects %)))]
|
||||||
(if (d/not-empty? ids)
|
(if (d/not-empty? ids)
|
||||||
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
|
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
(ptk/reify ::create-layout-from-id
|
(ptk/reify ::create-layout-from-id
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
parent (get objects id)
|
parent (get objects id)
|
||||||
undo-id (js/Symbol)
|
undo-id (js/Symbol)
|
||||||
layout-initializer (get-layout-initializer type from-frame? calculate-params?)]
|
layout-initializer (get-layout-initializer type from-frame? calculate-params?)]
|
||||||
|
@ -162,8 +162,8 @@
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
selected-shapes (map (d/getf objects) selected)
|
selected-shapes (map (d/getf objects) selected)
|
||||||
single? (= (count selected-shapes) 1)
|
single? (= (count selected-shapes) 1)
|
||||||
has-group? (->> selected-shapes (d/seek cfh/group-shape?))
|
has-group? (->> selected-shapes (d/seek cfh/group-shape?))
|
||||||
|
@ -229,8 +229,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
selected-shapes (map (d/getf objects) selected)
|
selected-shapes (map (d/getf objects) selected)
|
||||||
single? (= (count selected-shapes) 1)
|
single? (= (count selected-shapes) 1)
|
||||||
is-frame? (= :frame (:type (first selected-shapes)))
|
is-frame? (= :frame (:type (first selected-shapes)))
|
||||||
|
@ -248,8 +248,8 @@
|
||||||
(ptk/reify ::toggle-shape-layout
|
(ptk/reify ::toggle-shape-layout
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
selected-shapes (map (d/getf objects) selected)
|
selected-shapes (map (d/getf objects) selected)
|
||||||
single? (= (count selected-shapes) 1)
|
single? (= (count selected-shapes) 1)
|
||||||
has-layout? (and single?
|
has-layout? (and single?
|
||||||
|
@ -300,7 +300,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [undo-id (js/Symbol)]
|
(let [undo-id (js/Symbol)]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
shapes-to-delete
|
shapes-to-delete
|
||||||
(when with-shapes?
|
(when with-shapes?
|
||||||
|
@ -334,10 +334,10 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
page (wsh/lookup-page state)
|
page (dsh/lookup-page state)
|
||||||
objects (:objects page)
|
objects (:objects page)
|
||||||
libraries (wsh/get-libraries state)
|
libraries (dsh/lookup-libraries state)
|
||||||
library-data (wsh/get-file state file-id)
|
library-data (dsh/lookup-file state file-id)
|
||||||
shape-id (first ids)
|
shape-id (first ids)
|
||||||
base-shape (get objects shape-id)
|
base-shape (get objects shape-id)
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@
|
||||||
(ptk/reify ::hover-layout-track
|
(ptk/reify ::hover-layout-track
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects (first ids))
|
shape (get objects (first ids))
|
||||||
|
|
||||||
highlighted
|
highlighted
|
||||||
|
@ -524,7 +524,7 @@
|
||||||
(ptk/reify ::update-layout-child
|
(ptk/reify ::update-layout-child
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
children-ids (->> ids (mapcat #(cfh/get-children-ids objects %)))
|
children-ids (->> ids (mapcat #(cfh/get-children-ids objects %)))
|
||||||
parent-ids (->> ids (map #(cfh/get-parent-id objects %)))
|
parent-ids (->> ids (map #(cfh/get-parent-id objects %)))
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
@ -694,7 +694,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
frame-id (uuid/next)
|
frame-id (uuid/next)
|
||||||
|
|
||||||
undo-id (js/Symbol)
|
undo-id (js/Symbol)
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.comments :as dc]
|
[app.main.data.comments :as dc]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.edition :as dwe]
|
[app.main.data.workspace.edition :as dwe]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (or page-id (:current-page-id state))
|
(let [page-id (or page-id (:current-page-id state))
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
ids (into [] (filter some?) ids)
|
ids (into [] (filter some?) ids)
|
||||||
|
|
||||||
update-layout-ids
|
update-layout-ids
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
|
|
||||||
[shape changes]
|
[shape changes]
|
||||||
(-> (pcb/empty-changes it page-id)
|
(-> (pcb/empty-changes it page-id)
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shapes (->> shapes
|
shapes (->> shapes
|
||||||
(remove #(dm/get-in objects [% :blocked]))
|
(remove #(dm/get-in objects [% :blocked]))
|
||||||
(cfh/order-by-indexed-shapes objects))
|
(cfh/order-by-indexed-shapes objects))
|
||||||
|
@ -169,16 +169,19 @@
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
page-id (or page-id (:current-page-id state))
|
page-id (or page-id (:current-page-id state))
|
||||||
file (wsh/get-file state file-id)
|
|
||||||
page (wsh/lookup-page state page-id)
|
fdata (dsh/lookup-file-data state file-id)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
page (dsh/get-page fdata page-id)
|
||||||
|
objects (:objects page)
|
||||||
|
|
||||||
components-v2 (features/active-feature? state "components/v2")
|
components-v2 (features/active-feature? state "components/v2")
|
||||||
undo-id (or (:undo-id options) (js/Symbol))
|
undo-id (or (:undo-id options) (js/Symbol))
|
||||||
[all-parents changes] (-> (pcb/empty-changes it (:id page))
|
[all-parents changes] (-> (pcb/empty-changes it (:id page))
|
||||||
(cls/generate-delete-shapes file page objects ids {:components-v2 components-v2
|
(cls/generate-delete-shapes fdata page objects ids
|
||||||
:ignore-touched (:component-swap options)
|
{:components-v2 components-v2
|
||||||
:undo-group (:undo-group options)
|
:ignore-touched (:component-swap options)
|
||||||
:undo-id undo-id}))]
|
:undo-group (:undo-group options)
|
||||||
|
:undo-id undo-id}))]
|
||||||
|
|
||||||
(rx/of (dwu/start-undo-transaction undo-id)
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
(dc/detach-comment-thread ids)
|
(dc/detach-comment-thread ids)
|
||||||
|
@ -191,15 +194,15 @@
|
||||||
(ptk/reify ::create-and-add-shape
|
(ptk/reify ::create-and-add-shape
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [vbc (wsh/viewport-center state)
|
(let [vbc (dsh/get-viewport-center state)
|
||||||
x (:x attrs (- (:x vbc) (/ width 2)))
|
x (:x attrs (- (:x vbc) (/ width 2)))
|
||||||
y (:y attrs (- (:y vbc) (/ height 2)))
|
y (:y attrs (- (:y vbc) (/ height 2)))
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
frame-id (-> (wsh/lookup-page-objects state page-id)
|
frame-id (-> (dsh/lookup-page-objects state page-id)
|
||||||
(ctst/top-nested-frame {:x frame-x :y frame-y}))
|
(ctst/top-nested-frame {:x frame-x :y frame-y}))
|
||||||
|
|
||||||
selected (wsh/lookup-selected state)
|
selected (dsh/lookup-selected state)
|
||||||
base (cfh/get-base-shape objects selected)
|
base (cfh/get-base-shape objects selected)
|
||||||
|
|
||||||
parent-id (if (or (and (= 1 (count selected))
|
parent-id (if (or (and (= 1 (count selected))
|
||||||
|
@ -241,8 +244,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (->> (wsh/lookup-selected state)
|
selected (->> (dsh/lookup-selected state)
|
||||||
(cfh/clean-loops objects)
|
(cfh/clean-loops objects)
|
||||||
(remove #(ctn/has-any-copy-parent? objects (get objects %))))
|
(remove #(ctn/has-any-copy-parent? objects (get objects %))))
|
||||||
|
|
||||||
|
@ -291,7 +294,7 @@
|
||||||
(cond-> obj
|
(cond-> obj
|
||||||
(boolean? blocked) (assoc :blocked blocked)
|
(boolean? blocked) (assoc :blocked blocked)
|
||||||
(boolean? hidden) (assoc :hidden hidden)))
|
(boolean? hidden) (assoc :hidden hidden)))
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
;; We have change only the hidden behaviour, to hide only the
|
;; We have change only the hidden behaviour, to hide only the
|
||||||
;; selected shape, block behaviour remains the same.
|
;; selected shape, block behaviour remains the same.
|
||||||
ids (if (boolean? blocked)
|
ids (if (boolean? blocked)
|
||||||
|
@ -304,7 +307,7 @@
|
||||||
(ptk/reify ::toggle-visibility-selected
|
(ptk/reify ::toggle-visibility-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/of (update-shapes selected #(update % :hidden not)))))))
|
(rx/of (update-shapes selected #(update % :hidden not)))))))
|
||||||
|
|
||||||
(defn toggle-lock-selected
|
(defn toggle-lock-selected
|
||||||
|
@ -312,7 +315,7 @@
|
||||||
(ptk/reify ::toggle-lock-selected
|
(ptk/reify ::toggle-lock-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(rx/of (update-shapes selected #(update % :blocked not)))))))
|
(rx/of (update-shapes selected #(update % :blocked not)))))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,8 +326,9 @@
|
||||||
(ptk/reify ::toggle-file-thumbnail-selected
|
(ptk/reify ::toggle-file-thumbnail-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
pages (-> state :workspace-data :pages-index vals)
|
fdata (dsh/lookup-file-data state)
|
||||||
|
pages (-> fdata :pages-index vals)
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
(ns app.main.data.workspace.specialized-panel
|
(ns app.main.data.workspace.specialized-panel
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.common :as-alias dwc]
|
[app.main.data.workspace.common :as-alias dwc]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected-ids (wsh/lookup-selected state)
|
selected-ids (dsh/lookup-selected state)
|
||||||
selected-shapes (map (d/getf objects) selected-ids)]
|
selected-shapes (map (d/getf objects) selected-ids)]
|
||||||
(assoc state :specialized-panel {:type type :shapes selected-shapes})))
|
(assoc state :specialized-panel {:type type :shapes selected-shapes})))
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
|
|
@ -1,168 +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) KALEIDOS INC
|
|
||||||
|
|
||||||
(ns app.main.data.workspace.state-helpers
|
|
||||||
(:require
|
|
||||||
[app.common.data :as d]
|
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.files.helpers :as cfh]
|
|
||||||
[app.common.geom.point :as gpt]
|
|
||||||
[app.common.geom.shapes :as gsh]
|
|
||||||
[app.common.svg.path.command :as upc]
|
|
||||||
[app.common.uuid :as uuid]))
|
|
||||||
|
|
||||||
(defn lookup-page
|
|
||||||
([state]
|
|
||||||
(lookup-page state (:current-page-id state)))
|
|
||||||
([state page-id]
|
|
||||||
(get-in state [:workspace-data :pages-index page-id])))
|
|
||||||
|
|
||||||
(defn lookup-page-objects
|
|
||||||
([state]
|
|
||||||
(lookup-page-objects state (:current-page-id state)))
|
|
||||||
([state page-id]
|
|
||||||
(-> (lookup-page state page-id)
|
|
||||||
(get :objects))))
|
|
||||||
|
|
||||||
(defn lookup-library-objects
|
|
||||||
[state file-id page-id]
|
|
||||||
(dm/get-in state [:libraries file-id :data :pages-index page-id :objects]))
|
|
||||||
|
|
||||||
(defn lookup-objects
|
|
||||||
[state file-id page-id]
|
|
||||||
(let [current-file? (= file-id (:current-file-id state))]
|
|
||||||
(if ^boolean current-file?
|
|
||||||
(lookup-page-objects state page-id)
|
|
||||||
(lookup-library-objects state file-id page-id))))
|
|
||||||
|
|
||||||
(defn lookup-local-components
|
|
||||||
([state]
|
|
||||||
(dm/get-in state [:workspace-data :components])))
|
|
||||||
|
|
||||||
(defn process-selected-shapes
|
|
||||||
([objects selected]
|
|
||||||
(process-selected-shapes objects selected nil))
|
|
||||||
|
|
||||||
([objects selected {:keys [omit-blocked?] :or {omit-blocked? false}}]
|
|
||||||
(letfn [(selectable? [id]
|
|
||||||
(and (contains? objects id)
|
|
||||||
(or (not omit-blocked?)
|
|
||||||
(not (get-in objects [id :blocked] false)))))]
|
|
||||||
(let [selected (->> selected (cfh/clean-loops objects))]
|
|
||||||
(into (d/ordered-set)
|
|
||||||
(filter selectable?)
|
|
||||||
selected)))))
|
|
||||||
|
|
||||||
(defn lookup-selected-raw
|
|
||||||
[state]
|
|
||||||
(dm/get-in state [:workspace-local :selected]))
|
|
||||||
|
|
||||||
(defn lookup-selected
|
|
||||||
([state]
|
|
||||||
(lookup-selected state nil))
|
|
||||||
([state options]
|
|
||||||
(lookup-selected state (:current-page-id state) options))
|
|
||||||
([state page-id options]
|
|
||||||
(let [objects (lookup-page-objects state page-id)
|
|
||||||
selected (dm/get-in state [:workspace-local :selected])]
|
|
||||||
(process-selected-shapes objects selected options))))
|
|
||||||
|
|
||||||
(defn lookup-shape
|
|
||||||
([state id]
|
|
||||||
(lookup-shape state (:current-page-id state) id))
|
|
||||||
|
|
||||||
([state page-id id]
|
|
||||||
(let [objects (lookup-page-objects state page-id)]
|
|
||||||
(get objects id))))
|
|
||||||
|
|
||||||
(defn lookup-shapes
|
|
||||||
([state ids]
|
|
||||||
(lookup-shapes state (:current-page-id state) ids))
|
|
||||||
([state page-id ids]
|
|
||||||
(let [objects (lookup-page-objects state page-id)]
|
|
||||||
(into [] (keep (d/getf objects)) ids))))
|
|
||||||
|
|
||||||
(defn filter-shapes
|
|
||||||
([state filter-fn]
|
|
||||||
(filter-shapes state (:current-page-id state) filter-fn))
|
|
||||||
([state page-id filter-fn]
|
|
||||||
(let [objects (lookup-page-objects state page-id)]
|
|
||||||
(into [] (filter filter-fn) (vals objects)))))
|
|
||||||
|
|
||||||
(defn get-local-file
|
|
||||||
"Get the data content of the file you are currently working with."
|
|
||||||
[state]
|
|
||||||
(get state :workspace-data))
|
|
||||||
|
|
||||||
(defn get-local-file-full
|
|
||||||
[state]
|
|
||||||
(-> (get state :workspace-file)
|
|
||||||
(assoc :data (get state :workspace-data))))
|
|
||||||
|
|
||||||
(defn get-file
|
|
||||||
"Get the data content of the given file (it may be the current file
|
|
||||||
or one library)."
|
|
||||||
[state file-id]
|
|
||||||
(if (= file-id (:current-file-id state))
|
|
||||||
(get state :workspace-data)
|
|
||||||
(dm/get-in state [:libraries file-id :data])))
|
|
||||||
|
|
||||||
(defn get-file-full
|
|
||||||
"Get the data content of the given file (it may be the current file
|
|
||||||
or one library)."
|
|
||||||
[state file-id]
|
|
||||||
(if (= file-id (:current-file-id state))
|
|
||||||
(-> (get state :workspace-file)
|
|
||||||
(assoc :data (get state :workspace-data)))
|
|
||||||
(dm/get-in state [:libraries file-id :data])))
|
|
||||||
|
|
||||||
(defn get-libraries
|
|
||||||
"Retrieve all libraries, including the local file."
|
|
||||||
[state]
|
|
||||||
(let [{:keys [id] :as local} (:workspace-data state)]
|
|
||||||
(-> (:libraries state)
|
|
||||||
(assoc id {:id id
|
|
||||||
:data local}))))
|
|
||||||
|
|
||||||
(defn- set-content-modifiers [state]
|
|
||||||
(fn [id shape]
|
|
||||||
(let [content-modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers])]
|
|
||||||
(if (some? content-modifiers)
|
|
||||||
(update shape :content upc/apply-content-modifiers content-modifiers)
|
|
||||||
shape))))
|
|
||||||
|
|
||||||
(defn select-bool-children
|
|
||||||
[parent-id state]
|
|
||||||
(let [objects (lookup-page-objects state)
|
|
||||||
modifiers (:workspace-modifiers state)
|
|
||||||
children-ids (cfh/get-children-ids objects parent-id)
|
|
||||||
children
|
|
||||||
(-> (select-keys objects children-ids)
|
|
||||||
(update-vals
|
|
||||||
(fn [child]
|
|
||||||
(cond-> child
|
|
||||||
(contains? modifiers (:id child))
|
|
||||||
(gsh/transform-shape (get-in modifiers [(:id child) :modifiers]))))))]
|
|
||||||
|
|
||||||
(as-> children $
|
|
||||||
(d/mapm (set-content-modifiers state) $))))
|
|
||||||
|
|
||||||
(defn viewport-center
|
|
||||||
[state]
|
|
||||||
(let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])]
|
|
||||||
(gpt/point (+ x (/ width 2)) (+ y (/ height 2)))))
|
|
||||||
|
|
||||||
(defn find-orphan-shapes
|
|
||||||
([state]
|
|
||||||
(find-orphan-shapes state (:current-page-id state)))
|
|
||||||
([state page-id]
|
|
||||||
(let [objects (lookup-page-objects state page-id)
|
|
||||||
objects (filter (fn [item]
|
|
||||||
(and
|
|
||||||
(not= (key item) uuid/zero)
|
|
||||||
(not (contains? objects (:parent-id (val item))))))
|
|
||||||
objects)]
|
|
||||||
objects)))
|
|
|
@ -15,8 +15,8 @@
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.util.webapi :as wapi]
|
[app.util.webapi :as wapi]
|
||||||
|
@ -72,8 +72,8 @@
|
||||||
(try
|
(try
|
||||||
(let [id (d/nilv id (uuid/next))
|
(let [id (d/nilv id (uuid/next))
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (if ignore-selection? #{} (wsh/lookup-selected state))
|
selected (if ignore-selection? #{} (dsh/lookup-selected state))
|
||||||
base (cfh/get-base-shape objects selected)
|
base (cfh/get-base-shape objects selected)
|
||||||
|
|
||||||
selected-id (first selected)
|
selected-id (first selected)
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
[app.common.types.modifiers :as ctm]
|
[app.common.types.modifiers :as ctm]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.modifiers :as dwm]
|
[app.main.data.workspace.modifiers :as dwm]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(when (dwc/initialized? state)
|
(when (dwc/initialized? state)
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
editor-state (get-in state [:workspace-editor-state id])
|
editor-state (get-in state [:workspace-editor-state id])
|
||||||
content (-> editor-state
|
content (-> editor-state
|
||||||
|
@ -321,7 +321,7 @@
|
||||||
(ptk/reify ::update-text-range
|
(ptk/reify ::update-text-range
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
|
|
||||||
update-fn
|
update-fn
|
||||||
|
@ -347,7 +347,7 @@
|
||||||
(ptk/reify ::update-root-attrs
|
(ptk/reify ::update-root-attrs
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
|
|
||||||
update-fn
|
update-fn
|
||||||
|
@ -372,7 +372,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(when-not (some? (get-in state [:workspace-editor-state id]))
|
(when-not (some? (get-in state [:workspace-editor-state id]))
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
|
|
||||||
merge-fn (fn [node attrs]
|
merge-fn (fn [node attrs]
|
||||||
|
@ -398,7 +398,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(when-not (some? (get-in state [:workspace-editor-state id]))
|
(when-not (some? (get-in state [:workspace-editor-state id]))
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
update-node? (fn [node]
|
update-node? (fn [node]
|
||||||
(or (txt/is-text-node? node)
|
(or (txt/is-text-node? node)
|
||||||
|
@ -446,9 +446,8 @@
|
||||||
(when (or
|
(when (or
|
||||||
(and (features/active-feature? state "text-editor/v2") (nil? (:workspace-editor state)))
|
(and (features/active-feature? state "text-editor/v2") (nil? (:workspace-editor state)))
|
||||||
(and (not (features/active-feature? state "text-editor/v2")) (nil? (get-in state [:workspace-editor-state id]))))
|
(and (not (features/active-feature? state "text-editor/v2")) (nil? (get-in state [:workspace-editor-state id]))))
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
|
|
||||||
update-node? (some-fn txt/is-text-node? txt/is-paragraph-node?)
|
update-node? (some-fn txt/is-text-node? txt/is-paragraph-node?)
|
||||||
|
|
||||||
shape-ids
|
shape-ids
|
||||||
|
@ -485,8 +484,8 @@
|
||||||
(ptk/reify ::start-edit-if-selected
|
(ptk/reify ::start-edit-if-selected
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (->> state wsh/lookup-selected (mapv #(get objects %)))]
|
selected (->> state dsh/lookup-selected (mapv #(get objects %)))]
|
||||||
(cond-> state
|
(cond-> state
|
||||||
(and (= 1 (count selected))
|
(and (= 1 (count selected))
|
||||||
(= (-> selected first :type) :text))
|
(= (-> selected first :type) :text))
|
||||||
|
@ -501,7 +500,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [props (::resize-text-debounce-props state)
|
(let [props (::resize-text-debounce-props state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
|
||||||
(letfn [(changed-text? [id]
|
(letfn [(changed-text? [id]
|
||||||
|
@ -765,7 +764,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [editor-state (:workspace-editor-state state)
|
(let [editor-state (:workspace-editor-state state)
|
||||||
ids (d/nilv ids (wsh/lookup-selected state))
|
ids (d/nilv ids (dsh/lookup-selected state))
|
||||||
attrs (-> typography
|
attrs (-> typography
|
||||||
(assoc :typography-ref-file file-id)
|
(assoc :typography-ref-file file-id)
|
||||||
(assoc :typography-ref-id (:id typography))
|
(assoc :typography-ref-id (:id typography))
|
||||||
|
@ -794,8 +793,8 @@
|
||||||
(ptk/reify ::add-typography
|
(ptk/reify ::add-typography
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [selected (wsh/lookup-selected state)
|
(let [selected (dsh/lookup-selected state)
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
xform (comp (keep (d/getf objects))
|
xform (comp (keep (d/getf objects))
|
||||||
(filter cfh/text-shape?))
|
(filter cfh/text-shape?))
|
||||||
|
@ -863,7 +862,7 @@
|
||||||
(ptk/reify ::v2-update-text-shape-content
|
(ptk/reify ::v2-update-text-shape-content
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
modifiers (get-in state [:workspace-text-modifier id])
|
modifiers (get-in state [:workspace-text-modifier id])
|
||||||
new-shape? (nil? (:content shape))]
|
new-shape? (nil? (:content shape))]
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
[app.common.thumbnails :as thc]
|
[app.common.thumbnails :as thc]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.persistence :as-alias dps]
|
[app.main.data.persistence :as-alias dps]
|
||||||
[app.main.data.workspace.notifications :as-alias wnt]
|
[app.main.data.workspace.notifications :as-alias wnt]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.rasterizer :as thr]
|
[app.main.rasterizer :as thr]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.render :as render]
|
[app.main.render :as render]
|
||||||
|
@ -65,7 +65,9 @@
|
||||||
[state file-id page-id frame-id tag]
|
[state file-id page-id frame-id tag]
|
||||||
(let [object-id (thc/fmt-object-id file-id page-id frame-id tag)
|
(let [object-id (thc/fmt-object-id file-id page-id frame-id tag)
|
||||||
tp (tp/tpoint-ms)
|
tp (tp/tpoint-ms)
|
||||||
objects (wsh/lookup-objects state file-id page-id)
|
objects (-> (dsh/lookup-file state file-id)
|
||||||
|
(dsh/get-page page-id)
|
||||||
|
:objects)
|
||||||
shape (get objects frame-id)]
|
shape (get objects frame-id)]
|
||||||
|
|
||||||
(->> (render/render-frame objects shape object-id)
|
(->> (render/render-frame objects shape object-id)
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.collapse :as dwc]
|
[app.main.data.workspace.collapse :as dwc]
|
||||||
[app.main.data.workspace.modifiers :as dwm]
|
[app.main.data.workspace.modifiers :as dwm]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
@ -262,7 +262,7 @@
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
focus (:workspace-focus-selected state)
|
focus (:workspace-focus-selected state)
|
||||||
zoom (dm/get-in state [:workspace-local :zoom] 1)
|
zoom (dm/get-in state [:workspace-local :zoom] 1)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shapes (map (d/getf objects) ids)]
|
shapes (map (d/getf objects) ids)]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
|
@ -313,10 +313,9 @@
|
||||||
(ptk/reify ::update-dimensions
|
(ptk/reify ::update-dimensions
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
get-modifier
|
get-modifier
|
||||||
(fn [shape] (ctm/change-dimensions-modifiers shape attr value))
|
(fn [shape] (ctm/change-dimensions-modifiers shape attr value))
|
||||||
|
|
||||||
modif-tree
|
modif-tree
|
||||||
(-> (dwm/build-modif-tree ids objects get-modifier)
|
(-> (dwm/build-modif-tree ids objects get-modifier)
|
||||||
(gm/set-objects-modifiers objects))]
|
(gm/set-objects-modifiers objects))]
|
||||||
|
@ -341,7 +340,7 @@
|
||||||
(ptk/reify ::change-orientation
|
(ptk/reify ::change-orientation
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
|
|
||||||
get-modifier
|
get-modifier
|
||||||
(fn [shape] (ctm/change-orientation-modifiers shape orientation))
|
(fn [shape] (ctm/change-orientation-modifiers shape orientation))
|
||||||
|
@ -408,7 +407,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shapes (->> ids (map #(get objects %)))]
|
shapes (->> ids (map #(get objects %)))]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (dwm/set-delta-rotation-modifiers rotation shapes params))
|
(rx/of (dwm/set-delta-rotation-modifiers rotation shapes params))
|
||||||
|
@ -438,7 +437,7 @@
|
||||||
|
|
||||||
;; We toggle the selection so we don't have to wait for the event
|
;; We toggle the selection so we don't have to wait for the event
|
||||||
selected
|
selected
|
||||||
(cond-> (wsh/lookup-selected state {:omit-blocked? true})
|
(cond-> (dsh/lookup-selected state {:omit-blocked? true})
|
||||||
(some? id)
|
(some? id)
|
||||||
(d/toggle-selection id shift?))]
|
(d/toggle-selection id shift?))]
|
||||||
|
|
||||||
|
@ -502,8 +501,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
selected (dsh/lookup-selected state {:omit-blocked? true})
|
||||||
ids (if (nil? ids) selected ids)
|
ids (if (nil? ids) selected ids)
|
||||||
shapes (into []
|
shapes (into []
|
||||||
(comp (map (d/getf objects))
|
(comp (map (d/getf objects))
|
||||||
|
@ -625,8 +624,8 @@
|
||||||
(ptk/reify ::reorder-layout-child
|
(ptk/reify ::reorder-layout-child
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [selected (wsh/lookup-selected state {:omit-blocked? true})
|
(let [selected (dsh/lookup-selected state {:omit-blocked? true})
|
||||||
objects (wsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
|
|
||||||
get-move-to-index
|
get-move-to-index
|
||||||
|
@ -734,7 +733,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(if (= same-event (get state ::current-move-selected))
|
(if (= same-event (get state ::current-move-selected))
|
||||||
(let [selected (wsh/lookup-selected state {:omit-blocked? true})
|
(let [selected (dsh/lookup-selected state {:omit-blocked? true})
|
||||||
nudge (get-in state [:profile :props :nudge] {:big 10 :small 1})
|
nudge (get-in state [:profile :props :nudge] {:big 10 :small 1})
|
||||||
move-events (->> stream
|
move-events (->> stream
|
||||||
(rx/filter (ptk/type? ::nudge-selected-shapes))
|
(rx/filter (ptk/type? ::nudge-selected-shapes))
|
||||||
|
@ -776,8 +775,8 @@
|
||||||
(ptk/reify ::move-selected
|
(ptk/reify ::move-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
selected (dsh/lookup-selected state {:omit-blocked? true})
|
||||||
selected-shapes (->> selected (map (d/getf objects)))]
|
selected-shapes (->> selected (map (d/getf objects)))]
|
||||||
(if (every? #(and (ctl/any-layout-immediate-child? objects %)
|
(if (every? #(and (ctl/any-layout-immediate-child? objects %)
|
||||||
(not (ctl/position-absolute? %)))
|
(not (ctl/position-absolute? %)))
|
||||||
|
@ -794,7 +793,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
|
|
||||||
;; FIXME: performance rect
|
;; FIXME: performance rect
|
||||||
|
@ -817,7 +816,7 @@
|
||||||
(ptk/reify ::position-shapes
|
(ptk/reify ::position-shapes
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shapes (d/index-by :id shapes)
|
shapes (d/index-by :id shapes)
|
||||||
|
|
||||||
modif-tree
|
modif-tree
|
||||||
|
@ -864,7 +863,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
ids (cleanup-invalid-moving-shapes ids objects frame-id)
|
ids (cleanup-invalid-moving-shapes ids objects frame-id)
|
||||||
changes (cls/generate-relocate (pcb/empty-changes it)
|
changes (cls/generate-relocate (pcb/empty-changes it)
|
||||||
objects
|
objects
|
||||||
|
@ -898,8 +897,8 @@
|
||||||
(ptk/reify ::flip-horizontal-selected
|
(ptk/reify ::flip-horizontal-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (or ids (wsh/lookup-selected state {:omit-blocked? true}))
|
selected (or ids (dsh/lookup-selected state {:omit-blocked? true}))
|
||||||
shapes (map #(get objects %) selected)
|
shapes (map #(get objects %) selected)
|
||||||
selrect (gsh/shapes->rect shapes)
|
selrect (gsh/shapes->rect shapes)
|
||||||
center (grc/rect->center selrect)
|
center (grc/rect->center selrect)
|
||||||
|
@ -913,8 +912,8 @@
|
||||||
(ptk/reify ::flip-vertical-selected
|
(ptk/reify ::flip-vertical-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (or ids (wsh/lookup-selected state {:omit-blocked? true}))
|
selected (or ids (dsh/lookup-selected state {:omit-blocked? true}))
|
||||||
shapes (map #(get objects %) selected)
|
shapes (map #(get objects %) selected)
|
||||||
selrect (gsh/shapes->rect shapes)
|
selrect (gsh/shapes->rect shapes)
|
||||||
center (grc/rect->center selrect)
|
center (grc/rect->center selrect)
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -186,7 +186,7 @@
|
||||||
(ptk/reify ::undo-to-index
|
(ptk/reify ::undo-to-index
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/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) (some? (:object drawing)))
|
(when-not (and (or (some? edition) (some? (:object drawing)))
|
||||||
|
@ -219,7 +219,7 @@
|
||||||
(ptk/reify ::undo
|
(ptk/reify ::undo
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/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)]
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@
|
||||||
(ptk/reify ::redo
|
(ptk/reify ::redo
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/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 (and (or (nil? edition) (ctl/grid-layout? objects edition))
|
(when (and (or (nil? edition) (ctl/grid-layout? objects edition))
|
||||||
|
@ -291,7 +291,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
pages (dm/get-in state [:workspace-data :pages])]
|
pages (-> (dsh/lookup-file-data state)
|
||||||
|
(get :pages))]
|
||||||
(if (contains? pages page-id)
|
(if (contains? pages page-id)
|
||||||
(rx/empty)
|
(rx/empty)
|
||||||
(rx/of (dcm/go-to-workspace :page-id (first pages))))))))
|
(rx/of (dcm/go-to-workspace :page-id (first pages))))))))
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
[app.common.geom.rect :as gpr]
|
[app.common.geom.rect :as gpr]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
(initialize [state local]
|
(initialize [state local]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shapes (cfh/get-immediate-children objects)
|
shapes (cfh/get-immediate-children objects)
|
||||||
srect (gsh/shapes->rect shapes)
|
srect (gsh/shapes->rect shapes)
|
||||||
local (assoc local :vport size :zoom 1 :zoom-inverse 1 :hide-toolbar false)]
|
local (assoc local :vport size :zoom 1 :zoom-inverse 1 :hide-toolbar false)]
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.rect :as grc]
|
[app.common.geom.rect :as grc]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
shapes (cfh/get-immediate-children objects)
|
shapes (cfh/get-immediate-children objects)
|
||||||
srect (gsh/shapes->rect shapes)]
|
srect (gsh/shapes->rect shapes)]
|
||||||
(if (empty? shapes)
|
(if (empty? shapes)
|
||||||
|
@ -101,11 +101,11 @@
|
||||||
(ptk/reify ::zoom-to-selected-shape
|
(ptk/reify ::zoom-to-selected-shape
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [selected (wsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(if (empty? selected)
|
(if (empty? selected)
|
||||||
state
|
state
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
srect (->> selected
|
srect (->> selected
|
||||||
(map #(get objects %))
|
(map #(get objects %))
|
||||||
(gsh/shapes->rect))]
|
(gsh/shapes->rect))]
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
(if (empty? ids)
|
(if (empty? ids)
|
||||||
state
|
state
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
srect (->> ids
|
srect (->> ids
|
||||||
(map #(get objects %))
|
(map #(get objects %))
|
||||||
(gsh/shapes->rect))]
|
(gsh/shapes->rect))]
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.workspace.tokens.token-set :as wtts]
|
[app.main.ui.workspace.tokens.token-set :as wtts]
|
||||||
[okulary.core :as l]))
|
[okulary.core :as l]))
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
(def exception
|
(def exception
|
||||||
(l/derived :exception st/state))
|
(l/derived :exception st/state))
|
||||||
|
|
||||||
(def threads-ref
|
(def threads
|
||||||
(l/derived :comment-threads st/state))
|
(l/derived :comment-threads st/state))
|
||||||
|
|
||||||
(def share-links
|
(def share-links
|
||||||
|
@ -71,13 +71,22 @@
|
||||||
(def files
|
(def files
|
||||||
(l/derived :files st/state))
|
(l/derived :files st/state))
|
||||||
|
|
||||||
|
(def file
|
||||||
|
(l/derived (fn [state]
|
||||||
|
(let [file-id (:current-file-id state)
|
||||||
|
files (:files state)]
|
||||||
|
(get files file-id)))
|
||||||
|
st/state))
|
||||||
|
|
||||||
(def shared-files
|
(def shared-files
|
||||||
"A derived state that points to the current list of shared
|
"A derived state that points to the current list of shared
|
||||||
files (without the content, only summary)"
|
files (without the content, only summary)"
|
||||||
(l/derived :shared-files st/state))
|
(l/derived :shared-files st/state))
|
||||||
|
|
||||||
(def libraries
|
(def libraries
|
||||||
(l/derived :libraries st/state))
|
"A derived state that contanins the currently loaded shared libraries
|
||||||
|
with all its content; including the current file"
|
||||||
|
(l/derived :files st/state))
|
||||||
|
|
||||||
(defn extract-selected-files
|
(defn extract-selected-files
|
||||||
[files selected]
|
[files selected]
|
||||||
|
@ -121,7 +130,7 @@
|
||||||
(def ^:private selected-shapes-data
|
(def ^:private selected-shapes-data
|
||||||
(l/derived
|
(l/derived
|
||||||
(fn [state]
|
(fn [state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
selected (dm/get-in state [:workspace-local :selected])]
|
selected (dm/get-in state [:workspace-local :selected])]
|
||||||
{:objects objects :selected selected}))
|
{:objects objects :selected selected}))
|
||||||
st/state (fn [v1 v2]
|
st/state (fn [v1 v2]
|
||||||
|
@ -131,7 +140,7 @@
|
||||||
(def selected-shapes
|
(def selected-shapes
|
||||||
(l/derived
|
(l/derived
|
||||||
(fn [{:keys [objects selected]}]
|
(fn [{:keys [objects selected]}]
|
||||||
(wsh/process-selected-shapes objects selected))
|
(dsh/process-selected-shapes objects selected))
|
||||||
selected-shapes-data))
|
selected-shapes-data))
|
||||||
|
|
||||||
(defn make-selected-ref
|
(defn make-selected-ref
|
||||||
|
@ -217,20 +226,10 @@
|
||||||
(def rulers?
|
(def rulers?
|
||||||
(l/derived #(contains? % :rulers) workspace-layout))
|
(l/derived #(contains? % :rulers) workspace-layout))
|
||||||
|
|
||||||
(def workspace-file
|
;; FIXME: rename to current-file-data
|
||||||
"A ref to a striped vision of file (without data)."
|
|
||||||
(l/derived (fn [state]
|
|
||||||
(let [file (:workspace-file state)
|
|
||||||
data (:workspace-data state)]
|
|
||||||
(-> file
|
|
||||||
(dissoc :data)
|
|
||||||
;; FIXME: still used in sitemaps but sitemaps
|
|
||||||
;; should declare its own lense for it
|
|
||||||
(assoc :pages (:pages data)))))
|
|
||||||
st/state =))
|
|
||||||
|
|
||||||
(def workspace-data
|
(def workspace-data
|
||||||
(l/derived :workspace-data st/state))
|
"Currently working file data on workspace"
|
||||||
|
(l/derived dsh/lookup-file-data st/state))
|
||||||
|
|
||||||
(def workspace-file-colors
|
(def workspace-file-colors
|
||||||
(l/derived (fn [{:keys [id] :as data}]
|
(l/derived (fn [{:keys [id] :as data}]
|
||||||
|
@ -238,18 +237,19 @@
|
||||||
workspace-data
|
workspace-data
|
||||||
=))
|
=))
|
||||||
|
|
||||||
(def workspace-recent-colors
|
(def recent-colors
|
||||||
|
"Recent colors for the currently selected file"
|
||||||
(l/derived (fn [state]
|
(l/derived (fn [state]
|
||||||
(when-let [file-id (:current-file-id state)]
|
(when-let [file-id (:current-file-id state)]
|
||||||
(dm/get-in state [:recent-colors file-id])))
|
(dm/get-in state [:recent-colors file-id])))
|
||||||
st/state))
|
st/state))
|
||||||
|
|
||||||
;; FIXME: fonts are not prefixed, so the recent font list is shared
|
(def recent-fonts
|
||||||
;; across all teams. This may not be expected behavior
|
"Recent fonts for the currently selected file"
|
||||||
(def workspace-recent-fonts
|
(l/derived (fn [state]
|
||||||
(l/derived (fn [data]
|
(when-let [file-id (:current-file-id state)]
|
||||||
(get data :recent-fonts []))
|
(dm/get-in state [:recent-fonts file-id])))
|
||||||
workspace-data))
|
st/state))
|
||||||
|
|
||||||
(def workspace-file-typography
|
(def workspace-file-typography
|
||||||
(l/derived :typographies workspace-data))
|
(l/derived :typographies workspace-data))
|
||||||
|
@ -258,23 +258,20 @@
|
||||||
(l/derived :workspace-presence st/state))
|
(l/derived :workspace-presence st/state))
|
||||||
|
|
||||||
(def workspace-page
|
(def workspace-page
|
||||||
(l/derived (fn [state]
|
"Ref to currently active page on workspace"
|
||||||
(let [page-id (:current-page-id state)
|
(l/derived dsh/lookup-page st/state))
|
||||||
data (:workspace-data state)]
|
|
||||||
(dm/get-in data [:pages-index page-id])))
|
|
||||||
st/state))
|
|
||||||
|
|
||||||
(def workspace-page-flows
|
(def workspace-page-flows
|
||||||
(l/derived #(-> % :flows not-empty) workspace-page))
|
(l/derived #(-> % :flows not-empty) workspace-page))
|
||||||
|
|
||||||
(defn workspace-page-object-by-id
|
(defn workspace-page-object-by-id
|
||||||
[page-id shape-id]
|
[page-id shape-id]
|
||||||
(l/derived #(wsh/lookup-shape % page-id shape-id) st/state =))
|
(l/derived #(dsh/lookup-shape % page-id shape-id) st/state =))
|
||||||
|
|
||||||
;; TODO: Looks like using the `=` comparator can be pretty expensive
|
;; TODO: Looks like using the `=` comparator can be pretty expensive
|
||||||
;; on large pages, we are using this for some reason?
|
;; on large pages, we are using this for some reason?
|
||||||
(def workspace-page-objects
|
(def workspace-page-objects
|
||||||
(l/derived wsh/lookup-page-objects st/state =))
|
(l/derived dsh/lookup-page-objects st/state =))
|
||||||
|
|
||||||
(def workspace-read-only?
|
(def workspace-read-only?
|
||||||
(l/derived :read-only? workspace-global))
|
(l/derived :read-only? workspace-global))
|
||||||
|
@ -348,7 +345,7 @@
|
||||||
(l/derived
|
(l/derived
|
||||||
(fn [state]
|
(fn [state]
|
||||||
{:modifiers (:workspace-modifiers state)
|
{:modifiers (:workspace-modifiers state)
|
||||||
:objects (wsh/lookup-page-objects state)})
|
:objects (dsh/lookup-page-objects state)})
|
||||||
st/state
|
st/state
|
||||||
(fn [a b]
|
(fn [a b]
|
||||||
(and (= (:modifiers a) (:modifiers b))
|
(and (= (:modifiers a) (:modifiers b))
|
||||||
|
@ -379,11 +376,11 @@
|
||||||
(l/derived #(get % frame-id) workspace-frame-modifiers =))
|
(l/derived #(get % frame-id) workspace-frame-modifiers =))
|
||||||
|
|
||||||
(defn select-bool-children [id]
|
(defn select-bool-children [id]
|
||||||
(l/derived (partial wsh/select-bool-children id) st/state =))
|
(l/derived #(dsh/select-bool-children % id) st/state =))
|
||||||
|
|
||||||
(def selected-data
|
(def selected-data
|
||||||
(l/derived #(let [selected (wsh/lookup-selected %)
|
(l/derived #(let [selected (dsh/lookup-selected %)
|
||||||
objects (wsh/lookup-page-objects %)]
|
objects (dsh/lookup-page-objects %)]
|
||||||
(hash-map :selected selected
|
(hash-map :selected selected
|
||||||
:objects objects))
|
:objects objects))
|
||||||
st/state =))
|
st/state =))
|
||||||
|
@ -415,7 +412,7 @@
|
||||||
[ids]
|
[ids]
|
||||||
(l/derived
|
(l/derived
|
||||||
(fn [state]
|
(fn [state]
|
||||||
(let [objects (wsh/lookup-page-objects state)]
|
(let [objects (dsh/lookup-page-objects state)]
|
||||||
(into []
|
(into []
|
||||||
(comp (map (d/getf objects))
|
(comp (map (d/getf objects))
|
||||||
(filter (partial ctl/flex-layout-immediate-child? objects)))
|
(filter (partial ctl/flex-layout-immediate-child? objects)))
|
||||||
|
|
|
@ -28,7 +28,8 @@
|
||||||
(r/map->Match data))
|
(r/map->Match data))
|
||||||
|
|
||||||
(defn resolve
|
(defn resolve
|
||||||
([router id] (resolve router id {}))
|
([router id]
|
||||||
|
(resolve router id {}))
|
||||||
([router id params]
|
([router id params]
|
||||||
(when router
|
(when router
|
||||||
(when-let [match (r/match-by-name router id)]
|
(when-let [match (r/match-by-name router id)]
|
||||||
|
|
|
@ -37,14 +37,13 @@
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def comments-local-options (l/derived :options refs/comments-local))
|
(def ^:private ref:comments-local-options
|
||||||
|
(l/derived :options refs/comments-local))
|
||||||
|
|
||||||
(def mentions-context (mf/create-context nil))
|
(def mentions-context (mf/create-context nil))
|
||||||
|
|
||||||
(def r-mentions-split #"@\[[^\]]*\]\([^\)]*\)")
|
(def r-mentions-split #"@\[[^\]]*\]\([^\)]*\)")
|
||||||
(def r-mentions #"@\[([^\]]*)\]\(([^\)]*)\)")
|
(def r-mentions #"@\[([^\]]*)\]\(([^\)]*)\)")
|
||||||
|
|
||||||
|
|
||||||
(defn- parse-comment
|
(defn- parse-comment
|
||||||
"Parse a comment into its elements (texts and mentions)"
|
"Parse a comment into its elements (texts and mentions)"
|
||||||
[comment]
|
[comment]
|
||||||
|
@ -58,7 +57,7 @@
|
||||||
:content user
|
:content user
|
||||||
:data {:id id}})))))
|
:data {:id id}})))))
|
||||||
|
|
||||||
(defn parse-nodes
|
(defn- parse-nodes
|
||||||
"Parse the nodes to format a comment"
|
"Parse the nodes to format a comment"
|
||||||
[node]
|
[node]
|
||||||
(->> (dom/get-children node)
|
(->> (dom/get-children node)
|
||||||
|
@ -72,8 +71,7 @@
|
||||||
(.-textContent node))))
|
(.-textContent node))))
|
||||||
(str/join "")))
|
(str/join "")))
|
||||||
|
|
||||||
|
(defn- create-text-node
|
||||||
(defn create-text-node
|
|
||||||
"Creates a text-only node"
|
"Creates a text-only node"
|
||||||
([]
|
([]
|
||||||
(create-text-node ""))
|
(create-text-node ""))
|
||||||
|
@ -82,7 +80,7 @@
|
||||||
(dom/set-data! "type" "text")
|
(dom/set-data! "type" "text")
|
||||||
(dom/set-html! (if (empty? text) "​" text)))))
|
(dom/set-html! (if (empty? text) "​" text)))))
|
||||||
|
|
||||||
(defn create-mention-node
|
(defn- create-mention-node
|
||||||
"Creates a mention node"
|
"Creates a mention node"
|
||||||
[id fullname]
|
[id fullname]
|
||||||
(-> (dom/create-element "span")
|
(-> (dom/create-element "span")
|
||||||
|
@ -91,7 +89,7 @@
|
||||||
(dom/set-data! "fullname" fullname)
|
(dom/set-data! "fullname" fullname)
|
||||||
(obj/set! "textContent" fullname)))
|
(obj/set! "textContent" fullname)))
|
||||||
|
|
||||||
(defn current-text-node
|
(defn- current-text-node
|
||||||
"Retrieves the text node and the offset that the cursor is positioned on"
|
"Retrieves the text node and the offset that the cursor is positioned on"
|
||||||
[node]
|
[node]
|
||||||
|
|
||||||
|
@ -108,7 +106,7 @@
|
||||||
(when (= node container)
|
(when (= node container)
|
||||||
[span-node anchor-offset])))))
|
[span-node anchor-offset])))))
|
||||||
|
|
||||||
(defn absolute-offset
|
(defn- absolute-offset
|
||||||
[node child offset]
|
[node child offset]
|
||||||
(loop [nodes (seq (dom/get-children node))
|
(loop [nodes (seq (dom/get-children node))
|
||||||
acc 0]
|
acc 0]
|
||||||
|
@ -118,7 +116,7 @@
|
||||||
(recur (rest nodes) (+ acc (.-length (.-textContent head)))))
|
(recur (rest nodes) (+ acc (.-length (.-textContent head)))))
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
(defn get-prev-node
|
(defn- get-prev-node
|
||||||
[parent node]
|
[parent node]
|
||||||
(->> (d/with-prev (dom/get-children parent))
|
(->> (d/with-prev (dom/get-children parent))
|
||||||
(d/seek (fn [[it _]] (= node it)))
|
(d/seek (fn [[it _]] (= node it)))
|
||||||
|
@ -126,8 +124,7 @@
|
||||||
|
|
||||||
;; Component that renders the component content
|
;; Component that renders the component content
|
||||||
(mf/defc comment-content*
|
(mf/defc comment-content*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
|
||||||
[{:keys [content]}]
|
[{:keys [content]}]
|
||||||
(let [comment-elements (mf/use-memo (mf/deps content) #(parse-comment content))]
|
(let [comment-elements (mf/use-memo (mf/deps content) #(parse-comment content))]
|
||||||
(for [[idx {:keys [type content]}] (d/enumerate comment-elements)]
|
(for [[idx {:keys [type content]}] (d/enumerate comment-elements)]
|
||||||
|
@ -141,22 +138,20 @@
|
||||||
|
|
||||||
;; Input text for comments with mentions
|
;; Input text for comments with mentions
|
||||||
(mf/defc comment-input*
|
(mf/defc comment-input*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true
|
[{:keys [value placeholder max-length autofocus on-focus on-blur on-change on-esc on-ctrl-enter]}]
|
||||||
::mf/wrap-props false}
|
|
||||||
[{:keys [value placeholder max-length autofocus? on-focus on-blur on-change on-esc on-ctrl-enter]}]
|
|
||||||
|
|
||||||
(let [value (d/nilv value "")
|
(let [value (d/nilv value "")
|
||||||
prev-value (h/use-previous value)
|
prev-value (h/use-previous value)
|
||||||
|
|
||||||
local-ref (mf/use-ref nil)
|
local-ref (mf/use-ref nil)
|
||||||
mentions-str (mf/use-ctx mentions-context)
|
mentions-s (mf/use-ctx mentions-context)
|
||||||
cur-mention (mf/use-var nil)
|
cur-mention (mf/use-var nil)
|
||||||
|
|
||||||
prev-selection (mf/use-var nil)
|
prev-selection (mf/use-var nil)
|
||||||
|
|
||||||
init-input
|
init-input
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(fn [node]
|
(fn [node]
|
||||||
(mf/set-ref-val! local-ref node)
|
(mf/set-ref-val! local-ref node)
|
||||||
(when node
|
(when node
|
||||||
|
@ -167,13 +162,13 @@
|
||||||
nil)))))
|
nil)))))
|
||||||
|
|
||||||
handle-input
|
handle-input
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(mf/deps on-change)
|
(mf/deps on-change)
|
||||||
(fn []
|
(fn []
|
||||||
(let [node (mf/ref-val local-ref)
|
(let [node (mf/ref-val local-ref)
|
||||||
children (dom/get-children node)]
|
children (dom/get-children node)]
|
||||||
|
|
||||||
(doseq [child-node children]
|
(doseq [^js child-node children]
|
||||||
;; Remove nodes that are not span. This can happen if the user copy/pastes
|
;; Remove nodes that are not span. This can happen if the user copy/pastes
|
||||||
(when (not= (.-tagName child-node) "SPAN")
|
(when (not= (.-tagName child-node) "SPAN")
|
||||||
(.remove child-node))
|
(.remove child-node))
|
||||||
|
@ -198,7 +193,7 @@
|
||||||
(on-change new-input))))))
|
(on-change new-input))))))
|
||||||
|
|
||||||
handle-select
|
handle-select
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(fn []
|
(fn []
|
||||||
(let [node (mf/ref-val local-ref)
|
(let [node (mf/ref-val local-ref)
|
||||||
selection (wapi/get-selection)
|
selection (wapi/get-selection)
|
||||||
|
@ -240,16 +235,16 @@
|
||||||
(if (re-matches #"@\w*" mention-text)
|
(if (re-matches #"@\w*" mention-text)
|
||||||
(do
|
(do
|
||||||
(reset! cur-mention mention-text)
|
(reset! cur-mention mention-text)
|
||||||
(rx/push! mentions-str {:type :display-mentions})
|
(rx/push! mentions-s {:type :display-mentions})
|
||||||
(let [mention (subs mention-text 1)]
|
(let [mention (subs mention-text 1)]
|
||||||
(when (d/not-empty? mention)
|
(when (d/not-empty? mention)
|
||||||
(rx/push! mentions-str {:type :filter-mentions :data mention}))))
|
(rx/push! mentions-s {:type :filter-mentions :data mention}))))
|
||||||
(do
|
(do
|
||||||
(reset! cur-mention nil)
|
(reset! cur-mention nil)
|
||||||
(rx/push! mentions-str {:type :hide-mentions}))))))))
|
(rx/push! mentions-s {:type :hide-mentions}))))))))
|
||||||
|
|
||||||
handle-focus
|
handle-focus
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(dom/set-css-property! (mf/ref-val local-ref) "--placeholder" "")
|
(dom/set-css-property! (mf/ref-val local-ref) "--placeholder" "")
|
||||||
|
@ -257,7 +252,7 @@
|
||||||
(on-focus event))))
|
(on-focus event))))
|
||||||
|
|
||||||
handle-blur
|
handle-blur
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(mf/deps value)
|
(mf/deps value)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (empty? value)
|
(when (empty? value)
|
||||||
|
@ -268,38 +263,40 @@
|
||||||
(on-blur event))))
|
(on-blur event))))
|
||||||
|
|
||||||
handle-insert-mention
|
handle-insert-mention
|
||||||
(fn [data]
|
(mf/use-fn
|
||||||
(let [node (mf/ref-val local-ref)
|
(mf/deps on-change)
|
||||||
[span-node offset] (current-text-node node)]
|
(fn [data]
|
||||||
(when span-node
|
(let [node (mf/ref-val local-ref)
|
||||||
(let [node-text
|
[span-node offset] (current-text-node node)]
|
||||||
(dom/get-text span-node)
|
(when span-node
|
||||||
|
(let [node-text
|
||||||
|
(dom/get-text span-node)
|
||||||
|
|
||||||
current-at-symbol
|
current-at-symbol
|
||||||
(or (str/last-index-of (subs node-text 0 offset) "@")
|
(or (str/last-index-of (subs node-text 0 offset) "@")
|
||||||
(absolute-offset node span-node offset))
|
(absolute-offset node span-node offset))
|
||||||
|
|
||||||
mention
|
mention
|
||||||
(re-find #"@\w*" (subs node-text current-at-symbol))
|
(re-find #"@\w*" (subs node-text current-at-symbol))
|
||||||
|
|
||||||
prefix
|
prefix
|
||||||
(subs node-text 0 current-at-symbol)
|
(subs node-text 0 current-at-symbol)
|
||||||
|
|
||||||
suffix
|
suffix
|
||||||
(subs node-text (+ current-at-symbol (count mention)))
|
(subs node-text (+ current-at-symbol (count mention)))
|
||||||
|
|
||||||
mention-span (create-mention-node (-> data :user :id) (-> data :user :fullname))
|
mention-span (create-mention-node (-> data :user :id) (-> data :user :fullname))
|
||||||
after-span (create-text-node (dm/str " " suffix))
|
after-span (create-text-node (dm/str " " suffix))
|
||||||
sel (wapi/get-selection)]
|
sel (wapi/get-selection)]
|
||||||
|
|
||||||
(dom/set-html! span-node (if (empty? prefix) "​" prefix))
|
(dom/set-html! span-node (if (empty? prefix) "​" prefix))
|
||||||
(dom/insert-after! node span-node mention-span)
|
(dom/insert-after! node span-node mention-span)
|
||||||
(dom/insert-after! node mention-span after-span)
|
(dom/insert-after! node mention-span after-span)
|
||||||
(wapi/set-cursor-after! after-span)
|
(wapi/set-cursor-after! after-span)
|
||||||
(wapi/collapse-end! sel)
|
(wapi/collapse-end! sel)
|
||||||
|
|
||||||
(when on-change
|
(when (fn? on-change)
|
||||||
(on-change (parse-nodes node)))))))
|
(on-change (parse-nodes node))))))))
|
||||||
|
|
||||||
handle-key-down
|
handle-key-down
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -314,22 +311,22 @@
|
||||||
(and @cur-mention (kbd/enter? event))
|
(and @cur-mention (kbd/enter? event))
|
||||||
(do (dom/prevent-default event)
|
(do (dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(rx/push! mentions-str {:type :insert-selected-mention}))
|
(rx/push! mentions-s {:type :insert-selected-mention}))
|
||||||
|
|
||||||
(and @cur-mention (kbd/down-arrow? event))
|
(and @cur-mention (kbd/down-arrow? event))
|
||||||
(do (dom/prevent-default event)
|
(do (dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(rx/push! mentions-str {:type :insert-next-mention}))
|
(rx/push! mentions-s {:type :insert-next-mention}))
|
||||||
|
|
||||||
(and @cur-mention (kbd/up-arrow? event))
|
(and @cur-mention (kbd/up-arrow? event))
|
||||||
(do (dom/prevent-default event)
|
(do (dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(rx/push! mentions-str {:type :insert-prev-mention}))
|
(rx/push! mentions-s {:type :insert-prev-mention}))
|
||||||
|
|
||||||
(and @cur-mention (kbd/esc? event))
|
(and @cur-mention (kbd/esc? event))
|
||||||
(do (dom/prevent-default event)
|
(do (dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(rx/push! mentions-str {:type :hide-mentions}))
|
(rx/push! mentions-s {:type :hide-mentions}))
|
||||||
|
|
||||||
(and (kbd/esc? event) (fn? on-esc))
|
(and (kbd/esc? event) (fn? on-esc))
|
||||||
(on-esc event)
|
(on-esc event)
|
||||||
|
@ -362,56 +359,49 @@
|
||||||
(.remove prev-node)))))))]
|
(.remove prev-node)))))))]
|
||||||
|
|
||||||
(mf/use-layout-effect
|
(mf/use-layout-effect
|
||||||
(mf/deps autofocus?)
|
(mf/deps autofocus)
|
||||||
(fn []
|
(fn []
|
||||||
(when autofocus?
|
(when autofocus
|
||||||
(dom/focus! (mf/ref-val local-ref)))))
|
(dom/focus! (mf/ref-val local-ref)))))
|
||||||
|
|
||||||
;; Creates the handlers for selection
|
;; Creates the handlers for selection
|
||||||
(mf/use-effect
|
(mf/with-effect [handle-select]
|
||||||
(mf/deps handle-select)
|
(let [handle-select* handle-select]
|
||||||
(fn []
|
(js/document.addEventListener "selectionchange" handle-select*)
|
||||||
(let [handle-select* handle-select]
|
#(js/document.removeEventListener "selectionchange" handle-select*)))
|
||||||
(js/document.addEventListener "selectionchange" handle-select*)
|
|
||||||
#(js/document.removeEventListener "selectionchange" handle-select*))))
|
|
||||||
|
|
||||||
;; Effect to communicate with the mentions panel
|
;; Effect to communicate with the mentions panel
|
||||||
(mf/use-effect
|
(mf/with-effect []
|
||||||
(fn []
|
(when mentions-s
|
||||||
(when mentions-str
|
(->> mentions-s
|
||||||
(->> mentions-str
|
(rx/subs!
|
||||||
(rx/subs!
|
(fn [{:keys [type data]}]
|
||||||
(fn [{:keys [type data]}]
|
(case type
|
||||||
(case type
|
:insert-mention
|
||||||
:insert-mention
|
(handle-insert-mention data)
|
||||||
(handle-insert-mention data)
|
|
||||||
|
|
||||||
nil)))))))
|
nil))))))
|
||||||
|
|
||||||
;; Auto resize input to display the comment
|
;; Auto resize input to display the comment
|
||||||
(mf/use-layout-effect
|
(mf/with-layout-effect nil
|
||||||
nil
|
(let [^js node (mf/ref-val local-ref)]
|
||||||
(fn []
|
(set! (.-height (.-style node)) "0")
|
||||||
(let [node (mf/ref-val local-ref)]
|
(set! (.-height (.-style node)) (str (+ 2 (.-scrollHeight node)) "px"))))
|
||||||
(set! (.-height (.-style node)) "0")
|
|
||||||
(set! (.-height (.-style node)) (str (+ 2 (.-scrollHeight node)) "px")))))
|
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/with-effect [value prev-value]
|
||||||
(mf/deps value prev-value)
|
(let [node (mf/ref-val local-ref)]
|
||||||
(fn []
|
(cond
|
||||||
(let [node (mf/ref-val local-ref)]
|
(and (d/not-empty? prev-value) (empty? value))
|
||||||
(cond
|
(do (dom/set-html! node "")
|
||||||
(and (d/not-empty? prev-value) (empty? value))
|
(dom/append-child! node (create-text-node))
|
||||||
(do (dom/set-html! node "")
|
(dom/set-css-property! node "--placeholder" "")
|
||||||
(dom/append-child! node (create-text-node))
|
(dom/focus! node))
|
||||||
(dom/set-css-property! node "--placeholder" "")
|
|
||||||
(dom/focus! node))
|
|
||||||
|
|
||||||
(and (some? node) (empty? value) (not (dom/focus? node)))
|
(and (some? node) (empty? value) (not (dom/focus? node)))
|
||||||
(dom/set-css-property! node "--placeholder" (dm/str "\"" placeholder "\""))
|
(dom/set-css-property! node "--placeholder" (dm/str "\"" placeholder "\""))
|
||||||
|
|
||||||
(some? node)
|
(some? node)
|
||||||
(dom/set-css-property! node "--placeholder" "")))))
|
(dom/set-css-property! node "--placeholder" ""))))
|
||||||
|
|
||||||
[:div
|
[:div
|
||||||
{:role "textbox"
|
{:role "textbox"
|
||||||
|
@ -425,84 +415,82 @@
|
||||||
:on-blur handle-blur}]))
|
:on-blur handle-blur}]))
|
||||||
|
|
||||||
(mf/defc mentions-panel*
|
(mf/defc mentions-panel*
|
||||||
{::mf/props :obj
|
[]
|
||||||
::mf/private true}
|
(let [mentions-s (mf/use-ctx mentions-context)
|
||||||
[{:keys [profiles]}]
|
profile (mf/deref refs/profile)
|
||||||
|
profiles (mf/deref refs/profiles)
|
||||||
|
|
||||||
(let [mentions-str (mf/use-ctx mentions-context)
|
state*
|
||||||
|
(mf/use-state
|
||||||
|
#(do {:display false
|
||||||
|
:mention-filter ""
|
||||||
|
:selected 0}))
|
||||||
|
|
||||||
profile (mf/deref refs/profile)
|
{:keys [display mention-filter selected]}
|
||||||
|
(deref state*)
|
||||||
mention-state
|
|
||||||
(mf/use-state {:display? false
|
|
||||||
:mention-filter ""
|
|
||||||
:selected 0})
|
|
||||||
|
|
||||||
{:keys [display? mention-filter selected]} @mention-state
|
|
||||||
|
|
||||||
mentions-users
|
mentions-users
|
||||||
(mf/use-memo
|
(mf/with-memo [mention-filter]
|
||||||
(mf/deps mention-filter)
|
|
||||||
#(->> (vals profiles)
|
|
||||||
(filter
|
(->> (vals profiles)
|
||||||
(fn [{:keys [id fullname email]}]
|
(filter (fn [{:keys [id fullname email]}]
|
||||||
(and
|
(and
|
||||||
(not= id (:id profile))
|
(not= id (:id profile))
|
||||||
(or (not mention-filter)
|
(or (not mention-filter)
|
||||||
(empty? mention-filter)
|
(empty? mention-filter)
|
||||||
(str/includes? (str/lower fullname) (str/lower mention-filter))
|
(str/includes? (str/lower fullname) (str/lower mention-filter))
|
||||||
(str/includes? (str/lower email) (str/lower mention-filter))))))
|
(str/includes? (str/lower email) (str/lower mention-filter))))))
|
||||||
(take 4)
|
(take 4)
|
||||||
(into [])))
|
(into [])))
|
||||||
|
|
||||||
selected (mth/clamp selected 0 (dec (count mentions-users)))
|
selected
|
||||||
|
(mth/clamp selected 0 (dec (count mentions-users)))
|
||||||
|
|
||||||
handle-click-mention
|
handle-click-mention
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(let [id (-> (dom/get-current-target event)
|
(let [id (-> (dom/get-current-target event)
|
||||||
(dom/get-data "user-id")
|
(dom/get-data "user-id")
|
||||||
(uuid/uuid))]
|
(uuid/uuid))]
|
||||||
(rx/push! mentions-str {:type :insert-mention
|
(rx/push! mentions-s {:type :insert-mention
|
||||||
:data {:user (get profiles id)}}))))]
|
:data {:user (get profiles id)}}))))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/with-effect [mentions-users selected]
|
||||||
(mf/deps mentions-users selected)
|
(let [sub
|
||||||
(fn []
|
(->> mentions-s
|
||||||
(let [sub
|
(rx/subs!
|
||||||
(->> mentions-str
|
(fn [{:keys [type data]}]
|
||||||
(rx/subs!
|
(case type
|
||||||
(fn [{:keys [type data]}]
|
;; Display the mentions dialog
|
||||||
(case type
|
:display-mentions
|
||||||
;; Display the mentions dialog
|
(swap! state* assoc :display true)
|
||||||
:display-mentions
|
|
||||||
(swap! mention-state assoc :display? true)
|
|
||||||
|
|
||||||
;; Hide mentions
|
;; Hide mentions
|
||||||
:hide-mentions
|
:hide-mentions
|
||||||
(swap! mention-state assoc :display? false :mention-filter "")
|
(swap! state* assoc :display false :mention-filter "")
|
||||||
|
|
||||||
;; Filter the metions by some characters
|
;; Filter the metions by some characters
|
||||||
:filter-mentions
|
:filter-mentions
|
||||||
(swap! mention-state assoc :mention-filter data)
|
(swap! state* assoc :mention-filter data)
|
||||||
|
|
||||||
:insert-selected-mention
|
:insert-selected-mention
|
||||||
(rx/push! mentions-str {:type :insert-mention
|
(rx/push! mentions-s {:type :insert-mention
|
||||||
:data {:user (get mentions-users selected)}})
|
:data {:user (get mentions-users selected)}})
|
||||||
|
|
||||||
:insert-next-mention
|
:insert-next-mention
|
||||||
(swap! mention-state update :selected #(mth/clamp (inc %) 0 (dec (count mentions-users))))
|
(swap! state* update :selected #(mth/clamp (inc %) 0 (dec (count mentions-users))))
|
||||||
|
|
||||||
:insert-prev-mention
|
:insert-prev-mention
|
||||||
(swap! mention-state update :selected #(mth/clamp (dec %) 0 (dec (count mentions-users))))
|
(swap! state* update :selected #(mth/clamp (dec %) 0 (dec (count mentions-users))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
nil))))]
|
nil))))]
|
||||||
#(rx/dispose! sub))))
|
#(rx/dispose! sub)))
|
||||||
|
|
||||||
(when display?
|
(when ^boolean display
|
||||||
[:div {:class (stl/css :comments-mentions-choice)}
|
[:div {:class (stl/css :comments-mentions-choice)}
|
||||||
(if (empty? mentions-users)
|
(if (empty? mentions-users)
|
||||||
[:div {:class (stl/css :comments-mentions-empty)}
|
[:div {:class (stl/css :comments-mentions-empty)}
|
||||||
|
@ -523,15 +511,15 @@
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/private true}
|
::mf/private true}
|
||||||
[]
|
[]
|
||||||
(let [mentions-str (mf/use-ctx mentions-context)
|
(let [mentions-s (mf/use-ctx mentions-context)
|
||||||
display-mentions* (mf/use-state false)
|
display-mentions* (mf/use-state false)
|
||||||
|
|
||||||
handle-mouse-down
|
handle-mouse-down
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(rx/push! mentions-str {:type :display-mentions})))]
|
(rx/push! mentions-s {:type :display-mentions})))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -542,7 +530,7 @@
|
||||||
:display-mentions (reset! display-mentions* true)
|
:display-mentions (reset! display-mentions* true)
|
||||||
:hide-mentions (reset! display-mentions* false)
|
:hide-mentions (reset! display-mentions* false)
|
||||||
nil))
|
nil))
|
||||||
mentions-str)]
|
mentions-s)]
|
||||||
#(rx/dispose! sub))))
|
#(rx/dispose! sub))))
|
||||||
|
|
||||||
[:> icon-button*
|
[:> icon-button*
|
||||||
|
@ -561,8 +549,7 @@
|
||||||
[:maybe [:enum "read" "unread" "solved"]]]])
|
[:maybe [:enum "read" "unread" "solved"]]]])
|
||||||
|
|
||||||
(mf/defc comment-avatar*
|
(mf/defc comment-avatar*
|
||||||
{::mf/props :obj
|
{::mf/schema schema:comment-avatar}
|
||||||
::mf/schema schema:comment-avatar}
|
|
||||||
[{:keys [image variant class] :rest props}]
|
[{:keys [image variant class] :rest props}]
|
||||||
(let [variant (or variant "read")
|
(let [variant (or variant "read")
|
||||||
class (dm/str class " " (stl/css-case :avatar true
|
class (dm/str class " " (stl/css-case :avatar true
|
||||||
|
@ -577,8 +564,7 @@
|
||||||
:avatar-darken (= variant "solved"))}]]))
|
:avatar-darken (= variant "solved"))}]]))
|
||||||
|
|
||||||
(mf/defc comment-info*
|
(mf/defc comment-info*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
|
||||||
[{:keys [item profile]}]
|
[{:keys [item profile]}]
|
||||||
[:*
|
[:*
|
||||||
[:div {:class (stl/css :author)}
|
[:div {:class (stl/css :author)}
|
||||||
|
@ -642,11 +628,12 @@
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dcm/add-comment thread @content))
|
(st/emit! (dcm/add-comment thread @content))
|
||||||
(on-cancel)))]
|
(on-cancel)))]
|
||||||
|
|
||||||
[:div {:class (stl/css :form)}
|
[:div {:class (stl/css :form)}
|
||||||
[:> comment-input*
|
[:> comment-input*
|
||||||
{:value @content
|
{:value @content
|
||||||
:placeholder (tr "labels.reply.thread")
|
:placeholder (tr "labels.reply.thread")
|
||||||
:autofocus? true
|
:autofocus true
|
||||||
:on-blur on-blur
|
:on-blur on-blur
|
||||||
:on-focus on-focus
|
:on-focus on-focus
|
||||||
:on-ctrl-enter on-submit
|
:on-ctrl-enter on-submit
|
||||||
|
@ -664,8 +651,7 @@
|
||||||
(tr "labels.post")]])]))
|
(tr "labels.post")]])]))
|
||||||
|
|
||||||
(mf/defc comment-edit-form*
|
(mf/defc comment-edit-form*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
|
||||||
[{:keys [content on-submit on-cancel]}]
|
[{:keys [content on-submit on-cancel]}]
|
||||||
(let [content (mf/use-state content)
|
(let [content (mf/use-state content)
|
||||||
|
|
||||||
|
@ -684,7 +670,7 @@
|
||||||
[:div {:class (stl/css :form)}
|
[:div {:class (stl/css :form)}
|
||||||
[:> comment-input*
|
[:> comment-input*
|
||||||
{:value @content
|
{:value @content
|
||||||
:autofocus? true
|
:autofocus true
|
||||||
:on-ctrl-enter on-submit*
|
:on-ctrl-enter on-submit*
|
||||||
:on-change on-change
|
:on-change on-change
|
||||||
:max-length 750}]
|
:max-length 750}]
|
||||||
|
@ -699,11 +685,10 @@
|
||||||
(tr "labels.post")]]]))
|
(tr "labels.post")]]]))
|
||||||
|
|
||||||
(mf/defc comment-floating-thread-draft*
|
(mf/defc comment-floating-thread-draft*
|
||||||
{::mf/props :obj}
|
[{:keys [draft zoom on-cancel on-submit position-modifier]}]
|
||||||
[{:keys [draft zoom on-cancel on-submit position-modifier profiles]}]
|
|
||||||
(let [profile (mf/deref refs/profile)
|
(let [profile (mf/deref refs/profile)
|
||||||
|
|
||||||
mentions-str (mf/use-memo #(rx/subject))
|
mentions-s (mf/use-memo #(rx/subject))
|
||||||
|
|
||||||
position (cond-> (:position draft)
|
position (cond-> (:position draft)
|
||||||
(some? position-modifier)
|
(some? position-modifier)
|
||||||
|
@ -736,7 +721,7 @@
|
||||||
(mf/deps draft)
|
(mf/deps draft)
|
||||||
(partial on-submit draft))]
|
(partial on-submit draft))]
|
||||||
|
|
||||||
[:> (mf/provider mentions-context) {:value mentions-str}
|
[:> (mf/provider mentions-context) {:value mentions-s}
|
||||||
[:div
|
[:div
|
||||||
{:class (stl/css :floating-preview-wrapper)
|
{:class (stl/css :floating-preview-wrapper)
|
||||||
:data-testid "floating-thread-bubble"
|
:data-testid "floating-thread-bubble"
|
||||||
|
@ -753,7 +738,7 @@
|
||||||
[:> comment-input*
|
[:> comment-input*
|
||||||
{:placeholder (tr "labels.write-new-comment")
|
{:placeholder (tr "labels.write-new-comment")
|
||||||
:value (or content "")
|
:value (or content "")
|
||||||
:autofocus? true
|
:autofocus true
|
||||||
:on-esc on-esc
|
:on-esc on-esc
|
||||||
:on-change on-change
|
:on-change on-change
|
||||||
:on-ctrl-enter on-submit
|
:on-ctrl-enter on-submit
|
||||||
|
@ -769,15 +754,14 @@
|
||||||
:disabled disabled?}
|
:disabled disabled?}
|
||||||
(tr "labels.post")]]]
|
(tr "labels.post")]]]
|
||||||
|
|
||||||
[:> mentions-panel* {:profiles profiles}]]]))
|
[:> mentions-panel*]]]))
|
||||||
|
|
||||||
(mf/defc comment-floating-thread-header*
|
(mf/defc comment-floating-thread-header*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
[{:keys [thread origin]}]
|
||||||
[{:keys [profiles thread origin]}]
|
(let [owner (dcm/get-owner thread)
|
||||||
(let [owner (get profiles (:owner-id thread))
|
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
options (mf/deref comments-local-options)
|
options (mf/deref ref:comments-local-options)
|
||||||
|
|
||||||
toggle-resolved
|
toggle-resolved
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -842,12 +826,11 @@
|
||||||
(tr "labels.delete-comment-thread")]]]]))
|
(tr "labels.delete-comment-thread")]]]]))
|
||||||
|
|
||||||
(mf/defc comment-floating-thread-item*
|
(mf/defc comment-floating-thread-item*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
[{:keys [comment thread]}]
|
||||||
[{:keys [comment thread profiles]}]
|
(let [owner (dcm/get-owner comment)
|
||||||
(let [owner (get profiles (:owner-id comment))
|
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
options (mf/deref comments-local-options)
|
options (mf/deref ref:comments-local-options)
|
||||||
edition? (mf/use-state false)
|
edition? (mf/use-state false)
|
||||||
|
|
||||||
on-toggle-options
|
on-toggle-options
|
||||||
|
@ -925,8 +908,8 @@
|
||||||
|
|
||||||
(defn- offset-position [position viewport zoom bubble-margin]
|
(defn- offset-position [position viewport zoom bubble-margin]
|
||||||
(let [viewport (or viewport {:offset-x 0 :offset-y 0 :width 0 :height 0})
|
(let [viewport (or viewport {:offset-x 0 :offset-y 0 :width 0 :height 0})
|
||||||
base-x (+ (* (:x position) zoom) (:offset-x viewport))
|
base-x (+ (* (:x position) zoom) (:offset-x viewport))
|
||||||
base-y (+ (* (:y position) zoom) (:offset-y viewport))
|
base-y (+ (* (:y position) zoom) (:offset-y viewport))
|
||||||
|
|
||||||
x (:x position)
|
x (:x position)
|
||||||
y (:y position)
|
y (:y position)
|
||||||
|
@ -945,11 +928,10 @@
|
||||||
{:x x :y y :h-dir h-dir :v-dir v-dir}))
|
{:x x :y y :h-dir h-dir :v-dir v-dir}))
|
||||||
|
|
||||||
(mf/defc comment-floating-thread*
|
(mf/defc comment-floating-thread*
|
||||||
{::mf/props :obj
|
{::mf/wrap [mf/memo]}
|
||||||
::mf/wrap [mf/memo]}
|
[{:keys [thread zoom origin position-modifier viewport]}]
|
||||||
[{:keys [thread zoom profiles origin position-modifier viewport]}]
|
|
||||||
(let [ref (mf/use-ref)
|
(let [ref (mf/use-ref)
|
||||||
mentions-str (mf/use-memo #(rx/subject))
|
mentions-s (mf/use-memo #(rx/subject))
|
||||||
thread-id (:id thread)
|
thread-id (:id thread)
|
||||||
thread-pos (:position thread)
|
thread-pos (:position thread)
|
||||||
|
|
||||||
|
@ -960,7 +942,7 @@
|
||||||
max-height (when (some? viewport) (int (* (:height viewport) 0.5)))
|
max-height (when (some? viewport) (int (* (:height viewport) 0.5)))
|
||||||
|
|
||||||
;; We should probably look for a better way of doing this.
|
;; We should probably look for a better way of doing this.
|
||||||
bubble-margin {:x 24 :y 24}
|
bubble-margin (gpt/point 24 24)
|
||||||
pos (offset-position base-pos viewport zoom bubble-margin)
|
pos (offset-position base-pos viewport zoom bubble-margin)
|
||||||
|
|
||||||
margin-x (* (:x bubble-margin) (if (= (:h-dir pos) :left) -1 1))
|
margin-x (* (:x bubble-margin) (if (= (:h-dir pos) :left) -1 1))
|
||||||
|
@ -988,7 +970,7 @@
|
||||||
(when-let [node (mf/ref-val ref)]
|
(when-let [node (mf/ref-val ref)]
|
||||||
(dom/scroll-into-view-if-needed! node)))
|
(dom/scroll-into-view-if-needed! node)))
|
||||||
|
|
||||||
[:& (mf/provider mentions-context) {:value mentions-str}
|
[:> (mf/provider mentions-context) {:value mentions-s}
|
||||||
(when (some? first-comment)
|
(when (some? first-comment)
|
||||||
[:div {:class (stl/css-case :floating-thread-wrapper true
|
[:div {:class (stl/css-case :floating-thread-wrapper true
|
||||||
:left (= (:h-dir pos) :left)
|
:left (= (:h-dir pos) :left)
|
||||||
|
@ -1000,29 +982,25 @@
|
||||||
:on-click dom/stop-propagation}
|
:on-click dom/stop-propagation}
|
||||||
|
|
||||||
[:div {:class (stl/css :floating-thread-header)}
|
[:div {:class (stl/css :floating-thread-header)}
|
||||||
[:> comment-floating-thread-header* {:profiles profiles
|
[:> comment-floating-thread-header* {:thread thread
|
||||||
:thread thread
|
|
||||||
:origin origin}]]
|
:origin origin}]]
|
||||||
|
|
||||||
[:div {:class (stl/css :floating-thread-main)}
|
[:div {:class (stl/css :floating-thread-main)}
|
||||||
[:> comment-floating-thread-item* {:comment first-comment
|
[:> comment-floating-thread-item* {:comment first-comment
|
||||||
:profiles profiles
|
|
||||||
:thread thread}]
|
:thread thread}]
|
||||||
(for [item (rest comments)]
|
(for [item (rest comments)]
|
||||||
[:* {:key (dm/str (:id item))}
|
[:* {:key (dm/str (:id item))}
|
||||||
[:> comment-floating-thread-item* {:comment item
|
[:> comment-floating-thread-item* {:comment item}]])]
|
||||||
:profiles profiles}]])]
|
|
||||||
|
|
||||||
[:> comment-reply-form* {:thread thread}]
|
[:> comment-reply-form* {:thread thread}]
|
||||||
|
|
||||||
[:> mentions-panel* {:profiles profiles}]])]))
|
[:> mentions-panel*]])]))
|
||||||
|
|
||||||
(mf/defc comment-floating-bubble*
|
(mf/defc comment-floating-bubble*
|
||||||
{::mf/props :obj
|
{::mf/wrap [mf/memo]}
|
||||||
::mf/wrap [mf/memo]}
|
[{:keys [thread zoom is-open on-click origin position-modifier]}]
|
||||||
[{:keys [thread profiles zoom is-open on-click origin position-modifier]}]
|
(let [owner (mf/with-memo [thread]
|
||||||
(let [owner (get profiles (:owner-id thread))
|
(dcm/get-owner thread))
|
||||||
|
|
||||||
base-pos (cond-> (:position thread)
|
base-pos (cond-> (:position thread)
|
||||||
(some? position-modifier)
|
(some? position-modifier)
|
||||||
(gpt/transform position-modifier))
|
(gpt/transform position-modifier))
|
||||||
|
@ -1036,11 +1014,12 @@
|
||||||
position (:position thread)
|
position (:position thread)
|
||||||
frame-id (:frame-id thread)
|
frame-id (:frame-id thread)
|
||||||
|
|
||||||
state (mf/use-state {:hover? false
|
state (mf/use-state
|
||||||
:grabbing? false
|
#(do {:is-hover false
|
||||||
:new-position-x nil
|
:is-grabbing false
|
||||||
:new-position-y nil
|
:new-position-x nil
|
||||||
:new-frame-id frame-id})
|
:new-position-y nil
|
||||||
|
:new-frame-id frame-id}))
|
||||||
|
|
||||||
pos-x (floor (* (or (:new-position-x @state) (:x base-pos)) zoom))
|
pos-x (floor (* (or (:new-position-x @state) (:x base-pos)) zoom))
|
||||||
pos-y (floor (* (or (:new-position-y @state) (:y base-pos)) zoom))
|
pos-y (floor (* (or (:new-position-y @state) (:y base-pos)) zoom))
|
||||||
|
@ -1050,7 +1029,7 @@
|
||||||
(mf/deps origin was-open? is-open drag?)
|
(mf/deps origin was-open? is-open drag?)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (not= origin :viewer)
|
(when (not= origin :viewer)
|
||||||
(swap! state assoc :grabbing? true)
|
(swap! state assoc :is-grabbing true)
|
||||||
(mf/set-ref-val! was-open? is-open)
|
(mf/set-ref-val! was-open? is-open)
|
||||||
(when is-open (st/emit! (dcm/close-thread)))
|
(when is-open (st/emit! (dcm/close-thread)))
|
||||||
(mf/set-ref-val! drag? false)
|
(mf/set-ref-val! drag? false)
|
||||||
|
@ -1064,7 +1043,7 @@
|
||||||
(mf/deps origin thread (select-keys @state [:new-position-x :new-position-y :new-frame-id]))
|
(mf/deps origin thread (select-keys @state [:new-position-x :new-position-y :new-frame-id]))
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (not= origin :viewer)
|
(when (not= origin :viewer)
|
||||||
(swap! state assoc :grabbing? false)
|
(swap! state assoc :is-grabbing false)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(dom/release-pointer event)
|
(dom/release-pointer event)
|
||||||
(mf/set-ref-val! dragging-ref false)
|
(mf/set-ref-val! dragging-ref false)
|
||||||
|
@ -1100,28 +1079,28 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(when (false? is-open)
|
(when (false? is-open)
|
||||||
(swap! state assoc :hover? true))))
|
(swap! state assoc :is-hover true))))
|
||||||
|
|
||||||
on-pointer-leave
|
on-pointer-leave
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(swap! state assoc :hover? false)))
|
(swap! state assoc :is-hover false)))
|
||||||
|
|
||||||
on-click*
|
on-click*
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps origin thread on-click was-open? drag? (select-keys @state [:hover?]))
|
(mf/deps origin thread on-click was-open? drag? (select-keys @state [:is-hover]))
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(when (or (and (mf/ref-val was-open?) (mf/ref-val drag?))
|
(when (or (and (mf/ref-val was-open?) (mf/ref-val drag?))
|
||||||
(and (not (mf/ref-val was-open?)) (not (mf/ref-val drag?))))
|
(and (not (mf/ref-val was-open?)) (not (mf/ref-val drag?))))
|
||||||
(swap! state assoc :hover? false)
|
(swap! state assoc :is-hover false)
|
||||||
(st/emit! (dcm/open-thread thread)))
|
(st/emit! (dcm/open-thread thread)))
|
||||||
(when (= origin :viewer)
|
(when (= origin :viewer)
|
||||||
(on-click thread))))]
|
(on-click thread))))]
|
||||||
|
|
||||||
[:div {:style {:top (str pos-y "px")
|
[:div {:style {:top (dm/str pos-y "px")
|
||||||
:left (str pos-x "px")}
|
:left (dm/str pos-x "px")}
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
:on-pointer-up on-pointer-up
|
:on-pointer-up on-pointer-up
|
||||||
:on-pointer-move on-pointer-move
|
:on-pointer-move on-pointer-move
|
||||||
|
@ -1129,29 +1108,30 @@
|
||||||
:on-pointer-leave on-pointer-leave
|
:on-pointer-leave on-pointer-leave
|
||||||
:on-click on-click*
|
:on-click on-click*
|
||||||
:class (stl/css-case :floating-preview-wrapper true
|
:class (stl/css-case :floating-preview-wrapper true
|
||||||
:floating-preview-bubble (false? (:hover? @state))
|
:floating-preview-bubble (false? (:is-hover @state))
|
||||||
:grabbing (true? (:grabbing? @state)))}
|
:grabbing (true? (:is-grabbing @state)))}
|
||||||
|
|
||||||
(if (:hover? @state)
|
(if (:is-hover @state)
|
||||||
[:div {:class (stl/css :floating-thread-wrapper :floating-preview-displacement)}
|
[:div {:class (stl/css :floating-thread-wrapper :floating-preview-displacement)}
|
||||||
[:div {:class (stl/css :floating-thread-item-wrapper)}
|
[:div {:class (stl/css :floating-thread-item-wrapper)}
|
||||||
[:div {:class (stl/css :floating-thread-item)}
|
[:div {:class (stl/css :floating-thread-item)}
|
||||||
[:> comment-info* {:item thread
|
[:> comment-info* {:item thread
|
||||||
:profile owner}]]]]
|
:profile owner}]]]]
|
||||||
|
|
||||||
[:> comment-avatar* {:image (cfg/resolve-profile-photo-url owner)
|
[:> comment-avatar*
|
||||||
:class (stl/css :avatar-lg)
|
{:image (cfg/resolve-profile-photo-url owner)
|
||||||
:data-testid (str "floating-thread-bubble-" (:seqn thread))
|
:class (stl/css :avatar-lg)
|
||||||
:variant (cond (:is-resolved thread) "solved"
|
:data-testid (dm/str "floating-thread-bubble-" (:seqn thread))
|
||||||
(pos? (:count-unread-comments thread)) "unread"
|
:variant (cond
|
||||||
:else "read")}])]))
|
(:is-resolved thread) "solved"
|
||||||
|
(pos? (:count-unread-comments thread)) "unread"
|
||||||
|
:else "read")}])]))
|
||||||
|
|
||||||
(mf/defc comment-sidebar-thread-item*
|
(mf/defc comment-sidebar-thread-item*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
[{:keys [item on-click]}]
|
||||||
[{:keys [item profiles on-click]}]
|
(let [owner (dcm/get-owner item)
|
||||||
(let [owner (get profiles (:owner-id item))
|
;; FIXME
|
||||||
|
|
||||||
frame (mf/deref (refs/workspace-page-object-by-id (:page-id item) (:frame-id item)))
|
frame (mf/deref (refs/workspace-page-object-by-id (:page-id item) (:frame-id item)))
|
||||||
|
|
||||||
on-click*
|
on-click*
|
||||||
|
@ -1176,21 +1156,18 @@
|
||||||
:profile owner}]]))
|
:profile owner}]]))
|
||||||
|
|
||||||
(mf/defc comment-sidebar-thread-group*
|
(mf/defc comment-sidebar-thread-group*
|
||||||
{::mf/props :obj}
|
[{:keys [group on-thread-click]}]
|
||||||
[{:keys [group profiles on-thread-click]}]
|
|
||||||
[:div
|
[:div
|
||||||
(for [item (:items group)]
|
(for [item (:items group)]
|
||||||
[:> comment-sidebar-thread-item*
|
[:> comment-sidebar-thread-item*
|
||||||
{:item item
|
{:item item
|
||||||
:on-click on-thread-click
|
:on-click on-thread-click
|
||||||
:profiles profiles
|
|
||||||
:key (:id item)}])])
|
:key (:id item)}])])
|
||||||
|
|
||||||
(mf/defc comment-dashboard-thread-item*
|
(mf/defc comment-dashboard-thread-item*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
[{:keys [item on-click]}]
|
||||||
[{:keys [item profiles on-click]}]
|
(let [owner (dcm/get-owner item)
|
||||||
(let [owner (get profiles (:owner-id item))
|
|
||||||
|
|
||||||
on-click*
|
on-click*
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -1215,12 +1192,10 @@
|
||||||
:profile owner}]]))
|
:profile owner}]]))
|
||||||
|
|
||||||
(mf/defc comment-dashboard-thread-group*
|
(mf/defc comment-dashboard-thread-group*
|
||||||
{::mf/props :obj}
|
[{:keys [group on-thread-click]}]
|
||||||
[{:keys [group profiles on-thread-click]}]
|
|
||||||
[:div
|
[:div
|
||||||
(for [item (:items group)]
|
(for [item (:items group)]
|
||||||
[:> comment-dashboard-thread-item*
|
[:> comment-dashboard-thread-item*
|
||||||
{:item item
|
{:item item
|
||||||
:on-click on-thread-click
|
:on-click on-thread-click
|
||||||
:profiles profiles
|
|
||||||
:key (:id item)}])])
|
:key (:id item)}])])
|
||||||
|
|
|
@ -50,9 +50,9 @@
|
||||||
(mf/defc comments-section
|
(mf/defc comments-section
|
||||||
[{:keys [profile team show? on-hide-comments]}]
|
[{:keys [profile team show? on-hide-comments]}]
|
||||||
(let [threads-map (mf/deref refs/comment-threads)
|
(let [threads-map (mf/deref refs/comment-threads)
|
||||||
profiles (mf/deref refs/profiles)
|
|
||||||
team-id (:id team)
|
|
||||||
|
|
||||||
|
;; FIXME: with-memo
|
||||||
|
team-id (:id team)
|
||||||
tgroups (->> (vals threads-map)
|
tgroups (->> (vals threads-map)
|
||||||
(sort-by :modified-at)
|
(sort-by :modified-at)
|
||||||
(reverse)
|
(reverse)
|
||||||
|
@ -93,14 +93,12 @@
|
||||||
[:> cmt/comment-dashboard-thread-group*
|
[:> cmt/comment-dashboard-thread-group*
|
||||||
{:group (first tgroups)
|
{:group (first tgroups)
|
||||||
:on-thread-click on-navigate
|
:on-thread-click on-navigate
|
||||||
:show-file-name true
|
:show-file-name true}]
|
||||||
:profiles profiles}]
|
|
||||||
(for [tgroup (rest tgroups)]
|
(for [tgroup (rest tgroups)]
|
||||||
[:> cmt/comment-dashboard-thread-group*
|
[:> cmt/comment-dashboard-thread-group*
|
||||||
{:group tgroup
|
{:group tgroup
|
||||||
:on-thread-click on-navigate
|
:on-thread-click on-navigate
|
||||||
:show-file-name true
|
:show-file-name true
|
||||||
:profiles profiles
|
|
||||||
:key (:page-id tgroup)}])]
|
:key (:page-id tgroup)}])]
|
||||||
|
|
||||||
[:div {:class (stl/css :thread-groups-placeholder)}
|
[:div {:class (stl/css :thread-groups-placeholder)}
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
[app.common.geom.shapes.points :as gpo]
|
[app.common.geom.shapes.points :as gpo]
|
||||||
[app.common.types.modifiers :as ctm]
|
[app.common.types.modifiers :as ctm]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.modifiers :as dwm]
|
[app.main.data.workspace.modifiers :as dwm]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.css-cursors :as cur]
|
[app.main.ui.css-cursors :as cur]
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
negate {:column-gap (if flip-x true false)
|
negate {:column-gap (if flip-x true false)
|
||||||
:row-gap (if flip-y true false)}
|
:row-gap (if flip-y true false)}
|
||||||
|
|
||||||
objects (wsh/lookup-page-objects @st/state)
|
objects (dsh/lookup-page-objects @st/state)
|
||||||
children (->> (cfh/get-immediate-children objects frame-id)
|
children (->> (cfh/get-immediate-children objects frame-id)
|
||||||
(remove ctl/position-absolute?))
|
(remove ctl/position-absolute?))
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@
|
||||||
|
|
||||||
(mf/defc comments-layer
|
(mf/defc comments-layer
|
||||||
{::mf/props :obj}
|
{::mf/props :obj}
|
||||||
[{:keys [zoom file users frame page]}]
|
[{:keys [zoom file frame page]}]
|
||||||
(let [profile (mf/deref refs/profile)
|
(let [profile (mf/deref refs/profile)
|
||||||
local (mf/deref refs/comments-local)
|
local (mf/deref refs/comments-local)
|
||||||
|
|
||||||
|
@ -208,7 +208,6 @@
|
||||||
(for [item threads]
|
(for [item threads]
|
||||||
[:> cmt/comment-floating-bubble*
|
[:> cmt/comment-floating-bubble*
|
||||||
{:thread item
|
{:thread item
|
||||||
:profiles users
|
|
||||||
:position-modifier modifier1
|
:position-modifier modifier1
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:on-click on-bubble-click
|
:on-click on-bubble-click
|
||||||
|
@ -219,7 +218,6 @@
|
||||||
(when-let [thread (get threads-map open-thread-id)]
|
(when-let [thread (get threads-map open-thread-id)]
|
||||||
[:> cmt/comment-floating-thread*
|
[:> cmt/comment-floating-thread*
|
||||||
{:thread thread
|
{:thread thread
|
||||||
:profiles users
|
|
||||||
:position-modifier modifier1
|
:position-modifier modifier1
|
||||||
:viewport {:offset-x 0 :offset-y 0 :width (:width vsize) :height (:height vsize)}
|
:viewport {:offset-x 0 :offset-y 0 :width (:width vsize) :height (:height vsize)}
|
||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
|
@ -227,7 +225,6 @@
|
||||||
(when-let [draft (:draft local)]
|
(when-let [draft (:draft local)]
|
||||||
[:> cmt/comment-floating-thread-draft*
|
[:> cmt/comment-floating-thread-draft*
|
||||||
{:draft draft
|
{:draft draft
|
||||||
:profiles users
|
|
||||||
:position-modifier modifier1
|
:position-modifier modifier1
|
||||||
:on-cancel on-draft-cancel
|
:on-cancel on-draft-cancel
|
||||||
:on-submit on-draft-submit
|
:on-submit on-draft-submit
|
||||||
|
|
|
@ -9,11 +9,13 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.persistence :as dps]
|
[app.main.data.persistence :as dps]
|
||||||
[app.main.data.plugins :as dpl]
|
[app.main.data.plugins :as dpl]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
|
[app.main.router :as-alias rt]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.ds.product.loader :refer [loader*]]
|
[app.main.ui.ds.product.loader :refer [loader*]]
|
||||||
|
@ -21,7 +23,7 @@
|
||||||
[app.main.ui.hooks.resize :refer [use-resize-observer]]
|
[app.main.ui.hooks.resize :refer [use-resize-observer]]
|
||||||
[app.main.ui.modal :refer [modal-container*]]
|
[app.main.ui.modal :refer [modal-container*]]
|
||||||
[app.main.ui.workspace.colorpicker]
|
[app.main.ui.workspace.colorpicker]
|
||||||
[app.main.ui.workspace.context-menu :refer [context-menu]]
|
[app.main.ui.workspace.context-menu :refer [context-menu*]]
|
||||||
[app.main.ui.workspace.coordinates :as coordinates]
|
[app.main.ui.workspace.coordinates :as coordinates]
|
||||||
[app.main.ui.workspace.libraries]
|
[app.main.ui.workspace.libraries]
|
||||||
[app.main.ui.workspace.nudge]
|
[app.main.ui.workspace.nudge]
|
||||||
|
@ -32,7 +34,7 @@
|
||||||
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
|
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
|
||||||
[app.main.ui.workspace.tokens.modals]
|
[app.main.ui.workspace.tokens.modals]
|
||||||
[app.main.ui.workspace.tokens.modals.themes]
|
[app.main.ui.workspace.tokens.modals.themes]
|
||||||
[app.main.ui.workspace.viewport :refer [viewport]]
|
[app.main.ui.workspace.viewport :refer [viewport*]]
|
||||||
[app.util.debug :as dbg]
|
[app.util.debug :as dbg]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.globals :as globals]
|
[app.util.globals :as globals]
|
||||||
|
@ -41,27 +43,19 @@
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(defn- make-file-ready-ref
|
(defn- make-workspace-ready-ref
|
||||||
[file-id]
|
[file-id]
|
||||||
(l/derived (fn [state]
|
(l/derived (fn [state]
|
||||||
(let [data (:workspace-data state)]
|
(and (= file-id (:workspace-ready state))
|
||||||
(and (:workspace-ready state)
|
(some? (dsh/lookup-file-data state file-id))))
|
||||||
(= file-id (:current-file-id state))
|
|
||||||
(= file-id (:id data)))))
|
|
||||||
st/state))
|
st/state))
|
||||||
|
|
||||||
(defn- make-page-ready-ref
|
(mf/defc workspace-content*
|
||||||
[page-id]
|
{::mf/private true}
|
||||||
(l/derived (fn [state]
|
[{:keys [file layout page wglobal]}]
|
||||||
(and (some? page-id)
|
|
||||||
(= page-id (:current-page-id state))))
|
|
||||||
st/state))
|
|
||||||
|
|
||||||
(mf/defc workspace-content
|
|
||||||
{::mf/wrap-props false}
|
|
||||||
[{:keys [file layout page-id wglobal]}]
|
|
||||||
(let [palete-size (mf/use-state nil)
|
(let [palete-size (mf/use-state nil)
|
||||||
selected (mf/deref refs/selected-shapes)
|
selected (mf/deref refs/selected-shapes)
|
||||||
|
page-id (:id page)
|
||||||
|
|
||||||
{:keys [vport] :as wlocal} (mf/deref refs/workspace-local)
|
{:keys [vport] :as wlocal} (mf/deref refs/workspace-local)
|
||||||
{:keys [options-mode]} wglobal
|
{:keys [options-mode]} wglobal
|
||||||
|
@ -102,14 +96,16 @@
|
||||||
[:button {:on-click #(st/emit! dw/reinitialize-undo)} "CLEAR"]
|
[:button {:on-click #(st/emit! dw/reinitialize-undo)} "CLEAR"]
|
||||||
[:> history-toolbox*]])
|
[:> history-toolbox*]])
|
||||||
|
|
||||||
[:& viewport {:file file
|
[:> viewport*
|
||||||
:wlocal wlocal
|
{:file file
|
||||||
:wglobal wglobal
|
:page page
|
||||||
:selected selected
|
:wlocal wlocal
|
||||||
:layout layout
|
:wglobal wglobal
|
||||||
:palete-size
|
:selected selected
|
||||||
(when (and (or colorpalette? textpalette?) (not hide-ui?))
|
:layout layout
|
||||||
@palete-size)}]]]
|
:palete-size
|
||||||
|
(when (and (or colorpalette? textpalette?) (not hide-ui?))
|
||||||
|
@palete-size)}]]]
|
||||||
|
|
||||||
(when-not hide-ui?
|
(when-not hide-ui?
|
||||||
[:*
|
[:*
|
||||||
|
@ -125,21 +121,17 @@
|
||||||
:page-id page-id}]])]))
|
:page-id page-id}]])]))
|
||||||
|
|
||||||
(mf/defc workspace-loader*
|
(mf/defc workspace-loader*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
|
||||||
[]
|
[]
|
||||||
[:> loader* {:title (tr "labels.loading")
|
[:> loader* {:title (tr "labels.loading")
|
||||||
:class (stl/css :workspace-loader)
|
:class (stl/css :workspace-loader)
|
||||||
:overlay true}])
|
:overlay true}])
|
||||||
|
|
||||||
(mf/defc workspace-page*
|
(mf/defc workspace-page*
|
||||||
{::mf/props :obj
|
{::mf/private true}
|
||||||
::mf/private true}
|
|
||||||
[{:keys [page-id file layout wglobal]}]
|
[{:keys [page-id file layout wglobal]}]
|
||||||
(let [page-id (hooks/use-equal-memo page-id)
|
(let [page-id (hooks/use-equal-memo page-id)
|
||||||
page-ready* (mf/with-memo [page-id]
|
page (mf/deref refs/workspace-page)]
|
||||||
(make-page-ready-ref page-id))
|
|
||||||
page-ready? (mf/deref page-ready*)]
|
|
||||||
|
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(let [focus-out #(st/emit! (dw/workspace-focus-lost))
|
(let [focus-out #(st/emit! (dw/workspace-focus-lost))
|
||||||
|
@ -149,29 +141,39 @@
|
||||||
(mf/with-effect [page-id]
|
(mf/with-effect [page-id]
|
||||||
(if (some? page-id)
|
(if (some? page-id)
|
||||||
(st/emit! (dw/initialize-page page-id))
|
(st/emit! (dw/initialize-page page-id))
|
||||||
(st/emit! (dcm/go-to-workspace)))
|
(st/emit! (dcm/go-to-workspace ::rt/replace true)))
|
||||||
|
|
||||||
(fn []
|
(fn []
|
||||||
(when (some? page-id)
|
(when (some? page-id)
|
||||||
(st/emit! (dw/finalize-page page-id)))))
|
(st/emit! (dw/finalize-page page-id)))))
|
||||||
|
|
||||||
(if ^boolean page-ready?
|
(if (some? page)
|
||||||
[:& workspace-content {:page-id page-id
|
[:> workspace-content* {:file file
|
||||||
:file file
|
:page page
|
||||||
:wglobal wglobal
|
:wglobal wglobal
|
||||||
:layout layout}]
|
:layout layout}]
|
||||||
[:& workspace-loader*])))
|
[:& workspace-loader*])))
|
||||||
|
|
||||||
|
|
||||||
|
(def ^:private ref:file-without-data
|
||||||
|
(l/derived (fn [file]
|
||||||
|
(dissoc file :data))
|
||||||
|
refs/file
|
||||||
|
=))
|
||||||
|
|
||||||
(mf/defc workspace*
|
(mf/defc workspace*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/wrap [mf/memo]}
|
::mf/wrap [mf/memo]}
|
||||||
[{:keys [project-id file-id page-id layout-name]}]
|
[{:keys [project-id file-id page-id layout-name]}]
|
||||||
|
|
||||||
(let [layout (mf/deref refs/workspace-layout)
|
(let [file-id (hooks/use-equal-memo file-id)
|
||||||
|
page-id (hooks/use-equal-memo page-id)
|
||||||
|
|
||||||
|
layout (mf/deref refs/workspace-layout)
|
||||||
wglobal (mf/deref refs/workspace-global)
|
wglobal (mf/deref refs/workspace-global)
|
||||||
|
|
||||||
team (mf/deref refs/team)
|
team (mf/deref refs/team)
|
||||||
file (mf/deref refs/workspace-file)
|
file (mf/deref ref:file-without-data)
|
||||||
|
|
||||||
file-name (:name file)
|
file-name (:name file)
|
||||||
permissions (:permissions team)
|
permissions (:permissions team)
|
||||||
|
@ -179,11 +181,10 @@
|
||||||
read-only? (mf/deref refs/workspace-read-only?)
|
read-only? (mf/deref refs/workspace-read-only?)
|
||||||
read-only? (or read-only? (not (:can-edit permissions)))
|
read-only? (or read-only? (not (:can-edit permissions)))
|
||||||
|
|
||||||
file-ready* (mf/with-memo [file-id]
|
ready* (mf/with-memo [file-id]
|
||||||
(make-file-ready-ref file-id))
|
(make-workspace-ready-ref file-id))
|
||||||
file-ready? (mf/deref file-ready*)
|
ready? (mf/deref ready*)
|
||||||
|
|
||||||
components-v2? (features/use-feature "components/v2")
|
|
||||||
design-tokens? (features/use-feature "design-tokens/v1")
|
design-tokens? (features/use-feature "design-tokens/v1")
|
||||||
|
|
||||||
background-color (:background-color wglobal)]
|
background-color (:background-color wglobal)]
|
||||||
|
@ -206,21 +207,21 @@
|
||||||
(st/emit! ::dps/force-persist
|
(st/emit! ::dps/force-persist
|
||||||
(dw/finalize-workspace file-id))))
|
(dw/finalize-workspace file-id))))
|
||||||
|
|
||||||
[:& (mf/provider ctx/current-project-id) {:value project-id}
|
[:> (mf/provider ctx/current-project-id) {:value project-id}
|
||||||
[:& (mf/provider ctx/current-file-id) {:value file-id}
|
[:> (mf/provider ctx/current-file-id) {:value file-id}
|
||||||
[:& (mf/provider ctx/current-page-id) {:value page-id}
|
[:> (mf/provider ctx/current-page-id) {:value page-id}
|
||||||
[:& (mf/provider ctx/components-v2) {:value components-v2?}
|
[:> (mf/provider ctx/components-v2) {:value true}
|
||||||
[:& (mf/provider ctx/design-tokens) {:value design-tokens?}
|
[:> (mf/provider ctx/design-tokens) {:value design-tokens?}
|
||||||
[:& (mf/provider ctx/workspace-read-only?) {:value read-only?}
|
[:> (mf/provider ctx/workspace-read-only?) {:value read-only?}
|
||||||
[:> modal-container*]
|
[:> modal-container*]
|
||||||
[:section {:class (stl/css :workspace)
|
[:section {:class (stl/css :workspace)
|
||||||
:style {:background-color background-color
|
:style {:background-color background-color
|
||||||
:touch-action "none"}}
|
:touch-action "none"}}
|
||||||
[:& context-menu]
|
[:> context-menu*]
|
||||||
|
|
||||||
(if ^boolean file-ready?
|
(if ^boolean ready?
|
||||||
[:> workspace-page* {:page-id page-id
|
[:> workspace-page* {:page-id page-id
|
||||||
:file file
|
:file file
|
||||||
:wglobal wglobal
|
:wglobal wglobal
|
||||||
:layout layout}]
|
:layout layout}]
|
||||||
[:> workspace-loader* {}])]]]]]]]))
|
[:> workspace-loader*])]]]]]]]))
|
||||||
|
|
|
@ -24,29 +24,30 @@
|
||||||
[potok.v2.core :as ptk]
|
[potok.v2.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc palette-item
|
(mf/defc palette-item*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [color size selected]}]
|
[{:keys [color size selected]}]
|
||||||
(letfn [(select-color [event]
|
(let [select-color
|
||||||
(st/emit!
|
(mf/use-fn
|
||||||
(dwl/add-recent-color color)
|
(mf/deps color selected)
|
||||||
(mdc/apply-color-from-palette color (kbd/alt? event))
|
(fn [event]
|
||||||
(when (not= selected :recent)
|
(st/emit! (dwl/add-recent-color color)
|
||||||
(ptk/event
|
(mdc/apply-color-from-palette color (kbd/alt? event))
|
||||||
::ev/event
|
(when (not= selected :recent)
|
||||||
{::ev/name "use-library-color"
|
(ptk/data-event ::ev/event
|
||||||
::ev/origin "color-palette"
|
{::ev/name "use-library-color"
|
||||||
:external-library (not= selected :file)}))))]
|
::ev/origin "color-palette"
|
||||||
[:div {:class (stl/css-case :color-cell true
|
:external-library (not= selected :file)})))))]
|
||||||
:is-not-library-color (nil? (:id color))
|
[:div {:class (stl/css-case
|
||||||
:no-text (<= size 64))
|
:color-cell true
|
||||||
|
:is-not-library-color (nil? (:id color))
|
||||||
|
:no-text (<= size 64))
|
||||||
:title (uc/get-color-name color)
|
:title (uc/get-color-name color)
|
||||||
:on-click select-color}
|
:on-click select-color}
|
||||||
[:& cb/color-bullet {:color color}]
|
[:& cb/color-bullet {:color color}]
|
||||||
[:& cb/color-name {:color color :size size :origin :palette}]]))
|
[:& cb/color-name {:color color :size size :origin :palette}]]))
|
||||||
|
|
||||||
|
(mf/defc palette*
|
||||||
(mf/defc palette
|
|
||||||
[{:keys [current-colors size width selected]}]
|
[{:keys [current-colors size width selected]}]
|
||||||
(let [;; We had to do this due to a bug that leave some bugged colors
|
(let [;; We had to do this due to a bug that leave some bugged colors
|
||||||
current-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) current-colors))
|
current-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) current-colors))
|
||||||
|
@ -140,7 +141,7 @@
|
||||||
:max-width (str width "px")
|
:max-width (str width "px")
|
||||||
:right (str (* offset-step offset) "px")}}
|
:right (str (* offset-step offset) "px")}}
|
||||||
(for [[idx item] (map-indexed vector current-colors)]
|
(for [[idx item] (map-indexed vector current-colors)]
|
||||||
[:& palette-item {:color item :key idx :size size :selected selected}])])]
|
[:> palette-item* {:color item :key idx :size size :selected selected}])])]
|
||||||
(when show-arrows?
|
(when show-arrows?
|
||||||
[:button {:class (stl/css :right-arrow)
|
[:button {:class (stl/css :right-arrow)
|
||||||
:disabled (= offset max-offset)
|
:disabled (= offset max-offset)
|
||||||
|
@ -155,7 +156,7 @@
|
||||||
(mf/defc color-palette
|
(mf/defc color-palette
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [size width selected] :as props}]
|
[{:keys [size width selected] :as props}]
|
||||||
(let [recent-colors (mf/deref refs/workspace-recent-colors)
|
(let [recent-colors (mf/deref refs/recent-colors)
|
||||||
file-colors (mf/deref refs/workspace-file-colors)
|
file-colors (mf/deref refs/workspace-file-colors)
|
||||||
shared-libs (mf/deref refs/libraries)
|
shared-libs (mf/deref refs/libraries)
|
||||||
colors (mf/use-state [])]
|
colors (mf/use-state [])]
|
||||||
|
@ -176,7 +177,7 @@
|
||||||
(reset! colors (into [] (->> (vals file-colors)
|
(reset! colors (into [] (->> (vals file-colors)
|
||||||
(sort-by :name))))))
|
(sort-by :name))))))
|
||||||
|
|
||||||
[:& palette {:current-colors @colors
|
[:> palette* {:current-colors @colors
|
||||||
:size size
|
:size size
|
||||||
:width width
|
:width width
|
||||||
:selected selected}]))
|
:selected selected}]))
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
(mf/defc color-palette-ctx-menu
|
(mf/defc color-palette-ctx-menu
|
||||||
[{:keys [show-menu? close-menu on-select-palette selected]}]
|
[{:keys [show-menu? close-menu on-select-palette selected]}]
|
||||||
(let [recent-colors (mf/deref refs/workspace-recent-colors)
|
(let [recent-colors (mf/deref refs/recent-colors)
|
||||||
file-colors (mf/deref refs/workspace-file-colors)
|
file-colors (mf/deref refs/workspace-file-colors)
|
||||||
shared-libs (mf/deref refs/libraries)]
|
shared-libs (mf/deref refs/libraries)]
|
||||||
[:& dropdown {:show show-menu?
|
[:& dropdown {:show show-menu?
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
shared-libs (mf/deref refs/libraries)
|
shared-libs (mf/deref refs/libraries)
|
||||||
file-colors (mf/deref refs/workspace-file-colors)
|
file-colors (mf/deref refs/workspace-file-colors)
|
||||||
recent-colors (mf/deref refs/workspace-recent-colors)
|
recent-colors (mf/deref refs/recent-colors)
|
||||||
recent-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) recent-colors))
|
recent-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) recent-colors))
|
||||||
|
|
||||||
on-library-change
|
on-library-change
|
||||||
|
|
|
@ -73,9 +73,8 @@
|
||||||
[:span {:class (stl/css :icon)} i/tick]]]))
|
[:span {:class (stl/css :icon)} i/tick]]]))
|
||||||
|
|
||||||
(mf/defc comments-sidebar*
|
(mf/defc comments-sidebar*
|
||||||
{::mf/props :obj}
|
|
||||||
[{:keys [profiles threads page-id from-viewer]}]
|
[{:keys [profiles threads page-id from-viewer]}]
|
||||||
(let [threads-map (mf/deref refs/threads-ref)
|
(let [threads-map (mf/deref refs/threads)
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
profiles' (mf/deref refs/profiles)
|
profiles' (mf/deref refs/profiles)
|
||||||
profiles (or profiles profiles')
|
profiles (or profiles profiles')
|
||||||
|
|
|
@ -748,7 +748,7 @@
|
||||||
|
|
||||||
;; FIXME: optimize because it is rendered always
|
;; FIXME: optimize because it is rendered always
|
||||||
|
|
||||||
(mf/defc context-menu
|
(mf/defc context-menu*
|
||||||
[]
|
[]
|
||||||
(let [mdata (mf/deref menu-ref)
|
(let [mdata (mf/deref menu-ref)
|
||||||
top (- (get-in mdata [:position :y]) 20)
|
top (- (get-in mdata [:position :y]) 20)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
[app.main.ui.components.link-button :as lb]
|
[app.main.ui.components.link-button :as lb]
|
||||||
[app.main.ui.components.search-bar :refer [search-bar]]
|
[app.main.ui.components.search-bar :refer [search-bar]]
|
||||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||||
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
|
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
|
||||||
[app.main.ui.hooks :as h]
|
[app.main.ui.hooks :as h]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
|
@ -38,7 +39,6 @@
|
||||||
[app.util.strings :refer [matches-search]]
|
[app.util.strings :refer [matches-search]]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[okulary.core :as l]
|
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def ^:private close-icon
|
(def ^:private close-icon
|
||||||
|
@ -53,25 +53,47 @@
|
||||||
(def ^:private library-icon
|
(def ^:private library-icon
|
||||||
(i/icon-xref :library (stl/css :library-icon)))
|
(i/icon-xref :library (stl/css :library-icon)))
|
||||||
|
|
||||||
(def ref:workspace-file
|
(defn- get-library-summary
|
||||||
(l/derived :workspace-file st/state))
|
"Given a library data return a summary representation of this library"
|
||||||
|
[data]
|
||||||
|
(let [colors (count (:colors data))
|
||||||
|
graphics 0
|
||||||
|
typographies (count (:typographies data))
|
||||||
|
components (count (ctkl/components-seq data))
|
||||||
|
empty? (and (zero? components)
|
||||||
|
(zero? graphics)
|
||||||
|
(zero? colors)
|
||||||
|
(zero? typographies))]
|
||||||
|
|
||||||
(defn create-file-library-ref
|
{:is-empty empty?
|
||||||
[library-id]
|
:colors colors
|
||||||
(letfn [(getter-fn [state]
|
:graphics graphics
|
||||||
(let [fdata (let [{:keys [id] :as wfile} (:workspace-data state)]
|
:typographies typographies
|
||||||
(if (= id library-id)
|
:components components}))
|
||||||
wfile
|
|
||||||
(dm/get-in state [:libraries library-id :data])))]
|
(defn- adapt-backend-summary
|
||||||
{:colors (-> fdata :colors vals)
|
[summary]
|
||||||
:media (-> fdata :media vals)
|
(let [components (or (-> summary :components :count) 0)
|
||||||
:components (ctkl/components-seq fdata)
|
graphics (or (-> summary :media :count) 0)
|
||||||
:typographies (-> fdata :typographies vals)}))]
|
typographies (or (-> summary :typographies :count) 0)
|
||||||
(l/derived getter-fn st/state =)))
|
colors (or (-> summary :colors :count) 0)
|
||||||
|
|
||||||
|
empty? (and (zero? components)
|
||||||
|
(zero? graphics)
|
||||||
|
(zero? colors)
|
||||||
|
(zero? typographies))]
|
||||||
|
{:is-empty empty?
|
||||||
|
:components components
|
||||||
|
:graphics graphics
|
||||||
|
:typographies typographies
|
||||||
|
:colors colors}))
|
||||||
|
|
||||||
(defn- describe-library
|
(defn- describe-library
|
||||||
[components-count graphics-count colors-count typography-count]
|
[components-count graphics-count colors-count typography-count]
|
||||||
(let [all-zero? (and (zero? components-count) (zero? graphics-count) (zero? colors-count) (zero? typography-count))]
|
(let [all-zero? (and (zero? components-count)
|
||||||
|
(zero? graphics-count)
|
||||||
|
(zero? colors-count)
|
||||||
|
(zero? typography-count))]
|
||||||
(str
|
(str
|
||||||
(str/join " · "
|
(str/join " · "
|
||||||
(cond-> []
|
(cond-> []
|
||||||
|
@ -88,26 +110,31 @@
|
||||||
(conj (tr "workspace.libraries.typography" typography-count))))
|
(conj (tr "workspace.libraries.typography" typography-count))))
|
||||||
"\u00A0")))
|
"\u00A0")))
|
||||||
|
|
||||||
(mf/defc describe-library-blocks*
|
(mf/defc library-description*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/private true}
|
::mf/private true}
|
||||||
[{:keys [components-count graphics-count colors-count typography-count]}]
|
[{:keys [summary]}]
|
||||||
[:*
|
(let [components-count (get summary :components)
|
||||||
(when (pos? components-count)
|
graphics-count (get summary :graphics)
|
||||||
[:li {:class (stl/css :element-count)}
|
typography-count (get summary :typographies)
|
||||||
(tr "workspace.libraries.components" components-count)])
|
colors-count (get summary :colors)]
|
||||||
|
|
||||||
(when (pos? graphics-count)
|
[:*
|
||||||
[:li {:class (stl/css :element-count)}
|
(when (pos? components-count)
|
||||||
(tr "workspace.libraries.graphics" graphics-count)])
|
[:li {:class (stl/css :element-count)}
|
||||||
|
(tr "workspace.libraries.components" components-count)])
|
||||||
|
|
||||||
(when (pos? colors-count)
|
(when (pos? graphics-count)
|
||||||
[:li {:class (stl/css :element-count)}
|
[:li {:class (stl/css :element-count)}
|
||||||
(tr "workspace.libraries.colors" colors-count)])
|
(tr "workspace.libraries.graphics" graphics-count)])
|
||||||
|
|
||||||
(when (pos? typography-count)
|
(when (pos? colors-count)
|
||||||
[:li {:class (stl/css :element-count)}
|
[:li {:class (stl/css :element-count)}
|
||||||
(tr "workspace.libraries.typography" typography-count)])])
|
(tr "workspace.libraries.colors" colors-count)])
|
||||||
|
|
||||||
|
(when (pos? typography-count)
|
||||||
|
[:li {:class (stl/css :element-count)}
|
||||||
|
(tr "workspace.libraries.typography" typography-count)])]))
|
||||||
|
|
||||||
(mf/defc sample-library-entry*
|
(mf/defc sample-library-entry*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
|
@ -146,26 +173,35 @@
|
||||||
:value (if (= importing? id) (tr "labels.adding") (tr "labels.add"))
|
:value (if (= importing? id) (tr "labels.adding") (tr "labels.add"))
|
||||||
:on-click import-library}]]))
|
:on-click import-library}]]))
|
||||||
|
|
||||||
|
(defn- empty-library?
|
||||||
|
"Check if currentt library summary has elements or not"
|
||||||
|
[summary]
|
||||||
|
(let [colors (or (-> summary :colors :count) 0)
|
||||||
|
components (or (-> summary :components :count) 0)
|
||||||
|
media (or (-> summary :media :count) 0)
|
||||||
|
typographies (or (-> summary :typographies :count) 0)]
|
||||||
|
|
||||||
|
(and (zero? colors)
|
||||||
|
(zero? components)
|
||||||
|
(zero? media)
|
||||||
|
(zero? typographies))))
|
||||||
|
|
||||||
(mf/defc libraries-tab*
|
(mf/defc libraries-tab*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/private true}
|
::mf/private true}
|
||||||
[{:keys [file-id is-shared linked-libraries shared-libraries]}]
|
[{:keys [is-shared linked-libraries shared-libraries]}]
|
||||||
(let [search-term* (mf/use-state "")
|
(let [file-id (mf/use-ctx ctx/current-file-id)
|
||||||
|
search-term* (mf/use-state "")
|
||||||
search-term (deref search-term*)
|
search-term (deref search-term*)
|
||||||
library-ref (mf/with-memo [file-id]
|
|
||||||
(create-file-library-ref file-id))
|
;; The summary of the current/local library
|
||||||
library (deref library-ref)
|
;; NOTE: we only need a snapshot of current library
|
||||||
colors (:colors library)
|
local-library (deref refs/workspace-data)
|
||||||
components (:components library)
|
summary (get-library-summary local-library)
|
||||||
media (:media library)
|
empty-library? (empty-library? summary)
|
||||||
typographies (:typographies library)
|
|
||||||
selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent)
|
selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent)
|
||||||
|
|
||||||
empty-library? (and
|
|
||||||
(zero? (count colors))
|
|
||||||
(zero? (count components))
|
|
||||||
(zero? (count media))
|
|
||||||
(zero? (count typographies)))
|
|
||||||
|
|
||||||
shared-libraries
|
shared-libraries
|
||||||
(mf/with-memo [shared-libraries linked-libraries file-id search-term]
|
(mf/with-memo [shared-libraries linked-libraries file-id search-term]
|
||||||
|
@ -263,10 +299,8 @@
|
||||||
[:div {:class (stl/css :item-content)}
|
[:div {:class (stl/css :item-content)}
|
||||||
[:div {:class (stl/css :item-name)} (tr "workspace.libraries.file-library")]
|
[:div {:class (stl/css :item-name)} (tr "workspace.libraries.file-library")]
|
||||||
[:ul {:class (stl/css :item-contents)}
|
[:ul {:class (stl/css :item-contents)}
|
||||||
[:> describe-library-blocks* {:components-count (count components)
|
[:> library-description* {:summary summary}]]]
|
||||||
:graphics-count (count media)
|
|
||||||
:colors-count (count colors)
|
|
||||||
:typography-count (count typographies)}]]]
|
|
||||||
(if ^boolean is-shared
|
(if ^boolean is-shared
|
||||||
[:input {:class (stl/css :item-unpublish)
|
[:input {:class (stl/css :item-unpublish)
|
||||||
:type "button"
|
:type "button"
|
||||||
|
@ -277,21 +311,15 @@
|
||||||
:value (tr "common.publish")
|
:value (tr "common.publish")
|
||||||
:on-click publish}])]
|
:on-click publish}])]
|
||||||
|
|
||||||
(for [{:keys [id name] :as library} linked-libraries]
|
(for [{:keys [id name data] :as library} linked-libraries]
|
||||||
[:div {:class (stl/css :section-list-item)
|
[:div {:class (stl/css :section-list-item)
|
||||||
:key (dm/str id)
|
:key (dm/str id)
|
||||||
:data-testid "library-item"}
|
:data-testid "library-item"}
|
||||||
[:div {:class (stl/css :item-content)}
|
[:div {:class (stl/css :item-content)}
|
||||||
[:div {:class (stl/css :item-name)} name]
|
[:div {:class (stl/css :item-name)} name]
|
||||||
[:ul {:class (stl/css :item-contents)}
|
[:ul {:class (stl/css :item-contents)}
|
||||||
(let [components-count (count (or (ctkl/components-seq (:data library)) []))
|
(let [summary (get-library-summary data)]
|
||||||
graphics-count (count (dm/get-in library [:data :media] []))
|
[:> library-description* {:summary summary}])]]
|
||||||
colors-count (count (dm/get-in library [:data :colors] []))
|
|
||||||
typography-count (count (dm/get-in library [:data :typographies] []))]
|
|
||||||
[:> describe-library-blocks* {:components-count components-count
|
|
||||||
:graphics-count graphics-count
|
|
||||||
:colors-count colors-count
|
|
||||||
:typography-count typography-count}])]]
|
|
||||||
|
|
||||||
[:button {:class (stl/css :item-button)
|
[:button {:class (stl/css :item-button)
|
||||||
:type "button"
|
:type "button"
|
||||||
|
@ -318,14 +346,10 @@
|
||||||
[:div {:class (stl/css :item-content)}
|
[:div {:class (stl/css :item-content)}
|
||||||
[:div {:class (stl/css :item-name)} name]
|
[:div {:class (stl/css :item-name)} name]
|
||||||
[:ul {:class (stl/css :item-contents)}
|
[:ul {:class (stl/css :item-contents)}
|
||||||
(let [components-count (dm/get-in library [:library-summary :components :count] 0)
|
(let [summary (-> (:library-summary library)
|
||||||
graphics-count (dm/get-in library [:library-summary :media :count] 0)
|
(adapt-backend-summary))]
|
||||||
colors-count (dm/get-in library [:library-summary :colors :count] 0)
|
[:> library-description* {:summary summary}])]]
|
||||||
typography-count (dm/get-in library [:library-summary :typographies :count] 0)]
|
|
||||||
[:> describe-library-blocks* {:components-count components-count
|
|
||||||
:graphics-count graphics-count
|
|
||||||
:colors-count colors-count
|
|
||||||
:typography-count typography-count}])]]
|
|
||||||
[:button {:class (stl/css :item-button-shared)
|
[:button {:class (stl/css :item-button-shared)
|
||||||
:data-library-id (dm/str id)
|
:data-library-id (dm/str id)
|
||||||
:title (tr "workspace.libraries.shared-library-btn")
|
:title (tr "workspace.libraries.shared-library-btn")
|
||||||
|
@ -414,11 +438,16 @@
|
||||||
(mf/defc updates-tab*
|
(mf/defc updates-tab*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/private true}
|
::mf/private true}
|
||||||
[{:keys [file-id file-data libraries]}]
|
[{:keys [file-id libraries]}]
|
||||||
|
;; FIXME: naming
|
||||||
(let [summary?* (mf/use-state true)
|
(let [summary?* (mf/use-state true)
|
||||||
summary? (deref summary?*)
|
summary? (deref summary?*)
|
||||||
updating? (mf/deref refs/updating-library)
|
updating? (mf/deref refs/updating-library)
|
||||||
|
|
||||||
|
;; NOTE: we don't want to react on file changes, we just want
|
||||||
|
;; a snapshot of file on the momento of open the dialog
|
||||||
|
file-data (deref refs/workspace-data)
|
||||||
|
|
||||||
see-all-assets
|
see-all-assets
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -544,22 +573,31 @@
|
||||||
(when (or (pos? (:components exceeded))
|
(when (or (pos? (:components exceeded))
|
||||||
(pos? (:colors exceeded))
|
(pos? (:colors exceeded))
|
||||||
(pos? (:typographies exceeded)))
|
(pos? (:typographies exceeded)))
|
||||||
[:& lb/link-button {:on-click see-all-assets
|
[:& lb/link-button
|
||||||
:class (stl/css :libraries-updates-see-all)
|
{:on-click see-all-assets
|
||||||
:value (str "(" (tr "workspace.libraries.update.see-all-changes") ")")}])])]])]]))
|
:class (stl/css :libraries-updates-see-all)
|
||||||
|
:value (str "(" (tr "workspace.libraries.update.see-all-changes") ")")}])])]])]]))
|
||||||
|
|
||||||
(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] :as props :or {starting-tab :libraries}}]
|
||||||
(let [file-data (mf/deref refs/workspace-data)
|
(let [;; NOTE: we don't want to react on file changes, we just want
|
||||||
file (mf/deref ref:workspace-file)
|
;; a snapshot of file on the momento of open the dialog
|
||||||
|
file (deref refs/file)
|
||||||
|
|
||||||
file-id (:id file)
|
file-id (:id file)
|
||||||
shared? (:is-shared file)
|
shared? (:is-shared file)
|
||||||
|
|
||||||
libraries (mf/deref refs/libraries)
|
linked-libraries
|
||||||
libraries (mf/with-memo [libraries]
|
(mf/deref refs/files)
|
||||||
(d/removem (fn [[_ val]] (:is-indirect val)) libraries))
|
|
||||||
|
linked-libraries
|
||||||
|
(mf/with-memo [linked-libraries file-id]
|
||||||
|
(d/removem (fn [[_ lib]]
|
||||||
|
(or (:is-indirect lib)
|
||||||
|
(= (:id lib) file-id)))
|
||||||
|
linked-libraries))
|
||||||
|
|
||||||
shared-libraries
|
shared-libraries
|
||||||
(mf/deref refs/shared-files)
|
(mf/deref refs/shared-files)
|
||||||
|
@ -578,16 +616,14 @@
|
||||||
|
|
||||||
libraries-tab
|
libraries-tab
|
||||||
(mf/html [:> libraries-tab*
|
(mf/html [:> libraries-tab*
|
||||||
{:file-id file-id
|
{:is-shared shared?
|
||||||
:is-shared shared?
|
:linked-libraries linked-libraries
|
||||||
:linked-libraries libraries
|
|
||||||
:shared-libraries shared-libraries}])
|
:shared-libraries shared-libraries}])
|
||||||
|
|
||||||
updates-tab
|
updates-tab
|
||||||
(mf/html [:> updates-tab*
|
(mf/html [:> updates-tab*
|
||||||
{:file-id file-id
|
{:file-id file-id
|
||||||
:file-data file-data
|
:libraries linked-libraries}])
|
||||||
:libraries libraries}])
|
|
||||||
|
|
||||||
tabs
|
tabs
|
||||||
#js [#js {:label (tr "workspace.libraries.libraries")
|
#js [#js {:label (tr "workspace.libraries.libraries")
|
||||||
|
@ -600,7 +636,9 @@
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(st/emit! (dtm/fetch-shared-files)))
|
(st/emit! (dtm/fetch-shared-files)))
|
||||||
|
|
||||||
[:div {:class (stl/css :modal-overlay) :on-click close-dialog-outside :data-testid "libraries-modal"}
|
[:div {:class (stl/css :modal-overlay)
|
||||||
|
:on-click close-dialog-outside
|
||||||
|
:data-testid "libraries-modal"}
|
||||||
[:div {:class (stl/css :modal-dialog)}
|
[:div {:class (stl/css :modal-dialog)}
|
||||||
[:button {:class (stl/css :close-btn)
|
[:button {:class (stl/css :close-btn)
|
||||||
:on-click close-dialog
|
:on-click close-dialog
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
[app.common.geom.shapes.bounds :as gsb]
|
[app.common.geom.shapes.bounds :as gsb]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.thumbnails :as thc]
|
[app.common.thumbnails :as thc]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.thumbnails :as dwt]
|
[app.main.data.workspace.thumbnails :as dwt]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
::mf/wrap-props false}
|
::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
(let [shape (unchecked-get props "shape")
|
(let [shape (unchecked-get props "shape")
|
||||||
objects (wsh/lookup-page-objects @st/state)
|
objects (dsh/lookup-page-objects @st/state)
|
||||||
|
|
||||||
frame-id (dm/get-prop shape :id)
|
frame-id (dm/get-prop shape :id)
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,11 @@
|
||||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||||
[app.main.ui.workspace.sidebar.assets.file-library :refer [file-library]]
|
[app.main.ui.workspace.sidebar.assets.file-library :refer [file-library*]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc assets-libraries*
|
(mf/defc assets-libraries*
|
||||||
|
@ -31,38 +32,39 @@
|
||||||
::mf/props :obj
|
::mf/props :obj
|
||||||
::mf/private true}
|
::mf/private true}
|
||||||
[{:keys [filters]}]
|
[{:keys [filters]}]
|
||||||
(let [libraries (mf/deref refs/libraries)
|
(let [file-id (mf/use-ctx ctx/current-file-id)
|
||||||
libraries (mf/with-memo [libraries]
|
|
||||||
|
libraries (mf/deref refs/libraries)
|
||||||
|
libraries (mf/with-memo [libraries file-id]
|
||||||
(->> (vals libraries)
|
(->> (vals libraries)
|
||||||
(remove :is-indirect)
|
(remove :is-indirect)
|
||||||
|
(remove #(= file-id (:id %)))
|
||||||
(map (fn [file]
|
(map (fn [file]
|
||||||
(update file :data dissoc :pages-index)))
|
(update file :data dissoc :pages-index)))
|
||||||
(sort-by #(str/lower (:name %)))))]
|
(sort-by #(str/lower (:name %)))))]
|
||||||
|
|
||||||
(for [file libraries]
|
(for [file libraries]
|
||||||
[:& file-library
|
[:> file-library*
|
||||||
{:key (dm/str (:id file))
|
{:key (dm/str (:id file))
|
||||||
:file file
|
:file file
|
||||||
:local? false
|
:is-local false
|
||||||
:default-open? false
|
:is-default-open false
|
||||||
:filters filters}])))
|
:filters filters}])))
|
||||||
|
|
||||||
|
(def ^:private ref:local-library
|
||||||
|
(l/derived (fn [file]
|
||||||
|
(update file :data dissoc :pages-index))
|
||||||
|
refs/file))
|
||||||
|
|
||||||
(mf/defc assets-local-library
|
(mf/defc assets-local-library
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
::mf/wrap-props false}
|
::mf/wrap-props false}
|
||||||
[{:keys [filters]}]
|
[{:keys [filters]}]
|
||||||
;; NOTE: as workspace-file is an incomplete view of file (it do not
|
(let [file (mf/deref ref:local-library)]
|
||||||
;; contain :data), we need to reconstruct it using workspace-data
|
[:> file-library*
|
||||||
(let [file (mf/deref refs/workspace-file)
|
|
||||||
data (mf/deref refs/workspace-data)
|
|
||||||
data (mf/with-memo [data]
|
|
||||||
(dissoc data :pages-index))
|
|
||||||
file (mf/with-memo [file data]
|
|
||||||
(assoc file :data data))]
|
|
||||||
|
|
||||||
[:& file-library
|
|
||||||
{:file file
|
{:file file
|
||||||
:local? true
|
:is-local true
|
||||||
:default-open? true
|
:is-default-open true
|
||||||
:filters filters}]))
|
:filters filters}]))
|
||||||
|
|
||||||
(defn- toggle-values
|
(defn- toggle-values
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
|
@ -58,7 +59,10 @@
|
||||||
(if reverse? "z" "a")
|
(if reverse? "z" "a")
|
||||||
path)]
|
path)]
|
||||||
(str/lower (cfh/merge-path-item path name))))
|
(str/lower (cfh/merge-path-item path name))))
|
||||||
(if ^boolean reverse? > <)))))
|
(if ^boolean reverse? > <))
|
||||||
|
|
||||||
|
:always
|
||||||
|
(vec))))
|
||||||
|
|
||||||
(defn add-group
|
(defn add-group
|
||||||
[asset group-name]
|
[asset group-name]
|
||||||
|
@ -315,10 +319,13 @@
|
||||||
copies (filter ctk/in-component-copy? shapes)
|
copies (filter ctk/in-component-copy? shapes)
|
||||||
|
|
||||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||||
objects (deref refs/workspace-page-objects)
|
current-page-id (mf/use-ctx ctx/current-page-id)
|
||||||
workspace-data (deref refs/workspace-data)
|
|
||||||
libraries (deref refs/libraries)
|
libraries (deref refs/libraries)
|
||||||
current-file {:id current-file-id :data workspace-data}
|
current-file (get libraries current-file-id)
|
||||||
|
|
||||||
|
objects (-> (dsh/get-page (:data current-file) current-page-id)
|
||||||
|
(get :objects))
|
||||||
|
|
||||||
find-component (fn [shape include-deleted?]
|
find-component (fn [shape include-deleted?]
|
||||||
(ctf/resolve-component
|
(ctf/resolve-component
|
||||||
|
|
|
@ -37,31 +37,23 @@
|
||||||
[potok.v2.core :as ptk]
|
[potok.v2.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def drag-data* (atom {:local? false}))
|
(def drag-data* (atom {:is-local false}))
|
||||||
|
|
||||||
(defn set-drag-data! [data]
|
(defn set-drag-data! [data]
|
||||||
(reset! drag-data* data))
|
(reset! drag-data* data))
|
||||||
|
|
||||||
(defn- get-component-root-and-container
|
(defn- get-component-root-and-container
|
||||||
[file-id component components-v2]
|
[file-id component]
|
||||||
(if (= file-id (:id @refs/workspace-file))
|
(let [data (dm/get-in @refs/libraries [file-id :data])
|
||||||
(let [data @refs/workspace-data]
|
root-shape (ctf/get-component-root data component)
|
||||||
[(ctf/get-component-root data component)
|
container (ctf/get-component-page data component)]
|
||||||
(if components-v2
|
[root-shape container]))
|
||||||
(ctf/get-component-page data component)
|
|
||||||
component)])
|
|
||||||
(let [data (dm/get-in @refs/libraries [file-id :data])
|
|
||||||
root-shape (ctf/get-component-root data component)
|
|
||||||
container (if components-v2
|
|
||||||
(ctf/get-component-page data component)
|
|
||||||
component)]
|
|
||||||
[root-shape container])))
|
|
||||||
|
|
||||||
(mf/defc components-item
|
(mf/defc components-item
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[{:keys [component renaming listing-thumbs? selected
|
[{:keys [component renaming listing-thumbs? selected
|
||||||
file-id on-asset-click on-context-menu on-drag-start do-rename
|
file-id on-asset-click on-context-menu on-drag-start do-rename
|
||||||
cancel-rename selected-full selected-paths local]}]
|
cancel-rename selected-full selected-paths is-local]}]
|
||||||
|
|
||||||
(let [item-ref (mf/use-ref)
|
(let [item-ref (mf/use-ref)
|
||||||
|
|
||||||
|
@ -69,7 +61,6 @@
|
||||||
dragging? (deref dragging*)
|
dragging? (deref dragging*)
|
||||||
|
|
||||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
components-v2 (mf/use-ctx ctx/components-v2)
|
|
||||||
component-id (:id component)
|
component-id (:id component)
|
||||||
|
|
||||||
visible? (h/use-visible item-ref :once? true)
|
visible? (h/use-visible item-ref :once? true)
|
||||||
|
@ -78,7 +69,7 @@
|
||||||
;; really need rerender on any change on the file change. If
|
;; really need rerender on any change on the file change. If
|
||||||
;; the component changes, it will trigger rerender anyway.
|
;; the component changes, it will trigger rerender anyway.
|
||||||
[root-shape container]
|
[root-shape container]
|
||||||
(get-component-root-and-container file-id component components-v2)
|
(get-component-root-and-container file-id component)
|
||||||
|
|
||||||
unselect-all
|
unselect-all
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -94,38 +85,38 @@
|
||||||
|
|
||||||
on-component-double-click
|
on-component-double-click
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps file-id component local)
|
(mf/deps file-id component is-local)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(if local
|
(if is-local
|
||||||
(st/emit! (dwl/go-to-local-component component-id))
|
(st/emit! (dwl/go-to-local-component component-id))
|
||||||
(st/emit! (dwl/go-to-component-file file-id component)))))
|
(st/emit! (dwl/go-to-component-file file-id component)))))
|
||||||
|
|
||||||
on-drop
|
on-drop
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps component dragging* selected selected-full selected-paths local drag-data*)
|
(mf/deps component dragging* selected selected-full selected-paths is-local drag-data*)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (and local (:local? @drag-data*))
|
(when (and is-local (:is-local @drag-data*))
|
||||||
(cmm/on-drop-asset event component dragging* selected selected-full
|
(cmm/on-drop-asset event component dragging* selected selected-full
|
||||||
selected-paths dwl/rename-component-and-main-instance))))
|
selected-paths dwl/rename-component-and-main-instance))))
|
||||||
|
|
||||||
on-drag-enter
|
on-drag-enter
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps component dragging* selected selected-paths local drag-data*)
|
(mf/deps component dragging* selected selected-paths is-local drag-data*)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (and local (:local? @drag-data*))
|
(when (and is-local (:is-local @drag-data*))
|
||||||
(cmm/on-drag-enter-asset event component dragging* selected selected-paths))))
|
(cmm/on-drag-enter-asset event component dragging* selected selected-paths))))
|
||||||
|
|
||||||
on-drag-leave
|
on-drag-leave
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps dragging* local drag-data*)
|
(mf/deps dragging* is-local drag-data*)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (and local (:local? @drag-data*))
|
(when (and is-local (:is-local @drag-data*))
|
||||||
(cmm/on-drag-leave-asset event dragging*))))
|
(cmm/on-drag-leave-asset event dragging*))))
|
||||||
|
|
||||||
on-component-drag-start
|
on-component-drag-start
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps file-id component selected item-ref on-drag-start read-only? local)
|
(mf/deps file-id component selected item-ref on-drag-start read-only? is-local)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(if read-only?
|
(if read-only?
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
|
@ -183,7 +174,7 @@
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[{:keys [file-id prefix groups open-groups force-open? renaming listing-thumbs? selected on-asset-click
|
[{:keys [file-id prefix groups open-groups force-open? renaming listing-thumbs? selected on-asset-click
|
||||||
on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-context-menu
|
on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-context-menu
|
||||||
selected-full local]}]
|
selected-full is-local]}]
|
||||||
|
|
||||||
(let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that
|
(let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that
|
||||||
false
|
false
|
||||||
|
@ -199,23 +190,23 @@
|
||||||
selected-full))
|
selected-full))
|
||||||
on-drag-enter
|
on-drag-enter
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps dragging* prefix selected-paths local drag-data*)
|
(mf/deps dragging* prefix selected-paths is-local drag-data*)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (and local (:local? @drag-data*))
|
(when (and is-local (:is-local @drag-data*))
|
||||||
(cmm/on-drag-enter-asset-group event dragging* prefix selected-paths))))
|
(cmm/on-drag-enter-asset-group event dragging* prefix selected-paths))))
|
||||||
|
|
||||||
on-drag-leave
|
on-drag-leave
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps dragging* local drag-data*)
|
(mf/deps dragging* is-local drag-data*)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (and local (:local? @drag-data*))
|
(when (and is-local (:is-local @drag-data*))
|
||||||
(cmm/on-drag-leave-asset event dragging*))))
|
(cmm/on-drag-leave-asset event dragging*))))
|
||||||
|
|
||||||
on-drop
|
on-drop
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps dragging* prefix selected-paths selected-full local drag-data*)
|
(mf/deps dragging* prefix selected-paths selected-full is-local drag-data*)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (and local (:local? @drag-data*))
|
(when (and is-local (:is-local @drag-data*))
|
||||||
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full dwl/rename-component-and-main-instance))))]
|
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full dwl/rename-component-and-main-instance))))]
|
||||||
|
|
||||||
[:div {:class (stl/css :component-group)
|
[:div {:class (stl/css :component-group)
|
||||||
|
@ -248,7 +239,7 @@
|
||||||
|
|
||||||
(when (and (empty? components)
|
(when (and (empty? components)
|
||||||
(some? groups)
|
(some? groups)
|
||||||
local)
|
is-local)
|
||||||
[:div {:class (stl/css-case :drop-space true
|
[:div {:class (stl/css-case :drop-space true
|
||||||
:drop-space-small (not dragging?))}])
|
:drop-space-small (not dragging?))}])
|
||||||
|
|
||||||
|
@ -268,7 +259,7 @@
|
||||||
:on-group on-group
|
:on-group on-group
|
||||||
:do-rename do-rename
|
:do-rename do-rename
|
||||||
:cancel-rename cancel-rename
|
:cancel-rename cancel-rename
|
||||||
:local local}])])
|
:is-local is-local}])])
|
||||||
|
|
||||||
(for [[path-item content] groups]
|
(for [[path-item content] groups]
|
||||||
(when-not (empty? path-item)
|
(when-not (empty? path-item)
|
||||||
|
@ -289,11 +280,11 @@
|
||||||
:on-ungroup on-ungroup
|
:on-ungroup on-ungroup
|
||||||
:on-context-menu on-context-menu
|
:on-context-menu on-context-menu
|
||||||
:selected-full selected-full
|
:selected-full selected-full
|
||||||
:local local}]))])]))
|
:is-local is-local}]))])]))
|
||||||
|
|
||||||
(mf/defc components-section
|
(mf/defc components-section
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[{:keys [file-id local? components listing-thumbs? open? force-open?
|
[{:keys [file-id is-local components listing-thumbs? open? force-open?
|
||||||
reverse-sort? selected on-asset-click on-assets-delete
|
reverse-sort? selected on-asset-click on-assets-delete
|
||||||
on-clear-selection open-status-ref]}]
|
on-clear-selection open-status-ref]}]
|
||||||
|
|
||||||
|
@ -466,7 +457,7 @@
|
||||||
(fn [component event]
|
(fn [component event]
|
||||||
|
|
||||||
(let [file-data
|
(let [file-data
|
||||||
(d/nilv (dm/get-in @refs/libraries [file-id :data]) @refs/workspace-data)
|
(dm/get-in @refs/libraries [file-id :data])
|
||||||
|
|
||||||
shape-main
|
shape-main
|
||||||
(ctf/get-component-root file-data component)]
|
(ctf/get-component-root file-data component)]
|
||||||
|
@ -476,7 +467,7 @@
|
||||||
(set-drag-data! {:file-id file-id
|
(set-drag-data! {:file-id file-id
|
||||||
:component component
|
:component component
|
||||||
:shape shape-main
|
:shape shape-main
|
||||||
:local? local?})
|
:is-local is-local})
|
||||||
|
|
||||||
(dnd/set-data! event "penpot/component" true)
|
(dnd/set-data! event "penpot/component" true)
|
||||||
|
|
||||||
|
@ -487,10 +478,10 @@
|
||||||
|
|
||||||
on-show-main
|
on-show-main
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps current-component-id file-id local?)
|
(mf/deps current-component-id file-id is-local)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(if local?
|
(if is-local
|
||||||
(st/emit! (dwl/go-to-local-component :id current-component-id))
|
(st/emit! (dwl/go-to-local-component :id current-component-id))
|
||||||
(let [component (d/seek #(= (:id %) current-component-id) components)]
|
(let [component (d/seek #(= (:id %) current-component-id) components)]
|
||||||
(st/emit! (dwl/go-to-component-file file-id component))))))
|
(st/emit! (dwl/go-to-component-file file-id component))))))
|
||||||
|
@ -518,7 +509,7 @@
|
||||||
:title (tr "workspace.assets.grid-view")
|
:title (tr "workspace.assets.grid-view")
|
||||||
:id "opt-grid"}]]])
|
:id "opt-grid"}]]])
|
||||||
|
|
||||||
(when (and components-v2 (not read-only?) local?)
|
(when (and components-v2 (not read-only?) is-local)
|
||||||
[:> icon-button* {:variant "ghost"
|
[:> icon-button* {:variant "ghost"
|
||||||
:aria-label (tr "workspace.assets.components.add-component")
|
:aria-label (tr "workspace.assets.components.add-component")
|
||||||
:on-click add-component
|
:on-click add-component
|
||||||
|
@ -547,27 +538,27 @@
|
||||||
:on-ungroup on-ungroup
|
:on-ungroup on-ungroup
|
||||||
:on-context-menu on-context-menu
|
:on-context-menu on-context-menu
|
||||||
:selected-full selected-full
|
:selected-full selected-full
|
||||||
:local ^boolean local?}])
|
:local ^boolean is-local}])
|
||||||
|
|
||||||
[:& cmm/assets-context-menu
|
[:& cmm/assets-context-menu
|
||||||
{:on-close on-close-menu
|
{:on-close on-close-menu
|
||||||
:state @menu-state
|
:state @menu-state
|
||||||
:options [(when (and local? (not (or multi-components? multi-assets? read-only?)))
|
:options [(when (and is-local (not (or multi-components? multi-assets? read-only?)))
|
||||||
{:name (tr "workspace.assets.rename")
|
{:name (tr "workspace.assets.rename")
|
||||||
:id "assets-rename-component"
|
:id "assets-rename-component"
|
||||||
:handler on-rename})
|
:handler on-rename})
|
||||||
(when (and local? (not (or multi-assets? read-only?)))
|
(when (and is-local (not (or multi-assets? read-only?)))
|
||||||
{:name (if components-v2
|
{:name (if components-v2
|
||||||
(tr "workspace.assets.duplicate-main")
|
(tr "workspace.assets.duplicate-main")
|
||||||
(tr "workspace.assets.duplicate"))
|
(tr "workspace.assets.duplicate"))
|
||||||
:id "assets-duplicate-component"
|
:id "assets-duplicate-component"
|
||||||
:handler on-duplicate})
|
:handler on-duplicate})
|
||||||
|
|
||||||
(when (and local? (not read-only?))
|
(when (and is-local (not read-only?))
|
||||||
{:name (tr "workspace.assets.delete")
|
{:name (tr "workspace.assets.delete")
|
||||||
:id "assets-delete-component"
|
:id "assets-delete-component"
|
||||||
:handler on-delete})
|
:handler on-delete})
|
||||||
(when (and local? (not (or multi-assets? read-only?)))
|
(when (and is-local (not (or multi-assets? read-only?)))
|
||||||
{:name (tr "workspace.assets.group")
|
{:name (tr "workspace.assets.group")
|
||||||
:id "assets-group-component"
|
:id "assets-group-component"
|
||||||
:handler on-group})
|
:handler on-group})
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.types.components-list :as ctkl]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
[app.main.ui.workspace.libraries :refer [create-file-library-ref]]
|
|
||||||
[app.main.ui.workspace.sidebar.assets.colors :refer [colors-section]]
|
[app.main.ui.workspace.sidebar.assets.colors :refer [colors-section]]
|
||||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||||
[app.main.ui.workspace.sidebar.assets.components :refer [components-section]]
|
[app.main.ui.workspace.sidebar.assets.components :refer [components-section]]
|
||||||
|
@ -33,6 +33,10 @@
|
||||||
[potok.v2.core :as ptk]
|
[potok.v2.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; REFS
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(def ^:private ref:open-status
|
(def ^:private ref:open-status
|
||||||
(l/derived (l/in [:workspace-assets :open-status]) st/state))
|
(l/derived (l/in [:workspace-assets :open-status]) st/state))
|
||||||
|
|
||||||
|
@ -40,8 +44,37 @@
|
||||||
(-> (l/in [:workspace-assets :selected])
|
(-> (l/in [:workspace-assets :selected])
|
||||||
(l/derived st/state)))
|
(l/derived st/state)))
|
||||||
|
|
||||||
|
(defn- create-file-ref
|
||||||
|
[library-id]
|
||||||
|
(l/derived (fn [state]
|
||||||
|
(dm/get-in state [:files library-id :data]))
|
||||||
|
st/state))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; LOCAL HELPER HOOKS
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn- use-library-ref
|
||||||
|
[file-id]
|
||||||
|
(let [library-ref (mf/with-memo [file-id]
|
||||||
|
(create-file-ref file-id))]
|
||||||
|
(mf/deref library-ref)))
|
||||||
|
|
||||||
|
(defn- use-selected
|
||||||
|
"Returns the currently selected assets set on the library"
|
||||||
|
[file-id]
|
||||||
|
(let [selected-ref
|
||||||
|
(mf/with-memo [file-id]
|
||||||
|
(-> (l/key file-id)
|
||||||
|
(l/derived ref:selected)))]
|
||||||
|
(mf/deref selected-ref)))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; COMPONENTS
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(mf/defc file-library-title*
|
(mf/defc file-library-title*
|
||||||
{::mf/props :obj}
|
{::mf/private true}
|
||||||
[{:keys [is-open is-local file-id page-id file-name]}]
|
[{:keys [is-open is-local file-id page-id file-name]}]
|
||||||
(let [router (mf/deref refs/router)
|
(let [router (mf/deref refs/router)
|
||||||
team-id (mf/use-ctx ctx/current-team-id)
|
team-id (mf/use-ctx ctx/current-team-id)
|
||||||
|
@ -61,8 +94,9 @@
|
||||||
(dom/stop-propagation ev)
|
(dom/stop-propagation ev)
|
||||||
(st/emit! (ptk/data-event ::ev/event {::ev/name "navigate-to-library-file"}))))]
|
(st/emit! (ptk/data-event ::ev/event {::ev/name "navigate-to-library-file"}))))]
|
||||||
|
|
||||||
[:div {:class (stl/css-case :library-title true
|
[:div {:class (stl/css-case
|
||||||
:open is-open)}
|
:library-title true
|
||||||
|
:open is-open)}
|
||||||
[:& title-bar {:collapsable true
|
[:& title-bar {:collapsable true
|
||||||
:collapsed (not is-open)
|
:collapsed (not is-open)
|
||||||
:all-clickable true
|
:all-clickable true
|
||||||
|
@ -71,10 +105,9 @@
|
||||||
(mf/html [:div {:class (stl/css :special-title)}
|
(mf/html [:div {:class (stl/css :special-title)}
|
||||||
(tr "workspace.assets.local-library")])
|
(tr "workspace.assets.local-library")])
|
||||||
;; Do we need to add shared info here?
|
;; Do we need to add shared info here?
|
||||||
|
|
||||||
(mf/html [:div {:class (stl/css :special-title)}
|
(mf/html [:div {:class (stl/css :special-title)}
|
||||||
file-name]))}
|
file-name]))}
|
||||||
(when-not is-local
|
(when-not ^boolean is-local
|
||||||
[:span {:title (tr "workspace.assets.open-library")}
|
[:span {:title (tr "workspace.assets.open-library")}
|
||||||
[:a {:class (stl/css :file-link)
|
[:a {:class (stl/css :file-link)
|
||||||
:href (str "#" url)
|
:href (str "#" url)
|
||||||
|
@ -82,102 +115,87 @@
|
||||||
:on-click on-click}
|
:on-click on-click}
|
||||||
i/open-link]])]]))
|
i/open-link]])]]))
|
||||||
|
|
||||||
(mf/defc file-library-content
|
(defn- extend-selected
|
||||||
{::mf/wrap-props false}
|
[selected type asset-groups asset-id file-id]
|
||||||
[{:keys [file local? open-status-ref on-clear-selection filters]}]
|
(letfn [(flatten-groups [groups]
|
||||||
(let [components-v2 (mf/use-ctx ctx/components-v2)
|
(reduce concat [(get groups "" [])
|
||||||
open-status (mf/deref open-status-ref)
|
(into []
|
||||||
|
(->> (filter #(seq (first %)) groups)
|
||||||
|
(map second)
|
||||||
|
(mapcat flatten-groups)))]))]
|
||||||
|
|
||||||
file-id (:id file)
|
(let [selected' (get selected type)]
|
||||||
project-id (:project-id file)
|
(if (zero? (count selected'))
|
||||||
|
(st/emit! (dw/select-single-asset file-id asset-id type))
|
||||||
|
(let [all-assets (flatten-groups asset-groups)
|
||||||
|
click-index (d/index-of-pred all-assets #(= (:id %) asset-id))
|
||||||
|
first-index (->> (get selected type)
|
||||||
|
(map (fn [asset] (d/index-of-pred all-assets #(= (:id %) asset))))
|
||||||
|
(sort)
|
||||||
|
(first))
|
||||||
|
|
||||||
filters-section (:section filters)
|
min-index (min first-index click-index)
|
||||||
|
max-index (max first-index click-index)
|
||||||
|
ids (->> (d/enumerate all-assets)
|
||||||
|
(into #{} (comp (filter #(<= min-index (first %) max-index))
|
||||||
|
(map (comp :id second)))))]
|
||||||
|
|
||||||
filters-term (:term filters)
|
(st/emit! (dw/select-assets file-id ids type)))))))
|
||||||
filters-ordering (:ordering filters)
|
|
||||||
filters-list-style (:list-style filters)
|
|
||||||
|
|
||||||
reverse-sort? (= :desc filters-ordering)
|
(mf/defc file-library-content*
|
||||||
listing-thumbs? (= :thumbs filters-list-style)
|
{::mf/private true}
|
||||||
|
[{:keys [file is-local open-status-ref on-clear-selection filters colors media typographies components]}]
|
||||||
|
(let [open-status (mf/deref open-status-ref)
|
||||||
|
|
||||||
library-ref (mf/with-memo [file-id]
|
file-id (:id file)
|
||||||
(create-file-library-ref file-id))
|
project-id (:project-id file)
|
||||||
|
|
||||||
library (mf/deref library-ref)
|
filters-section (:section filters)
|
||||||
colors (:colors library)
|
has-filters-term? (not ^boolean (str/empty? (:term filters)))
|
||||||
components (:components library)
|
|
||||||
media (:media library)
|
|
||||||
typographies (:typographies library)
|
|
||||||
|
|
||||||
colors (mf/with-memo [filters colors]
|
reverse-sort? (= :desc (:ordering filters))
|
||||||
(cmm/apply-filters colors filters))
|
listing-thumbs? (= :thumbs (:list-style filters))
|
||||||
components (mf/with-memo [filters components]
|
|
||||||
(cmm/apply-filters components filters))
|
|
||||||
media (mf/with-memo [filters media]
|
|
||||||
(cmm/apply-filters media filters))
|
|
||||||
typographies (mf/with-memo [filters typographies]
|
|
||||||
(cmm/apply-filters typographies filters))
|
|
||||||
|
|
||||||
show-components? (and (or (= filters-section "all")
|
selected (use-selected file-id)
|
||||||
(= filters-section "components"))
|
|
||||||
(or (pos? (count components))
|
|
||||||
(str/empty? filters-term)))
|
|
||||||
show-graphics? (and (or (= filters-section "all")
|
|
||||||
(= filters-section "graphics"))
|
|
||||||
(or (pos? (count media))
|
|
||||||
(and (str/empty? filters-term)
|
|
||||||
(not components-v2))))
|
|
||||||
show-colors? (and (or (= filters-section "all")
|
|
||||||
(= filters-section "colors"))
|
|
||||||
(or (> (count colors) 0)
|
|
||||||
(str/empty? filters-term)))
|
|
||||||
show-typography? (and (or (= filters-section "all")
|
|
||||||
(= filters-section "typographies"))
|
|
||||||
(or (pos? (count typographies))
|
|
||||||
(str/empty? filters-term)))
|
|
||||||
|
|
||||||
selected-lens (mf/with-memo [file-id]
|
show-components?
|
||||||
(-> (l/key file-id)
|
(and (or (= filters-section "all")
|
||||||
(l/derived ref:selected)))
|
(= filters-section "components"))
|
||||||
|
(or (pos? (count components))
|
||||||
|
(not has-filters-term?)))
|
||||||
|
|
||||||
selected (mf/deref selected-lens)
|
show-graphics?
|
||||||
|
(and (or (= filters-section "all")
|
||||||
|
(= filters-section "graphics"))
|
||||||
|
(pos? (count media)))
|
||||||
|
|
||||||
has-term? (not ^boolean (str/empty? filters-term))
|
show-colors?
|
||||||
force-open-components? (when ^boolean has-term? (> 60 (count components)))
|
(and (or (= filters-section "all")
|
||||||
force-open-colors? (when ^boolean has-term? (> 60 (count colors)))
|
(= filters-section "colors"))
|
||||||
force-open-graphics? (when ^boolean has-term? (> 60 (count media)))
|
(or (> (count colors) 0)
|
||||||
force-open-typographies? (when ^boolean has-term? (> 60 (count typographies)))
|
(not has-filters-term?)))
|
||||||
|
|
||||||
extend-selected
|
show-typography?
|
||||||
(fn [type asset-groups asset-id]
|
(and (or (= filters-section "all")
|
||||||
(letfn [(flatten-groups [groups]
|
(= filters-section "typographies"))
|
||||||
(reduce concat [(get groups "" [])
|
(or (pos? (count typographies))
|
||||||
(into []
|
(not has-filters-term?)))
|
||||||
(->> (filter #(seq (first %)) groups)
|
|
||||||
(map second)
|
|
||||||
(mapcat flatten-groups)))]))]
|
|
||||||
|
|
||||||
(let [selected' (get selected type)]
|
force-open-components?
|
||||||
(if (zero? (count selected'))
|
(when ^boolean has-filters-term? (> 60 (count components)))
|
||||||
(st/emit! (dw/select-single-asset file-id asset-id type))
|
|
||||||
(let [all-assets (flatten-groups asset-groups)
|
|
||||||
click-index (d/index-of-pred all-assets #(= (:id %) asset-id))
|
|
||||||
first-index (->> (get selected type)
|
|
||||||
(map (fn [asset] (d/index-of-pred all-assets #(= (:id %) asset))))
|
|
||||||
(sort)
|
|
||||||
(first))
|
|
||||||
|
|
||||||
min-index (min first-index click-index)
|
force-open-colors?
|
||||||
max-index (max first-index click-index)
|
(when ^boolean has-filters-term? (> 60 (count colors)))
|
||||||
ids (->> (d/enumerate all-assets)
|
|
||||||
(into #{} (comp (filter #(<= min-index (first %) max-index))
|
|
||||||
(map (comp :id second)))))]
|
|
||||||
|
|
||||||
(st/emit! (dw/select-assets file-id ids type)))))))
|
force-open-graphics?
|
||||||
|
(when ^boolean has-filters-term? (> 60 (count media)))
|
||||||
|
|
||||||
|
force-open-typographies?
|
||||||
|
(when ^boolean has-filters-term? (> 60 (count typographies)))
|
||||||
|
|
||||||
on-asset-click
|
on-asset-click
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps file-id extend-selected)
|
(mf/deps file-id selected)
|
||||||
(fn [asset-type asset-groups asset-id default-click event]
|
(fn [asset-type asset-groups asset-id default-click event]
|
||||||
(cond
|
(cond
|
||||||
(kbd/mod? event)
|
(kbd/mod? event)
|
||||||
|
@ -188,7 +206,7 @@
|
||||||
(kbd/shift? event)
|
(kbd/shift? event)
|
||||||
(do
|
(do
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(extend-selected asset-type asset-groups asset-id))
|
(extend-selected selected asset-type asset-groups asset-id file-id))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(when default-click
|
(when default-click
|
||||||
|
@ -232,7 +250,7 @@
|
||||||
(when ^boolean show-components?
|
(when ^boolean show-components?
|
||||||
[:& components-section
|
[:& components-section
|
||||||
{:file-id file-id
|
{:file-id file-id
|
||||||
:local? local?
|
:local? is-local
|
||||||
:components components
|
:components components
|
||||||
:listing-thumbs? listing-thumbs?
|
:listing-thumbs? listing-thumbs?
|
||||||
:open? (or ^boolean force-open-components?
|
:open? (or ^boolean force-open-components?
|
||||||
|
@ -249,7 +267,7 @@
|
||||||
[:& graphics-section
|
[:& graphics-section
|
||||||
{:file-id file-id
|
{:file-id file-id
|
||||||
:project-id project-id
|
:project-id project-id
|
||||||
:local? local?
|
:local? is-local
|
||||||
:objects media
|
:objects media
|
||||||
:listing-thumbs? listing-thumbs?
|
:listing-thumbs? listing-thumbs?
|
||||||
:open? (or ^boolean force-open-graphics?
|
:open? (or ^boolean force-open-graphics?
|
||||||
|
@ -265,7 +283,7 @@
|
||||||
(when ^boolean show-colors?
|
(when ^boolean show-colors?
|
||||||
[:& colors-section
|
[:& colors-section
|
||||||
{:file-id file-id
|
{:file-id file-id
|
||||||
:local? local?
|
:local? is-local
|
||||||
:colors colors
|
:colors colors
|
||||||
:open? (or ^boolean force-open-colors?
|
:open? (or ^boolean force-open-colors?
|
||||||
^boolean (get open-status :colors false))
|
^boolean (get open-status :colors false))
|
||||||
|
@ -281,7 +299,7 @@
|
||||||
[:& typographies-section
|
[:& typographies-section
|
||||||
{:file file
|
{:file file
|
||||||
:file-id (:id file)
|
:file-id (:id file)
|
||||||
:local? local?
|
:local? is-local
|
||||||
:typographies typographies
|
:typographies typographies
|
||||||
:open? (or ^boolean force-open-typographies?
|
:open? (or ^boolean force-open-typographies?
|
||||||
^boolean (get open-status :typographies false))
|
^boolean (get open-status :typographies false))
|
||||||
|
@ -303,67 +321,90 @@
|
||||||
[:span {:class (stl/css :no-found-text)}
|
[:span {:class (stl/css :no-found-text)}
|
||||||
(tr "workspace.assets.not-found")]])]))
|
(tr "workspace.assets.not-found")]])]))
|
||||||
|
|
||||||
(defn- force-lib-open? [file-id filters]
|
(mf/defc file-library*
|
||||||
(let [library-ref (mf/with-memo [file-id]
|
[{:keys [file is-local is-default-open? filters]}]
|
||||||
(create-file-library-ref file-id))
|
(let [file-id (:id file)
|
||||||
library (mf/deref library-ref)
|
file-name (:name file)
|
||||||
|
page-id (dm/get-in file [:data :pages 0])
|
||||||
|
|
||||||
colors (:colors library)
|
library (use-library-ref file-id)
|
||||||
components (:components library)
|
|
||||||
media (:media library)
|
|
||||||
typographies (:typographies library)
|
|
||||||
|
|
||||||
filtered-colors (mf/with-memo [filters colors]
|
colors (:colors library)
|
||||||
(cmm/apply-filters colors filters))
|
media (:media library)
|
||||||
filtered-components (mf/with-memo [filters components]
|
typographies (:typographies library)
|
||||||
(cmm/apply-filters components filters))
|
|
||||||
filtered-media (mf/with-memo [filters media]
|
|
||||||
(cmm/apply-filters media filters))
|
|
||||||
filtered-typographies (mf/with-memo [filters typographies]
|
|
||||||
(cmm/apply-filters typographies filters))
|
|
||||||
|
|
||||||
filters-term (:term filters)
|
filters-term (:term filters)
|
||||||
has-term? (not (str/blank? filters-term))]
|
|
||||||
(and has-term?
|
|
||||||
(some pos? (map count [filtered-components filtered-colors filtered-media filtered-typographies]))
|
|
||||||
(some #(> 60 (count %)) [filtered-components filtered-colors filtered-media filtered-typographies]))))
|
|
||||||
|
|
||||||
(mf/defc file-library
|
;; FIXME: maybe unused
|
||||||
{::mf/props :obj}
|
;; has-term? (not (str/blank? filters-term))
|
||||||
[{:keys [file local? default-open? filters]}]
|
|
||||||
(let [file-id (:id file)
|
|
||||||
file-name (:name file)
|
|
||||||
page-id (dm/get-in file [:data :pages 0])
|
|
||||||
|
|
||||||
open-status-ref (mf/with-memo [file-id]
|
filtered-colors
|
||||||
(-> (l/key file-id)
|
(mf/with-memo [filters colors]
|
||||||
(l/derived ref:open-status)))
|
(-> (vals colors)
|
||||||
open-status (mf/deref open-status-ref)
|
(cmm/apply-filters filters)))
|
||||||
force-open-lib? (force-lib-open? file-id filters)
|
|
||||||
|
|
||||||
open? (if (false? (:library open-status)) ;; if the user has closed it specifically, respect that
|
filtered-components
|
||||||
false
|
(mf/with-memo [filters library]
|
||||||
(or force-open-lib?
|
(-> (into [] (ctkl/components-seq library))
|
||||||
(d/nilv (:library open-status) default-open?)))
|
(cmm/apply-filters filters)))
|
||||||
|
|
||||||
|
filtered-media
|
||||||
|
(mf/with-memo [filters media]
|
||||||
|
(-> (vals media)
|
||||||
|
(cmm/apply-filters filters)))
|
||||||
|
|
||||||
|
filtered-typographies
|
||||||
|
(mf/with-memo [filters typographies]
|
||||||
|
(-> (vals typographies)
|
||||||
|
(cmm/apply-filters filters)))
|
||||||
|
|
||||||
|
open-status-ref
|
||||||
|
(mf/with-memo [file-id]
|
||||||
|
(-> (l/key file-id)
|
||||||
|
(l/derived ref:open-status)))
|
||||||
|
|
||||||
|
open-status
|
||||||
|
(mf/deref open-status-ref)
|
||||||
|
|
||||||
|
force-lib-open?
|
||||||
|
(and (not (str/blank? filters-term))
|
||||||
|
(or (> 60 (count filtered-colors))
|
||||||
|
(> 60 (count filtered-components))
|
||||||
|
(> 60 (count filtered-media))
|
||||||
|
(> 60 (count filtered-typographies))))
|
||||||
|
|
||||||
|
open?
|
||||||
|
(if (false? (:library open-status))
|
||||||
|
;; if the user has closed it specifically, respect that
|
||||||
|
false
|
||||||
|
(or force-lib-open?
|
||||||
|
(d/nilv (:library open-status) is-default-open?)))
|
||||||
|
|
||||||
unselect-all
|
unselect-all
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps file-id)
|
(mf/deps file-id)
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dw/unselect-all-assets file-id))))]
|
(st/emit! (dw/unselect-all-assets file-id))))]
|
||||||
|
|
||||||
[:div {:class (stl/css :tool-window)
|
[:div {:class (stl/css :tool-window)
|
||||||
:on-context-menu dom/prevent-default
|
:on-context-menu dom/prevent-default
|
||||||
:on-click unselect-all}
|
:on-click unselect-all}
|
||||||
|
|
||||||
[:> file-library-title*
|
[:> file-library-title*
|
||||||
{:file-id file-id
|
{:file-id file-id
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:file-name file-name
|
:file-name file-name
|
||||||
:is-open open?
|
:is-open open?
|
||||||
:is-local local?}]
|
:is-local is-local}]
|
||||||
|
|
||||||
(when ^boolean open?
|
(when ^boolean open?
|
||||||
[:& file-library-content
|
[:> file-library-content*
|
||||||
{:file file
|
{:file file
|
||||||
:local? local?
|
:is-local is-local
|
||||||
:filters filters
|
:filters filters
|
||||||
|
:colors filtered-colors
|
||||||
|
:components filtered-components
|
||||||
|
:media filtered-media
|
||||||
|
:typographies filtered-typographies
|
||||||
:on-clear-selection unselect-all
|
:on-clear-selection unselect-all
|
||||||
:open-status-ref open-status-ref}])]))
|
:open-status-ref open-status-ref}])]))
|
||||||
|
|
|
@ -249,6 +249,7 @@
|
||||||
|
|
||||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||||
|
|
||||||
typographies (mf/with-memo [typographies]
|
typographies (mf/with-memo [typographies]
|
||||||
(mapv dwl/extract-path-if-missing typographies))
|
(mapv dwl/extract-path-if-missing typographies))
|
||||||
|
|
||||||
|
|
|
@ -169,11 +169,12 @@
|
||||||
(defn use-search
|
(defn use-search
|
||||||
[page objects]
|
[page objects]
|
||||||
(let [state* (mf/use-state
|
(let [state* (mf/use-state
|
||||||
{:show-search false
|
#(do {:show-search false
|
||||||
:show-menu false
|
:show-menu false
|
||||||
:search-text ""
|
:search-text ""
|
||||||
:filters #{}
|
:filters #{}
|
||||||
:num-items 100})
|
:num-items 100}))
|
||||||
|
|
||||||
state (deref state*)
|
state (deref state*)
|
||||||
current-filters (:filters state)
|
current-filters (:filters state)
|
||||||
current-items (:num-items state)
|
current-items (:num-items state)
|
||||||
|
|
|
@ -268,15 +268,6 @@
|
||||||
[:span {:class (stl/css :arrow-icon)}
|
[:span {:class (stl/css :arrow-icon)}
|
||||||
i/arrow]]))
|
i/arrow]]))
|
||||||
|
|
||||||
(def ^:private ref:swap-libraries
|
|
||||||
(letfn [(get-libraries [state]
|
|
||||||
(let [file (:workspace-file state)
|
|
||||||
data (:workspace-data state)
|
|
||||||
libs (:libraries state)]
|
|
||||||
(assoc libs (:id file)
|
|
||||||
(assoc file :data data))))]
|
|
||||||
(l/derived get-libraries st/state)))
|
|
||||||
|
|
||||||
(defn- find-common-path
|
(defn- find-common-path
|
||||||
([components]
|
([components]
|
||||||
(let [paths (map (comp cfh/split-path :path) components)]
|
(let [paths (map (comp cfh/split-path :path) components)]
|
||||||
|
@ -298,14 +289,13 @@
|
||||||
(= (:component-id shape-a)
|
(= (:component-id shape-a)
|
||||||
(:component-id shape-b)))
|
(:component-id shape-b)))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc component-swap
|
(mf/defc component-swap
|
||||||
{::mf/props :obj}
|
{::mf/props :obj}
|
||||||
[{:keys [shapes]}]
|
[{:keys [shapes]}]
|
||||||
(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 ref:swap-libraries)
|
libraries (mf/deref refs/files)
|
||||||
objects (mf/deref refs/workspace-page-objects)
|
objects (mf/deref refs/workspace-page-objects)
|
||||||
|
|
||||||
^boolean
|
^boolean
|
||||||
|
@ -522,12 +512,13 @@
|
||||||
{::mf/props :obj}
|
{::mf/props :obj}
|
||||||
[{:keys [shapes swap-opened?]}]
|
[{:keys [shapes swap-opened?]}]
|
||||||
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
||||||
components-v2 (mf/use-ctx ctx/components-v2)
|
|
||||||
workspace-data (deref refs/workspace-data)
|
|
||||||
libraries (deref refs/libraries)
|
|
||||||
|
|
||||||
state* (mf/use-state {:show-content true
|
libraries (deref refs/libraries)
|
||||||
:menu-open false})
|
current-file (get libraries current-file-id)
|
||||||
|
|
||||||
|
state* (mf/use-state
|
||||||
|
#(do {:show-content true
|
||||||
|
:menu-open false}))
|
||||||
state (deref state*)
|
state (deref state*)
|
||||||
open? (:show-content state)
|
open? (:show-content state)
|
||||||
menu-open? (:menu-open state)
|
menu-open? (:menu-open state)
|
||||||
|
@ -535,18 +526,18 @@
|
||||||
shapes (filter ctk/instance-head? shapes)
|
shapes (filter ctk/instance-head? shapes)
|
||||||
multi (> (count shapes) 1)
|
multi (> (count shapes) 1)
|
||||||
copies (filter ctk/in-component-copy? shapes)
|
copies (filter ctk/in-component-copy? shapes)
|
||||||
can-swap? (and components-v2 (seq copies))
|
can-swap? (boolean (seq copies))
|
||||||
|
|
||||||
;; For when it's only one shape
|
;; For when it's only one shape
|
||||||
shape (first shapes)
|
shape (first shapes)
|
||||||
id (:id shape)
|
id (:id shape)
|
||||||
shape-name (:name shape)
|
shape-name (:name shape)
|
||||||
|
|
||||||
component (ctf/resolve-component shape
|
component (ctf/resolve-component shape
|
||||||
{:id current-file-id
|
current-file
|
||||||
:data workspace-data}
|
|
||||||
libraries
|
libraries
|
||||||
{:include-deleted? true})
|
{:include-deleted? true})
|
||||||
main-instance? (if components-v2 (ctk/main-instance? shape) true)
|
main-instance? (ctk/main-instance? shape)
|
||||||
|
|
||||||
toggle-content
|
toggle-content
|
||||||
(mf/use-fn #(swap! state* update :show-content not))
|
(mf/use-fn #(swap! state* update :show-content not))
|
||||||
|
@ -585,7 +576,7 @@
|
||||||
(fn []
|
(fn []
|
||||||
(swap! state* update :render inc)))
|
(swap! state* update :render inc)))
|
||||||
|
|
||||||
menu-entries (cmm/generate-components-menu-entries shapes components-v2)
|
menu-entries (cmm/generate-components-menu-entries shapes true)
|
||||||
show-menu? (seq menu-entries)
|
show-menu? (seq menu-entries)
|
||||||
path (->> component (:path) (cfh/split-path) (cfh/join-path-with-dot))]
|
path (->> component (:path) (cfh/split-path) (cfh/join-path-with-dot))]
|
||||||
|
|
||||||
|
@ -650,7 +641,7 @@
|
||||||
(when swap-opened?
|
(when swap-opened?
|
||||||
[:& component-swap {:shapes copies}])
|
[:& component-swap {:shapes copies}])
|
||||||
|
|
||||||
(when (and (not swap-opened?) (not multi) components-v2)
|
(when (and (not swap-opened?) (not multi))
|
||||||
[:& component-annotation {:id id :shape shape :component component :rerender-fn rerender-fn}])
|
[:& component-annotation {:id id :shape shape :component component :rerender-fn rerender-fn}])
|
||||||
(when (dbg/enabled? :display-touched)
|
(when (dbg/enabled? :display-touched)
|
||||||
[:div ":touched " (str (:touched shape))])])])))
|
[:div ":touched " (str (:touched shape))])])])))
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.main.data.exports.assets :as de]
|
[app.main.data.exports.assets :as de]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.select :refer [select]]
|
[app.main.ui.components.select :refer [select]]
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
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)
|
shapes-with-exports (->> (dsh/lookup-shapes @st/state ids)
|
||||||
(filter #(pos? (count (:exports %)))))
|
(filter #(pos? (count (:exports %)))))
|
||||||
|
|
||||||
sname (when (seqable? exports)
|
sname (when (seqable? exports)
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.colors :as clr]
|
[app.common.colors :as clr]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.types.color :as ctc]
|
||||||
[app.common.types.shape.attrs :refer [default-color]]
|
[app.common.types.shape.attrs :refer [default-color]]
|
||||||
[app.main.data.workspace.colors :as dc]
|
[app.main.data.workspace.colors :as dc]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -167,12 +168,7 @@
|
||||||
(seq fills)
|
(seq fills)
|
||||||
[:& h/sortable-container {}
|
[:& h/sortable-container {}
|
||||||
(for [[index value] (d/enumerate (:fills values []))]
|
(for [[index value] (d/enumerate (:fills values []))]
|
||||||
[:& color-row {:color {:color (:fill-color value)
|
[:& color-row {:color (ctc/fill->color value)
|
||||||
:opacity (:fill-opacity value)
|
|
||||||
:id (:fill-color-ref-id value)
|
|
||||||
:file-id (:fill-color-ref-file value)
|
|
||||||
:gradient (:fill-color-gradient value)
|
|
||||||
:image (:fill-image value)}
|
|
||||||
:key index
|
:key index
|
||||||
:index index
|
:index index
|
||||||
:title (tr "workspace.options.fill")
|
:title (tr "workspace.options.fill")
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.numeric-input :refer [numeric-input*]]
|
[app.main.ui.components.numeric-input :refer [numeric-input*]]
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
wasm-renderer-enabled? (features/use-feature "render-wasm/v1")
|
wasm-renderer-enabled? (features/use-feature "render-wasm/v1")
|
||||||
|
|
||||||
shapes (->
|
shapes (->
|
||||||
(wsh/lookup-page-objects @st/state)
|
(dsh/lookup-page-objects @st/state)
|
||||||
(select-keys ids)
|
(select-keys ids)
|
||||||
vals)
|
vals)
|
||||||
|
|
||||||
|
|
|
@ -57,16 +57,16 @@
|
||||||
(or next (peek fonts)))
|
(or next (peek fonts)))
|
||||||
current))
|
current))
|
||||||
|
|
||||||
(mf/defc font-item
|
(mf/defc font-item*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [font current? on-click style]}]
|
[{:keys [font is-current on-click style]}]
|
||||||
(let [item-ref (mf/use-ref)
|
(let [item-ref (mf/use-ref)
|
||||||
on-click (mf/use-fn (mf/deps font) #(on-click font))]
|
on-click (mf/use-fn (mf/deps font) #(on-click font))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps current?)
|
(mf/deps is-current)
|
||||||
(fn []
|
(fn []
|
||||||
(when current?
|
(when is-current
|
||||||
(let [element (mf/ref-val item-ref)]
|
(let [element (mf/ref-val item-ref)]
|
||||||
(when-not (dom/is-in-viewport? element)
|
(when-not (dom/is-in-viewport? element)
|
||||||
(dom/scroll-into-view! element))))))
|
(dom/scroll-into-view! element))))))
|
||||||
|
@ -76,9 +76,9 @@
|
||||||
:ref item-ref
|
:ref item-ref
|
||||||
:on-click on-click}
|
:on-click on-click}
|
||||||
[:div {:class (stl/css-case :font-item true
|
[:div {:class (stl/css-case :font-item true
|
||||||
:selected current?)}
|
:selected is-current)}
|
||||||
[:span {:class (stl/css :label)} (:name font)]
|
[:span {:class (stl/css :label)} (:name font)]
|
||||||
[:span {:class (stl/css :icon)} (when current? i/tick)]]]))
|
[:span {:class (stl/css :icon)} (when is-current i/tick)]]]))
|
||||||
|
|
||||||
(declare row-renderer)
|
(declare row-renderer)
|
||||||
|
|
||||||
|
@ -93,18 +93,23 @@
|
||||||
(comp (filter #(contains? backends (:backend %)))))]
|
(comp (filter #(contains? backends (:backend %)))))]
|
||||||
(into [] xform fonts)))
|
(into [] xform fonts)))
|
||||||
|
|
||||||
(mf/defc font-selector
|
(mf/defc font-selector*
|
||||||
[{:keys [on-select on-close current-font show-recent full-size] :as props}]
|
[{:keys [on-select on-close current-font show-recent full-size]}]
|
||||||
(let [selected (mf/use-state current-font)
|
(let [selected (mf/use-state current-font)
|
||||||
state (mf/use-state {:term "" :backends #{}})
|
state* (mf/use-state
|
||||||
|
#(do {:term "" :backends #{}}))
|
||||||
|
state (deref state*)
|
||||||
|
|
||||||
flist (mf/use-ref)
|
flist (mf/use-ref)
|
||||||
input (mf/use-ref)
|
input (mf/use-ref)
|
||||||
|
|
||||||
fonts (mf/use-memo (mf/deps @state) #(filter-fonts @state @fonts/fonts))
|
fonts (mf/deref fonts/fonts)
|
||||||
recent-fonts (mf/deref refs/workspace-recent-fonts)
|
fonts (mf/with-memo [state fonts]
|
||||||
|
(filter-fonts state fonts))
|
||||||
|
|
||||||
full-size? (boolean (and full-size show-recent))
|
recent-fonts (mf/deref refs/recent-fonts)
|
||||||
|
|
||||||
|
full-size? (boolean (and full-size show-recent))
|
||||||
|
|
||||||
select-next
|
select-next
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -136,7 +141,7 @@
|
||||||
on-filter-change
|
on-filter-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(swap! state assoc :term event)))
|
(swap! state* assoc :term event)))
|
||||||
|
|
||||||
on-select-and-close
|
on-select-and-close
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -145,9 +150,6 @@
|
||||||
(on-select font)
|
(on-select font)
|
||||||
(on-close)))]
|
(on-close)))]
|
||||||
|
|
||||||
(mf/with-effect [fonts]
|
|
||||||
(st/emit! (fts/load-recent-fonts fonts)))
|
|
||||||
|
|
||||||
(mf/with-effect [fonts]
|
(mf/with-effect [fonts]
|
||||||
(let [key (events/listen js/document "keydown" on-key-down)]
|
(let [key (events/listen js/document "keydown" on-key-down)]
|
||||||
#(events/unlistenByKey key)))
|
#(events/unlistenByKey key)))
|
||||||
|
@ -176,18 +178,18 @@
|
||||||
[:div {:class (stl/css-case :font-selector-dropdown true :font-selector-dropdown-full-size full-size?)}
|
[:div {:class (stl/css-case :font-selector-dropdown true :font-selector-dropdown-full-size full-size?)}
|
||||||
[:div {:class (stl/css :header)}
|
[:div {:class (stl/css :header)}
|
||||||
[:& search-bar {:on-change on-filter-change
|
[:& search-bar {:on-change on-filter-change
|
||||||
:value (:term @state)
|
:value (:term state)
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
:placeholder (tr "workspace.options.search-font")}]
|
:placeholder (tr "workspace.options.search-font")}]
|
||||||
(when (and recent-fonts show-recent)
|
(when (and recent-fonts show-recent)
|
||||||
[:section {:class (stl/css :show-recent)}
|
[:section {:class (stl/css :show-recent)}
|
||||||
[:p {:class (stl/css :title)} (tr "workspace.options.recent-fonts")]
|
[:p {:class (stl/css :title)} (tr "workspace.options.recent-fonts")]
|
||||||
(for [[idx font] (d/enumerate recent-fonts)]
|
(for [[idx font] (d/enumerate recent-fonts)]
|
||||||
[:& font-item {:key (dm/str "font-" idx)
|
[:> font-item* {:key (dm/str "font-" idx)
|
||||||
:font font
|
:font font
|
||||||
:style {}
|
:style {}
|
||||||
:on-click on-select-and-close
|
:on-click on-select-and-close
|
||||||
:current? (= (:id font) (:id @selected))}])])]
|
:is-current (= (:id font) (:id @selected))}])])]
|
||||||
|
|
||||||
[:div {:class (stl/css-case :fonts-list true
|
[:div {:class (stl/css-case :fonts-list true
|
||||||
:fonts-list-full-size full-size?)}
|
:fonts-list-full-size full-size?)}
|
||||||
|
@ -211,11 +213,11 @@
|
||||||
style (unchecked-get props "style")
|
style (unchecked-get props "style")
|
||||||
font (nth fonts index)]
|
font (nth fonts index)]
|
||||||
(mf/html
|
(mf/html
|
||||||
[:& font-item {:key key
|
[:> font-item* {:key key
|
||||||
:font font
|
:font font
|
||||||
:style style
|
:style style
|
||||||
:on-click on-select
|
:on-click on-select
|
||||||
:current? (= (:id font) (:id selected))}])))
|
:is-current (= (:id font) (:id selected))}])))
|
||||||
|
|
||||||
(mf/defc font-options
|
(mf/defc font-options
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
@ -228,14 +230,14 @@
|
||||||
|
|
||||||
fonts (mf/deref fonts/fontsdb)
|
fonts (mf/deref fonts/fontsdb)
|
||||||
font (get fonts font-id)
|
font (get fonts font-id)
|
||||||
recent-fonts (mf/deref refs/workspace-recent-fonts)
|
|
||||||
last-font (mf/use-ref nil)
|
last-font (mf/use-ref nil)
|
||||||
|
|
||||||
open-selector? (mf/use-state false)
|
open-selector? (mf/use-state false)
|
||||||
|
|
||||||
change-font
|
change-font
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps on-change fonts recent-fonts)
|
(mf/deps on-change fonts)
|
||||||
(fn [new-font-id]
|
(fn [new-font-id]
|
||||||
(let [{:keys [family] :as font} (get fonts new-font-id)
|
(let [{:keys [family] :as font} (get fonts new-font-id)
|
||||||
{:keys [id name weight style]} (fonts/get-default-variant font)]
|
{:keys [id name weight style]} (fonts/get-default-variant font)]
|
||||||
|
@ -286,7 +288,7 @@
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
(when @open-selector?
|
(when @open-selector?
|
||||||
[:& font-selector
|
[:> font-selector*
|
||||||
{:current-font font
|
{:current-font font
|
||||||
:on-close on-font-selector-close
|
:on-close on-font-selector-close
|
||||||
:on-select on-font-select
|
:on-select on-font-select
|
||||||
|
@ -448,7 +450,7 @@
|
||||||
|
|
||||||
(mf/defc typography-advanced-options
|
(mf/defc typography-advanced-options
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [visible? typography editable? name-input-ref on-close on-change on-name-blur local? navigate-to-library on-key-down]}]
|
[{:keys [visible? typography editable? name-input-ref on-close on-change on-name-blur local? navigate-to-library on-key-down]}]
|
||||||
(let [ref (mf/use-ref nil)
|
(let [ref (mf/use-ref nil)
|
||||||
font-data (fonts/get-font-data (:font-id typography))]
|
font-data (fonts/get-font-data (:font-id typography))]
|
||||||
(fonts/ensure-loaded! (:font-id typography))
|
(fonts/ensure-loaded! (:font-id typography))
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def lens:background-color
|
(def ^:private ref:background-color
|
||||||
(-> (l/key :background)
|
(-> (l/key :background)
|
||||||
(l/derived refs/workspace-page)))
|
(l/derived refs/workspace-page)))
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
::mf/wrap-props false}
|
::mf/wrap-props false}
|
||||||
[]
|
[]
|
||||||
(let [background (mf/deref lens:background-color)
|
(let [background (mf/deref ref:background-color)
|
||||||
on-change (mf/use-fn #(st/emit! (dw/change-canvas-color %)))
|
on-change (mf/use-fn #(st/emit! (dw/change-canvas-color %)))
|
||||||
on-open (mf/use-fn #(st/emit! (dwu/start-undo-transaction :options)))
|
on-open (mf/use-fn #(st/emit! (dwu/start-undo-transaction :options)))
|
||||||
on-close (mf/use-fn #(st/emit! (dwu/commit-undo-transaction :options)))]
|
on-close (mf/use-fn #(st/emit! (dwu/commit-undo-transaction :options)))]
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
|
@ -27,6 +28,29 @@
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
;; FIXME: can we unify this two refs in one?
|
||||||
|
|
||||||
|
(def ^:private ref:file-with-pages
|
||||||
|
"A derived state of the current file, without data with the
|
||||||
|
exception of list of pages"
|
||||||
|
(l/derived (fn [{:keys [data] :as file}]
|
||||||
|
(-> file
|
||||||
|
(dissoc :data)
|
||||||
|
(assoc :pages (:pages data))))
|
||||||
|
refs/file
|
||||||
|
=))
|
||||||
|
|
||||||
|
(defn- make-page-ref
|
||||||
|
"Create a derived state that poins to a page identified by `page-id`
|
||||||
|
without including the page objects (mainly for avoid rerender on
|
||||||
|
each object change)"
|
||||||
|
[page-id]
|
||||||
|
(l/derived (fn [fdata]
|
||||||
|
(-> (dsh/get-page fdata page-id)
|
||||||
|
(dissoc :objects)))
|
||||||
|
refs/workspace-data
|
||||||
|
=))
|
||||||
|
|
||||||
;; --- Page Item
|
;; --- Page Item
|
||||||
|
|
||||||
(mf/defc page-item
|
(mf/defc page-item
|
||||||
|
@ -155,17 +179,11 @@
|
||||||
|
|
||||||
;; --- Page Item Wrapper
|
;; --- Page Item Wrapper
|
||||||
|
|
||||||
(defn- make-page-ref
|
|
||||||
[page-id]
|
|
||||||
(l/derived (fn [state]
|
|
||||||
(let [page (get-in state [:workspace-data :pages-index page-id])]
|
|
||||||
(select-keys page [:id :name])))
|
|
||||||
st/state =))
|
|
||||||
|
|
||||||
(mf/defc page-item-wrapper
|
(mf/defc page-item-wrapper
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[{:keys [page-id index deletable? selected? editing?]}]
|
[{:keys [page-id index deletable? selected? editing?]}]
|
||||||
(let [page-ref (mf/use-memo (mf/deps page-id) #(make-page-ref page-id))
|
(let [page-ref (mf/with-memo [page-id]
|
||||||
|
(make-page-ref page-id))
|
||||||
page (mf/deref page-ref)]
|
page (mf/deref page-ref)]
|
||||||
[:& page-item {:page page
|
[:& page-item {:page page
|
||||||
:index index
|
:index index
|
||||||
|
@ -198,7 +216,7 @@
|
||||||
(mf/defc sitemap
|
(mf/defc sitemap
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[{:keys [size show-pages? toggle-pages]}]
|
[{:keys [size show-pages? toggle-pages]}]
|
||||||
(let [file (mf/deref refs/workspace-file)
|
(let [file (mf/deref ref:file-with-pages)
|
||||||
file-id (get file :id)
|
file-id (get file :id)
|
||||||
project-id (get file :project-id)
|
project-id (get file :project-id)
|
||||||
|
|
||||||
|
@ -207,6 +225,7 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(st/emit! (dw/create-page {:file-id file-id :project-id project-id}))
|
(st/emit! (dw/create-page {:file-id file-id :project-id project-id}))
|
||||||
(-> event dom/get-current-target dom/blur!)))
|
(-> event dom/get-current-target dom/blur!)))
|
||||||
|
|
||||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
permissions (mf/use-ctx ctx/permissions)]
|
permissions (mf/use-ctx ctx/permissions)]
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
[app.common.types.shape.radius :as ctsr]
|
[app.common.types.shape.radius :as ctsr]
|
||||||
[app.common.types.token :as ctt]
|
[app.common.types.token :as ctt]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace :as udw]
|
[app.main.data.workspace :as udw]
|
||||||
[app.main.data.workspace.colors :as wdc]
|
[app.main.data.workspace.colors :as wdc]
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.transforms :as dwt]
|
[app.main.data.workspace.transforms :as dwt]
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -36,7 +36,8 @@
|
||||||
(ptk/reify ::apply-token
|
(ptk/reify ::apply-token
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(when-let [tokens (some-> (get-in state [:workspace-data :tokens-lib])
|
(when-let [tokens (some-> (dsh/lookup-file-data state)
|
||||||
|
(get :tokens-lib)
|
||||||
(ctob/get-active-themes-set-tokens))]
|
(ctob/get-active-themes-set-tokens))]
|
||||||
(->> (rx/from (sd/resolve-tokens+ tokens))
|
(->> (rx/from (sd/resolve-tokens+ tokens))
|
||||||
(rx/mapcat
|
(rx/mapcat
|
||||||
|
@ -179,7 +180,7 @@
|
||||||
(ptk/reify ::update-layout-spacing
|
(ptk/reify ::update-layout-spacing
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [layout-shape-ids (->> (wsh/lookup-shapes state shape-ids)
|
(let [layout-shape-ids (->> (dsh/lookup-shapes state shape-ids)
|
||||||
(eduction
|
(eduction
|
||||||
(filter :layout)
|
(filter :layout)
|
||||||
(map :id)))
|
(map :id)))
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
(ns app.main.ui.workspace.tokens.token-set
|
(ns app.main.ui.workspace.tokens.token-set
|
||||||
(:require
|
(:require
|
||||||
[app.common.types.tokens-lib :as ctob]))
|
[app.common.types.tokens-lib :as ctob]
|
||||||
|
[app.main.data.helpers :as dsh]))
|
||||||
|
|
||||||
(defn get-workspace-tokens-lib [state]
|
(defn get-workspace-tokens-lib
|
||||||
(get-in state [:workspace-data :tokens-lib]))
|
[state]
|
||||||
|
(-> (dsh/lookup-file-data state)
|
||||||
|
(get :tokens-lib)))
|
||||||
|
|
||||||
;; Themes ----------------------------------------------------------------------
|
;; Themes ----------------------------------------------------------------------
|
||||||
|
|
||||||
(defn get-active-theme-ids [state]
|
(defn get-active-theme-ids
|
||||||
(get-in state [:workspace-data :token-active-themes] #{}))
|
[state]
|
||||||
|
(-> (dsh/lookup-file-data state)
|
||||||
|
(get :token-active-themes #{})))
|
||||||
|
|
||||||
(defn get-temp-theme-id [state]
|
(defn get-temp-theme-id
|
||||||
(get-in state [:workspace-data :token-theme-temporary-id]))
|
[state]
|
||||||
|
(-> (dsh/lookup-file-data state)
|
||||||
|
(get :token-theme-temporary-id)))
|
||||||
|
|
||||||
(defn update-theme-id
|
(defn update-theme-id
|
||||||
[state]
|
[state]
|
||||||
|
@ -22,8 +29,11 @@
|
||||||
(= 1 (count active-themes)) (first active-themes)
|
(= 1 (count active-themes)) (first active-themes)
|
||||||
:else temporary-theme-id)))
|
:else temporary-theme-id)))
|
||||||
|
|
||||||
(defn get-workspace-token-theme [id state]
|
(defn get-workspace-token-theme
|
||||||
(get-in state [:workspace-data :token-themes-index id]))
|
[id state]
|
||||||
|
(-> (dsh/lookup-file-data state)
|
||||||
|
(get :token-themes-index)
|
||||||
|
(get id)))
|
||||||
|
|
||||||
(defn add-token-set-to-token-theme [token-set-id token-theme]
|
(defn add-token-set-to-token-theme [token-set-id token-theme]
|
||||||
(update token-theme :sets conj token-set-id))
|
(update token-theme :sets conj token-set-id))
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
(ns app.main.ui.workspace.tokens.update
|
(ns app.main.ui.workspace.tokens.update
|
||||||
(:require
|
(:require
|
||||||
[app.common.types.token :as ctt]
|
[app.common.types.token :as ctt]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||||
[app.main.ui.workspace.tokens.style-dictionary :as wtsd]
|
[app.main.ui.workspace.tokens.style-dictionary :as wtsd]
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
shapes-update-info))
|
shapes-update-info))
|
||||||
|
|
||||||
(defn update-tokens [state resolved-tokens]
|
(defn update-tokens [state resolved-tokens]
|
||||||
(->> (wsh/lookup-page-objects state)
|
(->> (dsh/lookup-page-objects state)
|
||||||
(collect-shapes-update-info resolved-tokens)
|
(collect-shapes-update-info resolved-tokens)
|
||||||
(actionize-shapes-update-info)))
|
(actionize-shapes-update-info)))
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,8 @@
|
||||||
objects
|
objects
|
||||||
selected))
|
selected))
|
||||||
|
|
||||||
(mf/defc viewport-classic
|
(mf/defc viewport-classic*
|
||||||
[{:keys [selected wglobal wlocal layout file palete-size] :as props}]
|
[{:keys [selected wglobal wlocal layout file page palete-size]}]
|
||||||
(let [;; When adding data from workspace-local revisit `app.main.ui.workspace` to check
|
(let [;; When adding data from workspace-local revisit `app.main.ui.workspace` to check
|
||||||
;; that the new parameter is sent
|
;; that the new parameter is sent
|
||||||
{:keys [edit-path
|
{:keys [edit-path
|
||||||
|
@ -100,13 +100,12 @@
|
||||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
|
|
||||||
;; DEREFS
|
;; DEREFS
|
||||||
|
|
||||||
drawing (mf/deref refs/workspace-drawing)
|
drawing (mf/deref refs/workspace-drawing)
|
||||||
focus (mf/deref refs/workspace-focus-selected)
|
focus (mf/deref refs/workspace-focus-selected)
|
||||||
|
|
||||||
page (mf/deref refs/workspace-page)
|
file-id (get file :id)
|
||||||
objects (get page :objects)
|
|
||||||
page-id (get page :id)
|
page-id (get page :id)
|
||||||
|
objects (get page :objects)
|
||||||
background (get page :background clr/canvas)
|
background (get page :background clr/canvas)
|
||||||
|
|
||||||
base-objects (ui-hooks/with-focus-objects objects focus)
|
base-objects (ui-hooks/with-focus-objects objects focus)
|
||||||
|
@ -158,7 +157,6 @@
|
||||||
drawing-tool (:tool drawing)
|
drawing-tool (:tool drawing)
|
||||||
drawing-obj (:object drawing)
|
drawing-obj (:object drawing)
|
||||||
|
|
||||||
|
|
||||||
selected-frames (into #{} (map :frame-id) selected-shapes)
|
selected-frames (into #{} (map :frame-id) selected-shapes)
|
||||||
|
|
||||||
;; Only when we have all the selected shapes in one frame
|
;; Only when we have all the selected shapes in one frame
|
||||||
|
@ -302,12 +300,12 @@
|
||||||
:edition edition}])]]]
|
:edition edition}])]]]
|
||||||
|
|
||||||
(when show-comments?
|
(when show-comments?
|
||||||
[:& comments/comments-layer {:vbox vbox
|
[:> comments/comments-layer* {:vbox vbox
|
||||||
:vport vport
|
:page-id page-id
|
||||||
:zoom zoom
|
:file-id file-id
|
||||||
:drawing drawing
|
:vport vport
|
||||||
:page-id page-id
|
:zoom zoom
|
||||||
:file-id (:id file)}])
|
:drawing drawing}])
|
||||||
|
|
||||||
(when picking-color?
|
(when picking-color?
|
||||||
[:& pixel-overlay/pixel-overlay {:vport vport
|
[:& pixel-overlay/pixel-overlay {:vport vport
|
||||||
|
@ -568,6 +566,7 @@
|
||||||
[:> guides/viewport-guides*
|
[:> guides/viewport-guides*
|
||||||
{:zoom zoom
|
{:zoom zoom
|
||||||
:vbox vbox
|
:vbox vbox
|
||||||
|
:guides (:guides page)
|
||||||
:hover-frame guide-frame
|
:hover-frame guide-frame
|
||||||
:disabled-guides disabled-guides?
|
:disabled-guides disabled-guides?
|
||||||
:modifiers modifiers}])
|
:modifiers modifiers}])
|
||||||
|
@ -648,6 +647,7 @@
|
||||||
:modifiers modifiers
|
:modifiers modifiers
|
||||||
:shape frame
|
:shape frame
|
||||||
:view-only true}]))]
|
:view-only true}]))]
|
||||||
|
|
||||||
[:g.scrollbar-wrapper {:clipPath "url(#clip-handlers)"}
|
[:g.scrollbar-wrapper {:clipPath "url(#clip-handlers)"}
|
||||||
[:& scroll-bars/viewport-scrollbars
|
[:& scroll-bars/viewport-scrollbars
|
||||||
{:objects base-objects
|
{:objects base-objects
|
||||||
|
@ -655,9 +655,9 @@
|
||||||
:vbox vbox
|
:vbox vbox
|
||||||
:bottom-padding (when palete-size (+ palete-size 8))}]]]]]))
|
:bottom-padding (when palete-size (+ palete-size 8))}]]]]]))
|
||||||
|
|
||||||
(mf/defc viewport
|
(mf/defc viewport*
|
||||||
[props]
|
[props]
|
||||||
(let [wasm-renderer-enabled? (features/use-feature "render-wasm/v1")]
|
(let [wasm-renderer-enabled? (features/use-feature "render-wasm/v1")]
|
||||||
(if ^boolean wasm-renderer-enabled?
|
(if ^boolean wasm-renderer-enabled?
|
||||||
[:& viewport.wasm/viewport props]
|
[:> viewport.wasm/viewport* props]
|
||||||
[:& viewport-classic props])))
|
[:> viewport-classic* props])))
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.comments :as dcm]
|
[app.main.data.comments :as dcm]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.comments :as dwcm]
|
[app.main.data.workspace.comments :as dwcm]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -24,38 +25,43 @@
|
||||||
(assoc :frame-id (dm/get-in positions [id :frame-id])))
|
(assoc :frame-id (dm/get-in positions [id :frame-id])))
|
||||||
thread))
|
thread))
|
||||||
|
|
||||||
(mf/defc comments-layer
|
(def ^:private ref:thread-positions
|
||||||
{::mf/props :obj}
|
(l/derived (fn [state]
|
||||||
[{:keys [vbox vport zoom file-id page-id drawing] :as props}]
|
(-> (dsh/lookup-page state)
|
||||||
(let [vbox-x (dm/get-prop vbox :x)
|
(get :comment-thread-positions)))
|
||||||
vbox-y (dm/get-prop vbox :y)
|
st/state))
|
||||||
vport-w (dm/get-prop vport :width)
|
|
||||||
vport-h (dm/get-prop vport :height)
|
|
||||||
|
|
||||||
pos-x (* (- vbox-x) zoom)
|
(mf/defc comments-layer*
|
||||||
pos-y (* (- vbox-y) zoom)
|
[{:keys [vbox vport zoom drawing file-id page-id]}]
|
||||||
|
(let [vbox-x (dm/get-prop vbox :x)
|
||||||
|
vbox-y (dm/get-prop vbox :y)
|
||||||
|
vport-w (dm/get-prop vport :width)
|
||||||
|
vport-h (dm/get-prop vport :height)
|
||||||
|
|
||||||
profile (mf/deref refs/profile)
|
pos-x (* (- vbox-x) zoom)
|
||||||
profiles (mf/deref refs/profiles)
|
pos-y (* (- vbox-y) zoom)
|
||||||
local (mf/deref refs/comments-local)
|
|
||||||
|
|
||||||
positions-ref
|
profile (mf/deref refs/profile)
|
||||||
(mf/with-memo [page-id]
|
local (mf/deref refs/comments-local)
|
||||||
;; FIXME: use lookup helpers here
|
|
||||||
(-> (l/in [:workspace-data :pages-index page-id :comment-thread-positions])
|
|
||||||
(l/derived st/state)))
|
|
||||||
|
|
||||||
positions (mf/deref positions-ref)
|
positions (mf/deref ref:thread-positions)
|
||||||
threads-map (mf/deref refs/threads-ref)
|
|
||||||
|
threads-map (mf/deref refs/threads)
|
||||||
|
threads-map (mf/with-memo [threads-map page-id positions]
|
||||||
|
(reduce-kv (fn [threads id thread]
|
||||||
|
(if (= (:page-id thread) page-id)
|
||||||
|
(assoc threads id (update-position positions thread))
|
||||||
|
threads))
|
||||||
|
{}
|
||||||
|
threads-map))
|
||||||
|
|
||||||
threads
|
threads
|
||||||
(mf/with-memo [threads-map positions local profile]
|
(mf/with-memo [threads-map local profile]
|
||||||
(->> (vals threads-map)
|
(->> (vals threads-map)
|
||||||
(filter #(= (:page-id %) page-id))
|
|
||||||
(mapv (partial update-position positions))
|
|
||||||
(dcm/apply-filters local profile)))
|
(dcm/apply-filters local profile)))
|
||||||
|
|
||||||
viewport (assoc vport :offset-x pos-x :offset-y pos-y)
|
viewport
|
||||||
|
(assoc vport :offset-x pos-x :offset-y pos-y)
|
||||||
|
|
||||||
on-draft-cancel
|
on-draft-cancel
|
||||||
(mf/use-fn #(st/emit! :interrupt))
|
(mf/use-fn #(st/emit! :interrupt))
|
||||||
|
@ -78,7 +84,6 @@
|
||||||
:style {:transform (dm/fmt "translate(%px, %px)" pos-x pos-y)}}
|
:style {:transform (dm/fmt "translate(%px, %px)" pos-x pos-y)}}
|
||||||
(for [item threads]
|
(for [item threads]
|
||||||
[:> cmt/comment-floating-bubble* {:thread item
|
[:> cmt/comment-floating-bubble* {:thread item
|
||||||
:profiles profiles
|
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:is-open (= (:id item) (:open local))
|
:is-open (= (:id item) (:open local))
|
||||||
:key (:seqn item)}])
|
:key (:seqn item)}])
|
||||||
|
@ -86,15 +91,14 @@
|
||||||
(when-let [id (:open local)]
|
(when-let [id (:open local)]
|
||||||
(when-let [thread (get threads-map id)]
|
(when-let [thread (get threads-map id)]
|
||||||
(when (seq (dcm/apply-filters local profile [thread]))
|
(when (seq (dcm/apply-filters local profile [thread]))
|
||||||
[:> cmt/comment-floating-thread* {:thread (update-position positions thread)
|
[:> cmt/comment-floating-thread*
|
||||||
:profiles profiles
|
{:thread (update-position positions thread)
|
||||||
:viewport viewport
|
:viewport viewport
|
||||||
:zoom zoom}])))
|
:zoom zoom}])))
|
||||||
|
|
||||||
(when-let [draft (:comment drawing)]
|
(when-let [draft (:comment drawing)]
|
||||||
[:> cmt/comment-floating-thread-draft* {:draft draft
|
[:> cmt/comment-floating-thread-draft*
|
||||||
:profiles profiles
|
{:draft draft
|
||||||
:on-cancel on-draft-cancel
|
:on-cancel on-draft-cancel
|
||||||
:on-submit on-draft-submit
|
:on-submit on-draft-submit
|
||||||
:zoom zoom}])]]]))
|
:zoom zoom}])]]]))
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
[app.main.ui.formats :as fmt]
|
[app.main.ui.formats :as fmt]
|
||||||
[app.main.ui.workspace.viewport.rulers :as rulers]
|
[app.main.ui.workspace.viewport.rulers :as rulers]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[okulary.core :as l]
|
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def guide-width 1)
|
(def guide-width 1)
|
||||||
|
@ -448,18 +447,14 @@
|
||||||
:is-hover true
|
:is-hover true
|
||||||
:hover-frame frame}])]))
|
:hover-frame frame}])]))
|
||||||
|
|
||||||
(def ^:private lens:workspace-guides
|
|
||||||
(-> (l/key :guides)
|
|
||||||
(l/derived refs/workspace-page)))
|
|
||||||
|
|
||||||
(mf/defc viewport-guides*
|
(mf/defc viewport-guides*
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
::mf/props :obj}
|
::mf/props :obj}
|
||||||
[{:keys [zoom vbox hover-frame disabled-guides modifiers]}]
|
[{:keys [zoom vbox hover-frame disabled-guides modifiers guides]}]
|
||||||
(let [guides (mf/deref lens:workspace-guides)
|
(let [guides
|
||||||
guides (mf/with-memo [guides vbox]
|
(mf/with-memo [guides vbox]
|
||||||
(->> (vals guides)
|
(->> (vals guides)
|
||||||
(filter (partial guide-inside-vbox? zoom vbox))))
|
(filter (partial guide-inside-vbox? zoom vbox))))
|
||||||
|
|
||||||
focus (mf/deref refs/workspace-focus-selected)
|
focus (mf/deref refs/workspace-focus-selected)
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,8 @@
|
||||||
objects
|
objects
|
||||||
selected))
|
selected))
|
||||||
|
|
||||||
(mf/defc viewport
|
(mf/defc viewport*
|
||||||
[{:keys [selected wglobal wlocal layout file palete-size] :as props}]
|
[{:keys [selected wglobal wlocal layout file page palete-size]}]
|
||||||
(let [;; When adding data from workspace-local revisit `app.main.ui.workspace` to check
|
(let [;; When adding data from workspace-local revisit `app.main.ui.workspace` to check
|
||||||
;; that the new parameter is sent
|
;; that the new parameter is sent
|
||||||
{:keys [edit-path
|
{:keys [edit-path
|
||||||
|
@ -102,7 +102,6 @@
|
||||||
drawing (mf/deref refs/workspace-drawing)
|
drawing (mf/deref refs/workspace-drawing)
|
||||||
focus (mf/deref refs/workspace-focus-selected)
|
focus (mf/deref refs/workspace-focus-selected)
|
||||||
|
|
||||||
page (mf/deref refs/workspace-page)
|
|
||||||
objects (get page :objects)
|
objects (get page :objects)
|
||||||
page-id (get page :id)
|
page-id (get page :id)
|
||||||
background (get page :background clr/canvas)
|
background (get page :background clr/canvas)
|
||||||
|
@ -341,12 +340,11 @@
|
||||||
:edition edition}])]]]
|
:edition edition}])]]]
|
||||||
|
|
||||||
(when show-comments?
|
(when show-comments?
|
||||||
[:& comments/comments-layer {:vbox vbox
|
[:> comments/comments-layer* {:vbox vbox
|
||||||
:vport vport
|
:page-id page-id
|
||||||
:zoom zoom
|
:vport vport
|
||||||
:drawing drawing
|
:zoom zoom
|
||||||
:page-id page-id
|
:drawing drawing}])
|
||||||
:file-id (:id file)}])
|
|
||||||
|
|
||||||
(when picking-color?
|
(when picking-color?
|
||||||
[:& pixel-overlay/pixel-overlay {:vport vport
|
[:& pixel-overlay/pixel-overlay {:vport vport
|
||||||
|
@ -571,6 +569,7 @@
|
||||||
[:> guides/viewport-guides*
|
[:> guides/viewport-guides*
|
||||||
{:zoom zoom
|
{:zoom zoom
|
||||||
:vbox vbox
|
:vbox vbox
|
||||||
|
:guides (:guides page)
|
||||||
:hover-frame guide-frame
|
:hover-frame guide-frame
|
||||||
:disabled-guides disabled-guides?
|
:disabled-guides disabled-guides?
|
||||||
:modifiers modifiers}])
|
:modifiers modifiers}])
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.files.changes-builder :as cb]
|
[app.common.files.changes-builder :as cb]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
|
@ -19,6 +18,7 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as ch]
|
[app.main.data.changes :as ch]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.bool :as dwb]
|
[app.main.data.workspace.bool :as dwb]
|
||||||
[app.main.data.workspace.colors :as dwc]
|
[app.main.data.workspace.colors :as dwc]
|
||||||
|
@ -48,15 +48,17 @@
|
||||||
;;
|
;;
|
||||||
(defn create-shape
|
(defn create-shape
|
||||||
[plugin-id type]
|
[plugin-id type]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [page (dsh/lookup-page @st/state)
|
||||||
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
|
||||||
shape (cts/setup-shape {:type type
|
shape (cts/setup-shape {:type type
|
||||||
:x 0 :y 0 :width 100 :height 100})
|
:x 0 :y 0
|
||||||
|
:width 100
|
||||||
|
:height 100})
|
||||||
changes
|
changes
|
||||||
(-> (cb/empty-changes)
|
(-> (cb/empty-changes)
|
||||||
(cb/with-page page)
|
(cb/with-page page)
|
||||||
(cb/with-objects (:objects page))
|
(cb/with-objects (:objects page))
|
||||||
(cb/add-object shape))]
|
(cb/add-object shape))]
|
||||||
|
|
||||||
(st/emit! (ch/commit-changes changes))
|
(st/emit! (ch/commit-changes changes))
|
||||||
(shape/shape-proxy plugin-id (:id shape))))
|
(shape/shape-proxy plugin-id (:id shape))))
|
||||||
|
|
||||||
|
@ -160,7 +162,7 @@
|
||||||
(map #(obj/get % "$id"))
|
(map #(obj/get % "$id"))
|
||||||
(mapcat #(cfh/get-children-with-self objects %)))
|
(mapcat #(cfh/get-children-with-self objects %)))
|
||||||
file-id (:current-file-id @st/state)
|
file-id (:current-file-id @st/state)
|
||||||
shared-libs (:libraries @st/state)]
|
shared-libs (:files @st/state)]
|
||||||
|
|
||||||
(->> (ctc/extract-all-colors shapes file-id shared-libs)
|
(->> (ctc/extract-all-colors shapes file-id shared-libs)
|
||||||
(group-by :attrs)
|
(group-by :attrs)
|
||||||
|
@ -182,7 +184,7 @@
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(let [file-id (:current-file-id @st/state)
|
(let [file-id (:current-file-id @st/state)
|
||||||
shared-libs (:libraries @st/state)
|
shared-libs (:files @st/state)
|
||||||
objects (u/locate-objects)
|
objects (u/locate-objects)
|
||||||
shapes
|
shapes
|
||||||
(->> shapes
|
(->> shapes
|
||||||
|
@ -295,8 +297,7 @@
|
||||||
|
|
||||||
:createPath
|
:createPath
|
||||||
(fn []
|
(fn []
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [page (dsh/lookup-page @st/state)
|
||||||
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
|
||||||
shape (cts/setup-shape
|
shape (cts/setup-shape
|
||||||
{:type :path
|
{:type :path
|
||||||
:content [{:command :move-to :params {:x 0 :y 0}}
|
:content [{:command :move-to :params {:x 0 :y 0}}
|
||||||
|
@ -306,6 +307,7 @@
|
||||||
(cb/with-page page)
|
(cb/with-page page)
|
||||||
(cb/with-objects (:objects page))
|
(cb/with-objects (:objects page))
|
||||||
(cb/add-object shape))]
|
(cb/add-object shape))]
|
||||||
|
|
||||||
(st/emit! (ch/commit-changes changes))
|
(st/emit! (ch/commit-changes changes))
|
||||||
(shape/shape-proxy plugin-id (:id shape))))
|
(shape/shape-proxy plugin-id (:id shape))))
|
||||||
|
|
||||||
|
@ -316,9 +318,7 @@
|
||||||
(u/display-not-valid :createText text)
|
(u/display-not-valid :createText text)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(let [file-id (:current-file-id @st/state)
|
(let [page (dsh/lookup-page @st/state)
|
||||||
page-id (:current-page-id @st/state)
|
|
||||||
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
|
||||||
shape (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
shape (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||||
(txt/change-text text)
|
(txt/change-text text)
|
||||||
(assoc :position-data nil))
|
(assoc :position-data nil))
|
||||||
|
@ -327,8 +327,9 @@
|
||||||
(cb/with-page page)
|
(cb/with-page page)
|
||||||
(cb/with-objects (:objects page))
|
(cb/with-objects (:objects page))
|
||||||
(cb/add-object shape))]
|
(cb/add-object shape))]
|
||||||
|
|
||||||
(st/emit! (ch/commit-changes changes))
|
(st/emit! (ch/commit-changes changes))
|
||||||
(shape/shape-proxy plugin-id file-id page-id (:id shape)))))
|
(shape/shape-proxy plugin-id (:id shape)))))
|
||||||
|
|
||||||
:createShapeFromSvg
|
:createShapeFromSvg
|
||||||
(fn [svg-string]
|
(fn [svg-string]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.main.data.comments :as dc]
|
[app.main.data.comments :as dc]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.comments :as dwc]
|
[app.main.data.workspace.comments :as dwc]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -25,7 +26,7 @@
|
||||||
(obj/type-of? p "CommentProxy"))
|
(obj/type-of? p "CommentProxy"))
|
||||||
|
|
||||||
(defn comment-proxy
|
(defn comment-proxy
|
||||||
[plugin-id file-id page-id thread-id users data]
|
[plugin-id file-id page-id thread-id data]
|
||||||
(let [data* (atom data)]
|
(let [data* (atom data)]
|
||||||
(obj/reify {:name "CommentProxy"}
|
(obj/reify {:name "CommentProxy"}
|
||||||
;; Private properties
|
;; Private properties
|
||||||
|
@ -36,9 +37,15 @@
|
||||||
:$id {:enumerable false :get (fn [] (:id data))}
|
:$id {:enumerable false :get (fn [] (:id data))}
|
||||||
|
|
||||||
;; Public properties
|
;; Public properties
|
||||||
|
|
||||||
|
;; FIXME: inconsistent with comment-thread: owner
|
||||||
:user
|
:user
|
||||||
{:get
|
{:get #(->> (dc/get-owner data)
|
||||||
(fn [] (user/user-proxy plugin-id (get users (:owner-id data))))}
|
(user/user-proxy plugin-id))}
|
||||||
|
|
||||||
|
:owner
|
||||||
|
{:get #(->> (dc/get-owner data)
|
||||||
|
(user/user-proxy plugin-id))}
|
||||||
|
|
||||||
:date
|
:date
|
||||||
{:get
|
{:get
|
||||||
|
@ -86,20 +93,22 @@
|
||||||
(obj/type-of? p "CommentThreadProxy"))
|
(obj/type-of? p "CommentThreadProxy"))
|
||||||
|
|
||||||
(defn comment-thread-proxy
|
(defn comment-thread-proxy
|
||||||
[plugin-id file-id page-id users data]
|
[plugin-id file-id page-id data]
|
||||||
(let [data* (atom data)]
|
(let [data* (atom data)]
|
||||||
(obj/reify {:name "CommentThreadProxy"}
|
(obj/reify {:name "CommentThreadProxy"}
|
||||||
:$plugin {:enumerable false :get (fn [] plugin-id)}
|
:$plugin {:enumerable false :get (fn [] plugin-id)}
|
||||||
:$file {:enumerable false :get (fn [] file-id)}
|
:$file {:enumerable false :get (fn [] file-id)}
|
||||||
:$page {:enumerable false :get (fn [] page-id)}
|
:$page {:enumerable false :get (fn [] page-id)}
|
||||||
:$id {:enumerable false :get (fn [] (:id data))}
|
:$id {:enumerable false :get (fn [] (:id data))}
|
||||||
:$users {:enumerable false :get (fn [] users)}
|
|
||||||
|
|
||||||
:page {:enumerable false :get #(u/locate-page file-id page-id)}
|
:page {:enumerable false :get #(u/locate-page file-id page-id)}
|
||||||
:seqNumber {:get #(:seqn data)}
|
:seqNumber {:get #(:seqn data)}
|
||||||
:owner {:get #(user/user-proxy plugin-id (get users (:owner-id data)))}
|
|
||||||
:board {:get #(shape/shape-proxy plugin-id file-id page-id (:frame-id data))}
|
:board {:get #(shape/shape-proxy plugin-id file-id page-id (:frame-id data))}
|
||||||
|
|
||||||
|
:owner
|
||||||
|
{:get #(->> (dc/get-owner data)
|
||||||
|
(user/user-proxy plugin-id))}
|
||||||
|
|
||||||
:position
|
:position
|
||||||
{:get
|
{:get
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -152,7 +161,7 @@
|
||||||
(fn [comments]
|
(fn [comments]
|
||||||
(resolve
|
(resolve
|
||||||
(format/format-array
|
(format/format-array
|
||||||
#(comment-proxy plugin-id file-id page-id (:id data) users %) comments)))
|
#(comment-proxy plugin-id file-id page-id (:id data) %) comments)))
|
||||||
reject))))))
|
reject))))))
|
||||||
|
|
||||||
:reply
|
:reply
|
||||||
|
@ -168,12 +177,12 @@
|
||||||
(js/Promise.
|
(js/Promise.
|
||||||
(fn [resolve reject]
|
(fn [resolve reject]
|
||||||
(->> (rp/cmd! :create-comment {:thread-id (:id data) :content content})
|
(->> (rp/cmd! :create-comment {:thread-id (:id data) :content content})
|
||||||
(rx/subs! #(resolve (comment-proxy plugin-id file-id page-id (:id data) users %)) reject))))))
|
(rx/subs! #(resolve (comment-proxy plugin-id file-id page-id (:id data) %)) reject))))))
|
||||||
|
|
||||||
:remove
|
:remove
|
||||||
(fn []
|
(fn []
|
||||||
(let [profile (:profile @st/state)
|
(let [profile (:profile @st/state)
|
||||||
owner (get users (:owner-id data))]
|
owner (dsh/lookup-profile @st/state (:owner-id data))]
|
||||||
(cond
|
(cond
|
||||||
(not (r/check-permission plugin-id "comment:write"))
|
(not (r/check-permission plugin-id "comment:write"))
|
||||||
(u/display-not-valid :remove "Plugin doesn't have 'comment:write' permission")
|
(u/display-not-valid :remove "Plugin doesn't have 'comment:write' permission")
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
(ns app.plugins.events
|
(ns app.plugins.events
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.file :as file]
|
[app.plugins.file :as file]
|
||||||
[app.plugins.page :as page]
|
[app.plugins.page :as page]
|
||||||
|
@ -63,8 +63,8 @@
|
||||||
(defmethod handle-state-change "shapechange"
|
(defmethod handle-state-change "shapechange"
|
||||||
[_ plugin-id old-val new-val props]
|
[_ plugin-id old-val new-val props]
|
||||||
(if-let [shape-id (-> (obj/get props "shapeId") parser/parse-id)]
|
(if-let [shape-id (-> (obj/get props "shapeId") parser/parse-id)]
|
||||||
(let [old-shape (wsh/lookup-shape old-val shape-id)
|
(let [old-shape (dsh/lookup-shape old-val shape-id)
|
||||||
new-shape (wsh/lookup-shape new-val shape-id)
|
new-shape (dsh/lookup-shape new-val shape-id)
|
||||||
|
|
||||||
file-id (:current-file-id new-val)
|
file-id (:current-file-id new-val)
|
||||||
page-id (:current-page-id new-val)]
|
page-id (:current-page-id new-val)]
|
||||||
|
|
|
@ -929,7 +929,7 @@
|
||||||
:connected
|
:connected
|
||||||
{:get
|
{:get
|
||||||
(fn []
|
(fn []
|
||||||
(let [libraries (get @st/state :libraries)]
|
(let [libraries (get @st/state :files)]
|
||||||
(apply array (->> libraries keys (map (partial library-proxy plugin-id))))))}
|
(apply array (->> libraries keys (map (partial library-proxy plugin-id))))))}
|
||||||
|
|
||||||
:availableLibraries
|
:availableLibraries
|
||||||
|
@ -937,7 +937,7 @@
|
||||||
(let [team-id (:current-team-id @st/state)]
|
(let [team-id (:current-team-id @st/state)]
|
||||||
(js/Promise.
|
(js/Promise.
|
||||||
(fn [resolve reject]
|
(fn [resolve reject]
|
||||||
(let [current-libs (into #{} (map first) (get @st/state :libraries))]
|
(let [current-libs (into #{} (map first) (get @st/state :files))]
|
||||||
(->> (rp/cmd! :get-team-shared-files {:team-id team-id})
|
(->> (rp/cmd! :get-team-shared-files {:team-id team-id})
|
||||||
(rx/map (fn [result]
|
(rx/map (fn [result]
|
||||||
(->> result
|
(->> result
|
||||||
|
|
|
@ -369,11 +369,7 @@
|
||||||
:content content}
|
:content content}
|
||||||
|
|
||||||
(fn [data]
|
(fn [data]
|
||||||
(->> (rp/cmd! :get-team-users {:file-id file-id})
|
(resolve (pc/comment-thread-proxy plugin-id file-id id data)))
|
||||||
(rx/subs!
|
|
||||||
(fn [users]
|
|
||||||
(let [users (d/index-by :id users)]
|
|
||||||
(resolve (pc/comment-thread-proxy plugin-id file-id id users data)))))))
|
|
||||||
false))))))))
|
false))))))))
|
||||||
|
|
||||||
:removeCommentThread
|
:removeCommentThread
|
||||||
|
@ -396,7 +392,7 @@
|
||||||
(fn [criteria]
|
(fn [criteria]
|
||||||
(let [only-yours (boolean (obj/get criteria "onlyYours" false))
|
(let [only-yours (boolean (obj/get criteria "onlyYours" false))
|
||||||
show-resolved (boolean (obj/get criteria "showResolved" true))
|
show-resolved (boolean (obj/get criteria "showResolved" true))
|
||||||
user-id (-> @st/state :profile :id)]
|
user-id (:profile-id @st/state)]
|
||||||
(js/Promise.
|
(js/Promise.
|
||||||
(fn [resolve reject]
|
(fn [resolve reject]
|
||||||
(cond
|
(cond
|
||||||
|
@ -406,14 +402,11 @@
|
||||||
(reject "Plugin doesn't have 'comment:read' permission"))
|
(reject "Plugin doesn't have 'comment:read' permission"))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(->> (rx/zip (rp/cmd! :get-team-users {:file-id file-id})
|
(->> (rp/cmd! :get-comment-threads {:file-id file-id})
|
||||||
(rp/cmd! :get-comment-threads {:file-id file-id}))
|
|
||||||
(rx/take 1)
|
|
||||||
(rx/subs!
|
(rx/subs!
|
||||||
(fn [[users comments]]
|
(fn [threads]
|
||||||
(let [users (d/index-by :id users)
|
(let [threads
|
||||||
comments
|
(cond->> threads
|
||||||
(cond->> comments
|
|
||||||
(not show-resolved)
|
(not show-resolved)
|
||||||
(filter (comp not :is-resolved))
|
(filter (comp not :is-resolved))
|
||||||
|
|
||||||
|
@ -421,5 +414,5 @@
|
||||||
(filter #(contains? (:participants %) user-id)))]
|
(filter #(contains? (:participants %) user-id)))]
|
||||||
(resolve
|
(resolve
|
||||||
(format/format-array
|
(format/format-array
|
||||||
#(pc/comment-thread-proxy plugin-id file-id id users %) comments))))
|
#(pc/comment-thread-proxy plugin-id file-id id %) threads))))
|
||||||
reject)))))))))
|
reject)))))))))
|
||||||
|
|
|
@ -11,21 +11,20 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(defn locate-file
|
(defn locate-file
|
||||||
[id]
|
[id]
|
||||||
(assert (uuid? id) "File not valid uuid")
|
(assert (uuid? id) "File not valid uuid")
|
||||||
(if (= id (:current-file-id @st/state))
|
(dsh/lookup-file @st/state id))
|
||||||
(-> (:workspace-file @st/state)
|
|
||||||
(assoc :data (:workspace-data @st/state)))
|
|
||||||
(dm/get-in @st/state [:libraries id])))
|
|
||||||
|
|
||||||
(defn locate-page
|
(defn locate-page
|
||||||
[file-id id]
|
[file-id id]
|
||||||
(assert (uuid? id) "Page not valid uuid")
|
(assert (uuid? id) "Page not valid uuid")
|
||||||
(dm/get-in (locate-file file-id) [:data :pages-index id]))
|
(-> (dsh/lookup-file-data @st/state file-id)
|
||||||
|
(dsh/get-page id)))
|
||||||
|
|
||||||
(defn locate-objects
|
(defn locate-objects
|
||||||
([]
|
([]
|
||||||
|
@ -62,13 +61,15 @@
|
||||||
(let [{:keys [profile-id]} (locate-presence session-id)]
|
(let [{:keys [profile-id]} (locate-presence session-id)]
|
||||||
(dm/get-in @st/state [:users profile-id])))
|
(dm/get-in @st/state [:users profile-id])))
|
||||||
|
|
||||||
|
;; FIXME: the impl looks strange: objects is passed by parameters but
|
||||||
|
;; then the rest of the file is looked up directly from state.... (?)
|
||||||
(defn locate-component
|
(defn locate-component
|
||||||
[objects shape]
|
[objects shape]
|
||||||
(let [current-file-id (:current-file-id @st/state)
|
(let [state (deref st/state)
|
||||||
workspace-data (:workspace-data @st/state)
|
file (dsh/lookup-file state)
|
||||||
libraries (:libraries @st/state)
|
libraries (dsh/lookup-libraries state)
|
||||||
root (ctn/get-instance-root objects shape)]
|
root (ctn/get-instance-root objects shape)]
|
||||||
[root (ctf/resolve-component root {:id current-file-id :data workspace-data} libraries {:include-deleted? true})]))
|
[root (ctf/resolve-component root file libraries {:include-deleted? true})]))
|
||||||
|
|
||||||
(defn proxy->file
|
(defn proxy->file
|
||||||
[proxy]
|
[proxy]
|
||||||
|
@ -87,7 +88,7 @@
|
||||||
[proxy]
|
[proxy]
|
||||||
(let [file-id (obj/get proxy "$file")
|
(let [file-id (obj/get proxy "$file")
|
||||||
page-id (obj/get proxy "$page")
|
page-id (obj/get proxy "$page")
|
||||||
id (obj/get proxy "$id")]
|
id (obj/get proxy "$id")]
|
||||||
(when (and (some? file-id) (some? page-id) (some? id))
|
(when (and (some? file-id) (some? page-id) (some? id))
|
||||||
(locate-shape file-id page-id id))))
|
(locate-shape file-id page-id id))))
|
||||||
|
|
||||||
|
@ -167,9 +168,12 @@
|
||||||
|
|
||||||
(defn get-state
|
(defn get-state
|
||||||
([self attr]
|
([self attr]
|
||||||
(let [id (get-data self :id)
|
(let [id (get-data self :id)
|
||||||
page-id (d/nilv (get-data self :page-id) (:current-page-id @st/state))]
|
page-id (or (get-data self :page-id)
|
||||||
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects id attr])))
|
(:current-page-id @st/state))]
|
||||||
|
(-> (dsh/lookup-page-objects @st/state page-id)
|
||||||
|
(dm/get-in [:objects id attr]))))
|
||||||
|
|
||||||
([self attr mapfn]
|
([self attr mapfn]
|
||||||
(-> (get-state self attr)
|
(-> (get-state self attr)
|
||||||
(mapfn))))
|
(mapfn))))
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
[app.main.data.changes :as dwc]
|
[app.main.data.changes :as dwc]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.dashboard.shortcuts]
|
[app.main.data.dashboard.shortcuts]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.preview :as dp]
|
[app.main.data.preview :as dp]
|
||||||
[app.main.data.viewer.shortcuts]
|
[app.main.data.viewer.shortcuts]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
|
@ -149,8 +150,10 @@
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defn ^:export dump-data []
|
(defn ^:export dump-data []
|
||||||
(logjs "workspace-data" (get @st/state :workspace-data))
|
(let [fdata (-> (dsh/lookup-file @st/state)
|
||||||
nil)
|
(get :data))]
|
||||||
|
(logjs "file-data" fdata)
|
||||||
|
nil))
|
||||||
|
|
||||||
(defn ^:export dump-buffer []
|
(defn ^:export dump-buffer []
|
||||||
(logjs "last-events" @st/last-events)
|
(logjs "last-events" @st/last-events)
|
||||||
|
@ -165,8 +168,7 @@
|
||||||
|
|
||||||
(defn dump-objects'
|
(defn dump-objects'
|
||||||
[state]
|
[state]
|
||||||
(let [page-id (get state :current-page-id)
|
(let [objects (dsh/lookup-page-objects state)]
|
||||||
objects (get-in state [:workspace-data :pages-index page-id :objects])]
|
|
||||||
(logjs "objects" objects)
|
(logjs "objects" objects)
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
@ -174,33 +176,25 @@
|
||||||
[]
|
[]
|
||||||
(dump-objects' @st/state))
|
(dump-objects' @st/state))
|
||||||
|
|
||||||
(defn dump-object'
|
(defn get-object
|
||||||
[state name]
|
[state name]
|
||||||
(let [page-id (get state :current-page-id)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
objects (get-in state [:workspace-data :pages-index page-id :objects])
|
|
||||||
result (or (d/seek (fn [shape] (= name (:name shape))) (vals objects))
|
result (or (d/seek (fn [shape] (= name (:name shape))) (vals objects))
|
||||||
(get objects (uuid/uuid name)))]
|
(get objects (uuid/uuid name)))]
|
||||||
#_(logjs name result)
|
result))
|
||||||
result
|
|
||||||
|
|
||||||
#_nil))
|
|
||||||
|
|
||||||
(defn ^:export dump-object
|
(defn ^:export dump-object
|
||||||
[name]
|
[name]
|
||||||
(dump-object' @st/state name))
|
(get-object @st/state name))
|
||||||
|
|
||||||
(defn dump-selected'
|
(defn get-selected
|
||||||
[state]
|
[state]
|
||||||
(let [page-id (get state :current-page-id)
|
(dsh/lookup-selected state))
|
||||||
objects (get-in state [:workspace-data :pages-index page-id :objects])
|
|
||||||
selected (get-in state [:workspace-local :selected])
|
|
||||||
result (->> selected (map (d/getf objects)))]
|
|
||||||
(logjs "selected" result)
|
|
||||||
nil))
|
|
||||||
|
|
||||||
(defn ^:export dump-selected
|
(defn ^:export dump-selected
|
||||||
[]
|
[]
|
||||||
(dump-selected' @st/state))
|
(logjs "selected" (get-selected @st/state))
|
||||||
|
nil)
|
||||||
|
|
||||||
(defn ^:export preview-selected
|
(defn ^:export preview-selected
|
||||||
[]
|
[]
|
||||||
|
@ -208,26 +202,20 @@
|
||||||
|
|
||||||
(defn ^:export parent
|
(defn ^:export parent
|
||||||
[]
|
[]
|
||||||
(let [state @st/state
|
(let [objects (dsh/lookup-page-objects @st/state)
|
||||||
page-id (get state :current-page-id)
|
selected-id (first (dsh/get-selected-ids @st/state))
|
||||||
objects (get-in state [:workspace-data :pages-index page-id :objects])
|
parent-id (dm/get-in objects [selected-id :parent-id])]
|
||||||
selected (first (get-in state [:workspace-local :selected]))
|
(when-let [parent (get objects parent-id)]
|
||||||
parent-id (get-in objects [selected :parent-id])
|
(js/console.log (str (:name parent) " - " (:id parent))))
|
||||||
parent (get objects parent-id)]
|
|
||||||
(when parent
|
|
||||||
(prn (str (:name parent) " - " (:id parent))))
|
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defn ^:export frame
|
(defn ^:export frame
|
||||||
[]
|
[]
|
||||||
(let [state @st/state
|
(let [objects (dsh/lookup-page-objects @st/state)
|
||||||
page-id (get state :current-page-id)
|
selected-id (first (dsh/get-selected-ids @st/state))
|
||||||
objects (get-in state [:workspace-data :pages-index page-id :objects])
|
frame-id (dm/get-in objects [selected-id :frame-id])]
|
||||||
selected (first (get-in state [:workspace-local :selected]))
|
(when-let [frame (get objects frame-id)]
|
||||||
frame-id (get-in objects [selected :frame-id])
|
(js/console.log (str (:name frame) " - " (:id frame))))
|
||||||
frame (get objects frame-id)]
|
|
||||||
(when frame
|
|
||||||
(prn (str (:name frame) " - " (:id frame))))
|
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defn ^:export select-by-object-id
|
(defn ^:export select-by-object-id
|
||||||
|
@ -246,9 +234,8 @@
|
||||||
([state show-ids show-touched] (dump-tree' state show-ids show-touched false))
|
([state show-ids show-touched] (dump-tree' state show-ids show-touched false))
|
||||||
([state show-ids show-touched show-modified]
|
([state show-ids show-touched show-modified]
|
||||||
(let [page-id (get state :current-page-id)
|
(let [page-id (get state :current-page-id)
|
||||||
file (assoc (get state :workspace-file)
|
file (dsh/lookup-file state)
|
||||||
:data (get state :workspace-data))
|
libraries (get state :files)]
|
||||||
libraries (get state :libraries)]
|
|
||||||
(ctf/dump-tree file page-id libraries {:show-ids show-ids
|
(ctf/dump-tree file page-id libraries {:show-ids show-ids
|
||||||
:show-touched show-touched
|
:show-touched show-touched
|
||||||
:show-modified show-modified}))))
|
:show-modified show-modified}))))
|
||||||
|
@ -264,14 +251,11 @@
|
||||||
([state shape-id show-ids show-touched] (dump-subtree' state shape-id show-ids show-touched false))
|
([state shape-id show-ids show-touched] (dump-subtree' state shape-id show-ids show-touched false))
|
||||||
([state shape-id show-ids show-touched show-modified]
|
([state shape-id show-ids show-touched show-modified]
|
||||||
(let [page-id (get state :current-page-id)
|
(let [page-id (get state :current-page-id)
|
||||||
file (assoc (get state :workspace-file)
|
file (dsh/lookup-file state)
|
||||||
:data (get state :workspace-data))
|
libraries (get state :files)
|
||||||
libraries (get state :libraries)
|
|
||||||
shape-id (if (some? shape-id)
|
shape-id (if (some? shape-id)
|
||||||
(uuid/uuid shape-id)
|
(uuid/uuid shape-id)
|
||||||
(let [objects (get-in state [:workspace-data :pages-index page-id :objects])
|
(first (dsh/lookup-selected state)))]
|
||||||
selected (get-in state [:workspace-local :selected])]
|
|
||||||
(->> selected (map (d/getf objects)) first :id)))]
|
|
||||||
(if (some? shape-id)
|
(if (some? shape-id)
|
||||||
(ctf/dump-subtree file page-id shape-id libraries {:show-ids show-ids
|
(ctf/dump-subtree file page-id shape-id libraries {:show-ids show-ids
|
||||||
:show-touched show-touched
|
:show-touched show-touched
|
||||||
|
@ -363,10 +347,10 @@
|
||||||
|
|
||||||
(defn ^:export dump-modifiers
|
(defn ^:export dump-modifiers
|
||||||
[]
|
[]
|
||||||
(let [page-id (get @st/state :current-page-id)
|
(let [objects (dsh/lookup-page-objects @st/state)
|
||||||
objects (get-in @st/state [:workspace-data :pages-index page-id :objects])]
|
modifiers (:workspace-modifiers @st/state)]
|
||||||
(.log js/console (modif->js (:workspace-modifiers @st/state) objects)))
|
(js/console.log (modif->js modifiers objects))
|
||||||
nil)
|
nil))
|
||||||
|
|
||||||
(defn ^:export set-workspace-read-only
|
(defn ^:export set-workspace-read-only
|
||||||
[read-only?]
|
[read-only?]
|
||||||
|
@ -381,10 +365,8 @@
|
||||||
(defn ^:export validate
|
(defn ^:export validate
|
||||||
([] (validate nil))
|
([] (validate nil))
|
||||||
([shape-id]
|
([shape-id]
|
||||||
(let [file (assoc (get @st/state :workspace-file)
|
(let [file (dsh/lookup-file @st/state)
|
||||||
:data (get @st/state :workspace-data))
|
libraries (get @st/state :files)]
|
||||||
libraries (get @st/state :libraries)]
|
|
||||||
|
|
||||||
(try
|
(try
|
||||||
(->> (if-let [shape-id (some-> shape-id parse-uuid)]
|
(->> (if-let [shape-id (some-> shape-id parse-uuid)]
|
||||||
(let [page (dm/get-in file [:data :pages-index (get @st/state :current-page-id)])]
|
(let [page (dm/get-in file [:data :pages-index (get @st/state :current-page-id)])]
|
||||||
|
@ -398,9 +380,8 @@
|
||||||
(defn ^:export validate-schema
|
(defn ^:export validate-schema
|
||||||
[]
|
[]
|
||||||
(try
|
(try
|
||||||
(-> (get @st/state :workspace-file)
|
(let [file (dsh/lookup-file @st/state)]
|
||||||
(assoc :data (get @st/state :workspace-data))
|
(cfv/validate-file-schema! file))
|
||||||
(cfv/validate-file-schema!))
|
|
||||||
(catch :default cause
|
(catch :default cause
|
||||||
(errors/print-error! cause))))
|
(errors/print-error! cause))))
|
||||||
|
|
||||||
|
@ -413,11 +394,8 @@
|
||||||
(let [features (features/get-team-enabled-features state)
|
(let [features (features/get-team-enabled-features state)
|
||||||
sid (:session-id state)
|
sid (:session-id state)
|
||||||
|
|
||||||
file (get state :workspace-file)
|
file (dsh/lookup-file state)
|
||||||
fdata (get state :workspace-data)
|
libs (get state :files)
|
||||||
|
|
||||||
file (assoc file :data fdata)
|
|
||||||
libs (get state :libraries)
|
|
||||||
|
|
||||||
errors (cfv/validate-file file libs)
|
errors (cfv/validate-file file libs)
|
||||||
_ (l/dbg :hint "repair current file" :errors (count errors))
|
_ (l/dbg :hint "repair current file" :errors (count errors))
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.test-helpers.files :as cthf]
|
[app.common.test-helpers.files :as cthf]
|
||||||
[app.common.test-helpers.ids-map :as cthi]
|
[app.common.test-helpers.ids-map :as cthi]
|
||||||
[app.common.test-helpers.shapes :as cths]
|
[app.common.test-helpers.shapes :as cths]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.colors :as dc]
|
[app.main.data.workspace.colors :as dc]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[cljs.test :as t :include-macros true]
|
[cljs.test :as t :include-macros true]
|
||||||
|
@ -34,13 +35,10 @@
|
||||||
store done events
|
store done events
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
(let [;; ==== Get
|
(let [;; ==== Get
|
||||||
shape1' (get-in new-state [:workspace-data
|
objects (dsh/lookup-page-objects new-state)
|
||||||
:pages-index
|
shape1' (get objects (cthi/id :shape1))
|
||||||
(cthi/id :page1)
|
fills' (:fills shape1')
|
||||||
:objects
|
fill' (first fills')]
|
||||||
(cthi/id :shape1)])
|
|
||||||
fills' (:fills shape1')
|
|
||||||
fill' (first fills')]
|
|
||||||
|
|
||||||
;; ==== Check
|
;; ==== Check
|
||||||
(t/is (some? shape1'))
|
(t/is (some? shape1'))
|
||||||
|
@ -68,15 +66,11 @@
|
||||||
store done events
|
store done events
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
(let [;; ==== Get
|
(let [;; ==== Get
|
||||||
shape1' (get-in new-state [:workspace-data
|
objects (dsh/lookup-page-objects new-state)
|
||||||
:pages-index
|
shape1' (get objects (cthi/id :shape1))
|
||||||
(cthi/id :page1)
|
stroke' (first (:strokes shape1'))]
|
||||||
:objects
|
|
||||||
(cthi/id :shape1)])
|
|
||||||
stroke' (-> (:strokes shape1')
|
|
||||||
first)]
|
|
||||||
|
|
||||||
;; ==== Check
|
;; ==== Check
|
||||||
;; (println stroke')
|
;; (println stroke')
|
||||||
(t/is (some? shape1'))
|
(t/is (some? shape1'))
|
||||||
(t/is (= (:stroke-alignment stroke') :inner))
|
(t/is (= (:stroke-alignment stroke') :inner))
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[cljs.test :as t :include-macros true]
|
[cljs.test :as t :include-macros true]
|
||||||
[frontend-tests.helpers.pages :as thp]))
|
[frontend-tests.helpers.pages :as thp]))
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
root-inst (ctn/get-shape page root-inst-id)
|
root-inst (ctn/get-shape page root-inst-id)
|
||||||
main-instance? (:main-instance root-inst)
|
main-instance? (:main-instance root-inst)
|
||||||
|
|
||||||
libs (wsh/get-libraries state)
|
libs (dsh/lookup-libraries state)
|
||||||
component (ctf/get-component libs (:component-file root-inst) (:component-id root-inst))
|
component (ctf/get-component libs (:component-file root-inst) (:component-id root-inst))
|
||||||
library (ctf/get-component-library libs root-inst)
|
library (ctf/get-component-library libs root-inst)
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
(let [page (thp/current-page state)
|
(let [page (thp/current-page state)
|
||||||
root-inst (ctn/get-shape page root-inst-id)
|
root-inst (ctn/get-shape page root-inst-id)
|
||||||
|
|
||||||
libs (wsh/get-libraries state)
|
libs (dsh/lookup-libraries state)
|
||||||
component (ctf/get-component libs (:component-file root-inst) (:component-id root-inst))
|
component (ctf/get-component libs (:component-file root-inst) (:component-id root-inst))
|
||||||
library (ctf/get-component-library libs root-inst)
|
library (ctf/get-component-library libs root-inst)
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@
|
||||||
(defn resolve-component
|
(defn resolve-component
|
||||||
"Get the component with the given id and all its shapes."
|
"Get the component with the given id and all its shapes."
|
||||||
[state component-file component-id]
|
[state component-file component-id]
|
||||||
(let [libs (wsh/get-libraries state)
|
(let [libs (dsh/lookup-libraries state)
|
||||||
component (ctf/get-component libs component-file component-id)
|
component (ctf/get-component libs component-file component-id)
|
||||||
library (ctf/get-component-library libs component)
|
library (ctf/get-component-library libs component)
|
||||||
shapes-main (ctf/get-component-shapes (:data library) component)]
|
shapes-main (ctf/get-component-shapes (:data library) component)]
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.workspace.groups :as dwg]
|
[app.main.data.workspace.groups :as dwg]
|
||||||
[app.main.data.workspace.layout :as layout]
|
[app.main.data.workspace.layout :as layout]))
|
||||||
[app.main.data.workspace.state-helpers :as wsh]))
|
|
||||||
|
|
||||||
;; ---- Helpers to manage pages and objects
|
;; ---- Helpers to manage pages and objects
|
||||||
|
|
||||||
|
@ -33,12 +33,15 @@
|
||||||
:current-page-id nil
|
:current-page-id nil
|
||||||
:workspace-layout layout/default-layout
|
:workspace-layout layout/default-layout
|
||||||
:workspace-global layout/default-global
|
:workspace-global layout/default-global
|
||||||
:workspace-data {:id current-file-id
|
|
||||||
:options {:components-v2 true}
|
:files
|
||||||
:components {}
|
{current-file-id
|
||||||
:pages []
|
{:id current-file-id
|
||||||
:pages-index {}}
|
:data {:id current-file-id
|
||||||
:workspace-libraries {}
|
:options {:components-v2 true}
|
||||||
|
:components {}
|
||||||
|
:pages []
|
||||||
|
:pages-index {}}}}
|
||||||
:features-team #{"components/v2"}})
|
:features-team #{"components/v2"}})
|
||||||
|
|
||||||
(def ^:private idmap (atom {}))
|
(def ^:private idmap (atom {}))
|
||||||
|
@ -48,8 +51,9 @@
|
||||||
|
|
||||||
(defn current-page
|
(defn current-page
|
||||||
[state]
|
[state]
|
||||||
(let [page-id (:current-page-id state)]
|
(let [page-id (:current-page-id state)
|
||||||
(get-in state [:workspace-data :pages-index page-id])))
|
file-id (:current-file-id state)]
|
||||||
|
(get-in state [:files file-id :data :pages-index page-id])))
|
||||||
|
|
||||||
(defn id
|
(defn id
|
||||||
[label]
|
[label]
|
||||||
|
@ -65,20 +69,22 @@
|
||||||
(let [page (current-page state)]
|
(let [page (current-page state)]
|
||||||
(cfh/get-children (:objects page) (id label))))
|
(cfh/get-children (:objects page) (id label))))
|
||||||
|
|
||||||
|
(defn apply-changes
|
||||||
|
[state changes]
|
||||||
|
(let [file-id (:current-file-id state)]
|
||||||
|
(update-in state [:files file-id :data] cp/process-changes changes)))
|
||||||
|
|
||||||
(defn sample-page
|
(defn sample-page
|
||||||
([state] (sample-page state {}))
|
([state] (sample-page state {}))
|
||||||
([state {:keys [id name] :as props
|
([state {:keys [id name] :as props
|
||||||
:or {id (uuid/next)
|
:or {id (uuid/next)
|
||||||
name "page1"}}]
|
name "page1"}}]
|
||||||
|
|
||||||
(swap! idmap assoc :page id)
|
(swap! idmap assoc :page id)
|
||||||
(-> state
|
(-> state
|
||||||
(assoc :current-page-id id)
|
(assoc :current-page-id id)
|
||||||
(update :workspace-data
|
(apply-changes [{:type :add-page
|
||||||
cp/process-changes
|
:id id
|
||||||
[{:type :add-page
|
:name name}]))))
|
||||||
:id id
|
|
||||||
:name name}]))))
|
|
||||||
|
|
||||||
(defn sample-shape
|
(defn sample-shape
|
||||||
([state label type] (sample-shape state type {}))
|
([state label type] (sample-shape state type {}))
|
||||||
|
@ -87,13 +93,12 @@
|
||||||
frame (cfh/get-frame (:objects page))
|
frame (cfh/get-frame (:objects page))
|
||||||
shape (cts/setup-shape (merge {:type type :x 0 :y 0 :width 1 :height 1} props))]
|
shape (cts/setup-shape (merge {:type type :x 0 :y 0 :width 1 :height 1} props))]
|
||||||
(swap! idmap assoc label (:id shape))
|
(swap! idmap assoc label (:id shape))
|
||||||
(update state :workspace-data
|
(apply-changes state
|
||||||
cp/process-changes
|
[{:type :add-obj
|
||||||
[{:type :add-obj
|
:id (:id shape)
|
||||||
:id (:id shape)
|
:page-id (:id page)
|
||||||
:page-id (:id page)
|
:frame-id (:id frame)
|
||||||
:frame-id (:id frame)
|
:obj shape}]))))
|
||||||
:obj shape}]))))
|
|
||||||
|
|
||||||
(defn group-shapes
|
(defn group-shapes
|
||||||
([state label ids] (group-shapes state label ids "Group"))
|
([state label ids] (group-shapes state label ids "Group"))
|
||||||
|
@ -106,8 +111,7 @@
|
||||||
(dwg/prepare-create-group (pcb/empty-changes) nil (:objects page) (:id page) shapes prefix true)]
|
(dwg/prepare-create-group (pcb/empty-changes) nil (:objects page) (:id page) shapes prefix true)]
|
||||||
|
|
||||||
(swap! idmap assoc label (:id group))
|
(swap! idmap assoc label (:id group))
|
||||||
(update state :workspace-data
|
(apply-changes state (:redo-changes changes)))))))
|
||||||
cp/process-changes (:redo-changes changes)))))))
|
|
||||||
|
|
||||||
(defn frame-shapes
|
(defn frame-shapes
|
||||||
([state label ids] (frame-shapes state label ids "Board"))
|
([state label ids] (frame-shapes state label ids "Board"))
|
||||||
|
@ -128,13 +132,12 @@
|
||||||
true)]
|
true)]
|
||||||
|
|
||||||
(swap! idmap assoc label (:id frame))
|
(swap! idmap assoc label (:id frame))
|
||||||
(update state :workspace-data
|
(apply-changes state (:redo-changes changes)))))))
|
||||||
cp/process-changes (:redo-changes changes)))))))
|
|
||||||
|
|
||||||
(defn make-component
|
(defn make-component
|
||||||
[state instance-label component-label shape-ids]
|
[state instance-label component-label shape-ids]
|
||||||
(let [page (current-page state)
|
(let [page (current-page state)
|
||||||
objects (wsh/lookup-page-objects state (:id page))
|
objects (dsh/lookup-page-objects state (:id page))
|
||||||
shapes (dwg/shapes-for-grouping objects shape-ids)
|
shapes (dwg/shapes-for-grouping objects shape-ids)
|
||||||
|
|
||||||
[group component-id changes]
|
[group component-id changes]
|
||||||
|
@ -149,15 +152,14 @@
|
||||||
|
|
||||||
(swap! idmap assoc instance-label (:id group)
|
(swap! idmap assoc instance-label (:id group)
|
||||||
component-label component-id)
|
component-label component-id)
|
||||||
(update state :workspace-data
|
(apply-changes state (:redo-changes changes))))
|
||||||
cp/process-changes (:redo-changes changes))))
|
|
||||||
|
|
||||||
(defn instantiate-component
|
(defn instantiate-component
|
||||||
([state label component-id]
|
([state label component-id]
|
||||||
(instantiate-component state label component-id current-file-id))
|
(instantiate-component state label component-id current-file-id))
|
||||||
([state label component-id file-id]
|
([state label component-id file-id]
|
||||||
(let [page (current-page state)
|
(let [page (current-page state)
|
||||||
libraries (wsh/get-libraries state)
|
libraries (dsh/lookup-libraries state)
|
||||||
objects (:objects page)
|
objects (:objects page)
|
||||||
|
|
||||||
changes (-> (pcb/empty-changes nil (:id page))
|
changes (-> (pcb/empty-changes nil (:id page))
|
||||||
|
@ -173,26 +175,27 @@
|
||||||
libraries)]
|
libraries)]
|
||||||
|
|
||||||
(swap! idmap assoc label (:id new-shape))
|
(swap! idmap assoc label (:id new-shape))
|
||||||
(update state :workspace-data
|
(apply-changes state (:redo-changes changes)))))
|
||||||
cp/process-changes (:redo-changes changes)))))
|
|
||||||
|
|
||||||
(defn move-to-library
|
(defn move-to-library
|
||||||
[state label name]
|
[state label name]
|
||||||
(let [library-id (uuid/next)
|
(let [library-id (uuid/next)
|
||||||
data (get state :workspace-data)]
|
file-id (:current-file-id state)
|
||||||
|
data (get-in state [:files file-id :data])]
|
||||||
(swap! idmap assoc label library-id)
|
(swap! idmap assoc label library-id)
|
||||||
(-> state
|
(-> state
|
||||||
(update :workspace-libraries
|
(update :files assoc library-id
|
||||||
assoc library-id {:id library-id
|
{:id library-id
|
||||||
:name name
|
:name name
|
||||||
:data {:id library-id
|
:data {:id library-id
|
||||||
:options (:options data)
|
:options (:options data)
|
||||||
:pages (:pages data)
|
:pages (:pages data)
|
||||||
:pages-index (:pages-index data)
|
:pages-index (:pages-index data)
|
||||||
:components (:components data)}})
|
:components (:components data)}})
|
||||||
(update :workspace-data
|
(update-in [:files file-id :data] assoc
|
||||||
assoc :components {} :pages [] :pages-index {}))))
|
:components {}
|
||||||
|
:pages []
|
||||||
|
:pages-index {}))))
|
||||||
|
|
||||||
(defn simulate-copy-shape
|
(defn simulate-copy-shape
|
||||||
[selected objects libraries page file features version]
|
[selected objects libraries page file features version]
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
:workspace-global layout/default-global
|
:workspace-global layout/default-global
|
||||||
:current-file-id nil
|
:current-file-id nil
|
||||||
:current-page-id nil
|
:current-page-id nil
|
||||||
:workspace-data nil
|
|
||||||
:workspace-libraries {}
|
|
||||||
:features-team #{"components/v2"}})
|
:features-team #{"components/v2"}})
|
||||||
|
|
||||||
(defn- on-error
|
(defn- on-error
|
||||||
|
@ -34,8 +32,7 @@
|
||||||
(assoc :current-file-id (:id file)
|
(assoc :current-file-id (:id file)
|
||||||
:current-page-id (cthf/current-page-id file)
|
:current-page-id (cthf/current-page-id file)
|
||||||
:permissions {:can-edit true}
|
:permissions {:can-edit true}
|
||||||
:workspace-file (dissoc file :data)
|
:files {(:id file) file}))
|
||||||
:workspace-data (:data file)))
|
|
||||||
store (ptk/store {:state state :on-error on-error})]
|
store (ptk/store {:state state :on-error on-error})]
|
||||||
store))
|
store))
|
||||||
|
|
||||||
|
@ -64,7 +61,7 @@
|
||||||
|
|
||||||
(ptk/emit! store :the/end))))
|
(ptk/emit! store :the/end))))
|
||||||
|
|
||||||
(defn get-file-from-store
|
(defn get-file-from-state
|
||||||
[store]
|
[state]
|
||||||
(-> (:workspace-file store)
|
(let [file-id (:current-file-id state)]
|
||||||
(assoc :data (:workspace-data store))))
|
(get-in state [:files file-id])))
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue