mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 16:21:57 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
c3f0657652
26 changed files with 143 additions and 97 deletions
11
CHANGES.md
11
CHANGES.md
|
@ -50,6 +50,7 @@
|
|||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Remove gitter information from feedback page [Taiga #4157](https://tree.taiga.io/project/penpot/issue/4157)
|
||||
- Fix overlay remains open on frame change [Taiga #4066](https://tree.taiga.io/project/penpot/issue/4066)
|
||||
- Fix toggle overlay position [Taiga #4091](https://tree.taiga.io/project/penpot/issue/4091)
|
||||
- Fix overlay closed on clicked outside [Taiga #4027](https://tree.taiga.io/project/penpot/issue/4027)
|
||||
|
@ -57,6 +58,16 @@
|
|||
- Fix problem with snap to grids [#2221](https://github.com/penpot/penpot/issues/2221)
|
||||
- Fix issue when scaling to value 0 [#2252](https://github.com/penpot/penpot/issues/2252)
|
||||
- Fix problem when moving shapes inside nested frames [Taiga #4113](https://tree.taiga.io/project/penpot/issue/4113)
|
||||
- Fix color type icon does not change [Taiga #4133](https://tree.taiga.io/project/penpot/issue/4133)
|
||||
- Fix recent colors are not working [Taiga #4153](https://tree.taiga.io/project/penpot/issue/4153)
|
||||
- Fix change opacity in colorpicker cause bugged color [Taiga #4154](https://tree.taiga.io/project/penpot/issue/4154)
|
||||
- Fix gradient colors don't arrive in recent colors palette (https://tree.taiga.io/project/penpot/issue/4155)
|
||||
- Fix selected colors allow gradients in shadows [Taiga #4156](https://tree.taiga.io/project/penpot/issue/4156)
|
||||
- Fix import files with unexpected format or invalid content [Taiga #4136](https://tree.taiga.io/project/penpot/issue/4136)
|
||||
- Fix wrong shortcut button tip of "Delete" function [Taiga #4162](https://tree.taiga.io/project/penpot/issue/4162)
|
||||
- Fix error after user drags any layer in search functionality [Taiga #4161](https://tree.taiga.io/project/penpot/issue/4161)
|
||||
- Fix font search works only with lowercase letters [Taiga #4140](https://tree.taiga.io/project/penpot/issue/4140)
|
||||
- Fix Terms and Privacy links overlapping [Taiga #4137](https://tree.taiga.io/project/penpot/issue/4137)
|
||||
|
||||
|
||||
## 1.15.3-beta
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
org.postgresql/postgresql {:mvn/version "42.4.0"}
|
||||
com.zaxxer/HikariCP {:mvn/version "5.0.1"}
|
||||
|
||||
io.whitfin/siphash {:mvn/version "2.0.0"}
|
||||
|
||||
buddy/buddy-hashers {:mvn/version "1.8.158"}
|
||||
buddy/buddy-sign {:mvn/version "3.4.333"}
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
com.zaxxer.hikari.HikariConfig
|
||||
com.zaxxer.hikari.HikariDataSource
|
||||
com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory
|
||||
io.whitfin.siphash.SipHasher
|
||||
io.whitfin.siphash.SipHasherContainer
|
||||
java.io.InputStream
|
||||
java.io.OutputStream
|
||||
java.lang.AutoCloseable
|
||||
|
@ -431,10 +433,19 @@
|
|||
|
||||
;; --- Locks
|
||||
|
||||
(def ^:private siphash-state
|
||||
(SipHasher/container
|
||||
(uuid/get-bytes uuid/zero)))
|
||||
|
||||
(defn uuid->hash-code
|
||||
[o]
|
||||
(.hash ^SipHasherContainer siphash-state
|
||||
^bytes (uuid/get-bytes o)))
|
||||
|
||||
(defn- xact-check-param
|
||||
[n]
|
||||
(cond
|
||||
(uuid? n) (uuid/get-word-high n)
|
||||
(uuid? n) (uuid->hash-code n)
|
||||
(int? n) n
|
||||
:else (throw (IllegalArgumentException. "uuid or number allowed"))))
|
||||
|
||||
|
|
|
@ -229,17 +229,6 @@
|
|||
(when (zero? (:exit res))
|
||||
foutput)))
|
||||
|
||||
(ttf-or-otf->woff2 [data]
|
||||
;; NOTE: foutput is not used directly, it represents the
|
||||
;; default output of the exection of the underlying
|
||||
;; command.
|
||||
(let [finput (tmp/tempfile :prefix "penpot.font." :suffix ".tmp")
|
||||
foutput (fs/path (str (fs/base finput) ".woff2"))
|
||||
_ (io/write-to-file! data finput)
|
||||
res (sh/sh "woff2_compress" (str finput))]
|
||||
(when (zero? (:exit res))
|
||||
foutput)))
|
||||
|
||||
(woff->sfnt [data]
|
||||
(let [finput (tmp/tempfile :prefix "penpot" :suffix "")
|
||||
_ (io/write-to-file! data finput)
|
||||
|
@ -271,15 +260,13 @@
|
|||
(let [data (get input "font/ttf")]
|
||||
(-> input
|
||||
(update "font/otf" gen-if-nil #(ttf->otf data))
|
||||
(update "font/woff" gen-if-nil #(ttf-or-otf->woff data))
|
||||
(assoc "font/woff2" (ttf-or-otf->woff2 data))))
|
||||
(update "font/woff" gen-if-nil #(ttf-or-otf->woff data))))
|
||||
|
||||
(contains? current "font/otf")
|
||||
(let [data (get input "font/otf")]
|
||||
(-> input
|
||||
(update "font/woff" gen-if-nil #(ttf-or-otf->woff data))
|
||||
(assoc "font/ttf" (otf->ttf data))
|
||||
(assoc "font/woff2" (ttf-or-otf->woff2 data))))
|
||||
(assoc "font/ttf" (otf->ttf data))))
|
||||
|
||||
(contains? current "font/woff")
|
||||
(let [data (get input "font/woff")
|
||||
|
@ -291,8 +278,7 @@
|
|||
(let [stype (get-sfnt-type sfnt)]
|
||||
(cond-> input
|
||||
true
|
||||
(-> (assoc "font/woff" data)
|
||||
(assoc "font/woff2" (ttf-or-otf->woff2 sfnt)))
|
||||
(-> (assoc "font/woff" data))
|
||||
|
||||
(= stype :otf)
|
||||
(-> (assoc "font/otf" sfnt)
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
(t/is (uuid? (:ttf-file-id result)))
|
||||
(t/is (uuid? (:otf-file-id result)))
|
||||
(t/is (uuid? (:woff1-file-id result)))
|
||||
(t/is (uuid? (:woff2-file-id result)))
|
||||
(t/are [k] (= (get params k)
|
||||
(get result k))
|
||||
:team-id
|
||||
|
@ -81,7 +80,6 @@
|
|||
(t/is (uuid? (:ttf-file-id result)))
|
||||
(t/is (uuid? (:otf-file-id result)))
|
||||
(t/is (uuid? (:woff1-file-id result)))
|
||||
(t/is (uuid? (:woff2-file-id result)))
|
||||
(t/are [k] (= (get params k)
|
||||
(get result k))
|
||||
:team-id
|
||||
|
|
|
@ -232,7 +232,7 @@
|
|||
;; run the touched gc task
|
||||
(let [task (:app.storage/gc-touched-task th/*system*)
|
||||
res (task {})]
|
||||
(t/is (= 6 (:freeze res)))
|
||||
(t/is (= 5 (:freeze res)))
|
||||
(t/is (= 0 (:delete res)))
|
||||
|
||||
(let [result-1 (:result out1)
|
||||
|
@ -247,7 +247,7 @@
|
|||
;; Run the task again
|
||||
(let [res (task {})]
|
||||
(t/is (= 2 (:freeze res)))
|
||||
(t/is (= 4 (:delete res))))
|
||||
(t/is (= 3 (:delete res))))
|
||||
|
||||
;; now check that there are no touched objects
|
||||
(let [res (db/exec-one! th/*pool* ["select count(*) from storage_object where touched_at is not null"])]
|
||||
|
@ -255,7 +255,7 @@
|
|||
|
||||
;; now check that all objects are marked to be deleted
|
||||
(let [res (db/exec-one! th/*pool* ["select count(*) from storage_object where deleted_at is not null"])]
|
||||
(t/is (= 4 (:count res))))))))
|
||||
(t/is (= 3 (:count res))))))))
|
||||
|
||||
(t/deftest test-touched-gc-task-3
|
||||
(let [storage (-> (:app.storage/storage th/*system*)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
[app.common.spec :as us]
|
||||
[clojure.spec.alpha :as s]))
|
||||
|
||||
(def precision 3)
|
||||
(def precision 6)
|
||||
|
||||
;; --- Matrix Impl
|
||||
|
||||
|
|
|
@ -11,8 +11,9 @@
|
|||
#?(:cljs [app.common.uuid-impl :as impl])
|
||||
#?(:cljs [cljs.core :as c]))
|
||||
#?(:clj (:import
|
||||
app.common.UUIDv8
|
||||
java.util.UUID
|
||||
app.common.UUIDv8)))
|
||||
java.nio.ByteBuffer)))
|
||||
|
||||
(def zero #uuid "00000000-0000-0000-0000-000000000000")
|
||||
|
||||
|
@ -50,3 +51,11 @@
|
|||
(defn get-word-low
|
||||
[id]
|
||||
(.getLeastSignificantBits ^UUID id)))
|
||||
|
||||
#?(:clj
|
||||
(defn get-bytes
|
||||
[^UUID o]
|
||||
(let [buf (ByteBuffer/allocate 16)]
|
||||
(.putLong buf (.getMostSignificantBits o))
|
||||
(.putLong buf (.getLeastSignificantBits o))
|
||||
(.array buf))))
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
grid-template-columns: 33% auto;
|
||||
height: 100vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.auth-sidebar {
|
||||
|
@ -53,6 +55,7 @@
|
|||
height: 100vh;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
min-height: 48rem;
|
||||
|
||||
input {
|
||||
margin-bottom: 0px;
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
[]
|
||||
(if (cf/check-platform? :macos)
|
||||
mac-delete
|
||||
"Supr"))
|
||||
"Del"))
|
||||
|
||||
(defn esc
|
||||
[]
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[app.main.data.modal :as md]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.layout :as layout]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.util.color :as uc]
|
||||
|
@ -242,7 +243,10 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (dch/update-shapes ids (fn [shape]
|
||||
(let [new-attrs (merge (get-in shape [:shadow index :color]) attrs)]
|
||||
(let [;; If we try to set a gradient to a shadow (for example using the color selection from multiple shapes) let's use the first stop color
|
||||
attrs (cond-> attrs
|
||||
(:gradient attrs) (get-in [:gradient :stops 0]))
|
||||
new-attrs (merge (get-in shape [:shadow index :color]) attrs)]
|
||||
(assoc-in shape [:shadow index :color] new-attrs))))))))
|
||||
|
||||
(defn add-stroke
|
||||
|
@ -487,7 +491,7 @@
|
|||
(dissoc :stops)))))))))
|
||||
|
||||
(defn update-colorpicker-color
|
||||
[changes]
|
||||
[changes add-recent?]
|
||||
(ptk/reify ::update-colorpicker-color
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
@ -495,14 +499,22 @@
|
|||
(fn [state]
|
||||
(let [state (-> state
|
||||
(update :current-color merge changes)
|
||||
(update :current-color materialize-color-components))]
|
||||
(update :current-color materialize-color-components)
|
||||
;; current color can be a library one I'm changing via colorpicker
|
||||
(d/dissoc-in [:current-color :id])
|
||||
(d/dissoc-in [:current-color :file-id]))]
|
||||
(if-let [stop (:editing-stop state)]
|
||||
(update-in state [:stops stop] (fn [data] (->> changes
|
||||
(merge data)
|
||||
(materialize-color-components))))
|
||||
(-> state
|
||||
(assoc :type :color)
|
||||
(dissoc :gradient :stops :editing-stop)))))))))
|
||||
(dissoc :gradient :stops :editing-stop)))))))
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(when add-recent?
|
||||
(let [formated-color (get-color-from-colorpicker-state (:colorpicker state))]
|
||||
(rx/of (dwl/add-recent-color formated-color)))))))
|
||||
|
||||
(defn update-colorpicker-gradient
|
||||
[changes]
|
||||
|
|
|
@ -292,7 +292,7 @@
|
|||
(mf/use-callback
|
||||
(fn [event]
|
||||
(let [val (dom/get-target-val event)]
|
||||
(reset! sterm val))))]
|
||||
(reset! sterm (str/lower val)))))]
|
||||
|
||||
[:div.dashboard-installed-fonts
|
||||
[:h3 (tr "labels.installed-fonts")]
|
||||
|
|
|
@ -347,7 +347,11 @@
|
|||
success-files (->> @state :files (filter #(and (= (:status %) :import-finish) (empty? (:errors %)))) count)
|
||||
pending-analysis? (> (->> @state :files (filter #(= (:status %) :analyzing)) count) 0)
|
||||
pending-import? (> num-importing 0)
|
||||
files (->> (:files @state) (filterv (comp not :deleted?)))]
|
||||
files (->> (:files @state) (filterv (comp not :deleted?)))
|
||||
;; pending-import? (> (->> @state :files (filter #(= (:status %) :importing)) count) 0)
|
||||
;; files (->> (:files @state) (filterv (comp not :deleted?)))
|
||||
valid-files? (or (some? template)
|
||||
(> (+ (->> files (filterv (fn [x] (not= (:status x) :analyze-error))) count)) 0))]
|
||||
|
||||
(mf/use-effect
|
||||
(fn []
|
||||
|
@ -408,7 +412,7 @@
|
|||
{:class "primary"
|
||||
:type "button"
|
||||
:value (tr "labels.continue")
|
||||
:disabled pending-analysis?
|
||||
:disabled (or pending-analysis? (not valid-files?))
|
||||
:on-click handle-continue}])
|
||||
|
||||
(when (= :importing (:status @state))
|
||||
|
@ -416,5 +420,5 @@
|
|||
{:class "primary"
|
||||
:type "button"
|
||||
:value (tr "labels.accept")
|
||||
:disabled pending-import?
|
||||
:disabled (or pending-import? (not valid-files?))
|
||||
:on-click handle-accept}])]]]]))
|
||||
|
|
|
@ -300,13 +300,13 @@
|
|||
[key default]
|
||||
(let [id (use-id)
|
||||
state (mf/use-state (get @storage key default))
|
||||
stream (mf/with-memo []
|
||||
stream (mf/with-memo [id]
|
||||
(->> mbc/stream
|
||||
(rx/filter #(= (:type %) key))
|
||||
(rx/filter #(not= (:id %) id))
|
||||
(rx/filter #(= (:type %) key))
|
||||
(rx/map deref)))]
|
||||
|
||||
(mf/with-effect [@state key]
|
||||
(mf/with-effect [@state key id]
|
||||
(mbc/emit! id key @state)
|
||||
(swap! storage assoc key @state))
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
(remove #(= "transform" (.-attributeName ^js %))))]
|
||||
(when (d/not-empty? mutations)
|
||||
(on-change (mf/ref-val node-ref))))))
|
||||
|
||||
|
||||
set-node
|
||||
(mf/use-callback
|
||||
(mf/deps on-mutation)
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
(st/emit! (ptk/event ::ev/event {::ev/name "arengu-form-load-success"
|
||||
::ev/origin "onboarding-questions"
|
||||
::ev/type "fact"}))
|
||||
|
||||
(resolve)))
|
||||
(p/catch reject))))
|
||||
|
||||
|
@ -54,9 +53,7 @@
|
|||
(st/emit! (ptk/event ::ev/event {::ev/name "arengu-form-load-error"
|
||||
::ev/origin "onboarding-questions"
|
||||
::ev/type "fact"}))
|
||||
(mark-as-answered))
|
||||
|
||||
]
|
||||
(mark-as-answered))]
|
||||
|
||||
(let [cleaners (atom #{})]
|
||||
(-> (p/create (partial initialize cleaners))
|
||||
|
|
|
@ -96,14 +96,6 @@
|
|||
{:href "https://twitter.com/PenpotSupport" :target "_blank"}
|
||||
(tr "feedback.twitter-go-to")]
|
||||
|
||||
[:hr]
|
||||
|
||||
[:h2 "Gitter"]
|
||||
[:p (tr "feedback.chat-subtitle")]
|
||||
[:a.btn-secondary.btn-large
|
||||
{:href "https://gitter.im/penpot/community" :target "_blank"}
|
||||
(tr "feedback.chat-start")]
|
||||
|
||||
]))
|
||||
|
||||
(mf/defc feedback-page
|
||||
|
|
|
@ -36,16 +36,18 @@
|
|||
|
||||
(mf/defc palette
|
||||
[{:keys [current-colors recent-colors file-colors shared-libs selected on-select]}]
|
||||
(let [state (mf/use-state {:show-menu false})
|
||||
(let [;; We had to do this due to a bug that leave some bugged colors
|
||||
current-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %)) current-colors))
|
||||
state (mf/use-state {:show-menu false})
|
||||
|
||||
width (:width @state 0)
|
||||
visible (/ width 66)
|
||||
width (:width @state 0)
|
||||
visible (/ width 66)
|
||||
|
||||
offset (:offset @state 0)
|
||||
max-offset (- (count current-colors)
|
||||
visible)
|
||||
offset (:offset @state 0)
|
||||
max-offset (- (count current-colors)
|
||||
visible)
|
||||
|
||||
container (mf/use-ref nil)
|
||||
container (mf/use-ref nil)
|
||||
|
||||
{:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]}
|
||||
(use-resize-hook :palette 72 54 80 :y true :bottom)
|
||||
|
@ -137,7 +139,7 @@
|
|||
(tr "workspace.libraries.colors.file-library")
|
||||
(str/ffmt " (%)" (count file-colors)))]
|
||||
[:div.color-sample
|
||||
(for [[i color] (map-indexed vector (take 7 (vals file-colors))) ]
|
||||
(for [[i color] (map-indexed vector (take 7 (vals file-colors)))]
|
||||
[:& cb/color-bullet {:key (dm/str "color-" i)
|
||||
:color color}])]]
|
||||
|
||||
|
@ -148,7 +150,7 @@
|
|||
[:div.library-name (str (tr "workspace.libraries.colors.recent-colors")
|
||||
(str/format " (%s)" (count recent-colors)))]
|
||||
[:div.color-sample
|
||||
(for [[idx color] (map-indexed vector (take 7 (reverse recent-colors))) ]
|
||||
(for [[idx color] (map-indexed vector (take 7 (reverse recent-colors)))]
|
||||
[:& cb/color-bullet {:key (str "color-" idx)
|
||||
:color color}])]]]]
|
||||
|
||||
|
@ -183,13 +185,11 @@
|
|||
on-select (mf/use-fn #(reset! selected %))]
|
||||
|
||||
(mf/with-effect [@selected]
|
||||
(fn []
|
||||
(reset! colors
|
||||
(into []
|
||||
(cond
|
||||
(= @selected :recent) (reverse recent-colors)
|
||||
(= @selected :file) (->> (vals file-colors) (sort-by :name))
|
||||
:else (->> (library->colors shared-libs @selected) (sort-by :name)))))))
|
||||
(let [colors' (cond
|
||||
(= @selected :recent) (reverse recent-colors)
|
||||
(= @selected :file) (->> (vals file-colors) (sort-by :name))
|
||||
:else (->> (library->colors shared-libs @selected) (sort-by :name)))]
|
||||
(reset! colors (into [] colors'))))
|
||||
|
||||
(mf/with-effect [recent-colors @selected]
|
||||
(when (= @selected :recent)
|
||||
|
|
|
@ -67,11 +67,9 @@
|
|||
(mf/use-fn
|
||||
(mf/deps @drag?)
|
||||
(fn [color]
|
||||
(let [recent-color (merge color)
|
||||
(let [recent-color (merge current-color color)
|
||||
recent-color (dc/materialize-color-components recent-color)]
|
||||
(when (not @drag?)
|
||||
(st/emit! (dwl/add-recent-color recent-color)))
|
||||
(st/emit! (dc/update-colorpicker-color color)))))
|
||||
(st/emit! (dc/update-colorpicker-color recent-color (not @drag?))))))
|
||||
|
||||
handle-click-picker
|
||||
(mf/use-fn
|
||||
|
|
|
@ -131,6 +131,7 @@
|
|||
:width canvas-side
|
||||
:height canvas-side
|
||||
:on-pointer-down handle-start-drag
|
||||
:on-pointer-up handle-stop-drag
|
||||
:on-lost-pointer-capture handle-stop-drag
|
||||
:on-click calculate-pos
|
||||
:on-mouse-move #(when @dragging? (calculate-pos %))}]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.main.ui.workspace.colorpicker.libraries
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
[app.main.data.workspace.colors :as mdc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||
|
@ -19,12 +19,13 @@
|
|||
|
||||
(mf/defc libraries
|
||||
[{:keys [on-select-color on-add-library-color disable-gradient disable-opacity]}]
|
||||
(let [selected (h/use-shared-state dc/colorpicker-selected-broadcast-key :recent)
|
||||
(let [selected (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent)
|
||||
current-colors (mf/use-state [])
|
||||
|
||||
shared-libs (mf/deref refs/workspace-libraries)
|
||||
file-colors (mf/deref refs/workspace-file-colors)
|
||||
recent-colors (mf/deref refs/workspace-recent-colors)
|
||||
recent-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %)) recent-colors))
|
||||
|
||||
on-library-change
|
||||
(mf/use-fn
|
||||
|
@ -80,7 +81,7 @@
|
|||
i/plus])
|
||||
|
||||
[:div.color-bullet.button {:style {:background-color "var(--color-white)"}
|
||||
:on-click #(st/emit! (dc/show-palette @selected))}
|
||||
:on-click #(st/emit! (mdc/show-palette @selected))}
|
||||
i/palette]
|
||||
|
||||
(for [[idx color] (map-indexed vector @current-colors)]
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
]
|
||||
[:div.value-saturation-selector
|
||||
{:on-pointer-down handle-start-drag
|
||||
:on-pointer-up handle-stop-drag
|
||||
:on-lost-pointer-capture handle-stop-drag
|
||||
:on-click calculate-pos
|
||||
:on-mouse-move #(when @dragging? (calculate-pos %))}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
[:div.slider-selector
|
||||
{:class (str (if vertical? "vertical " "") class)
|
||||
:on-pointer-down handle-start-drag
|
||||
:on-pointer-up handle-stop-drag
|
||||
:on-lost-pointer-capture handle-stop-drag
|
||||
:on-click calculate-pos
|
||||
:on-mouse-move #(when @dragging? (calculate-pos %))}
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
(when (seq (:touched shape)) " *")])))
|
||||
|
||||
(mf/defc layer-item
|
||||
[{:keys [index item selected objects] :as props}]
|
||||
[{:keys [index item selected objects sortable?] :as props}]
|
||||
(let [id (:id item)
|
||||
blocked? (:blocked item)
|
||||
hidden? (:hidden item)
|
||||
|
@ -199,16 +199,17 @@
|
|||
(when-not expanded?
|
||||
(st/emit! (dwc/toggle-collapse id)))))
|
||||
|
||||
[dprops dref] (hooks/use-sortable
|
||||
:data-type "penpot/layer"
|
||||
:on-drop on-drop
|
||||
:on-drag on-drag
|
||||
:on-hold on-hold
|
||||
:disabled @disable-drag
|
||||
:detect-center? container?
|
||||
:data {:id (:id item)
|
||||
:index index
|
||||
:name (:name item)})
|
||||
[dprops dref] (when sortable?
|
||||
(hooks/use-sortable
|
||||
:data-type "penpot/layer"
|
||||
:on-drop on-drop
|
||||
:on-drag on-drag
|
||||
:on-hold on-hold
|
||||
:disabled @disable-drag
|
||||
:detect-center? container?
|
||||
:data {:id (:id item)
|
||||
:index index
|
||||
:name (:name item)}))
|
||||
|
||||
ref (mf/use-ref)]
|
||||
|
||||
|
@ -309,13 +310,15 @@
|
|||
:selected selected
|
||||
:index index
|
||||
:objects objects
|
||||
:key id}]
|
||||
:key id
|
||||
:sortable? true}]
|
||||
[:& layer-item
|
||||
{:item obj
|
||||
:selected selected
|
||||
:index index
|
||||
:objects objects
|
||||
:key id}])))]]))
|
||||
:key id
|
||||
:sortable? true}])))]]))
|
||||
|
||||
(mf/defc filters-tree
|
||||
{::mf/wrap [#(mf/memo % =)
|
||||
|
@ -332,7 +335,8 @@
|
|||
:selected selected
|
||||
:index index
|
||||
:objects objects
|
||||
:key id}]))]))
|
||||
:key id
|
||||
:sortable? false}]))]))
|
||||
|
||||
|
||||
(defn calc-reparented-objects
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.color-bullet :as cb]
|
||||
[app.main.ui.components.color-input :refer [color-input]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
|
@ -73,18 +75,22 @@
|
|||
(mf/use-fn
|
||||
(mf/deps color on-change)
|
||||
(fn [new-value]
|
||||
(on-change (-> color
|
||||
(assoc :color new-value)
|
||||
(dissoc :gradient)))))
|
||||
(let [color (-> color
|
||||
(assoc :color new-value)
|
||||
(dissoc :gradient))]
|
||||
(st/emit! (dwl/add-recent-color color)
|
||||
(on-change color)))))
|
||||
|
||||
handle-opacity-change
|
||||
(mf/use-fn
|
||||
(mf/deps color on-change)
|
||||
(fn [value]
|
||||
(on-change (assoc color
|
||||
:opacity (/ value 100)
|
||||
:id nil
|
||||
:file-id nil))))
|
||||
(let [color (assoc color
|
||||
:opacity (/ value 100)
|
||||
:id nil
|
||||
:file-id nil)]
|
||||
(st/emit! (dwl/add-recent-color color)
|
||||
(on-change color)))))
|
||||
|
||||
handle-click-color
|
||||
(mf/use-fn
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.repo :as rp]
|
||||
[app.util.http :as http]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.import.parser :as cip]
|
||||
[app.util.json :as json]
|
||||
[app.util.webapi :as wapi]
|
||||
|
@ -584,7 +585,8 @@
|
|||
sg (areduce u8 i ret "" (str ret (if (zero? i) "" " ") (.toString (aget u8 i) 8)))]
|
||||
(case sg
|
||||
"120 113 3 4" "application/zip"
|
||||
"application/octet-stream")))
|
||||
"1 13 32 206" "application/octet-stream"
|
||||
"other")))
|
||||
|
||||
(defmethod impl/handler :analyze-import
|
||||
[{:keys [files]}]
|
||||
|
@ -618,8 +620,15 @@
|
|||
:file-id file-id
|
||||
:files {file-id {:name (:name file)}}
|
||||
:status :ready}
|
||||
:type "application/octet-stream"})))))
|
||||
(rx/catch #(rx/of {:uri (:uri file) :error (.-message %)}))))))))
|
||||
:type "application/octet-stream"}))))
|
||||
(->> st
|
||||
(rx/filter (fn [data] (= "other" (:type data))))
|
||||
(rx/map (fn [_]
|
||||
{:uri (:uri file)
|
||||
:error (tr "dashboard.import.analyze-error")}))))
|
||||
(rx/catch (fn [data]
|
||||
(let [error (or (.-message data) (tr "dashboard.import.analyze-error"))]
|
||||
(rx/of {:uri (:uri file) :error error}))))))))))
|
||||
|
||||
(defmethod impl/handler :import-files
|
||||
[{:keys [project-id files components-v2]}]
|
||||
|
|
Loading…
Add table
Reference in a new issue