mirror of
https://github.com/penpot/penpot.git
synced 2025-04-16 17:01:33 -05:00
Merge branch 'staging' into develop
This commit is contained in:
commit
0643ba03a1
258 changed files with 4870 additions and 2299 deletions
|
@ -15,7 +15,7 @@
|
|||
:hooks
|
||||
{:analyze-call
|
||||
{app.common.data.macros/export hooks.export/export
|
||||
potok.core/reify hooks.export/potok-reify
|
||||
potok.v2.core/reify hooks.export/potok-reify
|
||||
app.util.services/defmethod hooks.export/service-defmethod
|
||||
app.common.record/defrecord hooks.export/penpot-defrecord
|
||||
app.db/with-atomic hooks.export/penpot-with-atomic
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
<Logger name="app.redis" level="info" />
|
||||
<Logger name="app.rpc.rlimit" level="info" />
|
||||
<Logger name="app.rpc.climit" level="info" />
|
||||
<Logger name="app.rpc.mutations.files" level="info" />
|
||||
<Logger name="app.common.files.migrations" level="info" />
|
||||
|
||||
<Logger name="app.loggers" level="debug" additivity="false">
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.features :as cfeat]
|
||||
[app.common.files.changes :as cp]
|
||||
[app.common.files.changes-builder :as fcb]
|
||||
[app.common.files.helpers :as cfh]
|
||||
|
@ -769,12 +768,13 @@
|
|||
fdata (migrate-graphics fdata)]
|
||||
(update fdata :options assoc :components-v2 true)))))
|
||||
|
||||
(defn- prepare-fdata
|
||||
[fdata id]
|
||||
(-> fdata
|
||||
(assoc :id id)
|
||||
(fdata/process-pointers deref)
|
||||
(fmg/migrate-data)))
|
||||
(defn- get-file
|
||||
[system id]
|
||||
(binding [pmap/*load-fn* (partial fdata/load-pointer system id)]
|
||||
(-> (files/get-file system id :migrate? false)
|
||||
(update :data assoc :id id)
|
||||
(update :data fdata/process-pointers deref)
|
||||
(fmg/migrate-file))))
|
||||
|
||||
(defn- validate-file!
|
||||
[file libs throw-on-validate?]
|
||||
|
@ -788,18 +788,10 @@
|
|||
|
||||
(defn- process-file
|
||||
[{:keys [::db/conn] :as system} id & {:keys [validate? throw-on-validate?]}]
|
||||
(let [file (binding [cfeat/*new* (atom #{})
|
||||
pmap/*load-fn* (partial fdata/load-pointer system id)]
|
||||
(-> (files/get-file system id :migrate? false)
|
||||
(update :data prepare-fdata id)
|
||||
(update :features into (deref cfeat/*new*))
|
||||
(update :features cfeat/migrate-legacy-features)))
|
||||
(let [file (get-file system id)
|
||||
|
||||
libs (->> (files/get-file-libraries conn id)
|
||||
(into [file] (map (fn [{:keys [id]}]
|
||||
(binding [pmap/*load-fn* (partial fdata/load-pointer system id)]
|
||||
(-> (files/get-file system id :migrate? false)
|
||||
(update :data prepare-fdata id))))))
|
||||
(into [file] (comp (map :id) (map (partial get-file system))))
|
||||
(d/index-by :id))
|
||||
|
||||
file (-> file
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
(cond
|
||||
(or (= code :spec-validation)
|
||||
(= code :params-validation)
|
||||
(= code :schema-validation)
|
||||
(= code :data-validation))
|
||||
(let [explain (ex/explain data)]
|
||||
{::rres/status 400
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
[app.common.exceptions :as ex]
|
||||
[app.common.features :as cfeat]
|
||||
[app.common.files.defaults :as cfd]
|
||||
[app.common.files.migrations :as pmg]
|
||||
[app.common.files.migrations :as fmg]
|
||||
[app.common.files.validate :as fval]
|
||||
[app.common.fressian :as fres]
|
||||
[app.common.logging :as l]
|
||||
|
@ -701,23 +701,29 @@
|
|||
(update :object-id #(str/replace-first % #"^(.*?)/" (str file-id "/")))))
|
||||
thumbnails))
|
||||
|
||||
(defn- process-fdata
|
||||
[fdata id]
|
||||
(-> fdata
|
||||
(dissoc :recent-colors)
|
||||
(assoc :id id)
|
||||
(cond-> (> (:version fdata) cfd/version)
|
||||
(assoc :version cfd/version))
|
||||
;; FIXME: We're temporarily activating all
|
||||
;; migrations because a problem in the
|
||||
;; environments messed up with the version
|
||||
;; numbers When this problem is fixed delete
|
||||
;; the following line
|
||||
(assoc :version 22)
|
||||
(pmg/migrate-data)
|
||||
(update :pages-index relink-shapes)
|
||||
(update :components relink-shapes)
|
||||
(update :media relink-media)))
|
||||
(defn- process-file
|
||||
[{:keys [id] :as file}]
|
||||
(-> file
|
||||
(update :data (fn [fdata]
|
||||
(-> fdata
|
||||
(assoc :id id)
|
||||
(dissoc :recent-colors)
|
||||
(cond-> (> (:version fdata) cfd/version)
|
||||
(assoc :version cfd/version))
|
||||
;; FIXME: We're temporarily activating all
|
||||
;; migrations because a problem in the
|
||||
;; environments messed up with the version
|
||||
;; numbers When this problem is fixed delete
|
||||
;; the following line
|
||||
(cond-> (> (:version fdata) 22)
|
||||
(assoc :version 22)))))
|
||||
(fmg/migrate-file)
|
||||
(update :data (fn [fdata]
|
||||
(-> fdata
|
||||
(update :pages-index relink-shapes)
|
||||
(update :components relink-shapes)
|
||||
(update :media relink-media)
|
||||
(d/without-nils))))))
|
||||
|
||||
|
||||
(defmethod read-section :v1/files
|
||||
|
@ -730,19 +736,7 @@
|
|||
file-id (:id file)
|
||||
file-id' (lookup-index file-id)
|
||||
|
||||
thumbnails (:thumbnails file)
|
||||
file (update file :features cfeat/migrate-legacy-features)
|
||||
|
||||
features (-> enabled-features
|
||||
(set/difference cfeat/frontend-only-features)
|
||||
(set/union (cfeat/check-supported-features! (:features file))))]
|
||||
|
||||
;; All features that are enabled and requires explicit migration
|
||||
;; are added to the state for a posterior migration step
|
||||
(doseq [feature (-> enabled-features
|
||||
(set/difference cfeat/no-migration-features)
|
||||
(set/difference (:features file)))]
|
||||
(vswap! *state* update :pending-to-migrate (fnil conj []) [feature file-id']))
|
||||
thumbnails (:thumbnails file)]
|
||||
|
||||
(when (not= file-id expected-file-id)
|
||||
(ex/raise :type :validation
|
||||
|
@ -773,16 +767,28 @@
|
|||
(l/dbg :hint "update media references" ::l/sync? true)
|
||||
(vswap! *state* update :media into (map #(update % :id lookup-index)) media))
|
||||
|
||||
(let [file (binding [cfeat/*new* (atom #{})]
|
||||
(-> file
|
||||
(assoc :id file-id')
|
||||
(assoc :features features)
|
||||
(assoc :project-id project-id)
|
||||
(assoc :created-at timestamp)
|
||||
(assoc :modified-at timestamp)
|
||||
(dissoc :thumbnails)
|
||||
(update :data process-fdata file-id')
|
||||
(update :features into (deref cfeat/*new*))))
|
||||
(let [file (-> file
|
||||
(assoc :id file-id')
|
||||
(process-file))
|
||||
|
||||
;; All features that are enabled and requires explicit migration are
|
||||
;; added to the state for a posterior migration step.
|
||||
_ (doseq [feature (-> enabled-features
|
||||
(set/difference cfeat/no-migration-features)
|
||||
(set/difference (:features file)))]
|
||||
(vswap! *state* update :pending-to-migrate (fnil conj []) [feature file-id']))
|
||||
|
||||
file (-> file
|
||||
(assoc :project-id project-id)
|
||||
(assoc :created-at timestamp)
|
||||
(assoc :modified-at timestamp)
|
||||
(dissoc :thumbnails)
|
||||
(update :features
|
||||
(fn [features]
|
||||
(let [features (cfeat/check-supported-features! features)]
|
||||
(-> enabled-features
|
||||
(set/difference cfeat/frontend-only-features)
|
||||
(set/union features))))))
|
||||
|
||||
_ (when (contains? cf/flags :file-schema-validation)
|
||||
(fval/validate-file-schema! file))
|
||||
|
@ -803,7 +809,6 @@
|
|||
file))
|
||||
file)
|
||||
|
||||
|
||||
file (-> file
|
||||
(update :features #(db/create-array conn "text" %))
|
||||
(update :data blob/encode))]
|
||||
|
|
|
@ -224,11 +224,8 @@
|
|||
(defn- migrate-file
|
||||
[{:keys [::db/conn] :as cfg} {:keys [id] :as file}]
|
||||
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)
|
||||
pmap/*tracked* (pmap/create-tracked)
|
||||
cfeat/*new* (atom #{})]
|
||||
(let [file (-> (fmg/migrate-file file)
|
||||
(update :features into (deref cfeat/*new*))
|
||||
(update :features cfeat/migrate-legacy-features))]
|
||||
pmap/*tracked* (pmap/create-tracked)]
|
||||
(let [file (fmg/migrate-file file)]
|
||||
|
||||
;; NOTE: when file is migrated, we break the rule of no perform
|
||||
;; mutations on get operations and update the file with all
|
||||
|
@ -250,11 +247,13 @@
|
|||
file)))
|
||||
|
||||
(defn get-file
|
||||
[{:keys [::db/conn] :as cfg} id & {:keys [project-id migrate?
|
||||
[{:keys [::db/conn] :as cfg} id & {:keys [project-id
|
||||
migrate?
|
||||
include-deleted?
|
||||
lock-for-update?]
|
||||
:or {include-deleted? false
|
||||
lock-for-update? false}}]
|
||||
lock-for-update? false
|
||||
migrate? true}}]
|
||||
(dm/assert!
|
||||
"expected cfg with valid connection"
|
||||
(db/connection-map? cfg))
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.common.features :as cfeat]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.files.migrations :as fmg]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.thumbnails :as thc]
|
||||
|
@ -105,24 +106,12 @@
|
|||
(letfn [;; function responsible on finding the frame marked to be
|
||||
;; used as thumbnail; the returned frame always have
|
||||
;; the :page-id set to the page that it belongs.
|
||||
|
||||
(get-thumbnail-frame [file]
|
||||
;; NOTE: this is a hack for avoid perform blocking
|
||||
;; operation inside the for loop, clojure lazy-seq uses
|
||||
;; synchronized blocks that does not plays well with
|
||||
;; virtual threads where all rpc methods calls are
|
||||
;; dispatched, so we need to perform the load operation
|
||||
;; first. This operation forces all pointer maps load into
|
||||
;; the memory.
|
||||
;;
|
||||
;; FIXME: this is no longer true with clojure>=1.12
|
||||
(let [{:keys [data]} (update file :data feat.fdata/process-pointers pmap/load!)]
|
||||
;; Then proceed to find the frame set for thumbnail
|
||||
(d/seek #(or (:use-for-thumbnail %)
|
||||
(:use-for-thumbnail? %)) ; NOTE: backward comp (remove on v1.21)
|
||||
(for [page (-> data :pages-index vals)
|
||||
frame (-> page :objects ctt/get-frames)]
|
||||
(assoc frame :page-id (:id page))))))
|
||||
(get-thumbnail-frame [{:keys [data]}]
|
||||
(d/seek #(or (:use-for-thumbnail %)
|
||||
(:use-for-thumbnail? %)) ; NOTE: backward comp (remove on v1.21)
|
||||
(for [page (-> data :pages-index vals)
|
||||
frame (-> page :objects ctt/get-frames)]
|
||||
(assoc frame :page-id (:id page)))))
|
||||
|
||||
;; function responsible to filter objects data structure of
|
||||
;; all unneeded shapes if a concrete frame is provided. If no
|
||||
|
@ -166,30 +155,29 @@
|
|||
|
||||
objects)))]
|
||||
|
||||
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)]
|
||||
(let [frame (get-thumbnail-frame file)
|
||||
frame-id (:id frame)
|
||||
page-id (or (:page-id frame)
|
||||
(-> data :pages first))
|
||||
(let [frame (get-thumbnail-frame file)
|
||||
frame-id (:id frame)
|
||||
page-id (or (:page-id frame)
|
||||
(-> data :pages first))
|
||||
|
||||
page (dm/get-in data [:pages-index page-id])
|
||||
page (cond-> page (pmap/pointer-map? page) deref)
|
||||
frame-ids (if (some? frame) (list frame-id) (map :id (ctt/get-frames (:objects page))))
|
||||
page (dm/get-in data [:pages-index page-id])
|
||||
page (cond-> page (pmap/pointer-map? page) deref)
|
||||
frame-ids (if (some? frame) (list frame-id) (map :id (ctt/get-frames (:objects page))))
|
||||
|
||||
obj-ids (map #(thc/fmt-object-id (:id file) page-id % "frame") frame-ids)
|
||||
thumbs (get-object-thumbnails conn id obj-ids)]
|
||||
obj-ids (map #(thc/fmt-object-id (:id file) page-id % "frame") frame-ids)
|
||||
thumbs (get-object-thumbnails conn id obj-ids)]
|
||||
|
||||
(cond-> page
|
||||
;; If we have frame, we need to specify it on the page level
|
||||
;; and remove the all other unrelated objects.
|
||||
(some? frame-id)
|
||||
(-> (assoc :thumbnail-frame-id frame-id)
|
||||
(update :objects filter-objects frame-id))
|
||||
(cond-> page
|
||||
;; If we have frame, we need to specify it on the page level
|
||||
;; and remove the all other unrelated objects.
|
||||
(some? frame-id)
|
||||
(-> (assoc :thumbnail-frame-id frame-id)
|
||||
(update :objects filter-objects frame-id))
|
||||
|
||||
;; Assoc the available thumbnails and prune not visible shapes
|
||||
;; for avoid transfer unnecessary data.
|
||||
:always
|
||||
(update :objects assoc-thumbnails page-id thumbs))))))
|
||||
;; Assoc the available thumbnails and prune not visible shapes
|
||||
;; for avoid transfer unnecessary data.
|
||||
:always
|
||||
(update :objects assoc-thumbnails page-id thumbs)))))
|
||||
|
||||
(def ^:private
|
||||
schema:get-file-data-for-thumbnail
|
||||
|
@ -221,7 +209,10 @@
|
|||
:profile-id profile-id
|
||||
:file-id file-id)
|
||||
|
||||
file (files/get-file cfg file-id)]
|
||||
file (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg file-id)]
|
||||
(-> (files/get-file cfg file-id :migrate? false)
|
||||
(update :data feat.fdata/process-pointers deref)
|
||||
(fmg/migrate-file)))]
|
||||
|
||||
(-> (cfeat/get-team-enabled-features cf/flags team)
|
||||
(cfeat/check-client-features! (:features params))
|
||||
|
|
|
@ -106,41 +106,34 @@
|
|||
media
|
||||
media))
|
||||
|
||||
(update-fdata [fdata new-id]
|
||||
(-> fdata
|
||||
(assoc :id new-id)
|
||||
(feat.fdata/process-pointers deref)
|
||||
(pmg/migrate-data)
|
||||
(update :pages-index relink-shapes)
|
||||
(update :components relink-shapes)
|
||||
(update :media relink-media)
|
||||
(d/without-nils)))]
|
||||
(process-file [{:keys [id] :as file}]
|
||||
(-> file
|
||||
(update :data assoc :id id)
|
||||
(update :data feat.fdata/process-pointers deref)
|
||||
(pmg/migrate-file)
|
||||
(update :data (fn [data]
|
||||
(-> data
|
||||
(update :pages-index relink-shapes)
|
||||
(update :components relink-shapes)
|
||||
(update :media relink-media)
|
||||
(d/without-nils))))))]
|
||||
|
||||
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)
|
||||
pmap/*tracked* (pmap/create-tracked)
|
||||
cfeat/*new* (atom #{})]
|
||||
(let [new-id (get index id)
|
||||
file (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)]
|
||||
(-> (assoc file :id new-id)
|
||||
(process-file)))
|
||||
|
||||
(let [new-id (get index id)
|
||||
file (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)
|
||||
cfeat/*new* (atom #{})]
|
||||
(-> file
|
||||
(assoc :id new-id)
|
||||
(update :data update-fdata new-id)
|
||||
(update :features into (deref cfeat/*new*))
|
||||
(update :features cfeat/migrate-legacy-features)))
|
||||
file (if (contains? (:features file) "fdata/objects-map")
|
||||
(feat.fdata/enable-objects-map file)
|
||||
file)
|
||||
|
||||
file (if (contains? (:features file) "fdata/objects-map")
|
||||
(feat.fdata/enable-objects-map file)
|
||||
file)
|
||||
|
||||
file (if (contains? (:features file) "fdata/pointer-map")
|
||||
(binding [pmap/*tracked* (pmap/create-tracked)]
|
||||
(let [file (feat.fdata/enable-pointer-map file)]
|
||||
(feat.fdata/persist-pointers! cfg (:id file))
|
||||
file))
|
||||
file)]
|
||||
|
||||
file))))
|
||||
file (if (contains? (:features file) "fdata/pointer-map")
|
||||
(binding [pmap/*tracked* (pmap/create-tracked)]
|
||||
(let [file (feat.fdata/enable-pointer-map file)]
|
||||
(feat.fdata/persist-pointers! cfg (:id file))
|
||||
file))
|
||||
file)]
|
||||
file)))
|
||||
|
||||
(def sql:get-used-libraries
|
||||
"select flr.*
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
[app.common.spec :as us]
|
||||
[app.db :as db]
|
||||
[app.rpc :as-alias rpc]
|
||||
[app.rpc.commands.files :refer [resolve-public-uri]]
|
||||
[app.rpc.doc :as-alias doc]
|
||||
[app.util.services :as sv]
|
||||
[clojure.spec.alpha :as s]))
|
||||
|
@ -37,12 +38,15 @@
|
|||
)
|
||||
select distinct
|
||||
f.id,
|
||||
f.revn,
|
||||
f.project_id,
|
||||
f.created_at,
|
||||
f.modified_at,
|
||||
f.name,
|
||||
f.is_shared
|
||||
f.is_shared,
|
||||
ft.media_id
|
||||
from file as f
|
||||
left join file_thumbnail as ft on (ft.file_id = f.id and ft.revn = f.revn)
|
||||
inner join projects as pr on (f.project_id = pr.id)
|
||||
where f.name ilike ('%' || ? || '%')
|
||||
and (f.deleted_at is null or f.deleted_at > now())
|
||||
|
@ -50,10 +54,16 @@
|
|||
|
||||
(defn search-files
|
||||
[conn profile-id team-id search-term]
|
||||
(db/exec! conn [sql:search-files
|
||||
profile-id team-id
|
||||
profile-id team-id
|
||||
search-term]))
|
||||
(->> (db/exec! conn [sql:search-files
|
||||
profile-id team-id
|
||||
profile-id team-id
|
||||
search-term])
|
||||
(mapv (fn [row]
|
||||
(if-let [media-id (:media-id row)]
|
||||
(-> row
|
||||
(dissoc :media-id)
|
||||
(assoc :thumbnail-uri (resolve-public-uri media-id)))
|
||||
(dissoc row :media-id))))))
|
||||
|
||||
(s/def ::team-id ::us/uuid)
|
||||
(s/def ::search-files ::us/string)
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
|
||||
{:on-open
|
||||
(fn on-open [channel]
|
||||
(l/trace :fn "on-open" :conn-id id :channel channel)
|
||||
(l/dbg :fn "on-open" :conn-id (str id))
|
||||
(let [options (-> options
|
||||
(assoc ::channel channel)
|
||||
(on-connect))
|
||||
|
@ -114,10 +114,10 @@
|
|||
|
||||
:on-close
|
||||
(fn on-close [_channel code reason]
|
||||
(l/info :fn "on-ws-terminate"
|
||||
:conn-id id
|
||||
:code code
|
||||
:reason reason)
|
||||
(l/dbg :fn "on-close"
|
||||
:conn-id (str id)
|
||||
:code code
|
||||
:reason reason)
|
||||
(sp/close! close-ch))
|
||||
|
||||
:on-error
|
||||
|
@ -132,18 +132,19 @@
|
|||
|
||||
:on-pong
|
||||
(fn on-pong [_channel data]
|
||||
(l/trace :fn "on-pong" :data data)
|
||||
(sp/put! hbeat-ch data))}))
|
||||
|
||||
(defn- handle-ping!
|
||||
[{:keys [::id ::beats ::channel] :as wsp} beat-id]
|
||||
(l/trace :hint "send ping" :beat beat-id :conn-id id)
|
||||
(l/trc :hint "send ping" :beat beat-id :conn-id (str id))
|
||||
(rws/ping channel (encode-beat beat-id))
|
||||
(let [issued (swap! beats conj (long beat-id))]
|
||||
(not (>= (count issued) max-missed-heartbeats))))
|
||||
|
||||
(defn- start-io-loop!
|
||||
[{:keys [::id ::close-ch ::input-ch ::output-ch ::heartbeat-ch ::channel ::handler ::beats ::on-rcv-message ::on-snd-message] :as wsp}]
|
||||
[{:keys [::id ::close-ch ::input-ch ::output-ch ::heartbeat-ch
|
||||
::channel ::handler ::beats ::on-rcv-message ::on-snd-message]
|
||||
:as wsp}]
|
||||
(try
|
||||
(handler wsp {:type :open})
|
||||
(loop [i 0]
|
||||
|
@ -154,14 +155,16 @@
|
|||
(identical? p ping-ch)
|
||||
(if (handle-ping! wsp i)
|
||||
(recur (inc i))
|
||||
(rws/close channel 8802 "missing to many pings"))
|
||||
(do
|
||||
(l/trc :hint "closing" :reason "missing to many pings")
|
||||
(rws/close channel 8802 "missing to many pings")))
|
||||
|
||||
(or (identical? p close-ch) (nil? msg))
|
||||
(do :nothing)
|
||||
|
||||
(identical? p heartbeat-ch)
|
||||
(let [beat (decode-beat msg)]
|
||||
;; (l/trace :hint "pong" :beat beat :conn-id id)
|
||||
(l/trc :hint "pong received" :beat beat :conn-id (str id))
|
||||
(swap! beats disj beat)
|
||||
(recur i))
|
||||
|
||||
|
@ -179,7 +182,6 @@
|
|||
(identical? p output-ch)
|
||||
(let [message (on-snd-message msg)
|
||||
message (t/encode-str message {:type :json-verbose})]
|
||||
;; (l/trace :hint "writing message to output" :message msg)
|
||||
(rws/send channel message)
|
||||
(recur i))))))
|
||||
|
||||
|
@ -188,12 +190,12 @@
|
|||
(catch java.io.IOException _)
|
||||
|
||||
(catch InterruptedException _cause
|
||||
(l/debug :hint "websocket thread interrumpted" :conn-id id))
|
||||
(l/dbg :hint "websocket thread interrumpted" :conn-id id))
|
||||
|
||||
(catch Throwable cause
|
||||
(l/error :hint "unhandled exception on websocket thread"
|
||||
:conn-id id
|
||||
:cause cause))
|
||||
(l/err :hint "unhandled exception on websocket thread"
|
||||
:conn-id id
|
||||
:cause cause))
|
||||
(finally
|
||||
(try
|
||||
(handler wsp {:type :close})
|
||||
|
@ -212,4 +214,4 @@
|
|||
(catch Throwable cause
|
||||
(throw cause)))
|
||||
|
||||
(l/trace :hint "websocket thread terminated" :conn-id id))))
|
||||
(l/trc :hint "websocket thread terminated" :conn-id id))))
|
||||
|
|
|
@ -358,13 +358,13 @@
|
|||
|
||||
(defn changed-attrs
|
||||
"Returns the list of attributes that will change when `update-fn` is applied"
|
||||
[object update-fn {:keys [attrs]}]
|
||||
[object objects update-fn {:keys [attrs]}]
|
||||
(let [changed?
|
||||
(fn [old new attr]
|
||||
(let [old-val (get old attr)
|
||||
new-val (get new attr)]
|
||||
(not= old-val new-val)))
|
||||
new-obj (update-fn object)]
|
||||
new-obj (update-fn object objects)]
|
||||
(when-not (= object new-obj)
|
||||
(let [attrs (or attrs (d/concat-set (keys object) (keys new-obj)))]
|
||||
(filter (partial changed? object new-obj) attrs)))))
|
||||
|
@ -412,7 +412,7 @@
|
|||
update-shape
|
||||
(fn [changes id]
|
||||
(let [old-obj (get objects id)
|
||||
new-obj (update-fn old-obj)]
|
||||
new-obj (update-fn old-obj objects)]
|
||||
(if (= old-obj new-obj)
|
||||
changes
|
||||
(let [[rops uops] (-> (or attrs (d/concat-set (keys old-obj) (keys new-obj)))
|
||||
|
|
|
@ -42,18 +42,21 @@
|
|||
(reduce migrate-fn data (range (:version data 0) to-version))))))
|
||||
|
||||
(defn migrate-file
|
||||
[{:keys [id data] :as file}]
|
||||
(let [data (assoc data :id id)]
|
||||
(-> file
|
||||
(assoc ::orig-version (:version data))
|
||||
(assoc :data (migrate-data data)))))
|
||||
[{:keys [id data features] :as file}]
|
||||
(binding [cfeat/*new* (atom #{})]
|
||||
(let [file (-> file
|
||||
(update :data assoc :id id)
|
||||
(update :data migrate-data)
|
||||
(update :features (fnil into #{}) (deref cfeat/*new*))
|
||||
(update :features cfeat/migrate-legacy-features))]
|
||||
(if (or (not= (:version data) (:version (:data file)))
|
||||
(not= features (:features file)))
|
||||
(vary-meta file assoc ::migrated true)
|
||||
file))))
|
||||
|
||||
(defn migrated?
|
||||
[{:keys [data] :as file}]
|
||||
(or (::migrated file)
|
||||
(let [version (:version data)]
|
||||
(> version
|
||||
(::orig-version file version)))))
|
||||
[file]
|
||||
(true? (-> file meta ::migrated)))
|
||||
|
||||
;; Default handler, noop
|
||||
(defmethod migrate :default [data] data)
|
||||
|
|
|
@ -353,3 +353,19 @@
|
|||
(mth/max by1 y1)
|
||||
(mth/min bx2 x2)
|
||||
(mth/min by2 y2)))))
|
||||
(defn fix-aspect-ratio
|
||||
[bounds aspect-ratio]
|
||||
(if aspect-ratio
|
||||
(let [width (dm/get-prop bounds :width)
|
||||
height (dm/get-prop bounds :height)
|
||||
target-height (* width aspect-ratio)
|
||||
target-width (* height (/ 1 aspect-ratio))]
|
||||
(cond-> bounds
|
||||
(> target-height height)
|
||||
(-> (assoc :height target-height)
|
||||
(update :y - (/ (- target-height height ) 2)))
|
||||
|
||||
(< target-height height)
|
||||
(-> (assoc :width target-width)
|
||||
(update :x - (/ (- target-width width ) 2)))))
|
||||
bounds))
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
(ns app.common.thumbnails
|
||||
(:require [cuerdas.core :as str]))
|
||||
(:require
|
||||
[app.common.uuid :as uuid]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn fmt-object-id
|
||||
"Returns ids formatted as a string (object-id)"
|
||||
[file-id page-id frame-id tag]
|
||||
(str/ffmt "%/%/%/%" file-id page-id frame-id tag))
|
||||
|
||||
(defn file-id?
|
||||
"Returns ids formatted as a string (file-id)"
|
||||
[object-id file-id]
|
||||
(str/starts-with? object-id (str/concat file-id "/")))
|
||||
|
||||
(defn get-file-id
|
||||
[object-id]
|
||||
(uuid/uuid (str/slice object-id 0 (str/index-of object-id "/"))))
|
||||
|
|
|
@ -676,7 +676,7 @@
|
|||
[id cell])))
|
||||
|
||||
(defn remove-grid-column
|
||||
[parent index]
|
||||
[parent index objects]
|
||||
|
||||
(let [track-num (inc index)
|
||||
|
||||
|
@ -692,10 +692,10 @@
|
|||
(-> parent
|
||||
(update :layout-grid-columns d/remove-at-index index)
|
||||
(update :layout-grid-cells update-cells)
|
||||
(assign-cells))))
|
||||
(assign-cells objects))))
|
||||
|
||||
(defn remove-grid-row
|
||||
[parent index]
|
||||
[parent index objects]
|
||||
(let [track-num (inc index)
|
||||
|
||||
decrease-track-num (make-decrease-track-num :row :row-span track-num)
|
||||
|
@ -710,7 +710,7 @@
|
|||
(-> parent
|
||||
(update :layout-grid-rows d/remove-at-index index)
|
||||
(update :layout-grid-cells update-cells)
|
||||
(assign-cells))))
|
||||
(assign-cells objects))))
|
||||
|
||||
(defn- reorder-grid-tracks
|
||||
"Swap the positions of the tracks info"
|
||||
|
@ -781,6 +781,7 @@
|
|||
|
||||
parent
|
||||
(reorder-grid-tracks parent tracks-props from-index to-index)]
|
||||
|
||||
(cond-> parent
|
||||
move-content?
|
||||
(swap-track-content prop from-track to-track))))
|
||||
|
@ -828,14 +829,24 @@
|
|||
|
||||
(defn check-deassigned-cells
|
||||
"Clean the cells whith shapes that are no longer in the layout"
|
||||
[parent]
|
||||
[parent objects]
|
||||
|
||||
(let [child? (set (:shapes parent))
|
||||
cells (update-vals
|
||||
(:layout-grid-cells parent)
|
||||
(fn [cell] (update cell :shapes #(filterv child? %))))]
|
||||
(let [child-set (set (:shapes parent))
|
||||
|
||||
(assoc parent :layout-grid-cells cells)))
|
||||
assigned?
|
||||
(fn [id]
|
||||
(and (contains? child-set id)
|
||||
(not (position-absolute? objects id))))
|
||||
|
||||
cells
|
||||
(update-vals
|
||||
(:layout-grid-cells parent)
|
||||
(fn [cell]
|
||||
(-> cell
|
||||
(update :shapes #(filterv assigned? %)))))]
|
||||
|
||||
(-> parent
|
||||
(assoc :layout-grid-cells cells))))
|
||||
|
||||
(defn overlapping-cells
|
||||
"Find overlapping cells"
|
||||
|
@ -902,12 +913,12 @@
|
|||
;; - Shape duplication
|
||||
;; - (maybe) create group/frames. This case will assigna a cell that had one of its children
|
||||
(defn assign-cells
|
||||
[parent]
|
||||
[parent objects]
|
||||
(let [;; TODO: Remove this, shouldn't be happening
|
||||
;;overlaps (overlapping-cells parent)
|
||||
;;_ (when (not (empty? overlaps))
|
||||
;; (.warn js/console "OVERLAPS" overlaps))
|
||||
parent (cond-> (check-deassigned-cells parent)
|
||||
parent (cond-> (check-deassigned-cells parent objects)
|
||||
#_(d/not-empty? overlaps)
|
||||
#_(fix-overlaps overlaps))
|
||||
|
||||
|
@ -915,7 +926,9 @@
|
|||
(into #{} (mapcat (comp :shapes second)) (:layout-grid-cells parent))
|
||||
|
||||
no-cell-shapes
|
||||
(->> (:shapes parent) (remove shape-has-cell?))
|
||||
(->> (:shapes parent)
|
||||
(remove shape-has-cell?)
|
||||
(remove (partial position-absolute? objects)))
|
||||
|
||||
parent (position-auto-shapes parent)]
|
||||
|
||||
|
@ -1174,7 +1187,7 @@
|
|||
(let [;; Temporary remove the children when moving them
|
||||
frame (-> frame
|
||||
(update :shapes #(d/removev children %))
|
||||
(assign-cells))
|
||||
(assign-cells objects))
|
||||
|
||||
children (->> children (remove #(position-absolute? objects %)))]
|
||||
|
||||
|
@ -1182,7 +1195,7 @@
|
|||
(update :shapes d/concat-vec children)
|
||||
(cond-> (some? cell)
|
||||
(push-into-cell children row column))
|
||||
(assign-cells))))
|
||||
(assign-cells objects))))
|
||||
|
||||
(defn add-children-to-index
|
||||
[parent ids objects to-index]
|
||||
|
|
|
@ -6,10 +6,17 @@
|
|||
org.clojure/clojure {:mvn/version "1.11.1"}
|
||||
binaryage/devtools {:mvn/version "RELEASE"}
|
||||
metosin/reitit-core {:mvn/version "0.5.18"}
|
||||
|
||||
funcool/beicon {:mvn/version "2021.07.05-1"}
|
||||
funcool/okulary {:mvn/version "2022.04.11-16"}
|
||||
funcool/potok {:mvn/version "2022.12.16-71"}
|
||||
|
||||
funcool/potok2
|
||||
{:git/tag "v2.0"
|
||||
:git/sha "2bb377b"
|
||||
:git/url "https://github.com/funcool/potok.git"}
|
||||
|
||||
funcool/beicon2
|
||||
{:git/tag "v2.0"
|
||||
:git/sha "e7135e0"
|
||||
:git/url "https://github.com/funcool/beicon.git"}
|
||||
|
||||
funcool/rumext
|
||||
{:git/tag "v2.7"
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
"@storybook/react": "^7.5.3",
|
||||
"@storybook/react-vite": "^7.5.3",
|
||||
"@storybook/testing-library": "^0.2.2",
|
||||
"@types/node": "^20.10.5",
|
||||
"animate.css": "^4.1.1",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"concurrently": "^8.2.2",
|
||||
|
@ -73,6 +74,7 @@
|
|||
"sass": "^1.66.1",
|
||||
"shadow-cljs": "2.26.2",
|
||||
"storybook": "^7.5.3",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -90,7 +92,7 @@
|
|||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-virtualized": "^9.22.3",
|
||||
"rxjs": "~7.8.1",
|
||||
"rxjs": "8.0.0-alpha.13",
|
||||
"sax": "^1.2.4",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tdigest": "^0.1.2",
|
||||
|
|
BIN
frontend/resources/fonts/RobotoMono-Regular.ttf
Normal file
BIN
frontend/resources/fonts/RobotoMono-Regular.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3
frontend/resources/images/icons/expand-refactor.svg
Normal file
3
frontend/resources/images/icons/expand-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10.357 2.813h2.828v2.829m-10.37 4.713v2.829h2.828m7.071-9.9l-9.428 9.429z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 206 B |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 273 KiB After Width: | Height: | Size: 279 KiB |
3
frontend/resources/images/icons/reload-refactor.svg
Normal file
3
frontend/resources/images/icons/reload-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2.4 8a6 6 0 111.758 4.242M2.4 8l2.1-2zm0 0L1 5.5z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 182 B |
|
@ -148,6 +148,7 @@
|
|||
stroke: var(--button-tertiary-foreground-color-active);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.disabled),
|
||||
&[disabled],
|
||||
&:disabled {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "sass:color" as color;
|
||||
@use "sass:color";
|
||||
|
||||
:root {
|
||||
// DARK
|
||||
|
@ -31,10 +31,12 @@
|
|||
--light-gray-1: #fff;
|
||||
--light-gray-2: #e8eaee;
|
||||
--light-gray-2-30: rgba(232, 234, 238, 0.3);
|
||||
--light-gray-2-80: rgba(232, 234, 238, 0.8);
|
||||
--light-gray-3: #f3f4f6;
|
||||
--light-gray-4: #eef0f2;
|
||||
--black: #000;
|
||||
--off-black: #495e74;
|
||||
--off-black-30: #{color.change(#495e74, $alpha: 0.3)};
|
||||
--purple: #6911d4;
|
||||
--purple-30: rgba(105, 17, 212, 0.2);
|
||||
--blue: #1345aa;
|
||||
|
|
|
@ -157,6 +157,8 @@
|
|||
.btn-primary {
|
||||
@extend .button-primary;
|
||||
text-transform: uppercase;
|
||||
font-size: $fs-14;
|
||||
font-weight: $fw400;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
--menu-shortcut-foreground-color: var(--color-foreground-secondary);
|
||||
--menu-shortcut-foreground-color-selected: var(--color-foreground-primary);
|
||||
--menu-shortcut-foreground-color-hover: var(--color-foreground-primary);
|
||||
--menu-shadow-color: var(--color-background-subtle);
|
||||
--menu-shadow-color: var(--shadow-color);
|
||||
--menu-background-color-disabled: var(--color-background-primary);
|
||||
--menu-foreground-color-disabled: var(--color-foreground-secondary);
|
||||
--menu-border-color-disabled: var(--color-background-quaternary);
|
||||
|
@ -297,4 +297,13 @@
|
|||
--tag-background-color: var(--color-accent-primary);
|
||||
|
||||
--link-foreground-color: var(--color-accent-primary);
|
||||
|
||||
// VIEWER
|
||||
--viewer-background-color: var(--color-background-secondary);
|
||||
--viewer-paginator-background-color: var(--color-background-tertiary);
|
||||
--viewer-controls-background-color: var(--color-background-primary);
|
||||
--viewer-inspect-border-color: var(--color-background-tertiary);
|
||||
--viewer-thumbnails-control-foreground-color: var(--color-foreground-secondary);
|
||||
--viewer-thumbnail-border-color: var(--color-accent-primary);
|
||||
--viewer-thumbnail-background-color-selected: var(--color-accent-primary-muted);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,13 @@
|
|||
line-height: 1.2;
|
||||
}
|
||||
|
||||
@mixin codeTypography {
|
||||
font-family: "robotomono", monospace;
|
||||
font-size: $fs-12;
|
||||
font-weight: $fw400;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
@mixin textEllipsis {
|
||||
max-width: 99%;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
--color-accent-primary-muted: var(--green-30);
|
||||
--color-accent-secondary: var(--lilac);
|
||||
--color-accent-tertiary: var(--strong-green);
|
||||
|
||||
--overlay-color: rgba(0, 0, 0, 0.4);
|
||||
--ok-color: var(--dark-ok-color);
|
||||
--warning-color: var(--dark-warning-color);
|
||||
|
@ -28,5 +29,8 @@
|
|||
--error-color: var(--dark-error-color);
|
||||
--canvas-color: var(--color-canvas);
|
||||
|
||||
--shadow-color: var(--dark-gray-2-30);
|
||||
--radio-button-box-shadow: 0 0 0 1px var(--dark-gray-2-30) inset;
|
||||
|
||||
@include meta.load-css("hljs-dark-theme");
|
||||
}
|
||||
|
|
|
@ -1,98 +1,124 @@
|
|||
/**
|
||||
* Panda Syntax Theme for Highlight.js
|
||||
* Based on: https://github.com/tinkertrain/panda-syntax-vscode
|
||||
* Author: Annmarie Switzer <https://github.com/annmarie-switzer>
|
||||
*/
|
||||
/*!
|
||||
Theme: GitHub Dark Dimmed
|
||||
Description: Dark dimmed theme as seen on github.com
|
||||
Author: github.com
|
||||
Maintainer: @Hirse
|
||||
Updated: 2021-05-15
|
||||
|
||||
Colors taken from GitHub's CSS
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
color: #e6e6e6;
|
||||
background: #2a2c2d;
|
||||
color: #adbac7;
|
||||
background: #22272e;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-variable.language_ {
|
||||
/* prettylights-syntax-keyword */
|
||||
color: #f47067;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-title.function_ {
|
||||
/* prettylights-syntax-entity */
|
||||
color: #dcbdfb;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-attribute,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-operator,
|
||||
.hljs-variable,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-id {
|
||||
/* prettylights-syntax-constant */
|
||||
color: #6cb6ff;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-string {
|
||||
/* prettylights-syntax-string */
|
||||
color: #96d0ff;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-symbol {
|
||||
/* prettylights-syntax-variable */
|
||||
color: #f69d50;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-code,
|
||||
.hljs-formula {
|
||||
/* prettylights-syntax-comment */
|
||||
color: #768390;
|
||||
}
|
||||
|
||||
.hljs-name,
|
||||
.hljs-quote,
|
||||
.hljs-selector-tag,
|
||||
.hljs-selector-pseudo {
|
||||
/* prettylights-syntax-entity-tag */
|
||||
color: #8ddb8c;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
/* prettylights-syntax-storage-modifier-import */
|
||||
color: #adbac7;
|
||||
}
|
||||
|
||||
.hljs-section {
|
||||
/* prettylights-syntax-markup-heading */
|
||||
color: #316dca;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-bullet {
|
||||
/* prettylights-syntax-markup-list */
|
||||
color: #eac55f;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
/* prettylights-syntax-markup-italic */
|
||||
color: #adbac7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
/* prettylights-syntax-markup-bold */
|
||||
color: #adbac7;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
.hljs-addition {
|
||||
/* prettylights-syntax-markup-inserted */
|
||||
color: #b4f1b4;
|
||||
background-color: #1b4721;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #bbbbbb;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-params {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.hljs-punctuation,
|
||||
.hljs-attr {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-meta {
|
||||
color: #ff4b82;
|
||||
}
|
||||
|
||||
.hljs-operator,
|
||||
.hljs-char.escape_ {
|
||||
color: #b084eb;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-deletion {
|
||||
color: #ff75b5;
|
||||
/* prettylights-syntax-markup-deleted */
|
||||
color: #ffd8d3;
|
||||
background-color: #78191b;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-selector-attr,
|
||||
.hljs-variable.language_ {
|
||||
color: #ff9ac1;
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
.hljs-property,
|
||||
.hljs-code,
|
||||
.hljs-formula,
|
||||
.hljs-section,
|
||||
.hljs-title.function_ {
|
||||
color: #45a9f9;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-selector-class,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-meta .hljs-string {
|
||||
color: #19f9d8;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-char.escape_,
|
||||
.hljs-link,
|
||||
.hljs-built_in,
|
||||
.hljs-title,
|
||||
.hljs-selector-id,
|
||||
.hljs-tag,
|
||||
.hljs-doctag,
|
||||
.hljs-attribute,
|
||||
.hljs-template-tag,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-punctuation {
|
||||
color: #ffb86c;
|
||||
.hljs-params,
|
||||
.hljs-property,
|
||||
.hljs-punctuation,
|
||||
.hljs-tag {
|
||||
/* purposely ignored */
|
||||
}
|
||||
|
|
|
@ -1,94 +1,126 @@
|
|||
/**
|
||||
* Panda Syntax Theme for Highlight.js
|
||||
* Based on: https://github.com/tinkertrain/panda-syntax-vscode
|
||||
* Author: Annmarie Switzer <https://github.com/annmarie-switzer>
|
||||
*/
|
||||
/*!
|
||||
Theme: GitHub
|
||||
Description: Light theme as seen on github.com
|
||||
Author: github.com
|
||||
Maintainer: @Hirse
|
||||
Updated: 2021-05-15
|
||||
|
||||
Outdated base version: https://github.com/primer/github-syntax-light
|
||||
Current colors taken from GitHub's CSS
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
color: #2a2c2d;
|
||||
background: #e6e6e6;
|
||||
color: #24292e;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-variable.language_ {
|
||||
/* prettylights-syntax-keyword */
|
||||
color: #d73a49;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-title.function_ {
|
||||
/* prettylights-syntax-entity */
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-attribute,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-operator,
|
||||
.hljs-variable,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-id {
|
||||
/* prettylights-syntax-constant */
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-string {
|
||||
/* prettylights-syntax-string */
|
||||
color: #032f62;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-symbol {
|
||||
/* prettylights-syntax-variable */
|
||||
color: #e36209;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-code,
|
||||
.hljs-formula {
|
||||
/* prettylights-syntax-comment */
|
||||
color: #6a737d;
|
||||
}
|
||||
|
||||
.hljs-name,
|
||||
.hljs-quote,
|
||||
.hljs-selector-tag,
|
||||
.hljs-selector-pseudo {
|
||||
/* prettylights-syntax-entity-tag */
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
/* prettylights-syntax-storage-modifier-import */
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.hljs-section {
|
||||
/* prettylights-syntax-markup-heading */
|
||||
color: #005cc5;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-bullet {
|
||||
/* prettylights-syntax-markup-list */
|
||||
color: #735c0f;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
/* prettylights-syntax-markup-italic */
|
||||
color: #24292e;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
/* prettylights-syntax-markup-bold */
|
||||
color: #24292e;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
.hljs-addition {
|
||||
/* prettylights-syntax-markup-inserted */
|
||||
color: #22863a;
|
||||
background-color: #f0fff4;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #676b79;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-params {
|
||||
color: #676b79;
|
||||
}
|
||||
|
||||
.hljs-punctuation,
|
||||
.hljs-attr {
|
||||
color: #2a2c2d;
|
||||
}
|
||||
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-meta,
|
||||
.hljs-operator,
|
||||
.hljs-char.escape_ {
|
||||
color: #c56200;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-deletion {
|
||||
color: #d92792;
|
||||
/* prettylights-syntax-markup-deleted */
|
||||
color: #b31d28;
|
||||
background-color: #ffeef0;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-selector-attr,
|
||||
.hljs-variable.language_ {
|
||||
color: #cc5e91;
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
.hljs-property,
|
||||
.hljs-code,
|
||||
.hljs-formula,
|
||||
.hljs-section,
|
||||
.hljs-title.function_ {
|
||||
color: #3787c7;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-selector-class,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-meta .hljs-string {
|
||||
color: #0d7d6c;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-char.escape_,
|
||||
.hljs-link,
|
||||
.hljs-built_in,
|
||||
.hljs-title,
|
||||
.hljs-selector-id,
|
||||
.hljs-tag,
|
||||
.hljs-doctag,
|
||||
.hljs-attribute,
|
||||
.hljs-template-tag,
|
||||
.hljs-meta .hljs-keyword {
|
||||
color: #7641bb;
|
||||
.hljs-params,
|
||||
.hljs-property,
|
||||
.hljs-punctuation,
|
||||
.hljs-tag {
|
||||
/* purposely ignored */
|
||||
color: #6a737d;
|
||||
}
|
||||
|
|
|
@ -21,11 +21,16 @@
|
|||
--color-accent-primary-muted: var(--purple-30);
|
||||
--color-accent-secondary: var(--blue);
|
||||
--color-accent-tertiary: var(--strong-purple);
|
||||
|
||||
--overlay-color: rgba(255, 255, 255, 0.4);
|
||||
--ok-color: var(--light-ok-color);
|
||||
--warning-color: var(--light-warning-color);
|
||||
--pending-color: var(--light-pending-color);
|
||||
--error-color: var(--light-error-color);
|
||||
--canvas-color: var(--color-canvas);
|
||||
|
||||
--shadow-color: var(--off-black-30);
|
||||
--radio-button-box-shadow: 0 0 0 1px var(--light-gray-2) inset;
|
||||
|
||||
@include meta.load-css("hljs-light-theme");
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
[app.util.webapi :as wapi]
|
||||
[app.util.zip :as uz]
|
||||
[app.worker.export :as e]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn parse-data [data]
|
||||
|
@ -55,7 +55,7 @@
|
|||
|
||||
(->> (rx/from (vals media))
|
||||
(rx/map #(assoc % :file-id file-id))
|
||||
(rx/flat-map
|
||||
(rx/merge-map
|
||||
(fn [media]
|
||||
(let [file-path (str/concat file-id "/media/" (:id media) (cm/mtype->extension (:mtype media)))
|
||||
blob (data-uri->blob (:uri media))]
|
||||
|
@ -79,38 +79,38 @@
|
|||
|
||||
render-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/flat-map e/process-pages)
|
||||
(rx/merge-map vals)
|
||||
(rx/merge-map e/process-pages)
|
||||
(rx/observe-on :async)
|
||||
(rx/flat-map e/get-page-data)
|
||||
(rx/merge-map e/get-page-data)
|
||||
(rx/share))
|
||||
|
||||
colors-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/merge-map vals)
|
||||
(rx/map #(vector (:id %) (get-in % [:data :colors])))
|
||||
(rx/filter #(d/not-empty? (second %)))
|
||||
(rx/map e/parse-library-color))
|
||||
|
||||
typographies-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/merge-map vals)
|
||||
(rx/map #(vector (:id %) (get-in % [:data :typographies])))
|
||||
(rx/filter #(d/not-empty? (second %)))
|
||||
(rx/map e/parse-library-typographies))
|
||||
|
||||
media-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/merge-map vals)
|
||||
(rx/map #(vector (:id %) (get-in % [:data :media])))
|
||||
(rx/filter #(d/not-empty? (second %)))
|
||||
(rx/flat-map parse-library-media))
|
||||
(rx/merge-map parse-library-media))
|
||||
|
||||
components-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/merge-map vals)
|
||||
(rx/filter #(d/not-empty? (ctkl/components-seq (:data %))))
|
||||
(rx/flat-map e/parse-library-components))
|
||||
(rx/merge-map e/parse-library-components))
|
||||
|
||||
pages-stream
|
||||
(->> render-stream
|
||||
|
@ -132,7 +132,7 @@
|
|||
typographies-stream)
|
||||
(rx/reduce conj [])
|
||||
(rx/with-latest-from files-stream)
|
||||
(rx/flat-map (fn [[data _]]
|
||||
(rx/merge-map (fn [[data _]]
|
||||
(->> (uz/compress-files data)
|
||||
(rx/map #(vector file %)))))))))
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.render :as r]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(defn render-page-export
|
||||
|
@ -22,7 +22,7 @@
|
|||
(fn [resolve reject]
|
||||
(->> (r/render-page data)
|
||||
(rx/take 1)
|
||||
(rx/subs resolve reject))) )))
|
||||
(rx/subs! resolve reject))) )))
|
||||
|
||||
(defn exports []
|
||||
#js {:renderPage render-page-export})
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n]
|
||||
[app.util.theme :as theme]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[debug]
|
||||
[features]
|
||||
[potok.core :as ptk]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(log/setup! {:app :info})
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
(:require
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.transit :as t]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defrecord BroadcastMessage [id type data]
|
||||
cljs.core/IDeref
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.repo :as rp]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def ^:private schema:comment-thread
|
||||
(sm/define
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
[app.main.features :as features]
|
||||
[app.main.repo :as rp]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; SHARE LINK
|
||||
|
@ -106,9 +106,8 @@
|
|||
(:typography-count summary))]
|
||||
(modal/show
|
||||
{:type :confirm
|
||||
:message ""
|
||||
:title (tr "modals.add-shared-confirm.message" (:name summary))
|
||||
:hint (if (zero? count) (tr "modals.add-shared-confirm-empty.hint") (tr "modals.add-shared-confirm.hint"))
|
||||
:message (if (zero? count) (tr "modals.add-shared-confirm-empty.hint") (tr "modals.add-shared-confirm.hint"))
|
||||
:cancel-label (if (zero? count) (tr "labels.cancel") :omit)
|
||||
:accept-label (tr "modals.add-shared-confirm.accept")
|
||||
:accept-style :primary
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
[app.util.time :as dt]
|
||||
[app.util.timers :as tm]
|
||||
[app.util.webapi :as wapi]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[clojure.set :as set]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(log/set-level! :warn)
|
||||
|
||||
|
@ -419,7 +419,7 @@
|
|||
(rx/map di/validate-file)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/cmd! :update-team-photo %))
|
||||
(rx/do on-success)
|
||||
(rx/tap on-success)
|
||||
(rx/map du/fetch-teams)
|
||||
(rx/catch on-error))))))
|
||||
|
||||
|
@ -831,9 +831,15 @@
|
|||
(ptk/reify ::set-file-thumbnail
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(d/update-in-when [:dashboard-files file-id] assoc :thumbnail-uri thumbnail-uri)
|
||||
(d/update-in-when [:dashboard-recent-files file-id] assoc :thumbnail-uri thumbnail-uri)))))
|
||||
(letfn [(update-search-files [files]
|
||||
(->> files
|
||||
(mapv #(cond-> %
|
||||
(= file-id (:id %))
|
||||
(assoc :thumbnail-uri thumbnail-uri)))))]
|
||||
(-> state
|
||||
(d/update-in-when [:dashboard-files file-id] assoc :thumbnail-uri thumbnail-uri)
|
||||
(d/update-in-when [:dashboard-recent-files file-id] assoc :thumbnail-uri thumbnail-uri)
|
||||
(d/update-when :dashboard-search-result update-search-files))))))
|
||||
|
||||
;; --- EVENT: create-file
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
[app.util.object :as obj]
|
||||
[app.util.storage :refer [storage]]
|
||||
[app.util.time :as dt]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[beicon.v2.operators :as rxo]
|
||||
[lambdaisland.uri :as u]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(l/set-level! :info)
|
||||
|
||||
|
@ -238,7 +239,7 @@
|
|||
profile (->> (rx/from-atom storage {:emit-current-value? true})
|
||||
(rx/map :profile)
|
||||
(rx/map :id)
|
||||
(rx/dedupe))]
|
||||
(rx/pipe (rxo/distinct-contiguous)))]
|
||||
|
||||
(l/debug :hint "event instrumentation initialized")
|
||||
|
||||
|
@ -259,12 +260,12 @@
|
|||
(l/debug :hint "events chunk persisted" :total (count chunk))))
|
||||
(rx/map (constantly chunk))))))
|
||||
(rx/take-until stoper)
|
||||
(rx/subs (fn [chunk]
|
||||
(swap! buffer remove-from-buffer (count chunk)))
|
||||
(fn [cause]
|
||||
(l/error :hint "unexpected error on audit persistence" :cause cause))
|
||||
(fn []
|
||||
(l/debug :hint "audit persistence terminated"))))
|
||||
(rx/subs! (fn [chunk]
|
||||
(swap! buffer remove-from-buffer (count chunk)))
|
||||
(fn [cause]
|
||||
(l/error :hint "unexpected error on audit persistence" :cause cause))
|
||||
(fn []
|
||||
(l/debug :hint "audit persistence terminated"))))
|
||||
|
||||
(->> stream
|
||||
(rx/with-latest-from profile)
|
||||
|
@ -290,10 +291,10 @@
|
|||
|
||||
(rx/switch-map #(rx/timer (inst-ms session-timeout)))
|
||||
(rx/take-until stoper)
|
||||
(rx/subs (fn [_]
|
||||
(l/debug :hint "session reinitialized")
|
||||
(reset! session nil))
|
||||
(fn [cause]
|
||||
(l/error :hint "error on event batching stream" :cause cause))
|
||||
(fn []
|
||||
(l/debug :hitn "events batching stream terminated")))))))))
|
||||
(rx/subs! (fn [_]
|
||||
(l/debug :hint "session reinitialized")
|
||||
(reset! session nil))
|
||||
(fn [cause]
|
||||
(l/error :hint "error on event batching stream" :cause cause))
|
||||
(fn []
|
||||
(l/debug :hitn "events batching stream terminated")))))))))
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
[app.util.dom :as dom]
|
||||
[app.util.time :as dt]
|
||||
[app.util.websocket :as ws]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def default-timeout 5000)
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
[app.util.i18n :refer [tr]]
|
||||
[app.util.storage :refer [storage]]
|
||||
[app.util.webapi :as wa]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; General purpose events & IMPL
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
[app.main.data.messages :as dm]
|
||||
[app.main.store :as st]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.schema :as sm]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare hide)
|
||||
(declare show)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.store :as st]
|
||||
[cljs.core :as c]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defonce components (atom {}))
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
[app.main.refs :as refs]
|
||||
[app.util.code-gen :as cg]
|
||||
[app.util.timers :as ts]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def style-type "css")
|
||||
(def markup-type "html")
|
||||
|
@ -80,7 +80,7 @@
|
|||
(rx/merge-map fonts/fetch-font-css)
|
||||
(rx/reduce conj [])
|
||||
(rx/map #(str/join "\n" %))
|
||||
(rx/subs
|
||||
(rx/subs!
|
||||
(fn [fontfaces-css]
|
||||
(let [style-code
|
||||
(dm/str
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
[app.common.schema :as sm]
|
||||
[app.config :as cf]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(log/set-level! :warn)
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
[app.util.i18n :as i18n]
|
||||
[app.util.router :as rt]
|
||||
[app.util.storage :refer [storage]]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; --- SCHEMAS
|
||||
|
||||
|
@ -434,7 +434,7 @@
|
|||
(rx/map di/validate-file)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/cmd! :update-profile-photo %))
|
||||
(rx/do on-success)
|
||||
(rx/tap on-success)
|
||||
(rx/map (constantly (fetch-profile)))
|
||||
(rx/catch on-error))))))
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
[app.main.repo :as rp]
|
||||
[app.util.globals :as ug]
|
||||
[app.util.router :as rt]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; --- Local State Initialization
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
[app.common.uri :as u]
|
||||
[app.config :as cf]
|
||||
[app.util.websocket :as ws]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(l/set-level! :error)
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
|||
(ptk/reify ::initialize
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(l/trace :hint "event:initialize" :fn "watch")
|
||||
(l/trace :hint "initialize" :fn "watch")
|
||||
(let [sid (:session-id state)
|
||||
uri (prepare-uri {:session-id sid})
|
||||
ws (ws/create uri)]
|
||||
|
|
|
@ -78,10 +78,10 @@
|
|||
[app.util.router :as rt]
|
||||
[app.util.timers :as tm]
|
||||
[app.util.webapi :as wapi]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def default-workspace-local {:zoom 1})
|
||||
|
||||
|
@ -444,7 +444,7 @@
|
|||
uris (into #{} xform (wsh/lookup-page-objects state page-id))]
|
||||
|
||||
(->> (rx/from uris)
|
||||
(rx/subs #(http/fetch-data-uri % false)))))))
|
||||
(rx/subs! #(http/fetch-data-uri % false)))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Workspace Page CRUD
|
||||
|
@ -872,10 +872,10 @@
|
|||
(pcb/update-shapes [parent-id] #(ctl/add-children-to-index % ids objects to-index)))
|
||||
|
||||
(pcb/update-shapes parents
|
||||
(fn [parent]
|
||||
(fn [parent objects]
|
||||
(cond-> parent
|
||||
(ctl/grid-layout? parent)
|
||||
(ctl/assign-cells))))
|
||||
(ctl/assign-cells objects))))
|
||||
|
||||
(pcb/reorder-grid-children parents)
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn selected-shapes-idx
|
||||
[state]
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.worker :as uw]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; Change this to :info :debug or :trace to debug this module
|
||||
(log/set-level! :warn)
|
||||
|
@ -70,7 +70,7 @@
|
|||
update-layout-ids
|
||||
(->> ids
|
||||
(map (d/getf objects))
|
||||
(filter #(some update-layout-attr? (pcb/changed-attrs % update-fn {:attrs attrs})))
|
||||
(filter #(some update-layout-attr? (pcb/changed-attrs % objects update-fn {:attrs attrs})))
|
||||
(map :id))
|
||||
|
||||
changes (reduce
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.uuid :as uuid]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; --- Shape attrs (Layers Sidebar)
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.util.color :as uc]
|
||||
[app.util.storage :refer [storage]]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; A set of keys that are used for shared state identifiers
|
||||
(def ^:const colorpicker-selected-broadcast-key ::colorpicker-selected)
|
||||
|
@ -353,7 +353,7 @@
|
|||
;; Stream that updates the stroke/width and stops if `esc` pressed
|
||||
(->> sub
|
||||
(rx/take-until stop?)
|
||||
(rx/flat-map update-events))
|
||||
(rx/merge-map update-events))
|
||||
|
||||
;; Hide the modal if the stop event is emitted
|
||||
(->> stop?
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
[app.main.streams :as ms]
|
||||
[app.util.mouse :as mse]
|
||||
[app.util.router :as rt]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare handle-interrupt)
|
||||
(declare handle-comment-layer-click)
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.util.router :as rt]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; Change this to :info :debug or :trace to debug this module
|
||||
(log/set-level! :warn)
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
[app.main.data.workspace.drawing.common :as common]
|
||||
[app.main.data.workspace.drawing.curve :as curve]
|
||||
[app.main.data.workspace.path :as path]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare start-drawing)
|
||||
(declare handle-drawing)
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.snap :as snap]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.array :as array]
|
||||
[app.util.mouse :as mse]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn adjust-ratio
|
||||
[point initial]
|
||||
|
@ -128,12 +129,11 @@
|
|||
|
||||
(->> ms/mouse-position
|
||||
(rx/filter #(> (gpt/distance % initial) (/ 2 zoom)))
|
||||
(rx/with-latest vector ms/mouse-position-shift)
|
||||
(rx/with-latest conj ms/mouse-position-mod)
|
||||
(rx/with-latest-from ms/mouse-position-shift ms/mouse-position-mod)
|
||||
(rx/switch-map
|
||||
(fn [[point :as current]]
|
||||
(->> (snap/closest-snap-point page-id [shape] objects layout zoom focus point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/map (partial array/conj current)))))
|
||||
(rx/map
|
||||
(fn [[_ shift? mod? point]]
|
||||
#(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-prec)) shift? mod?)))))
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.worker :as uw]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn clear-drawing
|
||||
[]
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
[app.main.streams :as ms]
|
||||
[app.util.mouse :as mse]
|
||||
[app.util.path.simplify-curve :as ups]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def simplify-tolerance 0.3)
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn interrupt? [e] (= e :interrupt))
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; This event will update the file so the boolean data has a pre-generated path data
|
||||
;; to increase performance.
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
(ns app.main.data.workspace.fix-broken-shapes
|
||||
(:require
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn- generate-broken-link-changes
|
||||
[attr {:keys [objects id] :as container}]
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.fonts :as fonts]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; This event will update the file so the texts with non existing custom fonts try to be fixed.
|
||||
;; This can happen when:
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
[app.common.files.changes-builder :as pcb]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Grid
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[app.common.geom.rect :as grc]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn hover-grid-cell
|
||||
[grid-id cell-id add-to-set]
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.store :as st]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Shortcuts
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn shapes-for-grouping
|
||||
[objects selected]
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
[app.common.types.page :as ctp]
|
||||
[app.main.data.workspace.changes :as dwc]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn make-update-guide [guide]
|
||||
(fn [other]
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[clojure.set :as set]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; --- Manage shape's highlight status
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.mouse :as mse]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; --- Flows
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
[app.common.math :as mth]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; -- Opacity ----------------------------------------------------------
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.util.storage :refer [storage]]
|
||||
[clojure.set :as set]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def valid-flags
|
||||
#{:sitemap
|
||||
|
|
|
@ -45,9 +45,9 @@
|
|||
[app.util.i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
[app.util.time :as dt]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; Change this to :info :debug or :trace to debug this module, or :warn to reset to default
|
||||
(log/set-level! :warn)
|
||||
|
@ -754,6 +754,18 @@
|
|||
(dch/commit-changes (assoc nonlocal-changes
|
||||
:file-id file-id)))))))))))
|
||||
|
||||
(defn- update-component-thumbnail-sync
|
||||
[state component-id file-id tag]
|
||||
(let [current-file-id (:current-file-id state)
|
||||
current-file? (= current-file-id file-id)
|
||||
data (if current-file?
|
||||
(get state :workspace-data)
|
||||
(get-in state [:workspace-libraries file-id :data]))
|
||||
component (ctkl/get-component data component-id)
|
||||
page-id (:main-instance-page component)
|
||||
root-id (:main-instance-id component)]
|
||||
(dwt/request-thumbnail file-id page-id root-id tag)))
|
||||
|
||||
(defn update-component-sync
|
||||
([shape-id file-id] (update-component-sync shape-id file-id nil))
|
||||
([shape-id file-id undo-group]
|
||||
|
@ -761,14 +773,18 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [current-file-id (:current-file-id state)
|
||||
current-file? (= current-file-id file-id)
|
||||
page (wsh/lookup-page state)
|
||||
shape (ctn/get-shape page shape-id)
|
||||
component-id (:component-id shape)
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(update-component shape-id undo-group)
|
||||
(sync-file current-file-id file-id :components (:component-id shape) undo-group)
|
||||
(when (not= current-file-id file-id)
|
||||
(update-component-thumbnail-sync state component-id file-id "frame")
|
||||
(update-component-thumbnail-sync state component-id file-id "component")
|
||||
(when (not current-file?)
|
||||
(sync-file file-id file-id :components (:component-id shape) undo-group))
|
||||
(dwu/commit-undo-transaction undo-id)))))))
|
||||
|
||||
|
@ -795,7 +811,8 @@
|
|||
(ptk/reify ::update-component-thumbnail
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [data (get state :workspace-data)
|
||||
(rx/of (update-component-thumbnail-sync state component-id file-id "component"))
|
||||
#_(let [data (get state :workspace-data)
|
||||
component (ctkl/get-component data component-id)
|
||||
page-id (:main-instance-page component)
|
||||
root-id (:main-instance-id component)]
|
||||
|
|
|
@ -182,10 +182,10 @@
|
|||
(-> changes
|
||||
(pcb/update-shapes
|
||||
[(:parent-id first-shape)]
|
||||
(fn [shape]
|
||||
(fn [shape objects]
|
||||
(-> shape
|
||||
(ctl/push-into-cell [(:id first-shape)] row column)
|
||||
(ctl/assign-cells))))
|
||||
(ctl/assign-cells objects))))
|
||||
(pcb/reorder-grid-children [(:parent-id first-shape)])))
|
||||
changes)
|
||||
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
[app.main.store :as st]
|
||||
[app.util.http :as http]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]
|
||||
[potok.v2.core :as ptk]
|
||||
[promesa.core :as p]
|
||||
[tubax.core :as tubax]))
|
||||
|
||||
|
@ -122,13 +122,13 @@
|
|||
(->> (rx/from uris)
|
||||
(rx/filter (comp not svg-url?))
|
||||
(rx/mapcat upload)
|
||||
(rx/do on-image))
|
||||
(rx/tap on-image))
|
||||
|
||||
(->> (rx/from uris)
|
||||
(rx/filter svg-url?)
|
||||
(rx/merge-map (partial fetch-svg name))
|
||||
(rx/merge-map svg->clj)
|
||||
(rx/do on-svg)))))
|
||||
(rx/tap on-svg)))))
|
||||
|
||||
(defn- process-blobs
|
||||
[{:keys [file-id local? name blobs force-media on-image on-svg]}]
|
||||
|
@ -154,14 +154,14 @@
|
|||
(rx/filter (comp not svg-blob?))
|
||||
(rx/map prepare-blob)
|
||||
(rx/mapcat #(rp/cmd! :upload-file-media-object %))
|
||||
(rx/do on-image))
|
||||
(rx/tap on-image))
|
||||
|
||||
(->> (rx/from blobs)
|
||||
(rx/map dmm/validate-file)
|
||||
(rx/filter svg-blob?)
|
||||
(rx/merge-map extract-content)
|
||||
(rx/merge-map svg->clj)
|
||||
(rx/do on-svg)))))
|
||||
(rx/tap on-svg)))))
|
||||
|
||||
(defn handle-media-error [error on-error]
|
||||
(if (ex/ex-info? error)
|
||||
|
@ -278,7 +278,7 @@
|
|||
(rx/map dmm/validate-file)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/cmd! :upload-file-media-object %))
|
||||
(rx/do on-upload-success)
|
||||
(rx/tap on-upload-success)
|
||||
(rx/catch handle-media-error))))))
|
||||
|
||||
;; --- Upload File Media objects
|
||||
|
@ -423,7 +423,7 @@
|
|||
:timeout nil
|
||||
:tag :media-loading}))
|
||||
(->> (rp/cmd! :clone-file-media-object params)
|
||||
(rx/do on-success)
|
||||
(rx/tap on-success)
|
||||
(rx/catch on-error)
|
||||
(rx/finalize #(st/emit! (msg/hide-tag :media-loading)))))))))
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
[app.main.data.workspace.guides :as-alias dwg]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; -- temporary modifiers -------------------------------------------
|
||||
|
||||
|
@ -191,14 +191,14 @@
|
|||
;; Temporary remove the children when moving them
|
||||
frame (-> frame
|
||||
(update :shapes #(d/removev ids %))
|
||||
(ctl/assign-cells))
|
||||
(ctl/assign-cells objects))
|
||||
|
||||
ids (->> ids (remove #(ctl/position-absolute? objects %)))
|
||||
frame (-> frame
|
||||
(update :shapes d/concat-vec ids)
|
||||
(cond-> (some? cell)
|
||||
(ctl/push-into-cell ids row column))
|
||||
(ctl/assign-cells))]
|
||||
(ctl/assign-cells objects))]
|
||||
|
||||
(-> modifiers
|
||||
(ctm/change-property :layout-grid-rows (:layout-grid-rows frame))
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
[app.util.globals :refer [global]]
|
||||
[app.util.mouse :as mse]
|
||||
[app.util.object :as obj]
|
||||
[app.util.rxops :as rxs]
|
||||
[app.util.time :as dt]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[clojure.set :as set]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare process-message)
|
||||
(declare handle-presence)
|
||||
|
@ -82,7 +83,7 @@
|
|||
;; position changes.
|
||||
(->> stream
|
||||
(rx/filter mse/pointer-event?)
|
||||
(rx/sample 50)
|
||||
(rx/pipe (rxs/throttle 100))
|
||||
(rx/map #(handle-pointer-send file-id (:pt %)))))
|
||||
|
||||
(rx/take-until stoper))]
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
[app.main.data.workspace.path.helpers :as helpers]
|
||||
[app.main.data.workspace.path.state :as st]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn generate-path-changes
|
||||
"Generates changes to update the new content of the shape"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.workspace.path.state :as st]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def valid-commands
|
||||
#{:move-to
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
[app.main.data.workspace.path.undo :as undo]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.util.mouse :as mse]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare change-edit-mode)
|
||||
|
||||
|
@ -46,7 +46,8 @@
|
|||
command (helpers/next-node shape position last-point prev-handler)]
|
||||
(assoc-in state [:workspace-local :edit-path id :preview] command)))))
|
||||
|
||||
(defn add-node [{:keys [x y shift?]}]
|
||||
(defn add-node
|
||||
[{:keys [x y shift?]}]
|
||||
(ptk/reify ::add-node
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
@ -135,7 +136,7 @@
|
|||
(first handlers))
|
||||
|
||||
drag-events-stream
|
||||
(->> (streams/position-stream)
|
||||
(->> (streams/position-stream state)
|
||||
(rx/map #(drag-handler position idx prefix %))
|
||||
(rx/take-until
|
||||
(rx/merge
|
||||
|
@ -164,7 +165,7 @@
|
|||
(defn start-path-from-point [position]
|
||||
(ptk/reify ::start-path-from-point
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(watch [_ state stream]
|
||||
(let [stoper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
|
@ -172,7 +173,7 @@
|
|||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
|
||||
drag-events (->> (streams/position-stream)
|
||||
drag-events (->> (streams/position-stream state)
|
||||
(rx/map #(drag-handler %))
|
||||
(rx/take-until stoper))]
|
||||
(rx/concat
|
||||
|
@ -190,7 +191,12 @@
|
|||
(rx/merge-map #(rx/empty))))
|
||||
|
||||
(defn make-drag-stream
|
||||
[stream down-event]
|
||||
[state stream down-event]
|
||||
|
||||
(dm/assert!
|
||||
"should be a pointer"
|
||||
(gpt/point? down-event))
|
||||
|
||||
(let [stoper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
|
@ -198,7 +204,7 @@
|
|||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
|
||||
drag-events (->> (streams/position-stream)
|
||||
drag-events (->> (streams/position-stream state)
|
||||
(rx/map #(drag-handler %))
|
||||
(rx/take-until stoper))]
|
||||
(rx/concat
|
||||
|
@ -217,7 +223,7 @@
|
|||
(assoc-in state [:workspace-local :edit-path id :edit-mode] :draw)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(watch [_ state stream]
|
||||
(let [mouse-down (->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-down-event?))
|
||||
|
@ -226,7 +232,7 @@
|
|||
|
||||
;; Mouse move preview
|
||||
mousemove-events
|
||||
(->> (streams/position-stream)
|
||||
(->> (streams/position-stream state)
|
||||
(rx/take-until end-path-events)
|
||||
(rx/map #(preview-next-point %)))
|
||||
|
||||
|
@ -234,12 +240,13 @@
|
|||
mousedown-events
|
||||
(->> mouse-down
|
||||
(rx/take-until end-path-events)
|
||||
(rx/with-latest merge (streams/position-stream))
|
||||
|
||||
;; We just ignore the mouse event and stream down the
|
||||
;; last position event
|
||||
(rx/with-latest-from #(-> %2) (streams/position-stream state))
|
||||
;; We change to the stream that emits the first event
|
||||
(rx/switch-map
|
||||
#(rx/race (make-node-events-stream stream)
|
||||
(make-drag-stream stream %))))]
|
||||
(make-drag-stream state stream %))))]
|
||||
|
||||
(rx/concat
|
||||
(rx/of (undo/start-path-undo))
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
[app.main.streams :as ms]
|
||||
[app.util.mouse :as mse]
|
||||
[app.util.path.tools :as upt]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn modify-handler [id index prefix dx dy match-opposite?]
|
||||
(ptk/reify ::modify-handler
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
[app.common.svg.path.subpath :as ups]
|
||||
[app.main.data.workspace.path.common :as common]
|
||||
[app.util.mouse :as mse]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn end-path-event?
|
||||
[event]
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
[app.main.data.workspace.path.state :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.mouse :as mse]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn path-pointer-enter [position]
|
||||
(ptk/reify ::path-pointer-enter
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
[app.common.types.container :as ctn]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn convert-selected-to-path []
|
||||
(ptk/reify ::convert-selected-to-path
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.path :as drp]
|
||||
[app.main.store :as st]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Shortcuts
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.mouse :as mse]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[okulary.core :as l]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defonce drag-threshold 5)
|
||||
|
||||
|
@ -115,7 +115,6 @@
|
|||
|
||||
(defn move-handler-stream
|
||||
[start-point node handler opposite points]
|
||||
|
||||
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
|
||||
ranges (snap/create-ranges points)
|
||||
d-pos (/ snap/snap-path-accuracy zoom)
|
||||
|
@ -145,16 +144,20 @@
|
|||
(let [snap (snap/get-snap-delta [handler] ranges d-pos)]
|
||||
(merge position (gpt/add position snap)))))
|
||||
position))]
|
||||
|
||||
(->> ms/mouse-position
|
||||
(rx/map to-pixel-snap)
|
||||
(rx/with-latest merge (->> ms/mouse-position-shift (rx/map #(hash-map :shift? %))))
|
||||
(rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %))))
|
||||
(rx/with-latest-from
|
||||
(fn [position shift? alt?]
|
||||
(assoc position :shift? shift? :alt? alt?))
|
||||
ms/mouse-position-shift
|
||||
ms/mouse-position-alt)
|
||||
(rx/with-latest-from (snap-toggled-stream))
|
||||
(rx/map check-path-snap))))
|
||||
|
||||
(defn position-stream
|
||||
[]
|
||||
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
|
||||
[state]
|
||||
(let [zoom (get-in state [:workspace-local :zoom] 1)
|
||||
d-pos (/ snap/snap-path-accuracy zoom)
|
||||
get-content #(pst/get-path % :content)
|
||||
|
||||
|
@ -169,12 +172,14 @@
|
|||
|
||||
(->> ms/mouse-position
|
||||
(rx/map to-pixel-snap)
|
||||
(rx/with-latest vector ranges-stream)
|
||||
(rx/with-latest-from (snap-toggled-stream))
|
||||
(rx/map (fn [[[position ranges] snap-toggled]]
|
||||
(rx/with-latest-from ranges-stream (snap-toggled-stream))
|
||||
(rx/map (fn [[position ranges snap-toggled]]
|
||||
(if snap-toggled
|
||||
(let [snap (snap/get-snap-delta [position] ranges d-pos)]
|
||||
(gpt/add position snap))
|
||||
position)))
|
||||
(rx/with-latest merge (->> ms/mouse-position-shift (rx/map #(hash-map :shift? %))))
|
||||
(rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %)))))))
|
||||
(rx/with-latest-from
|
||||
(fn [position shift? alt?]
|
||||
(assoc position :shift? shift? :alt? alt?))
|
||||
ms/mouse-position-shift
|
||||
ms/mouse-position-alt))))
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
[app.main.data.workspace.path.state :as st]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.util.path.tools :as upt]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn process-path-tool
|
||||
"Generic function that executes path transformations with the content and selected nodes"
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
[app.main.data.workspace.path.changes :as changes]
|
||||
[app.main.data.workspace.path.state :as st]
|
||||
[app.main.store :as store]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[okulary.core :as l]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn undo-event?
|
||||
[event]
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
[app.main.store :as st]
|
||||
[app.util.router :as rt]
|
||||
[app.util.time :as dt]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[okulary.core :as l]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(log/set-level! :info)
|
||||
|
||||
|
|
|
@ -36,10 +36,11 @@
|
|||
[app.main.streams :as ms]
|
||||
[app.main.worker :as uw]
|
||||
[app.util.mouse :as mse]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[beicon.v2.operators :as rxo]
|
||||
[clojure.set :as set]
|
||||
[linked.set :as lks]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn interrupt?
|
||||
[e]
|
||||
|
@ -111,8 +112,8 @@
|
|||
|
||||
(->> selrect-stream
|
||||
(rx/buffer-time 100)
|
||||
(rx/map #(last %))
|
||||
(rx/dedupe)
|
||||
(rx/map last)
|
||||
(rx/pipe (rxo/distinct-contiguous))
|
||||
(rx/map #(select-shapes-by-current-selrect preserve? ignore-groups?))))
|
||||
|
||||
(->> (rx/of (update-selrect nil))
|
||||
|
@ -498,7 +499,8 @@
|
|||
changes (-> (pcb/add-object changes new-obj {:ignore-touched (and duplicating-component? child?)})
|
||||
(pcb/amend-last-change #(assoc % :old-id (:id obj)))
|
||||
(cond-> (ctl/grid-layout? objects (:parent-id obj))
|
||||
(-> (pcb/update-shapes [(:parent-id obj)] (fn [shape] (-> shape ctl/assign-cells ctl/check-deassigned-cells)))
|
||||
(-> (pcb/update-shapes [(:parent-id obj)] ctl/assign-cells)
|
||||
(pcb/update-shapes [(:parent-id obj)] ctl/check-deassigned-cells)
|
||||
(pcb/reorder-grid-children [(:parent-id obj)]))))
|
||||
|
||||
changes (cond-> changes
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
[app.main.data.workspace.shapes :as dws]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(def layout-keys
|
||||
[:layout
|
||||
|
@ -79,16 +79,13 @@
|
|||
(-> shape
|
||||
(merge initial-layout-data)
|
||||
|
||||
;; (cond-> (= type :grid) (-> ctl/assign-cells ctl/reorder-grid-children))
|
||||
;; If the original shape is not a frame we set clip content and show-viewer to false
|
||||
(cond-> (not from-frame?)
|
||||
(assoc :show-content true :hide-in-viewer true)))
|
||||
|
||||
params (calculate-params objects (cfh/get-immediate-children objects (:id shape)) shape)]
|
||||
|
||||
(cond-> (merge shape params)
|
||||
(= type :grid) (-> ctl/assign-cells ctl/reorder-grid-children)))
|
||||
)))
|
||||
(= type :grid) (-> (ctl/assign-cells objects) ctl/reorder-grid-children))))))
|
||||
|
||||
;; Never call this directly but through the data-event `:layout/update`
|
||||
;; Otherwise a lot of cycle dependencies could be generated
|
||||
|
@ -277,10 +274,10 @@
|
|||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dwc/update-shapes
|
||||
ids
|
||||
(fn [shape]
|
||||
(fn [shape objects]
|
||||
(case type
|
||||
:row (ctl/remove-grid-row shape index)
|
||||
:column (ctl/remove-grid-column shape index))))
|
||||
:row (ctl/remove-grid-row shape index objects)
|
||||
:column (ctl/remove-grid-column shape index objects))))
|
||||
(ptk/data-event :layout/update ids)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
|
@ -435,11 +432,11 @@
|
|||
(dwc/update-shapes children-ids (partial fix-child-sizing objects changes))
|
||||
(dwc/update-shapes
|
||||
parent-ids
|
||||
(fn [parent]
|
||||
(fn [parent objects]
|
||||
(-> parent
|
||||
(fix-parent-sizing objects (set ids) changes)
|
||||
(cond-> (ctl/grid-layout? parent)
|
||||
(ctl/assign-cells)))))
|
||||
(ctl/assign-cells objects)))))
|
||||
(ptk/data-event :layout/update ids)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
|
@ -475,10 +472,9 @@
|
|||
(let [undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
|
||||
(dwc/update-shapes
|
||||
[layout-id]
|
||||
(fn [shape]
|
||||
(fn [shape objects]
|
||||
(case mode
|
||||
:auto
|
||||
;; change the manual cells and move to auto
|
||||
|
@ -492,7 +488,7 @@
|
|||
(> (:column-span cell) 1))
|
||||
(-> (d/update-in-when [:layout-grid-cells cell-id] assoc :shapes [] :position :auto)
|
||||
(ctl/resize-cell-area (:row cell) (:column cell) (:row cell) (:column cell) 1 1)
|
||||
(ctl/assign-cells)))))
|
||||
(ctl/assign-cells objects)))))
|
||||
shape))
|
||||
|
||||
:manual
|
||||
|
@ -503,7 +499,7 @@
|
|||
(cond-> shape
|
||||
(contains? #{:area :auto} (:position cell))
|
||||
(-> (d/assoc-in-when [:layout-grid-cells cell-id :position] :manual)
|
||||
(ctl/assign-cells)))))
|
||||
(ctl/assign-cells objects)))))
|
||||
shape))
|
||||
|
||||
:area
|
||||
|
@ -522,7 +518,7 @@
|
|||
first-column
|
||||
(inc (- last-row first-row))
|
||||
(inc (- last-column first-column)))
|
||||
(ctl/assign-cells))]
|
||||
(ctl/assign-cells objects))]
|
||||
|
||||
(-> shape
|
||||
(d/update-in-when [:layout-grid-cells (:id target-cell)] assoc :position :area))))))
|
||||
|
@ -535,8 +531,9 @@
|
|||
|
||||
(ptk/reify ::update-grid-cell-position
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(dwc/update-shapes
|
||||
|
@ -550,6 +547,6 @@
|
|||
(ctl/resize-cell-area (:row prev-data) (:column prev-data)
|
||||
(:row new-data) (:column new-data)
|
||||
(:row-span new-data) (:column-span new-data))
|
||||
(ctl/assign-cells)))))
|
||||
(ctl/assign-cells objects)))))
|
||||
(ptk/data-event :layout/update [layout-id])
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.features :as features]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn add-shape
|
||||
([shape]
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
[app.common.data :as d]
|
||||
[app.main.data.workspace.common :as-alias dwc]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn interrupt? [e] (or (= e :interrupt) (= e ::interrupt)))
|
||||
|
||||
|
|
|
@ -34,6 +34,17 @@
|
|||
([state page-id]
|
||||
(dm/get-in state [:viewer :pages page-id :objects])))
|
||||
|
||||
(defn lookup-library-objects
|
||||
[state file-id page-id]
|
||||
(dm/get-in state [:workspace-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-page-options
|
||||
([state]
|
||||
(lookup-page-options state (:current-page-id state)))
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.repo :as rp]
|
||||
[app.util.webapi :as wapi]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn extract-name [href]
|
||||
(let [query-idx (str/last-index-of href "?")
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
[app.util.router :as rt]
|
||||
[app.util.text-editor :as ted]
|
||||
[app.util.timers :as ts]
|
||||
[beicon.core :as rx]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; -- Attrs
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue