mirror of
https://github.com/penpot/penpot.git
synced 2026-02-19 07:35:29 -05:00
Compare commits
14 Commits
1.5.0-alph
...
1.5.2-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4405bd95f9 | ||
|
|
3bb3fcfbda | ||
|
|
5e0101e424 | ||
|
|
2c96ecac87 | ||
|
|
9fcddc37f6 | ||
|
|
39066bfee3 | ||
|
|
2d75efbace | ||
|
|
8a8403834f | ||
|
|
e98b88f673 | ||
|
|
d2f8d4a306 | ||
|
|
2138530f3e | ||
|
|
94d94684c8 | ||
|
|
5352918ff8 | ||
|
|
57b6807333 |
17
CHANGES.md
17
CHANGES.md
@@ -8,6 +8,23 @@
|
||||
### :boom: Breaking changes
|
||||
### :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
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix issue with bitmap image clipboard.
|
||||
- Fix issue when removing all path points.
|
||||
- Increase default team invitation token expiration to 48h.
|
||||
- Fix wrong error message when an expired token is used.
|
||||
|
||||
|
||||
## 1.5.0-alpha
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
:opt-un [::uri]))
|
||||
|
||||
(defmethod ig/init-key ::reporter
|
||||
[_ {:keys [receiver] :as cfg}]
|
||||
(l/info :msg "intializing mattermost error reporter")
|
||||
[_ {:keys [receiver uri] :as cfg}]
|
||||
(l/info :msg "intializing mattermost error reporter" :uri uri)
|
||||
(let [output (a/chan (a/sliding-buffer 128)
|
||||
(filter #(= (:level %) "error")))]
|
||||
(receiver :sub output)
|
||||
@@ -63,10 +63,9 @@
|
||||
(let [uri (:uri cfg)
|
||||
text (str "Unhandled exception (@channel):\n"
|
||||
"- detail: " (cfg/get :public-uri) "/dbg/error-by-id/" id "\n"
|
||||
"- profile-id: `" (:profile-id cdata) "`\n"
|
||||
"- host: `" host "`\n"
|
||||
"- version: `" version "`\n"
|
||||
(when error
|
||||
(str "```\n" (:trace error) "\n```")))
|
||||
"- version: `" version "`\n")
|
||||
rsp (http/send! {:uri uri
|
||||
:method :post
|
||||
:headers {"content-type" "application/json"}
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
team (db/get-by-id conn :team team-id)
|
||||
itoken (tokens :generate
|
||||
{:iss :team-invitation
|
||||
:exp (dt/in-future "6h")
|
||||
:exp (dt/in-future "48h")
|
||||
:profile-id (:id profile)
|
||||
:role role
|
||||
:team-id team-id
|
||||
|
||||
@@ -41,29 +41,27 @@
|
||||
{:id uuid/zero
|
||||
:fullname "Anonymous User"}))
|
||||
|
||||
;; NOTE: this query make the assumption that union all preserves the
|
||||
;; order so the first id will always be the team id and the second the
|
||||
;; project_id; this is a postgresql behavior because UNION ALL works
|
||||
;; like APPEND operation.
|
||||
|
||||
(def ^:private sql:default-team-and-project
|
||||
"select t.id
|
||||
(def ^:private sql:default-profile-team
|
||||
"select t.id, name
|
||||
from team as t
|
||||
inner join team_profile_rel as tp on (tp.team_id = t.id)
|
||||
where tp.profile_id = ?
|
||||
and tp.is_owner is true
|
||||
and t.is_default is true
|
||||
union all
|
||||
select p.id
|
||||
and t.is_default is true")
|
||||
|
||||
(def ^:private sql:default-profile-project
|
||||
"select p.id, name
|
||||
from project as p
|
||||
inner join project_profile_rel as tp on (tp.project_id = p.id)
|
||||
where tp.profile_id = ?
|
||||
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
|
||||
[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-project-id (:id project)}))
|
||||
|
||||
|
||||
@@ -240,10 +240,13 @@
|
||||
(ptk/reify ::finalize-page
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [local (:workspace-local state)]
|
||||
(let [local (-> (:workspace-local state)
|
||||
(dissoc :edition)
|
||||
(dissoc :edit-path)
|
||||
(dissoc :selected))]
|
||||
(-> state
|
||||
(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
|
||||
@@ -1278,7 +1281,9 @@
|
||||
(let [obj (maybe-translate obj objects selected)]
|
||||
(if (= type :image)
|
||||
(let [url (cfg/resolve-file-media (:metadata obj))]
|
||||
(->> (http/send! {:method :get :uri url})
|
||||
(->> (http/send! {:method :get
|
||||
:uri url
|
||||
:response-type :blob})
|
||||
(rx/map :body)
|
||||
(rx/mapcat wapi/read-file-as-data-url)
|
||||
(rx/map #(assoc obj ::data %))
|
||||
|
||||
@@ -6,42 +6,67 @@
|
||||
|
||||
(ns app.main.data.workspace.path.changes
|
||||
(:require
|
||||
[app.common.pages :as cp]
|
||||
[app.common.spec :as us]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.path.helpers :as helpers]
|
||||
[app.main.data.workspace.path.spec :as spec]
|
||||
[app.main.data.workspace.path.state :as st]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
(defn generate-path-changes
|
||||
"Generates content changes and the undos for the content given"
|
||||
[page-id shape old-content new-content]
|
||||
[objects page-id shape old-content new-content]
|
||||
(us/verify ::spec/content old-content)
|
||||
(us/verify ::spec/content new-content)
|
||||
(let [shape-id (:id shape)
|
||||
frame-id (:frame-id shape)
|
||||
parent-id (:parent-id shape)
|
||||
parent-index (cp/position-on-parent shape-id objects)
|
||||
|
||||
[old-points old-selrect] (helpers/content->points+selrect shape old-content)
|
||||
[new-points new-selrect] (helpers/content->points+selrect shape new-content)
|
||||
|
||||
rch [{:type :mod-obj
|
||||
:id shape-id
|
||||
:page-id page-id
|
||||
:operations [{:type :set :attr :content :val new-content}
|
||||
{:type :set :attr :selrect :val new-selrect}
|
||||
{:type :set :attr :points :val new-points}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [shape-id]}]
|
||||
rch (if (empty? new-content)
|
||||
[{:type :del-obj
|
||||
:id shape-id
|
||||
:page-id page-id}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [shape-id]}]
|
||||
|
||||
uch [{:type :mod-obj
|
||||
:id shape-id
|
||||
:page-id page-id
|
||||
:operations [{:type :set :attr :content :val old-content}
|
||||
{:type :set :attr :selrect :val old-selrect}
|
||||
{:type :set :attr :points :val old-points}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [shape-id]}]]
|
||||
[{:type :mod-obj
|
||||
:id shape-id
|
||||
:page-id page-id
|
||||
:operations [{:type :set :attr :content :val new-content}
|
||||
{:type :set :attr :selrect :val new-selrect}
|
||||
{:type :set :attr :points :val new-points}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [shape-id]}])
|
||||
|
||||
uch (if (empty? new-content)
|
||||
[{:type :add-obj
|
||||
:id shape-id
|
||||
:obj shape
|
||||
:page-id page-id
|
||||
:frame-id frame-id
|
||||
:parent-id parent-id
|
||||
:index parent-index}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [shape-id]}]
|
||||
[{:type :mod-obj
|
||||
:id shape-id
|
||||
:page-id page-id
|
||||
:operations [{:type :set :attr :content :val old-content}
|
||||
{:type :set :attr :selrect :val old-selrect}
|
||||
{:type :set :attr :points :val old-points}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [shape-id]}])]
|
||||
[rch uch]))
|
||||
|
||||
(defn save-path-content
|
||||
@@ -61,12 +86,13 @@
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [id (get-in state [:workspace-local :edition])
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
id (get-in state [:workspace-local :edition])
|
||||
old-content (get-in state [:workspace-local :edit-path id :old-content])]
|
||||
(if (some? old-content)
|
||||
(let [shape (get-in state (st/get-path state))
|
||||
page-id (:current-page-id state)
|
||||
[rch uch] (generate-path-changes page-id shape old-content (:content shape))]
|
||||
[rch uch] (generate-path-changes objects page-id shape old-content (:content shape))]
|
||||
(rx/of (dch/commit-changes rch uch {:commit-local? true})))
|
||||
(rx/empty)))))))
|
||||
|
||||
|
||||
@@ -9,20 +9,22 @@
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.math :as mth]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.path.changes :as changes]
|
||||
[app.main.data.workspace.path.common :as common]
|
||||
[app.main.data.workspace.path.drawing :as drawing]
|
||||
[app.main.data.workspace.path.helpers :as helpers]
|
||||
[app.main.data.workspace.path.selection :as selection]
|
||||
[app.main.data.workspace.path.state :as st]
|
||||
[app.main.data.workspace.path.streams :as streams]
|
||||
[app.main.data.workspace.path.drawing :as drawing]
|
||||
[app.main.data.workspace.path.undo :as undo]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.path.commands :as upc]
|
||||
[app.util.path.geom :as upg]
|
||||
[app.util.path.tools :as upt]
|
||||
[app.util.path.subpaths :as ups]
|
||||
[app.util.path.tools :as upt]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
@@ -46,7 +48,9 @@
|
||||
(ptk/reify ::apply-content-modifiers
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [id (st/get-path-id state)
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
|
||||
id (st/get-path-id state)
|
||||
page-id (:current-page-id state)
|
||||
shape (get-in state (st/get-path state))
|
||||
content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers])
|
||||
@@ -58,11 +62,14 @@
|
||||
new-points (->> new-content upg/content->points)
|
||||
point-change (->> (map hash-map old-points new-points) (reduce merge))
|
||||
|
||||
[rch uch] (changes/generate-path-changes 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})
|
||||
(selection/update-selection point-change)
|
||||
(fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers :moving-nodes :moving-handler)))))))
|
||||
(if (empty? new-content)
|
||||
(rx/of (dch/commit-changes rch uch {:commit-local? true})
|
||||
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
|
||||
[content {dx :x dy :y} modifiers point]
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
(defn end-path-event? [{:keys [type shift] :as event}]
|
||||
(or (= (ptk/type event) ::common/finish-path)
|
||||
(= (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
|
||||
(and (ms/mouse-double-click? event))))
|
||||
|
||||
|
||||
@@ -51,9 +51,9 @@
|
||||
content (get-in state (st/get-path state :content))
|
||||
selected-point? #(gsh/has-point-rect? selrect %)
|
||||
selected-points (get-in state [:workspace-local :edit-path id :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?))
|
||||
content)]
|
||||
(cond-> state
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
|
||||
(ns app.main.data.workspace.path.tools
|
||||
(:require
|
||||
[app.common.geom.point :as gpt]
|
||||
[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.common :as common]
|
||||
[app.main.data.workspace.path.state :as st]
|
||||
[app.util.path.tools :as upt]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.util.path.subpaths :as ups]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.util.path.tools :as upt]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
@@ -24,15 +26,20 @@
|
||||
(ptk/reify ::process-path-tool
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [id (st/get-path-id state)
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
id (st/get-path-id state)
|
||||
page-id (:current-page-id state)
|
||||
shape (get-in state (st/get-path state))
|
||||
|
||||
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
|
||||
points (or points selected-points)
|
||||
new-content (-> (tool-fn (:content shape) points)
|
||||
(ups/close-subpaths))
|
||||
[rch uch] (changes/generate-path-changes page-id shape (:content shape) new-content)]
|
||||
(rx/of (dch/commit-changes rch uch {:commit-local? true})))))))
|
||||
points (or points selected-points)]
|
||||
(when-not (empty? points)
|
||||
(let [new-content (-> (tool-fn (:content shape) points)
|
||||
(ups/close-subpaths))
|
||||
[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
|
||||
([]
|
||||
|
||||
@@ -124,7 +124,8 @@
|
||||
dissoc :undo-lock :undo-stack)))))
|
||||
|
||||
(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
|
||||
(letfn [(selector [state]
|
||||
|
||||
@@ -74,18 +74,26 @@
|
||||
(rx/subs
|
||||
(fn [tdata]
|
||||
(handle-token tdata))
|
||||
(fn [error]
|
||||
(case (:code error)
|
||||
:email-already-exists
|
||||
(fn [{:keys [type code] :as error}]
|
||||
(cond
|
||||
(and (= :validation type)
|
||||
(= :invalid-token code)
|
||||
(= :token-expired (:reason error)))
|
||||
(let [msg (tr "errors.token-expired")]
|
||||
(ts/schedule 100 #(st/emit! (dm/error msg)))
|
||||
(st/emit! (rt/nav :auth-login)))
|
||||
|
||||
(= :email-already-exists code)
|
||||
(let [msg (tr "errors.email-already-exists")]
|
||||
(ts/schedule 100 #(st/emit! (dm/error msg)))
|
||||
(st/emit! (rt/nav :auth-login)))
|
||||
|
||||
:email-already-validated
|
||||
(= :email-already-validated code)
|
||||
(let [msg (tr "errors.email-already-validated")]
|
||||
(ts/schedule 100 #(st/emit! (dm/warn msg)))
|
||||
(st/emit! (rt/nav :auth-login)))
|
||||
|
||||
:else
|
||||
(let [msg (tr "errors.generic")]
|
||||
(ts/schedule 100 #(st/emit! (dm/error msg)))
|
||||
(st/emit! (rt/nav :auth-login)))))))))
|
||||
|
||||
@@ -85,7 +85,8 @@
|
||||
;; https://tree.taiga.io/project/uxboxproject/issue/1083
|
||||
;; {:value "viewer" :label (tr "labels.viewer")}]
|
||||
|
||||
initial (mf/use-memo (mf/deps team) (constantly {:team-id (:id team)}))
|
||||
initial (mf/use-memo (mf/deps team) (constantly {:team-id (:id team)
|
||||
:role "editor"}))
|
||||
form (fm/use-form :spec ::invite-member-form
|
||||
:initial initial)
|
||||
on-success
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
(ns app.main.ui.onboarding
|
||||
(:require
|
||||
[app.config :as cf]
|
||||
[app.common.spec :as us]
|
||||
[app.main.data.dashboard :as dd]
|
||||
[app.main.data.messages :as dm]
|
||||
@@ -38,9 +39,9 @@
|
||||
[:div.modal-right
|
||||
[:div.modal-title
|
||||
[:h2 "Welcome to Penpot!"]]
|
||||
[:span.release "Alpha version 1.0"]
|
||||
[:span.release "Alpha version " (:main @cf/version)]
|
||||
[:div.modal-content
|
||||
[:p "We are very happy to introduce you to the very first Alpha 1.0 release."]
|
||||
[:p "We are very happy to introduce you to the very first Alpha release."]
|
||||
[:p "Penpot is still at development stage and there will be constant updates. We hope you enjoy the first stable version."]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click next} "Continue"]]]
|
||||
|
||||
@@ -8,14 +8,10 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[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.util.path.commands :as upc]
|
||||
[app.util.path.geom :as upg]
|
||||
))
|
||||
[clojure.set :as set]))
|
||||
|
||||
(defn remove-line-curves
|
||||
"Remove all curves that have both handlers in the same position that the
|
||||
@@ -235,70 +231,73 @@
|
||||
to keep everything consistent"
|
||||
[content points]
|
||||
|
||||
(let [content (d/with-prev content)]
|
||||
(if (empty? points)
|
||||
content
|
||||
|
||||
(loop [result []
|
||||
last-handler nil
|
||||
[cur-cmd prev-cmd] (first content)
|
||||
content (rest content)]
|
||||
(let [content (d/with-prev content)]
|
||||
|
||||
(if (nil? 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 []))
|
||||
(loop [result []
|
||||
last-handler nil
|
||||
[cur-cmd prev-cmd] (first content)
|
||||
content (rest content)]
|
||||
|
||||
(let [move? (= :move-to (:command cur-cmd))
|
||||
curve? (= :curve-to (:command cur-cmd))
|
||||
(if (nil? 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
|
||||
result (if move? (conj result []) result)
|
||||
(let [move? (= :move-to (:command cur-cmd))
|
||||
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)
|
||||
|
||||
old-prev-point (upc/command->point prev-cmd)
|
||||
new-prev-point (upc/command->point (peek subpath))
|
||||
subpath (peek result)
|
||||
|
||||
remove? (contains? points point)
|
||||
point (upc/command->point cur-cmd)
|
||||
|
||||
|
||||
;; We store the first handler for the first curve to be removed to
|
||||
;; 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])
|
||||
old-prev-point (upc/command->point prev-cmd)
|
||||
new-prev-point (upc/command->point (peek subpath))
|
||||
|
||||
(not remove?)
|
||||
nil
|
||||
remove? (contains? points point)
|
||||
|
||||
:else
|
||||
last-handler)
|
||||
|
||||
cur-cmd (cond-> cur-cmd
|
||||
;; If we're starting a subpath and it's not a move make it a move
|
||||
(and (not move?) (empty? subpath))
|
||||
(assoc :command :move-to
|
||||
:params (select-keys (:params cur-cmd) [:x :y]))
|
||||
;; We store the first handler for the first curve to be removed to
|
||||
;; 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])
|
||||
|
||||
;; 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))
|
||||
(not remove?)
|
||||
nil
|
||||
|
||||
head-idx (dec (count result))
|
||||
:else
|
||||
last-handler)
|
||||
|
||||
result (cond-> result
|
||||
(not remove?)
|
||||
(update head-idx conj cur-cmd))]
|
||||
(recur result
|
||||
cur-handler
|
||||
(first content)
|
||||
(rest content)))))))
|
||||
cur-cmd (cond-> cur-cmd
|
||||
;; If we're starting a subpath and it's not a move make it a move
|
||||
(and (not move?) (empty? subpath))
|
||||
(assoc :command :move-to
|
||||
:params (select-keys (:params cur-cmd) [:x :y]))
|
||||
|
||||
;; 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
|
||||
"Creates new segments between points that weren't previously"
|
||||
|
||||
@@ -1,25 +1,16 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"PO-Revision-Date: 2021-04-22 13:43+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"PO-Revision-Date: 2021-04-14 13:44+0000\n"
|
||||
"Last-Translator: Andrés Moya <andres.moya@kaleidos.net>\n"
|
||||
"Language-Team: English "
|
||||
"<https://hosted.weblate.org/projects/penpot/frontend/en/>\n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=iso-8859-1\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.6-dev\n"
|
||||
|
||||
# ~ msgid ""
|
||||
# ~ msgstr ""
|
||||
# ~ "Language: en\n"
|
||||
# ~ "MIME-Version: 1.0\n"
|
||||
# ~ "Content-Type: text/plain; charset=utf-8\n"
|
||||
# ~ "Content-Transfer-Encoding: 8bit\n"
|
||||
# ~ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.already-have-account"
|
||||
msgstr "Already have an account?"
|
||||
@@ -492,6 +483,10 @@ msgstr "The registration is currently disabled."
|
||||
msgid "errors.terms-privacy-agreement-invalid"
|
||||
msgstr "You must accept our terms of service and privacy policy."
|
||||
|
||||
#: src/app/main/ui/auth/verify_token.cljs
|
||||
msgid "errors.token-expired"
|
||||
msgstr "Token expired"
|
||||
|
||||
#: src/app/main/data/media.cljs, src/app/main/ui/workspace/sidebar/options/menus/exports.cljs, src/app/main/ui/handoff/exports.cljs
|
||||
msgid "errors.unexpected-error"
|
||||
msgstr "An unexpected error occurred."
|
||||
@@ -1068,9 +1063,7 @@ msgstr "Verify new email"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "modals.change-email.info"
|
||||
msgstr ""
|
||||
"We'll send you an email to your current email “%s” to verify your "
|
||||
"identity."
|
||||
msgstr "We'll send you an email to your current email “%s” to verify your identity."
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "modals.change-email.new-email"
|
||||
@@ -1094,9 +1087,7 @@ msgstr "Yes, delete my account"
|
||||
|
||||
#: src/app/main/ui/settings/delete_account.cljs
|
||||
msgid "modals.delete-account.info"
|
||||
msgstr ""
|
||||
"By removing your account you’ll lose all your current projects and "
|
||||
"archives."
|
||||
msgstr "By removing your account you’ll lose all your current projects and archives."
|
||||
|
||||
#: src/app/main/ui/settings/delete_account.cljs
|
||||
msgid "modals.delete-account.title"
|
||||
|
||||
@@ -494,6 +494,10 @@ msgstr "El registro está actualmente desactivado."
|
||||
msgid "errors.terms-privacy-agreement-invalid"
|
||||
msgstr "Debes aceptar nuestros términos de servicio y política de privacidad."
|
||||
|
||||
#: src/app/main/ui/auth/verify_token.cljs
|
||||
msgid "errors.token-expired"
|
||||
msgstr "Token expirado"
|
||||
|
||||
#: src/app/main/data/media.cljs, src/app/main/ui/workspace/sidebar/options/menus/exports.cljs, src/app/main/ui/handoff/exports.cljs
|
||||
msgid "errors.unexpected-error"
|
||||
msgstr "Ha ocurrido un error inesperado."
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.5.0-alpha
|
||||
1.5.2-alpha
|
||||
|
||||
Reference in New Issue
Block a user