diff --git a/CHANGES.md b/CHANGES.md index 2e642a7b9..b045535b2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,11 @@ - Fix invite members button text [Taiga #4794](https://tree.taiga.io/project/penpot/issue/4794) - Fix problem with opacity in frames [Taiga #4795](https://tree.taiga.io/project/penpot/issue/4795) +<<<<<<< HEAD - Fix correct behaviour for space-around and added space-evenly option +======= +- Fix duplicate with alt and undo only undo one step [Taiga #4746](https://tree.taiga.io/project/penpot/issue/4746) +>>>>>>> d262fc2b7 (:bug: Fix duplicate with alt and undo only undo one step) ## 1.17.2 diff --git a/frontend/src/app/main/data/workspace/changes.cljs b/frontend/src/app/main/data/workspace/changes.cljs index 15d1c9b7e..6623b0821 100644 --- a/frontend/src/app/main/data/workspace/changes.cljs +++ b/frontend/src/app/main/data/workspace/changes.cljs @@ -34,6 +34,23 @@ (declare commit-changes) + +(defn- add-group-id + [changes state] + (let [undo (:workspace-undo state) + items (:items undo) + index (or (:index undo) (dec (count items))) + prev-item (when-not (or (empty? items) (= index -1)) + (get items index)) + group-id (:group-id prev-item) + add-group-id? (and + (not (nil? group-id)) + (= (get-in changes [:redo-changes 0 :type]) :mod-obj) + (= (get-in prev-item [:redo-changes 0 :type]) :add-obj)) ;; This is a copy-and-move with mouse+alt + ] + (cond-> changes add-group-id? (assoc :group-id group-id)))) + + (def commit-changes? (ptk/type? ::commit-changes)) (defn update-shapes @@ -64,7 +81,8 @@ (-> (pcb/empty-changes it page-id) (pcb/set-save-undo? save-undo?) (pcb/with-objects objects)) - ids)] + ids) + changes (add-group-id changes state)] (rx/concat (if (seq (:redo-changes changes)) (let [changes (cond-> changes reg-objects? (pcb/resize-parents ids))] @@ -147,7 +165,7 @@ (defn commit-changes [{:keys [redo-changes undo-changes - origin save-undo? file-id] + origin save-undo? file-id group-id] :or {save-undo? true}}] (log/debug :msg "commit-changes" :js/redo-changes redo-changes @@ -164,7 +182,8 @@ :changes redo-changes :page-id page-id :frames frames - :save-undo? save-undo?}) + :save-undo? save-undo? + :group-id group-id}) ptk/UpdateEvent (update [_ state] @@ -212,5 +231,6 @@ (when (and save-undo? (seq undo-changes)) (let [entry {:undo-changes undo-changes - :redo-changes redo-changes}] + :redo-changes redo-changes + :group-id group-id}] (rx/of (dwu/append-undo entry))))))))))) diff --git a/frontend/src/app/main/data/workspace/common.cljs b/frontend/src/app/main/data/workspace/common.cljs index 0cbd9877b..19f4a4ce3 100644 --- a/frontend/src/app/main/data/workspace/common.cljs +++ b/frontend/src/app/main/data/workspace/common.cljs @@ -27,6 +27,7 @@ (defn interrupt? [e] (= e :interrupt)) +(declare undo-to-index) (defn- assure-valid-current-page [] @@ -60,13 +61,25 @@ items (:items undo) index (or (:index undo) (dec (count items)))] (when-not (or (empty? items) (= index -1)) - (let [changes (get-in items [index :undo-changes])] - (rx/of (dwu/materialize-undo changes (dec index)) - (dch/commit-changes {:redo-changes changes - :undo-changes [] - :save-undo? false - :origin it}) - (assure-valid-current-page)))))))))) + (let [item (get items index) + changes (:undo-changes item) + group-id (:group-id item) + find-first-group-idx (fn ffgidx[index] + (let [item (get items index)] + (if (= (:group-id item) group-id) + (ffgidx (dec index)) + (inc index)))) + + undo-group-index (when group-id + (find-first-group-idx index))] + (if group-id + (rx/of (undo-to-index (dec undo-group-index))) + (rx/of (dwu/materialize-undo changes (dec index)) + (dch/commit-changes {:redo-changes changes + :undo-changes [] + :save-undo? false + :origin it}) + (assure-valid-current-page))))))))))) (def redo (ptk/reify ::redo @@ -79,12 +92,24 @@ items (:items undo) index (or (:index undo) (dec (count items)))] (when-not (or (empty? items) (= index (dec (count items)))) - (let [changes (get-in items [(inc index) :redo-changes])] - (rx/of (dwu/materialize-undo changes (inc index)) - (dch/commit-changes {:redo-changes changes - :undo-changes [] - :origin it - :save-undo? false})))))))))) + (let [item (get items (inc index)) + changes (:redo-changes item) + group-id (:group-id item) + find-last-group-idx (fn flgidx [index] + (let [item (get items index)] + (if (= (:group-id item) group-id) + (flgidx (inc index)) + (dec index)))) + + redo-group-index (when group-id + (find-last-group-idx (inc index)))] + (if group-id + (rx/of (undo-to-index redo-group-index)) + (rx/of (dwu/materialize-undo changes (inc index)) + (dch/commit-changes {:redo-changes changes + :undo-changes [] + :origin it + :save-undo? false}))))))))))) (defn undo-to-index "Repeat undoing or redoing until dest-index is reached." @@ -99,7 +124,7 @@ items (:items undo) index (or (:index undo) (dec (count items)))] (when (and (some? items) - (<= 0 dest-index (dec (count items)))) + (<= -1 dest-index (dec (count items)))) (let [changes (vec (apply concat (cond (< dest-index index) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 6ad54b229..02e78eae7 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -485,7 +485,10 @@ (gpt/subtract new-pos pt-obj))))) -(defn duplicate-selected [move-delta?] +(defn duplicate-selected + ([move-delta?] + (duplicate-selected move-delta? false)) + ([move-delta? add-group-id?] (ptk/reify ::duplicate-selected ptk/WatchEvent (watch [it state _] @@ -502,6 +505,8 @@ changes (->> (prepare-duplicate-changes objects page selected delta it) (duplicate-changes-update-indices objects selected)) + changes (cond-> changes add-group-id? (assoc :group-id (uuid/random))) + id-original (first selected) new-selected (->> changes @@ -525,7 +530,7 @@ (select-shapes new-selected) (ptk/data-event :layout/update frames) (memorize-duplicated id-original id-duplicated) - (dwu/commit-undo-transaction undo-id))))))))) + (dwu/commit-undo-transaction undo-id)))))))))) (defn change-hover-state [id value] diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 7cda5044a..5a62a135f 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -382,7 +382,7 @@ (if alt? ;; When alt is down we start a duplicate+move (rx/of (start-move-duplicate initial) - (dws/duplicate-selected false)) + (dws/duplicate-selected false true)) ;; Otherwise just plain old move (rx/of (start-move initial selected)))))) diff --git a/frontend/src/app/main/data/workspace/undo.cljs b/frontend/src/app/main/data/workspace/undo.cljs index b4dfd7a12..b0872fa47 100644 --- a/frontend/src/app/main/data/workspace/undo.cljs +++ b/frontend/src/app/main/data/workspace/undo.cljs @@ -55,10 +55,11 @@ state)) (defn- accumulate-undo-entry - [state {:keys [undo-changes redo-changes]}] + [state {:keys [undo-changes redo-changes group-id]}] (-> state (update-in [:workspace-undo :transaction :undo-changes] #(into undo-changes %)) - (update-in [:workspace-undo :transaction :redo-changes] #(into % redo-changes)))) + (update-in [:workspace-undo :transaction :redo-changes] #(into % redo-changes)) + (assoc-in [:workspace-undo :transaction :group-id] group-id))) (defn append-undo [entry]