mirror of
https://github.com/penpot/penpot.git
synced 2025-03-25 06:01:46 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
045e83e871
16 changed files with 165 additions and 28 deletions
|
@ -59,6 +59,11 @@
|
|||
- Export shapes that are rotated act a bit strange when reimported [Taiga #7585](https://tree.taiga.io/project/penpot/issue/7585)
|
||||
- Penpot crashes when a new colorpicker is created while uploading an image to another instance [Taiga #8119](https://tree.taiga.io/project/penpot/issue/8119)
|
||||
- Removing Underline and Strikethrough Affects the Previous Text Object [Taiga #8103](https://tree.taiga.io/project/penpot/issue/8103)
|
||||
- Color library loses association with shapes when exporting/importing the document [Taiga #8132](https://tree.taiga.io/project/penpot/issue/8132)
|
||||
- Fix can't collapse groups when searching in the assets tab [Taiga #8125](https://tree.taiga.io/project/penpot/issue/8125)
|
||||
- Fix 'Detach instance' shortcut is not working [Taiga #8102](https://tree.taiga.io/project/penpot/issue/8102)
|
||||
- Fix import file message does not detect 0 as error [Taiga #6824](https://tree.taiga.io/project/penpot/issue/6824)
|
||||
|
||||
|
||||
## 2.0.3
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
(let [result (handler)]
|
||||
(events/tap :end result))
|
||||
(catch Throwable cause
|
||||
(l/err :hint "unexpected error on processing sse response"
|
||||
:cause cause)
|
||||
(events/tap :error (errors/handle' cause request)))
|
||||
(finally
|
||||
(sp/close! events/*channel*)
|
||||
|
|
|
@ -30,14 +30,12 @@
|
|||
|
||||
;; --- Command: export-binfile
|
||||
|
||||
(def ^:private
|
||||
schema:export-binfile
|
||||
(sm/define
|
||||
[:map {:title "export-binfile"}
|
||||
[:name :string]
|
||||
[:file-id ::sm/uuid]
|
||||
[:include-libraries :boolean]
|
||||
[:embed-assets :boolean]]))
|
||||
(def ^:private schema:export-binfile
|
||||
[:map {:title "export-binfile"}
|
||||
[:name :string]
|
||||
[:file-id ::sm/uuid]
|
||||
[:include-libraries :boolean]
|
||||
[:embed-assets :boolean]])
|
||||
|
||||
(sv/defmethod ::export-binfile
|
||||
"Export a penpot file in a binary format."
|
||||
|
@ -76,13 +74,11 @@
|
|||
{:id project-id})
|
||||
result))
|
||||
|
||||
(def ^:private
|
||||
schema:import-binfile
|
||||
(sm/define
|
||||
[:map {:title "import-binfile"}
|
||||
[:name :string]
|
||||
[:project-id ::sm/uuid]
|
||||
[:file ::media/upload]]))
|
||||
(def ^:private schema:import-binfile
|
||||
[:map {:title "import-binfile"}
|
||||
[:name :string]
|
||||
[:project-id ::sm/uuid]
|
||||
[:file ::media/upload]])
|
||||
|
||||
(sv/defmethod ::import-binfile
|
||||
"Import a penpot file in a binary format."
|
||||
|
|
|
@ -582,6 +582,38 @@
|
|||
:deleted-at (dt/now)
|
||||
:id file-id})))))
|
||||
|
||||
|
||||
(defn process-deleted-teams-cascade
|
||||
[]
|
||||
(->> (db/exec! main/system ["select id, deleted_at from team where deleted_at is not null"])
|
||||
(run! (fn [{:keys [id deleted-at]}]
|
||||
(wrk/invoke! (-> main/system
|
||||
(assoc ::wrk/task :delete-object)
|
||||
(assoc ::wrk/params {:object :team
|
||||
:deleted-at deleted-at
|
||||
:id id})))))))
|
||||
|
||||
|
||||
(defn process-deleted-projects-cascade
|
||||
[]
|
||||
(->> (db/exec! main/system ["select id, deleted_at from project where deleted_at is not null"])
|
||||
(run! (fn [{:keys [id deleted-at]}]
|
||||
(wrk/invoke! (-> main/system
|
||||
(assoc ::wrk/task :delete-object)
|
||||
(assoc ::wrk/params {:object :project
|
||||
:deleted-at deleted-at
|
||||
:id id})))))))
|
||||
|
||||
(defn process-deleted-files-cascade
|
||||
[]
|
||||
(->> (db/exec! main/system ["select id, deleted_at from file where deleted_at is not null"])
|
||||
(run! (fn [{:keys [id deleted-at]}]
|
||||
(wrk/invoke! (-> main/system
|
||||
(assoc ::wrk/task :delete-object)
|
||||
(assoc ::wrk/params {:object :file
|
||||
:deleted-at deleted-at
|
||||
:id id})))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; MISC
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
(ns app.common.files.defaults)
|
||||
|
||||
(def version 49)
|
||||
(def version 50)
|
||||
|
|
|
@ -957,6 +957,54 @@
|
|||
|
||||
(update data :pages-index update-vals update-page)))
|
||||
|
||||
(defn migrate-up-50
|
||||
"This migration mainly fixes paths with curve-to segments
|
||||
without :c1x :c1y :c2x :c2y properties. Additionally, we found a
|
||||
case where the params instead to be plain hash-map, is a points
|
||||
instance. This migration normalizes all params to plain map."
|
||||
|
||||
[data]
|
||||
(let [update-segment
|
||||
(fn [{:keys [command params] :as segment}]
|
||||
(let [params (into {} params)
|
||||
params (cond
|
||||
(= :curve-to command)
|
||||
(let [x (get params :x)
|
||||
y (get params :y)]
|
||||
|
||||
(cond-> params
|
||||
(nil? (:c1x params))
|
||||
(assoc :c1x x)
|
||||
|
||||
(nil? (:c1y params))
|
||||
(assoc :c1y y)
|
||||
|
||||
(nil? (:c2x params))
|
||||
(assoc :c2x x)
|
||||
|
||||
(nil? (:c2y params))
|
||||
(assoc :c2y y)))
|
||||
|
||||
:else
|
||||
params)]
|
||||
|
||||
(assoc segment :params params)))
|
||||
|
||||
update-shape
|
||||
(fn [shape]
|
||||
(if (cfh/path-shape? shape)
|
||||
(d/update-when shape :content (fn [content] (mapv update-segment content)))
|
||||
shape))
|
||||
|
||||
update-container
|
||||
(fn [page]
|
||||
(d/update-when page :objects update-vals update-shape))]
|
||||
|
||||
(-> data
|
||||
(update :pages-index update-vals update-container)
|
||||
(update :components update-vals update-container))))
|
||||
|
||||
|
||||
(def migrations
|
||||
"A vector of all applicable migrations"
|
||||
[{:id 2 :migrate-up migrate-up-2}
|
||||
|
@ -997,4 +1045,5 @@
|
|||
{:id 46 :migrate-up migrate-up-46}
|
||||
{:id 47 :migrate-up migrate-up-47}
|
||||
{:id 48 :migrate-up migrate-up-48}
|
||||
{:id 49 :migrate-up migrate-up-49}])
|
||||
{:id 49 :migrate-up migrate-up-49}
|
||||
{:id 50 :migrate-up migrate-up-50}])
|
||||
|
|
|
@ -1046,7 +1046,6 @@
|
|||
(str/includes? data "<!DOCTYPE")
|
||||
(str/replace #"<\!DOCTYPE[^>]*>" "")))
|
||||
|
||||
|
||||
(defn parse
|
||||
[text]
|
||||
#?(:cljs (tubax/xml->clj text)
|
||||
|
|
|
@ -1124,6 +1124,14 @@
|
|||
(update [_ state]
|
||||
(assoc-in state [:workspace-assets :open-status file-id section] open?))))
|
||||
|
||||
(defn clear-assets-section-open
|
||||
[]
|
||||
(ptk/reify ::clear-assets-section-open
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:workspace-assets :open-status] {}))))
|
||||
|
||||
|
||||
(defn set-assets-group-open
|
||||
[file-id section path open?]
|
||||
(ptk/reify ::set-assets-group-open
|
||||
|
|
|
@ -609,9 +609,13 @@
|
|||
(assoc :type :color))))))))
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
;; Type can be null, because the colorpicker can be closed while a color image finish its upload
|
||||
(when (and add-recent? (some? (:type state)))
|
||||
(let [formated-color (get-color-from-colorpicker-state (:colorpicker state))]
|
||||
(let [selected-type (-> state
|
||||
:colorpicker
|
||||
:type)
|
||||
formated-color (get-color-from-colorpicker-state (:colorpicker state))
|
||||
;; Type is set to color on closing the colorpicker, but we can can close it while still uploading an image fill
|
||||
ignore-color? (and (= selected-type :color) (nil? (:color formated-color)))]
|
||||
(when (and add-recent? (not ignore-color?))
|
||||
(rx/of (dwl/add-recent-color formated-color)))))))
|
||||
|
||||
(defn update-colorpicker-gradient
|
||||
|
|
|
@ -615,7 +615,6 @@
|
|||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
file (wsh/get-local-file state)
|
||||
container (cfh/get-container file :page page-id)
|
||||
libraries (wsh/get-libraries state)
|
||||
selected (->> state
|
||||
(wsh/lookup-selected)
|
||||
|
@ -627,7 +626,7 @@
|
|||
changes (when can-detach?
|
||||
(reduce
|
||||
(fn [changes id]
|
||||
(cll/generate-detach-instance changes container libraries id))
|
||||
(cll/generate-detach-component changes id file page-id libraries))
|
||||
(pcb/empty-changes it)
|
||||
selected))]
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@
|
|||
|
||||
:else
|
||||
[:& context-notification
|
||||
{:type :success
|
||||
{:type (if (zero? success-num) :warning :success)
|
||||
:content (tr "dashboard.import.import-message" (i18n/c success-num))}]))
|
||||
|
||||
(for [entry entries]
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.assets :as dwa]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.context-menu-a11y :refer [context-menu-a11y]]
|
||||
[app.main.ui.components.search-bar :refer [search-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
|
@ -103,6 +105,7 @@
|
|||
on-search-term-change
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(st/emit! (dw/clear-assets-section-open))
|
||||
(swap! filters* assoc :term event)))
|
||||
|
||||
on-section-filter-change
|
||||
|
@ -112,6 +115,7 @@
|
|||
(dom/get-value))
|
||||
(as-> (dom/get-current-target event) $
|
||||
(dom/get-attribute $ "data-testid")))]
|
||||
(st/emit! (dw/clear-assets-section-open))
|
||||
(swap! filters* assoc :section value :open-menu false))))
|
||||
|
||||
show-libraries-dialog
|
||||
|
|
|
@ -192,8 +192,10 @@
|
|||
on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-context-menu
|
||||
selected-full local]}]
|
||||
|
||||
(let [group-open? (or ^boolean force-open?
|
||||
^boolean (get open-groups prefix (if (= prefix "") true false)))
|
||||
(let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that
|
||||
false
|
||||
(or ^boolean force-open?
|
||||
^boolean (get open-groups prefix (if (= prefix "") true false))))
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
|
|
|
@ -318,6 +318,7 @@
|
|||
(and has-term?
|
||||
(some pos? (map count [filtered-components filtered-colors filtered-media filtered-typographies]))
|
||||
(some #(> 60 (count %)) [filtered-components filtered-colors filtered-media filtered-typographies]))))
|
||||
|
||||
(mf/defc file-library
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file local? default-open? filters]}]
|
||||
|
@ -333,8 +334,10 @@
|
|||
open-status (mf/deref open-status-ref)
|
||||
force-open-lib? (force-lib-open? file-id filters)
|
||||
|
||||
open? (or force-open-lib?
|
||||
(d/nilv (:library open-status) default-open?))
|
||||
open? (if (false? (:library open-status)) ;; if the user has closed it specifically, respect that
|
||||
false
|
||||
(or force-open-lib?
|
||||
(d/nilv (:library open-status) default-open?)))
|
||||
|
||||
unselect-all
|
||||
(mf/use-fn
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
[app.common.svg.path.subpath :refer [pt=]]
|
||||
[app.util.array :as arr]))
|
||||
|
||||
;; TODO: move to common
|
||||
|
||||
(def path-precision 3)
|
||||
|
||||
(defn- join-params
|
||||
|
|
|
@ -223,6 +223,32 @@
|
|||
(uuid? (get item :typography-ref-file))
|
||||
(d/update-when :typography-ref-file resolve)))))))
|
||||
|
||||
(defn resolve-fills-content
|
||||
[fills context]
|
||||
(let [resolve (:resolve context)]
|
||||
(->> fills
|
||||
(mapv
|
||||
(fn [fill]
|
||||
(cond-> fill
|
||||
(uuid? (get fill :fill-color-ref-id))
|
||||
(d/update-when :fill-color-ref-id resolve)
|
||||
|
||||
(uuid? (get fill :fill-color-ref-file))
|
||||
(d/update-when :fill-color-ref-file resolve)))))))
|
||||
|
||||
(defn resolve-strokes-content
|
||||
[fills context]
|
||||
(let [resolve (:resolve context)]
|
||||
(->> fills
|
||||
(mapv
|
||||
(fn [fill]
|
||||
(cond-> fill
|
||||
(uuid? (get fill :stroke-color-ref-id))
|
||||
(d/update-when :stroke-color-ref-id resolve)
|
||||
|
||||
(uuid? (get fill :stroke-color-ref-file))
|
||||
(d/update-when :stroke-color-ref-file resolve)))))))
|
||||
|
||||
(defn resolve-data-ids
|
||||
[data type context]
|
||||
(let [resolve (:resolve context)]
|
||||
|
@ -238,6 +264,12 @@
|
|||
(cond-> (= type :text)
|
||||
(d/update-when :content resolve-text-content context))
|
||||
|
||||
(cond-> (:fills data)
|
||||
(d/update-when :fills resolve-fills-content context))
|
||||
|
||||
(cond-> (:strokes data)
|
||||
(d/update-when :strokes resolve-strokes-content context))
|
||||
|
||||
(cond-> (and (= type :frame) (= :grid (:layout data)))
|
||||
(update
|
||||
:layout-grid-cells
|
||||
|
|
Loading…
Add table
Reference in a new issue