mirror of
https://github.com/penpot/penpot.git
synced 2025-07-02 14:57:17 +02:00
Merge remote-tracking branch 'origin/main' into develop
This commit is contained in:
commit
6d5276c0c6
10 changed files with 100 additions and 83 deletions
|
@ -11,6 +11,13 @@
|
||||||
### :boom: Breaking changes
|
### :boom: Breaking changes
|
||||||
### :heart: Community contributions by (Thank you!)
|
### :heart: Community contributions by (Thank you!)
|
||||||
|
|
||||||
|
## 1.5.2-alpha
|
||||||
|
|
||||||
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
|
- Fix problem with `close-path` command [#917](https://github.com/penpot/penpot/issues/917)
|
||||||
|
- Fix wrong query for obtain the profile default project-id
|
||||||
|
- Fix problems with empty paths and shortcuts [#923](https://github.com/penpot/penpot/issues/923)
|
||||||
|
|
||||||
## 1.5.1-alpha
|
## 1.5.1-alpha
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,7 @@
|
||||||
"- detail: " (cfg/get :public-uri) "/dbg/error-by-id/" id "\n"
|
"- detail: " (cfg/get :public-uri) "/dbg/error-by-id/" id "\n"
|
||||||
"- profile-id: `" (:profile-id cdata) "`\n"
|
"- profile-id: `" (:profile-id cdata) "`\n"
|
||||||
"- host: `" host "`\n"
|
"- host: `" host "`\n"
|
||||||
"- version: `" version "`\n"
|
"- version: `" version "`\n")
|
||||||
(when error
|
|
||||||
(str "```\n" (:trace error) "\n```")))
|
|
||||||
rsp (http/send! {:uri uri
|
rsp (http/send! {:uri uri
|
||||||
:method :post
|
:method :post
|
||||||
:headers {"content-type" "application/json"}
|
:headers {"content-type" "application/json"}
|
||||||
|
|
|
@ -41,29 +41,27 @@
|
||||||
{:id uuid/zero
|
{:id uuid/zero
|
||||||
:fullname "Anonymous User"}))
|
:fullname "Anonymous User"}))
|
||||||
|
|
||||||
;; NOTE: this query make the assumption that union all preserves the
|
(def ^:private sql:default-profile-team
|
||||||
;; order so the first id will always be the team id and the second the
|
"select t.id, name
|
||||||
;; project_id; this is a postgresql behavior because UNION ALL works
|
|
||||||
;; like APPEND operation.
|
|
||||||
|
|
||||||
(def ^:private sql:default-team-and-project
|
|
||||||
"select t.id
|
|
||||||
from team as t
|
from team as t
|
||||||
inner join team_profile_rel as tp on (tp.team_id = t.id)
|
inner join team_profile_rel as tp on (tp.team_id = t.id)
|
||||||
where tp.profile_id = ?
|
where tp.profile_id = ?
|
||||||
and tp.is_owner is true
|
and tp.is_owner is true
|
||||||
and t.is_default is true
|
and t.is_default is true")
|
||||||
union all
|
|
||||||
select p.id
|
(def ^:private sql:default-profile-project
|
||||||
|
"select p.id, name
|
||||||
from project as p
|
from project as p
|
||||||
inner join project_profile_rel as tp on (tp.project_id = p.id)
|
inner join project_profile_rel as tp on (tp.project_id = p.id)
|
||||||
where tp.profile_id = ?
|
where tp.profile_id = ?
|
||||||
and tp.is_owner is true
|
and tp.is_owner is true
|
||||||
and p.is_default is true")
|
and p.is_default is true
|
||||||
|
and p.team_id = ?")
|
||||||
|
|
||||||
(defn retrieve-additional-data
|
(defn retrieve-additional-data
|
||||||
[conn id]
|
[conn id]
|
||||||
(let [[team project] (db/exec! conn [sql:default-team-and-project id id])]
|
(let [team (db/exec-one! conn [sql:default-profile-team id])
|
||||||
|
project (db/exec-one! conn [sql:default-profile-project id (:id team)])]
|
||||||
{:default-team-id (:id team)
|
{:default-team-id (:id team)
|
||||||
:default-project-id (:id project)}))
|
:default-project-id (:id project)}))
|
||||||
|
|
||||||
|
|
|
@ -240,10 +240,13 @@
|
||||||
(ptk/reify ::finalize-page
|
(ptk/reify ::finalize-page
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [local (:workspace-local state)]
|
(let [local (-> (:workspace-local state)
|
||||||
|
(dissoc :edition)
|
||||||
|
(dissoc :edit-path)
|
||||||
|
(dissoc :selected))]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc-in [:workspace-cache page-id] local)
|
(assoc-in [:workspace-cache page-id] local)
|
||||||
(dissoc :current-page-id :workspace-local :trimmed-page))))))
|
(dissoc :current-page-id :workspace-local :trimmed-page :workspace-drawing))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Workspace Page CRUD
|
;; Workspace Page CRUD
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.changes :as dch]
|
[app.main.data.workspace.changes :as dch]
|
||||||
[app.main.data.workspace.path.changes :as changes]
|
[app.main.data.workspace.path.changes :as changes]
|
||||||
[app.main.data.workspace.path.common :as common]
|
[app.main.data.workspace.path.common :as common]
|
||||||
|
@ -63,9 +64,12 @@
|
||||||
|
|
||||||
[rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)]
|
[rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)]
|
||||||
|
|
||||||
(rx/of (dch/commit-changes rch uch {:commit-local? true})
|
(if (empty? new-content)
|
||||||
(selection/update-selection point-change)
|
(rx/of (dch/commit-changes rch uch {:commit-local? true})
|
||||||
(fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers :moving-nodes :moving-handler)))))))
|
dwc/clear-edition-mode)
|
||||||
|
(rx/of (dch/commit-changes rch uch {:commit-local? true})
|
||||||
|
(selection/update-selection point-change)
|
||||||
|
(fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers :moving-nodes :moving-handler))))))))
|
||||||
|
|
||||||
(defn modify-content-point
|
(defn modify-content-point
|
||||||
[content {dx :x dy :y} modifiers point]
|
[content {dx :x dy :y} modifiers point]
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
(defn end-path-event? [{:keys [type shift] :as event}]
|
(defn end-path-event? [{:keys [type shift] :as event}]
|
||||||
(or (= (ptk/type event) ::common/finish-path)
|
(or (= (ptk/type event) ::common/finish-path)
|
||||||
(= (ptk/type event) :esc-pressed)
|
(= (ptk/type event) :esc-pressed)
|
||||||
|
(= :app.main.data.workspace.common/clear-edition-mode (ptk/type event))
|
||||||
|
(= :app.main.data.workspace/finalize-page (ptk/type event))
|
||||||
(= event :interrupt) ;; ESC
|
(= event :interrupt) ;; ESC
|
||||||
(and (ms/mouse-double-click? event))))
|
(and (ms/mouse-double-click? event))))
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,9 @@
|
||||||
content (get-in state (st/get-path state :content))
|
content (get-in state (st/get-path state :content))
|
||||||
selected-point? #(gsh/has-point-rect? selrect %)
|
selected-point? #(gsh/has-point-rect? selrect %)
|
||||||
selected-points (get-in state [:workspace-local :edit-path id :selected-points])
|
selected-points (get-in state [:workspace-local :edit-path id :selected-points])
|
||||||
|
|
||||||
positions (into (if shift? selected-points #{})
|
positions (into (if shift? selected-points #{})
|
||||||
(comp (map (comp gpt/point :params))
|
(comp (filter #(not (= (:command %) :close-path)))
|
||||||
|
(map (comp gpt/point :params))
|
||||||
(filter selected-point?))
|
(filter selected-point?))
|
||||||
content)]
|
content)]
|
||||||
(cond-> state
|
(cond-> state
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.main.data.workspace.changes :as dch]
|
[app.main.data.workspace.changes :as dch]
|
||||||
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.path.changes :as changes]
|
[app.main.data.workspace.path.changes :as changes]
|
||||||
[app.main.data.workspace.path.common :as common]
|
[app.main.data.workspace.path.common :as common]
|
||||||
[app.main.data.workspace.path.state :as st]
|
[app.main.data.workspace.path.state :as st]
|
||||||
|
@ -29,12 +30,16 @@
|
||||||
id (st/get-path-id state)
|
id (st/get-path-id state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
shape (get-in state (st/get-path state))
|
shape (get-in state (st/get-path state))
|
||||||
|
|
||||||
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
|
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
|
||||||
points (or points selected-points)
|
points (or points selected-points)]
|
||||||
new-content (-> (tool-fn (:content shape) points)
|
(when-not (empty? points)
|
||||||
(ups/close-subpaths))
|
(let [new-content (-> (tool-fn (:content shape) points)
|
||||||
[rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)]
|
(ups/close-subpaths))
|
||||||
(rx/of (dch/commit-changes rch uch {:commit-local? true})))))))
|
[rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)]
|
||||||
|
(rx/of (dch/commit-changes rch uch {:commit-local? true})
|
||||||
|
(when (empty? new-content)
|
||||||
|
dwc/clear-edition-mode)))))))))
|
||||||
|
|
||||||
(defn make-corner
|
(defn make-corner
|
||||||
([]
|
([]
|
||||||
|
|
|
@ -124,7 +124,8 @@
|
||||||
dissoc :undo-lock :undo-stack)))))
|
dissoc :undo-lock :undo-stack)))))
|
||||||
|
|
||||||
(defn- stop-undo? [event]
|
(defn- stop-undo? [event]
|
||||||
(= :app.main.data.workspace.common/clear-edition-mode (ptk/type event)))
|
(or (= :app.main.data.workspace.common/clear-edition-mode (ptk/type event))
|
||||||
|
(= :app.main.data.workspace/finalize-page (ptk/type event))))
|
||||||
|
|
||||||
(def path-content-ref
|
(def path-content-ref
|
||||||
(letfn [(selector [state]
|
(letfn [(selector [state]
|
||||||
|
|
|
@ -8,14 +8,10 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes.path :as gshp]
|
|
||||||
[app.util.svg :as usvg]
|
|
||||||
[cuerdas.core :as str]
|
|
||||||
[clojure.set :as set]
|
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.util.path.commands :as upc]
|
[app.util.path.commands :as upc]
|
||||||
[app.util.path.geom :as upg]
|
[app.util.path.geom :as upg]
|
||||||
))
|
[clojure.set :as set]))
|
||||||
|
|
||||||
(defn remove-line-curves
|
(defn remove-line-curves
|
||||||
"Remove all curves that have both handlers in the same position that the
|
"Remove all curves that have both handlers in the same position that the
|
||||||
|
@ -235,70 +231,73 @@
|
||||||
to keep everything consistent"
|
to keep everything consistent"
|
||||||
[content points]
|
[content points]
|
||||||
|
|
||||||
(let [content (d/with-prev content)]
|
(if (empty? points)
|
||||||
|
content
|
||||||
|
|
||||||
(loop [result []
|
(let [content (d/with-prev content)]
|
||||||
last-handler nil
|
|
||||||
[cur-cmd prev-cmd] (first content)
|
|
||||||
content (rest content)]
|
|
||||||
|
|
||||||
(if (nil? cur-cmd)
|
(loop [result []
|
||||||
;; The result with be an array of arrays were every entry is a subpath
|
last-handler nil
|
||||||
(->> result
|
[cur-cmd prev-cmd] (first content)
|
||||||
;; remove empty and only 1 node subpaths
|
content (rest content)]
|
||||||
(filter #(> (count %) 1))
|
|
||||||
;; flatten array-of-arrays plain array
|
|
||||||
(flatten)
|
|
||||||
(into []))
|
|
||||||
|
|
||||||
(let [move? (= :move-to (:command cur-cmd))
|
(if (nil? cur-cmd)
|
||||||
curve? (= :curve-to (:command cur-cmd))
|
;; The result with be an array of arrays were every entry is a subpath
|
||||||
|
(->> result
|
||||||
|
;; remove empty and only 1 node subpaths
|
||||||
|
(filter #(> (count %) 1))
|
||||||
|
;; flatten array-of-arrays plain array
|
||||||
|
(flatten)
|
||||||
|
(into []))
|
||||||
|
|
||||||
;; When the old command was a move we start a subpath
|
(let [move? (= :move-to (:command cur-cmd))
|
||||||
result (if move? (conj result []) result)
|
curve? (= :curve-to (:command cur-cmd))
|
||||||
|
|
||||||
subpath (peek result)
|
;; When the old command was a move we start a subpath
|
||||||
|
result (if move? (conj result []) result)
|
||||||
|
|
||||||
point (upc/command->point cur-cmd)
|
subpath (peek result)
|
||||||
|
|
||||||
old-prev-point (upc/command->point prev-cmd)
|
|
||||||
new-prev-point (upc/command->point (peek subpath))
|
|
||||||
|
|
||||||
remove? (contains? points point)
|
point (upc/command->point cur-cmd)
|
||||||
|
|
||||||
|
old-prev-point (upc/command->point prev-cmd)
|
||||||
;; We store the first handler for the first curve to be removed to
|
new-prev-point (upc/command->point (peek subpath))
|
||||||
;; use it for the first handler of the regenerated path
|
|
||||||
cur-handler (cond
|
|
||||||
(and (not last-handler) remove? curve?)
|
|
||||||
(select-keys (:params cur-cmd) [:c1x :c1y])
|
|
||||||
|
|
||||||
(not remove?)
|
remove? (contains? points point)
|
||||||
nil
|
|
||||||
|
|
||||||
:else
|
|
||||||
last-handler)
|
|
||||||
|
|
||||||
cur-cmd (cond-> cur-cmd
|
;; We store the first handler for the first curve to be removed to
|
||||||
;; If we're starting a subpath and it's not a move make it a move
|
;; use it for the first handler of the regenerated path
|
||||||
(and (not move?) (empty? subpath))
|
cur-handler (cond
|
||||||
(assoc :command :move-to
|
(and (not last-handler) remove? curve?)
|
||||||
:params (select-keys (:params cur-cmd) [:x :y]))
|
(select-keys (:params cur-cmd) [:c1x :c1y])
|
||||||
|
|
||||||
;; If have a curve the first handler will be relative to the previous
|
(not remove?)
|
||||||
;; point. We change the handler to the new previous point
|
nil
|
||||||
(and curve? (not (empty? subpath)) (not= old-prev-point new-prev-point))
|
|
||||||
(update :params merge last-handler))
|
|
||||||
|
|
||||||
head-idx (dec (count result))
|
:else
|
||||||
|
last-handler)
|
||||||
|
|
||||||
result (cond-> result
|
cur-cmd (cond-> cur-cmd
|
||||||
(not remove?)
|
;; If we're starting a subpath and it's not a move make it a move
|
||||||
(update head-idx conj cur-cmd))]
|
(and (not move?) (empty? subpath))
|
||||||
(recur result
|
(assoc :command :move-to
|
||||||
cur-handler
|
:params (select-keys (:params cur-cmd) [:x :y]))
|
||||||
(first content)
|
|
||||||
(rest content)))))))
|
;; If have a curve the first handler will be relative to the previous
|
||||||
|
;; point. We change the handler to the new previous point
|
||||||
|
(and curve? (not (empty? subpath)) (not= old-prev-point new-prev-point))
|
||||||
|
(update :params merge last-handler))
|
||||||
|
|
||||||
|
head-idx (dec (count result))
|
||||||
|
|
||||||
|
result (cond-> result
|
||||||
|
(not remove?)
|
||||||
|
(update head-idx conj cur-cmd))]
|
||||||
|
(recur result
|
||||||
|
cur-handler
|
||||||
|
(first content)
|
||||||
|
(rest content))))))))
|
||||||
|
|
||||||
(defn join-nodes
|
(defn join-nodes
|
||||||
"Creates new segments between points that weren't previously"
|
"Creates new segments between points that weren't previously"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue