mirror of
https://github.com/penpot/penpot.git
synced 2025-02-08 08:09:14 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
c2158b0f3c
15 changed files with 377 additions and 271 deletions
|
@ -6,6 +6,7 @@
|
|||
### :sparkles: New features
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Add title to color bullets [Taiga #4218](https://tree.taiga.io/project/penpot/task/4218)
|
||||
- Fix color bullets in library color modal [Taiga #4186](https://tree.taiga.io/project/penpot/issue/4186)
|
||||
- Fix shortcut texts alignment [Taiga #4275](https://tree.taiga.io/project/penpot/issue/4275)
|
||||
- Fix some texts and a typo [Taiga #4215](https://tree.taiga.io/project/penpot/issue/4215)
|
||||
|
@ -27,7 +28,7 @@
|
|||
|
||||
### :sparkles: New features
|
||||
|
||||
- Add title to color bullets [Taiga #4218](https://tree.taiga.io/project/penpot/task/4218)
|
||||
- Improve interactions with nested boards [Taiga #4054](https://tree.taiga.io/project/penpot/us/4054)
|
||||
- Add team hero in projects dashboard [Taiga #3863](https://tree.taiga.io/project/penpot/us/3863)
|
||||
- Add zoom style to shared link [Taiga #3874](https://tree.taiga.io/project/penpot/us/3874)
|
||||
- Add dashboard creation button as placeholder [Taiga #3861](https://tree.taiga.io/project/penpot/us/3861)
|
||||
|
@ -42,6 +43,7 @@
|
|||
- Newsletter Opt-in options for subscription categories [Taiga #3242](https://tree.taiga.io/project/penpot/us/3242)
|
||||
- Print emails to console by default if smtp is disabled
|
||||
- Add `email-verification` flag for enable/disable email verification
|
||||
- Make graphics thumbnails load lazy [Taiga #4252](https://tree.taiga.io/project/penpot/issue/4252)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
|
@ -55,6 +57,7 @@
|
|||
- Fix change multiple colors with SVG [Taiga #3889](https://tree.taiga.io/project/penpot/issue/3889)
|
||||
- Fix ungroup does not work for typographies [Taiga #4195](https://tree.taiga.io/project/penpot/issue/4195)
|
||||
- Fix inviting to non existing users can fail [Taiga #4108](https://tree.taiga.io/project/penpot/issue/4108)
|
||||
- Fix components marked as touched when moved [Taiga #4061](https://tree.taiga.io/project/penpot/task/4061)
|
||||
|
||||
### :arrow_up: Deps updates
|
||||
### :heart: Community contributions by (Thank you!)
|
||||
|
|
|
@ -11,17 +11,22 @@
|
|||
|
||||
io.prometheus/simpleclient {:mvn/version "0.16.0"}
|
||||
io.prometheus/simpleclient_hotspot {:mvn/version "0.16.0"}
|
||||
io.prometheus/simpleclient_jetty {:mvn/version "0.16.0"
|
||||
:exclusions [org.eclipse.jetty/jetty-server
|
||||
org.eclipse.jetty/jetty-servlet]}
|
||||
io.prometheus/simpleclient_jetty
|
||||
{:mvn/version "0.16.0"
|
||||
:exclusions [org.eclipse.jetty/jetty-server
|
||||
org.eclipse.jetty/jetty-servlet]}
|
||||
|
||||
|
||||
io.prometheus/simpleclient_httpserver {:mvn/version "0.16.0"}
|
||||
|
||||
io.lettuce/lettuce-core {:mvn/version "6.2.0.RELEASE"}
|
||||
java-http-clj/java-http-clj {:mvn/version "0.4.3"}
|
||||
|
||||
funcool/yetti {:git/tag "v9.8" :git/sha "fbe1d7d"
|
||||
:git/url "https://github.com/funcool/yetti.git"
|
||||
:exclusions [org.slf4j/slf4j-api]}
|
||||
funcool/yetti
|
||||
{:git/tag "v9.9"
|
||||
:git/sha "f0a455d"
|
||||
:git/url "https://github.com/funcool/yetti.git"
|
||||
:exclusions [org.slf4j/slf4j-api]}
|
||||
|
||||
com.github.seancorfield/next.jdbc {:mvn/version "1.3.828"}
|
||||
metosin/reitit-core {:mvn/version "0.5.18"}
|
||||
|
@ -34,8 +39,10 @@
|
|||
buddy/buddy-sign {:mvn/version "3.4.333"}
|
||||
|
||||
org.jsoup/jsoup {:mvn/version "1.15.1"}
|
||||
org.im4java/im4java {:git/tag "1.4.0-penpot-2" :git/sha "e2b3e16"
|
||||
:git/url "https://github.com/penpot/im4java"}
|
||||
org.im4java/im4java
|
||||
{:git/tag "1.4.0-penpot-2"
|
||||
:git/sha "e2b3e16"
|
||||
:git/url "https://github.com/penpot/im4java"}
|
||||
|
||||
org.lz4/lz4-java {:mvn/version "1.8.0"}
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@
|
|||
(assoc ::binf/file-ids file-ids)
|
||||
(assoc ::binf/embed-assets? embed?)
|
||||
(assoc ::binf/include-libraries? libs?)
|
||||
(binf/export!))]
|
||||
(binf/export-to-tmpfile!))]
|
||||
(if clone?
|
||||
(let [project-id (some-> (profile/retrieve-additional-data pool profile-id) :default-project-id)]
|
||||
(binf/import!
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
[id]
|
||||
(when-let [wsp (get @state id)]
|
||||
{:id id
|
||||
:created-at (dt/instant id)
|
||||
:created-at (::created-at @wsp)
|
||||
:profile-id (::profile-id @wsp)
|
||||
:session-id (::session-id @wsp)
|
||||
:user-agent (::ws/user-agent @wsp)
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
[clojure.walk :as walk]
|
||||
[cuerdas.core :as str]
|
||||
[datoteka.io :as io]
|
||||
[yetti.adapter :as yt])
|
||||
[yetti.adapter :as yt]
|
||||
[yetti.response :as yrs])
|
||||
(:import
|
||||
com.github.luben.zstd.ZstdInputStream
|
||||
com.github.luben.zstd.ZstdOutputStream
|
||||
|
@ -799,27 +800,40 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn export!
|
||||
[cfg]
|
||||
(let [path (tmp/tempfile :prefix "penpot.export.")
|
||||
id (uuid/next)
|
||||
ts (dt/now)
|
||||
cs (volatile! nil)]
|
||||
[cfg output]
|
||||
(let [id (uuid/next)
|
||||
tp (dt/tpoint)
|
||||
ab (volatile! false)
|
||||
cs (volatile! nil)]
|
||||
(try
|
||||
(l/info :hint "start exportation" :export-id id)
|
||||
(with-open [output (io/output-stream path)]
|
||||
(with-open [output (io/output-stream output)]
|
||||
(binding [*position* (atom 0)]
|
||||
(write-export! (assoc cfg ::output output))
|
||||
path))
|
||||
(write-export! (assoc cfg ::output output))))
|
||||
|
||||
(catch java.io.IOException _cause
|
||||
;; Do nothing, EOF means client closes connection abruptly
|
||||
(vreset! ab true)
|
||||
nil)
|
||||
|
||||
(catch Throwable cause
|
||||
(vreset! cs cause)
|
||||
(vreset! ab true)
|
||||
(throw cause))
|
||||
|
||||
(finally
|
||||
(l/info :hint "exportation finished" :export-id id
|
||||
:elapsed (str (inst-ms (dt/diff ts (dt/now))) "ms")
|
||||
:elapsed (str (inst-ms (tp)) "ms")
|
||||
:aborted @ab
|
||||
:cause @cs)))))
|
||||
|
||||
(defn export-to-tmpfile!
|
||||
[cfg]
|
||||
(let [path (tmp/tempfile :prefix "penpot.export.")]
|
||||
(with-open [output (io/output-stream path)]
|
||||
(export! cfg output)
|
||||
path)))
|
||||
|
||||
(defn import!
|
||||
[{:keys [::input] :as cfg}]
|
||||
(let [id (uuid/next)
|
||||
|
@ -855,17 +869,20 @@
|
|||
"Export a penpot file in a binary format."
|
||||
{::doc/added "1.15"}
|
||||
[{:keys [pool] :as cfg} {:keys [profile-id file-id include-libraries? embed-assets?] :as params}]
|
||||
(db/with-atomic [conn pool]
|
||||
(files/check-read-permissions! conn profile-id file-id)
|
||||
(let [path (export! (assoc cfg
|
||||
::file-ids [file-id]
|
||||
::embed-assets? embed-assets?
|
||||
::include-libraries? include-libraries?))]
|
||||
(with-meta {}
|
||||
{:transform-response (fn [_ response]
|
||||
(assoc response
|
||||
:body (io/input-stream path)
|
||||
:headers {"content-type" "application/octet-stream"}))}))))
|
||||
(files/check-read-permissions! pool profile-id file-id)
|
||||
(let [resp (reify yrs/StreamableResponseBody
|
||||
(-write-body-to-stream [_ _ output-stream]
|
||||
(-> cfg
|
||||
(assoc ::file-ids [file-id])
|
||||
(assoc ::embed-assets? embed-assets?)
|
||||
(assoc ::include-libraries? include-libraries?)
|
||||
(export! output-stream))))]
|
||||
|
||||
(with-meta (sv/wrap nil)
|
||||
{:transform-response (fn [_ response]
|
||||
(-> response
|
||||
(assoc :body resp)
|
||||
(assoc :headers {"content-type" "application/octet-stream"})))})))
|
||||
|
||||
(s/def ::file ::media/upload)
|
||||
(s/def ::import-binfile
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.exceptions :as ex]
|
||||
[app.common.logging :as l]
|
||||
[app.common.transit :as t]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.loggers.audit :refer [parse-client-ip]]
|
||||
[app.util.time :as dt]
|
||||
[clojure.core.async :as a]
|
||||
|
@ -21,9 +22,7 @@
|
|||
|
||||
(declare decode-beat)
|
||||
(declare encode-beat)
|
||||
(declare process-heartbeat)
|
||||
(declare process-input)
|
||||
(declare process-output)
|
||||
(declare start-io-loop)
|
||||
(declare ws-ping!)
|
||||
(declare ws-send!)
|
||||
(declare filter-options)
|
||||
|
@ -51,7 +50,7 @@
|
|||
::idle-timeout]
|
||||
:or {input-buff-size 64
|
||||
output-buff-size 64
|
||||
idle-timeout 30000
|
||||
idle-timeout 60000
|
||||
on-connect noop
|
||||
on-snd-message identity-3
|
||||
on-rcv-message identity-3}
|
||||
|
@ -64,17 +63,19 @@
|
|||
(fn [{:keys [::yws/channel session-id] :as request}]
|
||||
(let [input-ch (a/chan input-buff-size)
|
||||
output-ch (a/chan output-buff-size)
|
||||
pong-ch (a/chan (a/sliding-buffer 6))
|
||||
hbeat-ch (a/chan (a/sliding-buffer 6))
|
||||
close-ch (a/chan)
|
||||
stop-ch (a/chan)
|
||||
|
||||
ip-addr (parse-client-ip request)
|
||||
uagent (yr/get-header request "user-agent")
|
||||
id (inst-ms (dt/now))
|
||||
id (uuid/next)
|
||||
|
||||
options (-> (filter-options options)
|
||||
(merge {::id id
|
||||
::created-at (dt/now)
|
||||
::input-ch input-ch
|
||||
::heartbeat-ch hbeat-ch
|
||||
::output-ch output-ch
|
||||
::close-ch close-ch
|
||||
::stop-ch stop-ch
|
||||
|
@ -99,11 +100,13 @@
|
|||
|
||||
on-ws-error
|
||||
(fn [_ error]
|
||||
(a/close! close-ch)
|
||||
(when-not (or (instance? java.nio.channels.ClosedChannelException error)
|
||||
(instance? java.net.SocketException error)
|
||||
(instance? java.io.IOException error))
|
||||
(l/error :hint (ex-message error) :cause error)))
|
||||
(l/error :fn "on-ws-error" :conn-id id
|
||||
:hint (ex-message error)
|
||||
:cause error))
|
||||
(on-ws-terminate nil 8801 "close after error"))
|
||||
|
||||
on-ws-message
|
||||
(fn [_ message]
|
||||
|
@ -116,23 +119,18 @@
|
|||
(l/warn :hint "error on decoding incoming message from websocket"
|
||||
:wsmsg (pr-str message)
|
||||
:cause e)
|
||||
(a/>! close-ch [8801 "decode error"])
|
||||
(a/>! close-ch [8802 "decode error"])
|
||||
(a/close! close-ch))))
|
||||
|
||||
on-ws-pong
|
||||
(fn [_ buffers]
|
||||
(a/>!! pong-ch (yu/copy-many buffers)))]
|
||||
|
||||
;; Launch heartbeat process
|
||||
(-> @options
|
||||
(assoc ::pong-ch pong-ch)
|
||||
(process-heartbeat))
|
||||
(a/>!! hbeat-ch (yu/copy-many buffers)))]
|
||||
|
||||
;; Wait a close signal
|
||||
(a/go
|
||||
(let [[code reason] (a/<! close-ch)]
|
||||
(a/close! stop-ch)
|
||||
(a/close! pong-ch)
|
||||
(a/close! hbeat-ch)
|
||||
(a/close! output-ch)
|
||||
(a/close! input-ch)
|
||||
|
||||
|
@ -141,19 +139,14 @@
|
|||
(yws/close! channel code reason))
|
||||
|
||||
(when (fn? on-terminate)
|
||||
(on-terminate))))
|
||||
(on-terminate))
|
||||
|
||||
;; Forward all messages from output-ch to the websocket
|
||||
;; connection
|
||||
(a/go-loop []
|
||||
(when-let [val (a/<! output-ch)]
|
||||
(let [val (on-snd-message options val)]
|
||||
(a/<! (ws-send! channel (t/encode-str val)))
|
||||
(recur))))
|
||||
(l/trace :hint "connection terminated")))
|
||||
|
||||
;; React on messages received from the client
|
||||
|
||||
(process-input options handler)
|
||||
(a/go
|
||||
(a/<! (start-io-loop options handler on-snd-message on-ws-terminate))
|
||||
(l/trace :hint "io loop terminated"))
|
||||
|
||||
{:on-open on-ws-open
|
||||
:on-error on-ws-error
|
||||
|
@ -168,7 +161,7 @@
|
|||
(yws/send! channel s (fn [e]
|
||||
(when e (a/offer! ch e))
|
||||
(a/close! ch)))
|
||||
(catch java.io.IOException cause
|
||||
(catch Throwable cause
|
||||
(a/offer! ch cause)
|
||||
(a/close! ch)))
|
||||
ch))
|
||||
|
@ -178,9 +171,9 @@
|
|||
(let [ch (a/chan 1)]
|
||||
(try
|
||||
(yws/ping! channel s (fn [e]
|
||||
(when e (a/offer! ch e))
|
||||
(a/close! ch)))
|
||||
(catch java.io.IOException cause
|
||||
(when e (a/offer! ch e))
|
||||
(a/close! ch)))
|
||||
(catch Throwable cause
|
||||
(a/offer! ch cause)
|
||||
(a/close! ch)))
|
||||
ch))
|
||||
|
@ -203,51 +196,71 @@
|
|||
(locking wsp
|
||||
(handler wsp message))))
|
||||
|
||||
(defn- process-input
|
||||
[wsp handler]
|
||||
(let [{:keys [::input-ch ::output-ch ::stop-ch]} @wsp
|
||||
handler (wrap-handler handler)]
|
||||
(def max-missed-heartbeats 3)
|
||||
(def heartbeat-interval 5000)
|
||||
|
||||
(defn- start-io-loop
|
||||
[wsp handler on-snd-message on-ws-terminate]
|
||||
(let [input-ch (::input-ch @wsp)
|
||||
output-ch (::output-ch @wsp)
|
||||
stop-ch (::stop-ch @wsp)
|
||||
hbeat-pong-ch (::heartbeat-ch @wsp)
|
||||
channel (::channel @wsp)
|
||||
conn-id (::id @wsp)
|
||||
handler (wrap-handler handler)
|
||||
beats (atom #{})
|
||||
choices [stop-ch
|
||||
input-ch
|
||||
output-ch
|
||||
hbeat-pong-ch]]
|
||||
|
||||
;; Start IO loop
|
||||
(a/go
|
||||
(a/<! (handler wsp {:type :connect}))
|
||||
(a/<! (a/go-loop []
|
||||
(when-let [message (a/<! input-ch)]
|
||||
(let [[val port] (a/alts! [stop-ch (handler wsp message)] :priority true)]
|
||||
(when-not (= port stop-ch)
|
||||
(a/<! (a/go-loop [i 0]
|
||||
(let [hbeat-ping-ch (a/timeout heartbeat-interval)
|
||||
[v p] (a/alts! (conj choices hbeat-ping-ch))]
|
||||
(cond
|
||||
(not (yws/connected? channel))
|
||||
(on-ws-terminate nil 8800 "channel disconnected")
|
||||
|
||||
(= p hbeat-ping-ch)
|
||||
(do
|
||||
(l/trace :hint "ping" :beat i :conn-id conn-id)
|
||||
(a/<! (ws-ping! channel (encode-beat i)))
|
||||
(let [issued (swap! beats conj (long i))]
|
||||
(if (>= (count issued) max-missed-heartbeats)
|
||||
(on-ws-terminate nil 8802 "heartbeat: timeout")
|
||||
(recur (inc i)))))
|
||||
|
||||
(= p hbeat-pong-ch)
|
||||
(let [beat (decode-beat v)]
|
||||
(l/trace :hint "pong" :beat beat :conn-id conn-id)
|
||||
(swap! beats disj beat)
|
||||
(recur i))
|
||||
|
||||
(= p input-ch)
|
||||
(let [result (a/<! (handler wsp v))]
|
||||
;; (l/trace :hint "message received" :message v)
|
||||
(cond
|
||||
(ex/ex-info? val)
|
||||
(a/>! output-ch {:type :error :error (ex-data val)})
|
||||
(ex/ex-info? result)
|
||||
(a/>! output-ch {:type :error :error (ex-data result)})
|
||||
|
||||
(ex/exception? val)
|
||||
(a/>! output-ch {:type :error :error {:message (ex-message val)}})
|
||||
(ex/exception? result)
|
||||
(a/>! output-ch {:type :error :error {:message (ex-message result)}})
|
||||
|
||||
(map? result)
|
||||
(a/>! output-ch (cond-> result (:request-id v) (assoc :request-id (:request-id v)))))
|
||||
(recur i))
|
||||
|
||||
(= p output-ch)
|
||||
(let [v (on-snd-message wsp v)]
|
||||
;; (l/trace :hint "writing message to output" :message v)
|
||||
(a/<! (ws-send! channel (t/encode-str v)))
|
||||
(recur i))))))
|
||||
|
||||
(map? val)
|
||||
(a/>! output-ch (cond-> val (:request-id message) (assoc :request-id (:request-id message)))))
|
||||
(recur))))))
|
||||
(a/<! (handler wsp {:type :disconnect})))))
|
||||
|
||||
(defn- process-heartbeat
|
||||
[{:keys [::channel ::stop-ch ::close-ch ::pong-ch
|
||||
::heartbeat-interval ::max-missed-heartbeats]
|
||||
:or {heartbeat-interval 2000
|
||||
max-missed-heartbeats 4}}]
|
||||
(let [beats (atom #{})]
|
||||
(a/go-loop [i 0]
|
||||
(let [[_ port] (a/alts! [stop-ch (a/timeout heartbeat-interval)] :priority true)]
|
||||
(when (and (yws/connected? channel)
|
||||
(not= port stop-ch))
|
||||
(a/<! (ws-ping! channel (encode-beat i)))
|
||||
(let [issued (swap! beats conj (long i))]
|
||||
(if (>= (count issued) max-missed-heartbeats)
|
||||
(do
|
||||
(a/>! close-ch [8802 "heart-beat timeout"])
|
||||
(a/close! close-ch))
|
||||
(recur (inc i)))))))
|
||||
|
||||
(a/go-loop []
|
||||
(when-let [buffer (a/<! pong-ch)]
|
||||
(swap! beats disj (decode-beat buffer))
|
||||
(recur)))))
|
||||
|
||||
(defn- filter-options
|
||||
"Remove from options all namespace qualified keys that matches the
|
||||
current namespace."
|
||||
|
|
|
@ -512,6 +512,18 @@
|
|||
(assert (has-offset-effect? interaction))
|
||||
(update interaction :animation assoc :offset-effect offset-effect))
|
||||
|
||||
(defn dest-to?
|
||||
"Check if the interaction has the given frame as destination."
|
||||
[interaction frame-id]
|
||||
(and (has-destination interaction)
|
||||
(= (:destination interaction) frame-id)))
|
||||
|
||||
(defn navs-to?
|
||||
"Check if the interaction is a navigation to the given frame."
|
||||
[interaction frame-id]
|
||||
(and (= (:action-type interaction) :navigate)
|
||||
(= (:destination interaction) frame-id)))
|
||||
|
||||
;; -- Helpers for interactions
|
||||
|
||||
(defn add-interaction
|
||||
|
@ -543,6 +555,12 @@
|
|||
(d/update-when interaction :destination #(get ids-map % %)))))]
|
||||
(into [] xform interactions))))
|
||||
|
||||
(defn remove-interactions
|
||||
"Remove all interactions that the fn returns true."
|
||||
[f interactions]
|
||||
(-> (d/removev f interactions)
|
||||
not-empty))
|
||||
|
||||
(defn actionable?
|
||||
"Check if there is any interaction that is clickable by the user"
|
||||
[interactions]
|
||||
|
|
|
@ -142,7 +142,6 @@ RUN set -ex; \
|
|||
apt-get -qqy install postgresql-client-14; \
|
||||
rm -rf /var/lib/apt/lists/*;
|
||||
|
||||
|
||||
RUN set -eux; \
|
||||
ARCH="$(dpkg --print-architecture)"; \
|
||||
case "${ARCH}" in \
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.streams :as ms]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
@ -149,6 +150,29 @@
|
|||
(update shape :interactions
|
||||
ctsi/update-interaction index update-fn)))))))
|
||||
|
||||
(defn remove-all-interactions-nav-to
|
||||
"Remove all interactions that navigate to the given frame."
|
||||
[frame-id]
|
||||
(ptk/reify ::remove-all-interactions-nav-to
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
|
||||
remove-interactions-shape
|
||||
(fn [shape]
|
||||
(let [interactions (:interactions shape)
|
||||
new-interactions (ctsi/remove-interactions #(ctsi/navs-to? % frame-id)
|
||||
interactions)]
|
||||
(when (not= (count interactions) (count new-interactions))
|
||||
(dch/update-shapes [(:id shape)]
|
||||
(fn [shape]
|
||||
(assoc shape :interactions new-interactions))))))]
|
||||
|
||||
(rx/from (->> (vals objects)
|
||||
(map remove-interactions-shape)
|
||||
(d/vec-without-nils)))))))
|
||||
|
||||
(declare move-edit-interaction)
|
||||
(declare finish-edit-interaction)
|
||||
|
||||
|
@ -171,8 +195,7 @@
|
|||
(rx/map #(move-edit-interaction initial-pos %)))
|
||||
(rx/of (finish-edit-interaction index initial-pos))))))))
|
||||
|
||||
|
||||
(defn get-target-frame
|
||||
(defn- get-target-frame
|
||||
[state position]
|
||||
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
|
@ -185,8 +208,7 @@
|
|||
target-frame (ctst/frame-by-position objects position)]
|
||||
|
||||
(when (and (not= (:id target-frame) uuid/zero)
|
||||
(not= (:id target-frame) from-frame-id)
|
||||
(not (:hide-in-viewer target-frame)))
|
||||
(not= (:id target-frame) from-frame-id))
|
||||
target-frame)))
|
||||
|
||||
(defn move-edit-interaction
|
||||
|
@ -225,25 +247,34 @@
|
|||
:always
|
||||
(ctsi/set-destination (:id target-frame))))]
|
||||
|
||||
(cond
|
||||
(or (nil? shape)
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction)
|
||||
|
||||
;; Didn't changed the position for the interaction
|
||||
(= position initial-pos)
|
||||
(when (:hide-in-viewer target-frame)
|
||||
; If the target frame is hidden, we need to unhide it so
|
||||
; users can navigate to it.
|
||||
(dch/update-shapes [(:id target-frame)]
|
||||
#(dissoc % :hide-in-viewer)))
|
||||
|
||||
;; New interaction but invalid target
|
||||
(and (nil? index) (nil? target-frame)))
|
||||
nil
|
||||
(cond
|
||||
(or (nil? shape)
|
||||
;; Didn't changed the position for the interaction
|
||||
(= position initial-pos)
|
||||
;; New interaction but invalid target
|
||||
(and (nil? index) (nil? target-frame)))
|
||||
nil
|
||||
|
||||
;; Dropped interaction in an invalid target. We remove it
|
||||
(and (some? index) (nil? target-frame))
|
||||
(rx/of (remove-interaction shape index))
|
||||
;; Dropped interaction in an invalid target. We remove it
|
||||
(and (some? index) (nil? target-frame))
|
||||
(remove-interaction shape index)
|
||||
|
||||
(nil? index)
|
||||
(rx/of (add-new-interaction shape (:id target-frame)))
|
||||
(nil? index)
|
||||
(add-new-interaction shape (:id target-frame))
|
||||
|
||||
:else
|
||||
(rx/of (update-interaction shape index change-interaction)))))))
|
||||
:else
|
||||
(update-interaction shape index change-interaction))
|
||||
|
||||
(dwu/commit-undo-transaction))))))
|
||||
|
||||
;; --- Overlays
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.collapse :as dwc]
|
||||
[app.main.data.workspace.comments :as-alias dwcm]
|
||||
|
@ -243,7 +242,7 @@
|
|||
(defn- check-delta
|
||||
"If the shape is a component instance, check its relative position respect the
|
||||
root of the component, and see if it changes after applying a transformation."
|
||||
[shape root transformed-shape transformed-root objects]
|
||||
[shape root transformed-shape transformed-root objects modif-tree]
|
||||
(let [root
|
||||
(cond
|
||||
(:component-root? shape)
|
||||
|
@ -260,7 +259,8 @@
|
|||
transformed-shape
|
||||
|
||||
(nil? transformed-root)
|
||||
(cph/get-root-shape objects transformed-shape)
|
||||
(as-> (cph/get-root-shape objects transformed-shape) $
|
||||
(gsh/transform-shape (merge $ (get modif-tree (:id $)))))
|
||||
|
||||
:else transformed-root)
|
||||
|
||||
|
@ -298,7 +298,7 @@
|
|||
transformed-shape (gsh/transform-shape (merge shape (get modif-tree shape-id)))
|
||||
|
||||
[root transformed-root ignore-geometry?]
|
||||
(check-delta shape root transformed-shape transformed-root objects)
|
||||
(check-delta shape root transformed-shape transformed-root objects modif-tree)
|
||||
|
||||
ignore-tree (assoc ignore-tree shape-id ignore-geometry?)
|
||||
|
||||
|
@ -758,9 +758,6 @@
|
|||
(keep lookup)
|
||||
(remove #(= (:frame-id %) frame-id)))
|
||||
|
||||
moving-frames
|
||||
(filter #(cph/frame-shape? (lookup %)) ids)
|
||||
|
||||
changes
|
||||
(-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects)
|
||||
|
|
|
@ -355,8 +355,7 @@
|
|||
(dnd/has-type? e "application/x-moz-file"))
|
||||
(dom/prevent-default e)
|
||||
(reset! dragging? false)
|
||||
(import-files (.-files (.-dataTransfer e))))))
|
||||
]
|
||||
(import-files (.-files (.-dataTransfer e))))))]
|
||||
|
||||
[:section.dashboard-grid
|
||||
{:on-drag-enter on-drag-enter
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.math :as mth]
|
||||
[app.main.data.dashboard :as dd]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.dashboard.grid :refer [grid]]
|
||||
|
@ -20,20 +21,25 @@
|
|||
|
||||
(mf/defc libraries-page
|
||||
[{:keys [team] :as props}]
|
||||
(let [files-map (mf/deref refs/dashboard-shared-files)
|
||||
projects (mf/deref refs/dashboard-projects)
|
||||
(let [files-map (mf/deref refs/dashboard-shared-files)
|
||||
projects (mf/deref refs/dashboard-projects)
|
||||
default-project (->> projects vals (d/seek :is-default))
|
||||
files (->> (vals files-map)
|
||||
(sort-by :modified-at)
|
||||
(reverse))
|
||||
files (->> (vals files-map)
|
||||
(sort-by :modified-at)
|
||||
(reverse)
|
||||
(not-empty))
|
||||
|
||||
width (mf/use-state nil)
|
||||
rowref (mf/use-ref)
|
||||
itemsize 330
|
||||
ratio (if (some? @width) (/ @width itemsize) 0)
|
||||
nitems (mth/floor ratio)
|
||||
limit (min 10 nitems)
|
||||
limit (max 1 limit)]
|
||||
components-v2 (features/use-feature :components-v2)
|
||||
|
||||
width (mf/use-state nil)
|
||||
rowref (mf/use-ref)
|
||||
itemsize (if (>= @width 1030)
|
||||
280
|
||||
230)
|
||||
ratio (if (some? @width) (/ @width itemsize) 0)
|
||||
nitems (mth/floor ratio)
|
||||
limit (min 10 nitems)
|
||||
limit (max 1 limit)]
|
||||
(mf/use-effect
|
||||
(mf/deps team)
|
||||
(fn []
|
||||
|
@ -46,7 +52,7 @@
|
|||
(mf/use-effect
|
||||
#(st/emit! (dd/fetch-shared-files)
|
||||
(dd/clear-selected-files)))
|
||||
|
||||
|
||||
(mf/with-effect
|
||||
(let [node (mf/ref-val rowref)
|
||||
mnt? (volatile! true)
|
||||
|
@ -71,5 +77,5 @@
|
|||
:project default-project
|
||||
:origin :libraries
|
||||
:limit limit
|
||||
:library-view? true}]]]))
|
||||
:library-view? components-v2}]]]))
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.text :as txt]
|
||||
[app.config :as cfg]
|
||||
[app.config :as cf]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -31,6 +31,7 @@
|
|||
[app.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]]
|
||||
[app.util.color :as uc]
|
||||
|
@ -135,7 +136,7 @@
|
|||
on-close #(modal/hide!)
|
||||
|
||||
on-accept
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps form)
|
||||
(fn [_]
|
||||
(let [asset-name (get-in @form [:clean-data :asset-name])]
|
||||
|
@ -247,8 +248,6 @@
|
|||
(when (> num-selected 1)
|
||||
(set-drag-image event item-ref num-selected))))
|
||||
|
||||
|
||||
|
||||
(defn- on-drag-enter-asset-group
|
||||
[event dragging? prefix selected-assets-paths]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -270,9 +269,10 @@
|
|||
|
||||
;; ---- Common blocks ----
|
||||
|
||||
(def auto-pos-menu-state {:open? false
|
||||
:top nil
|
||||
:left nil})
|
||||
(def auto-pos-menu-state
|
||||
{:open? false
|
||||
:top nil
|
||||
:left nil})
|
||||
|
||||
(defn- open-auto-pos-menu
|
||||
[state event]
|
||||
|
@ -326,7 +326,7 @@
|
|||
menu-state (mf/use-state auto-pos-menu-state)
|
||||
|
||||
on-fold-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps file-id box path group-open?)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -335,12 +335,12 @@
|
|||
path
|
||||
(not group-open?)))))
|
||||
on-context-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(swap! menu-state #(open-auto-pos-menu % event))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state close-auto-pos-menu)))]
|
||||
|
||||
|
@ -371,12 +371,12 @@
|
|||
dragging? (mf/use-state false)
|
||||
|
||||
unselect-all
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (dw/unselect-all-assets))))
|
||||
|
||||
on-component-click
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps component selected-components)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -389,29 +389,29 @@
|
|||
(on-asset-click event (:id component) unselect-all)))))
|
||||
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps component dragging? selected-components selected-components-full selected-components-paths)
|
||||
(fn [event]
|
||||
(on-drop-asset event component dragging? selected-components selected-components-full
|
||||
selected-components-paths dwl/rename-component)))
|
||||
|
||||
on-drag-over
|
||||
(mf/use-callback #(dom/prevent-default %))
|
||||
(mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps component dragging? selected-components selected-components-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset event component dragging? selected-components selected-components-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-component-drag-start
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps component selected-components item-ref on-drag-start)
|
||||
(fn [event]
|
||||
(on-asset-drag-start event component selected-components item-ref :components on-drag-start)))]
|
||||
|
@ -466,21 +466,21 @@
|
|||
(map #(if (nil? %) "" %)))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-components-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset-group event dragging? prefix selected-components-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-drag-over (mf/use-callback #(dom/prevent-default %))
|
||||
on-drag-over (mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-components-paths selected-components-full)
|
||||
(fn [event]
|
||||
(on-drop-asset-group event dragging? prefix selected-components-paths selected-components-full dwl/rename-component)))]
|
||||
|
@ -567,7 +567,7 @@
|
|||
groups (group-assets components reverse-sort?)
|
||||
|
||||
on-duplicate
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state)
|
||||
(fn []
|
||||
(if (empty? selected-components)
|
||||
|
@ -578,7 +578,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))))
|
||||
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state file-id multi-components? multi-assets?)
|
||||
(fn []
|
||||
(if (or multi-components? multi-assets?)
|
||||
|
@ -589,25 +589,25 @@
|
|||
(dwu/commit-undo-transaction)))))
|
||||
|
||||
on-rename
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state)
|
||||
(fn []
|
||||
(swap! state assoc :renaming (:component-id @state))))
|
||||
|
||||
do-rename
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state)
|
||||
(fn [new-name]
|
||||
(st/emit! (dwl/rename-component (:renaming @state) new-name))
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
cancel-rename
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps selected-components on-clear-selection)
|
||||
(fn [component-id]
|
||||
(fn [event]
|
||||
|
@ -618,12 +618,12 @@
|
|||
(swap! menu-state #(open-auto-pos-menu % event))))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state close-auto-pos-menu)))
|
||||
|
||||
create-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps components selected-components on-clear-selection)
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
|
@ -639,7 +639,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps components)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
|
@ -653,14 +653,14 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
on-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps components selected-components)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept create-group})))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps components)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -669,7 +669,7 @@
|
|||
:accept rename-group})))
|
||||
|
||||
on-ungroup
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps components)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
|
@ -683,7 +683,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
on-drag-start
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [component event]
|
||||
(dnd/set-data! event "penpot/component" {:file-id file-id
|
||||
:component component})
|
||||
|
@ -730,36 +730,38 @@
|
|||
[{:keys [object renaming listing-thumbs? selected-objects
|
||||
on-asset-click on-context-menu on-drag-start do-rename cancel-rename
|
||||
selected-graphics-full selected-graphics-paths]}]
|
||||
(let [item-ref (mf/use-ref)
|
||||
|
||||
(let [item-ref (mf/use-ref)
|
||||
visible? (h/use-visible item-ref :once? true)
|
||||
dragging? (mf/use-state false)
|
||||
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps object dragging? selected-objects selected-graphics-full selected-graphics-paths)
|
||||
(fn [event]
|
||||
(on-drop-asset event object dragging? selected-objects selected-graphics-full
|
||||
selected-graphics-paths dwl/rename-media)))
|
||||
|
||||
on-drag-over (mf/use-callback #(dom/prevent-default %))
|
||||
on-drag-over (mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps object dragging? selected-objects selected-graphics-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset event object dragging? selected-objects selected-graphics-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-grahic-drag-start
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps object selected-objects item-ref on-drag-start)
|
||||
(fn [event]
|
||||
(on-asset-drag-start event object selected-objects item-ref :graphics on-drag-start)))]
|
||||
(on-asset-drag-start event object selected-objects item-ref :graphics on-drag-start)))
|
||||
|
||||
]
|
||||
|
||||
[:div {:ref item-ref
|
||||
:class-name (dom/classnames
|
||||
|
@ -774,28 +776,31 @@
|
|||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over on-drag-over
|
||||
:on-drop on-drop}
|
||||
[:img {:src (cfg/resolve-file-media object true)
|
||||
:draggable false}] ;; Also need to add css pointer-events: none
|
||||
|
||||
(let [renaming? (= renaming (:id object))]
|
||||
(when visible?
|
||||
[:*
|
||||
[:& editable-label
|
||||
{:class-name (dom/classnames
|
||||
:cell-name @listing-thumbs?
|
||||
:item-name (not @listing-thumbs?)
|
||||
:editing renaming?)
|
||||
:value (cph/merge-path-item (:path object) (:name object))
|
||||
:tooltip (cph/merge-path-item (:path object) (:name object))
|
||||
:display-value (if @listing-thumbs?
|
||||
(:name object)
|
||||
(cph/compact-name (:path object)
|
||||
(:name object)))
|
||||
:editing? renaming?
|
||||
:disable-dbl-click? true
|
||||
:on-change do-rename
|
||||
:on-cancel cancel-rename}]
|
||||
(when @dragging?
|
||||
[:div.dragging])])]))
|
||||
[:img {:src (when visible? (cf/resolve-file-media object true))
|
||||
:draggable false}] ;; Also need to add css pointer-events: none
|
||||
|
||||
(let [renaming? (= renaming (:id object))]
|
||||
[:*
|
||||
[:& editable-label
|
||||
{:class-name (dom/classnames
|
||||
:cell-name @listing-thumbs?
|
||||
:item-name (not @listing-thumbs?)
|
||||
:editing renaming?)
|
||||
:value (cph/merge-path-item (:path object) (:name object))
|
||||
:tooltip (cph/merge-path-item (:path object) (:name object))
|
||||
:display-value (if @listing-thumbs?
|
||||
(:name object)
|
||||
(cph/compact-name (:path object)
|
||||
(:name object)))
|
||||
:editing? renaming?
|
||||
:disable-dbl-click? true
|
||||
:on-change do-rename
|
||||
:on-cancel cancel-rename}]
|
||||
(when @dragging?
|
||||
[:div.dragging])])])]))
|
||||
|
||||
(mf/defc graphics-group
|
||||
[{:keys [file-id prefix groups open-groups renaming listing-thumbs? selected-objects on-asset-click
|
||||
|
@ -811,21 +816,21 @@
|
|||
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-graphics-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset-group event dragging? prefix selected-graphics-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-drag-over (mf/use-callback #(dom/prevent-default %))
|
||||
on-drag-over (mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-graphics-paths selected-graphics-full)
|
||||
(fn [event]
|
||||
(on-drop-asset-group event dragging? prefix selected-graphics-paths selected-graphics-full dwl/rename-media)))]
|
||||
|
@ -915,13 +920,13 @@
|
|||
groups (group-assets objects reverse-sort?)
|
||||
|
||||
add-graphic
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
#(st/emit! (dwl/set-assets-box-open file-id :graphics true))
|
||||
(dom/click (mf/ref-val input-ref))))
|
||||
|
||||
on-file-selected
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [blobs]
|
||||
(let [params {:file-id file-id
|
||||
|
@ -931,7 +936,7 @@
|
|||
:asset-type "graphics"})))))
|
||||
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state multi-objects? multi-assets?)
|
||||
(fn []
|
||||
(if (or multi-objects? multi-assets?)
|
||||
|
@ -939,25 +944,25 @@
|
|||
(st/emit! (dwl/delete-media {:id (:object-id @state)})))))
|
||||
|
||||
on-rename
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state)
|
||||
(fn []
|
||||
(swap! state assoc :renaming (:object-id @state))))
|
||||
|
||||
cancel-rename
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
do-rename
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state)
|
||||
(fn [new-name]
|
||||
(st/emit! (dwl/rename-media (:renaming @state) new-name))
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps selected-objects on-clear-selection)
|
||||
(fn [object-id]
|
||||
(fn [event]
|
||||
|
@ -968,12 +973,12 @@
|
|||
(swap! menu-state #(open-auto-pos-menu % event))))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state close-auto-pos-menu)))
|
||||
|
||||
create-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps objects selected-objects on-clear-selection)
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
|
@ -989,7 +994,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
|
@ -1003,14 +1008,14 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
on-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps objects selected-objects)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept create-group})))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -1018,7 +1023,7 @@
|
|||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
on-ungroup
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
|
@ -1032,7 +1037,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
on-drag-start
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [{:keys [name id mtype]} event]
|
||||
(dnd/set-data! event "text/asset-id" (str id))
|
||||
(dnd/set-data! event "text/asset-name" name)
|
||||
|
@ -1131,7 +1136,7 @@
|
|||
(st/emit! (dwl/update-color updated-color file-id))))
|
||||
|
||||
delete-color
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state multi-colors? multi-assets? file-id)
|
||||
(fn []
|
||||
(if (or multi-colors? multi-assets?)
|
||||
|
@ -1173,7 +1178,7 @@
|
|||
:position :right}))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps color selected-colors on-clear-selection)
|
||||
(fn [event]
|
||||
(when local?
|
||||
|
@ -1182,32 +1187,32 @@
|
|||
(swap! menu-state #(open-auto-pos-menu % event)))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state close-auto-pos-menu)))
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps color dragging? selected-colors selected-colors-full selected-colors-paths move-color)
|
||||
(fn [event]
|
||||
(on-drop-asset event color dragging? selected-colors selected-colors-full
|
||||
selected-colors-paths move-color)))
|
||||
|
||||
on-drag-over (mf/use-callback #(dom/prevent-default %))
|
||||
on-drag-over (mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps color dragging? selected-colors selected-colors-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset event color dragging? selected-colors selected-colors-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-color-drag-start
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps color selected-colors item-ref)
|
||||
(fn [event]
|
||||
(on-asset-drag-start event color selected-colors item-ref :colors identity)))]
|
||||
|
@ -1277,20 +1282,20 @@
|
|||
move-color (partial dwl/rename-color file-id)
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-colors-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset-group event dragging? prefix selected-colors-paths)))
|
||||
|
||||
on-drag-leave (mf/use-callback
|
||||
on-drag-leave (mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-drag-over (mf/use-callback #(dom/prevent-default %))
|
||||
on-drag-over (mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-colors-paths selected-colors-full move-color)
|
||||
(fn [event]
|
||||
(on-drop-asset-group event dragging? prefix selected-colors-paths selected-colors-full move-color)))]
|
||||
|
@ -1371,13 +1376,13 @@
|
|||
groups (group-assets colors reverse-sort?)
|
||||
|
||||
add-color
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [value _opacity]
|
||||
(st/emit! (dwl/add-color value))))
|
||||
|
||||
add-color-clicked
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(st/emit! (dwl/set-assets-box-open file-id :colors true)
|
||||
|
@ -1392,7 +1397,7 @@
|
|||
:position :right})))
|
||||
|
||||
create-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps colors selected-colors on-clear-selection file-id)
|
||||
(fn [color-id]
|
||||
(fn [group-name]
|
||||
|
@ -1410,7 +1415,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction)))))
|
||||
|
||||
rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps colors)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
|
@ -1425,7 +1430,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
on-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps colors selected-colors)
|
||||
(fn [color-id]
|
||||
(fn [event]
|
||||
|
@ -1433,7 +1438,7 @@
|
|||
(modal/show! :name-group-dialog {:accept (create-group color-id)}))))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps colors)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -1441,7 +1446,7 @@
|
|||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
on-ungroup
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps colors)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
|
@ -1492,28 +1497,28 @@
|
|||
(let [item-ref (mf/use-ref)
|
||||
dragging? (mf/use-state false)
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typography dragging? selected-typographies selected-typographies-full selected-typographies-paths move-typography)
|
||||
(fn [event]
|
||||
(on-drop-asset event typography dragging? selected-typographies selected-typographies-full
|
||||
selected-typographies-paths move-typography)))
|
||||
|
||||
on-drag-over (mf/use-callback #(dom/prevent-default %))
|
||||
on-drag-over (mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typography dragging? selected-typographies selected-typographies-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset event typography dragging? selected-typographies selected-typographies-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-typography-drag-start
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typography selected-typographies item-ref)
|
||||
(fn [event]
|
||||
(on-asset-drag-start event typography selected-typographies item-ref :typographies identity)))]
|
||||
|
@ -1554,21 +1559,21 @@
|
|||
move-typography (partial dwl/rename-typography file-id)
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-typographies-paths)
|
||||
(fn [event]
|
||||
(on-drag-enter-asset-group event dragging? prefix selected-typographies-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging?)
|
||||
(fn [event]
|
||||
(on-drag-leave-asset event dragging?)))
|
||||
|
||||
on-drag-over (mf/use-callback #(dom/prevent-default %))
|
||||
on-drag-over (mf/use-fn #(dom/prevent-default %))
|
||||
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps dragging? prefix selected-typographies-paths selected-typographies-full move-typography)
|
||||
(fn [event]
|
||||
(on-drop-asset-group event dragging? prefix selected-typographies-paths selected-typographies-full move-typography)))]
|
||||
|
@ -1653,7 +1658,7 @@
|
|||
(seq (:colors selected-assets)))
|
||||
|
||||
add-typography
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [_]
|
||||
(st/emit! (dwl/add-typography txt/default-typography)
|
||||
|
@ -1661,7 +1666,7 @@
|
|||
:asset-type "typography"}))))
|
||||
|
||||
handle-change
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [typography changes]
|
||||
(st/emit! (dwl/update-typography (merge typography changes) file-id))))
|
||||
|
@ -1681,7 +1686,7 @@
|
|||
ids)))
|
||||
|
||||
create-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typographies selected-typographies on-clear-selection file-id)
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
|
@ -1698,7 +1703,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typographies)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
|
@ -1713,14 +1718,14 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
on-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typographies selected-typographies)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept create-group})))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typographies)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -1728,7 +1733,7 @@
|
|||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
on-ungroup
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps typographies)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
|
@ -1743,7 +1748,7 @@
|
|||
(st/emit! (dwu/commit-undo-transaction))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps selected-typographies on-clear-selection)
|
||||
(fn [id event]
|
||||
(when local?
|
||||
|
@ -1753,7 +1758,7 @@
|
|||
(swap! menu-state #(open-auto-pos-menu % event)))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state close-auto-pos-menu)))
|
||||
|
||||
|
@ -1766,7 +1771,7 @@
|
|||
(st/emit! #(assoc-in % [:workspace-global :edit-typography] (:id @state))))
|
||||
|
||||
handle-delete-typography
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps @state multi-typographies? multi-assets?)
|
||||
(fn []
|
||||
(if (or multi-typographies? multi-assets?)
|
||||
|
@ -1936,17 +1941,17 @@
|
|||
components (apply-filters (mf/deref components-ref) filters @reverse-sort?)
|
||||
|
||||
toggle-sort
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [_]
|
||||
(swap! reverse-sort? not)))
|
||||
|
||||
toggle-listing
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [_]
|
||||
(swap! listing-thumbs? not)))
|
||||
|
||||
extend-selected-assets
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps selected-assets)
|
||||
(fn [asset-type asset-groups asset-id]
|
||||
(letfn [(flatten-groups
|
||||
|
@ -1977,12 +1982,12 @@
|
|||
(st/emit! (dw/select-assets values asset-type))))))))
|
||||
|
||||
unselect-all
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (dw/unselect-all-assets))))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps selected-assets)
|
||||
(fn [asset-type asset-groups event asset-id default-click]
|
||||
(cond
|
||||
|
@ -2001,7 +2006,7 @@
|
|||
(default-click event)))))
|
||||
|
||||
on-assets-delete
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps selected-assets)
|
||||
(fn []
|
||||
(st/emit! (dwu/start-undo-transaction))
|
||||
|
@ -2136,20 +2141,20 @@
|
|||
filters (mf/use-state {:term "" :box :all})
|
||||
|
||||
on-search-term-change
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps team-id)
|
||||
(fn [event]
|
||||
(let [value (dom/get-target-val event)]
|
||||
(swap! filters assoc :term value))))
|
||||
|
||||
on-search-clear-click
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps team-id)
|
||||
(fn [_]
|
||||
(swap! filters assoc :term "")))
|
||||
|
||||
on-box-filter-change
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps team-id)
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
|
|
|
@ -183,7 +183,7 @@
|
|||
(let [objects (deref refs/workspace-page-objects)
|
||||
destination (get objects (:destination interaction))
|
||||
|
||||
frames (mf/with-memo [objects] (ctt/get-viewer-frames objects {:all-frames? (not= :navigate (:action-type interaction))}))
|
||||
frames (mf/with-memo [objects] (ctt/get-viewer-frames objects {:all-frames? true}))
|
||||
|
||||
overlay-pos-type (:overlay-pos-type interaction)
|
||||
close-click-outside? (:close-click-outside interaction false)
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
[app.main.constants :refer [size-presets]]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.interactions :as dwi]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
|
@ -236,7 +238,16 @@
|
|||
(mf/deps ids)
|
||||
(fn [event]
|
||||
(let [value (-> event dom/get-target dom/checked?)]
|
||||
(st/emit! (dch/update-shapes ids (fn [shape] (assoc shape :hide-in-viewer (not value))))))))
|
||||
(do
|
||||
(st/emit! (dwu/start-undo-transaction)
|
||||
(dch/update-shapes ids (fn [shape] (assoc shape :hide-in-viewer (not value)))))
|
||||
|
||||
(when-not value
|
||||
;; when a frame is no longer shown in view mode, cannot have
|
||||
;; interactions that navigate to it.
|
||||
(apply st/emit! (map #(dwi/remove-all-interactions-nav-to %) ids)))
|
||||
|
||||
(st/emit! (dwu/commit-undo-transaction))))))
|
||||
|
||||
select-all #(-> % (dom/get-target) (.select))]
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue