0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 23:49:45 -05:00

🐛 Fixes problem with undo/redo

This commit is contained in:
alonso.torres 2020-09-15 11:37:54 +02:00 committed by Andrey Antukh
parent 50321895e5
commit 28da2406d3
7 changed files with 70 additions and 222 deletions

View file

@ -2,132 +2,43 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
// Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
// This Source Code Form is "Incompatible With Secondary Licenses", as
// defined by the Mozilla Public License, v. 2.0.
//
// Copyright (c) 2020 UXBOX Labs SL
.document-history {
.history-tabs {
background-color: $color-gray-60;
display: flex;
width: 100%;
li {
background: darken($color-gray-60, 12%);
border-top-right-radius: $br-small;
border-top-left-radius: $br-small;
color: $color-gray-60;
cursor: pointer;
font-size: $fs14;
font-weight: bold;
justify-content: center;
margin: $x-small $x-small 0 $x-small;
padding: $x-small $small;
text-align: center;
width: 50%;
&.selected {
background-color: $color-gray-50;
color: $color-primary;
}
}
}
.history-content {
.history-toolbox {
display: flex;
flex-direction: column;
width: 100%;
}
li {
align-items: center;
border-bottom: 1px solid $color-gray-60;
cursor: pointer;
display: flex;
font-size: $fs14;
width: 100%;
padding: $small;
.history-toolbox-title {
color: $color-gray-10;
font-size: $fs14;
padding: 0.5rem;
}
.page-actions {
align-items: center;
display: flex;
margin-left: auto;
.undo-history {
font-size: $fs12;
color: $color-gray-10;
a {
svg {
fill: $color-gray-60;
height: 15px;
margin-left: $x-small;
width: 15px;
&:hover {
fill: $color-gray-20;
}
}
}
}
.pin-icon {
cursor: pointer;
svg {
fill: $color-gray-60;
height: 12px;
margin-right: $small;
width: 12px;
&:hover {
fill: $color-gray-20;
}
}
.undo-entry {
max-height: 10rem;
overflow: auto;
margin: 0.5rem;
&.selected {
svg {
fill: $color-gray-20;
}
border: 2px solid $color-primary;
}
}
&:hover {
color: $color-primary;
}
&.current {
color: $color-primary;
font-weight: bold;
span {
align-items: center;
display: flex;
&::before {
background-color: $color-primary;
border-radius: 50%;
content: "";
height: 6px;
flex-shrink: 0;
margin: $x-small;
width: 6px;
}
}
}
.btn-primary {
width: 100%;
}
}
}
.undo-entry-change {
background-color: #1F1F1F;
padding: 0.5rem;
}
.separator {
margin: 0.5rem;
border-color: $color-primary;
}
}

View file

@ -383,10 +383,13 @@
(fn [flags]
(cond
(contains? (set flags-to-toggle) :assets)
(disj flags :sitemap :layers)
(disj flags :sitemap :layers :document-history)
(contains? (set flags-to-toggle) :sitemap)
(disj flags :assets)
(disj flags :assets :document-history)
(contains? (set flags-to-toggle) :document-history)
(disj flags :assets :sitemap :layers)
:else
flags))))

View file

@ -271,7 +271,8 @@
(ptk/reify ::append-undo
ptk/UpdateEvent
(update [_ state]
(update-in state [:workspace-undo :items] (fnil conj-undo-entry []) entry))))
(let [state (update-in state [:workspace-undo :items] (fnil conj-undo-entry []) entry)]
(assoc-in state [:workspace-undo :index] (dec (count (get-in state [:workspace-undo :items]))))))))
(def undo
(ptk/reify ::undo
@ -292,7 +293,7 @@
(let [undo (:workspace-undo state)
items (:items undo)
index (or (:index undo) (dec (count items)))]
(when-not (or (empty? items) (= index (dec items)))
(when-not (or (empty? items) (= index (dec (count items))))
(let [changes (get-in items [(inc index) :redo-changes])]
(rx/of (materialize-undo changes (inc index))
(commit-changes changes [] {:save-undo? false}))))))))

View file

@ -26,7 +26,6 @@
[app.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]]
[app.main.ui.workspace.scroll :as scroll]
[app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
[app.main.ui.workspace.sidebar.history :refer [history-dialog]]
[app.main.ui.workspace.viewport :refer [viewport coordinates]]
[app.util.dom :as dom]
[beicon.core :as rx]
@ -49,8 +48,6 @@
:team-id (:team-id project)}])
[:section.workspace-content {:class classes}
[:& history-dialog]
[:section.workspace-viewport
(when (contains? layout :rules)
[:*

View file

@ -105,7 +105,9 @@
:on-click #(st/emit! (dw/toggle-layout-flags :assets))}
i/library]
[:li.tooltip.tooltip-right
{:alt "History"}
{:alt "History"
:class (when (contains? layout :document-history) "selected")
:on-click #(st/emit! (dw/toggle-layout-flags :document-history))}
i/undo-history]
[:li.tooltip.tooltip-right
{:alt (t locale "workspace.toolbar.color-palette")

View file

@ -29,7 +29,7 @@
[:& sitemap {:file file
:page-id page-id
:layout layout}])
#_(when (contains? layout :document-history)
(when (contains? layout :document-history)
[:& history-toolbox])
(when (contains? layout :layers)
[:& layers-toolbox])

View file

@ -2,12 +2,15 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns app.main.ui.workspace.sidebar.history
(:require
[rumext.alpha :as mf]
[cuerdas.core :as str]
[app.main.ui.icons :as i]
[app.main.data.history :as udh]
[app.main.data.workspace :as dw]
@ -15,102 +18,33 @@
[app.main.store :as st]
[app.util.data :refer [read-string]]
[app.util.dom :as dom]
[app.util.i18n :refer (tr)]
[app.util.i18n :refer [t] :as i18n]
[app.util.router :as r]
[app.util.time :as dt]))
[app.util.time :as dt]
[okulary.core :as l]
[app.main.store :as st]))
;; --- History Item (Component)
(def workspace-undo
(l/derived :workspace-undo st/state))
(mf/defc history-item
[{:keys [item selected?] :as props}]
(letfn [(on-select [event]
(dom/prevent-default event)
(st/emit! (udh/select (:version item))))
(on-pinned [event]
(dom/prevent-default event)
(dom/stop-propagation event)
(let [item (assoc item
:label "no label"
:pinned (not (:pinned item)))]
(st/emit! (udh/update-history-item item))))]
[:li {:class (when selected? "current")
:on-click on-select}
[:div.pin-icon {:on-click on-pinned
:class (when (:pinned item) "selected")}
i/pin]
[:span (str "Version " (:version item)
" (" (dt/timeago (:created-at item)) ")")]]))
;; --- History List (Component)
(mf/defc history-list
[{:keys [history] :as props}]
(let [items (reverse (sort-by :version (:items history)))
show-more? (pos? (:min-version history))
load-more #(st/emit! udh/load-more)]
[:ul.history-content
(for [item items]
[:& history-item {:item item
:key (:id item)
:selected? (= (:selected history)
(:version item))}])
(when show-more?
[:li {:on-click load-more}
[:a.btn-primary.btn-small "view more"]])]))
;; --- History Pinned List (Component)
(mf/defc history-pinned-list
[{:keys [history] :as props}]
[:ul.history-content
(for [item (reverse (sort-by :version (:pinned history)))]
[:& history-item {:item item
:key (:id item)
:selected? (= (:selected history)
(:version item))}])])
;; --- History Toolbox (Component)
(mf/defc history-toolbox
[props]
(let [history nil #_(mf/deref refs/history)
section (mf/use-state :main)
;; close #(st/emit! (dw/toggle-flag :history))
close (constantly nil)
main? (= @section :main)
pinned? (= @section :pinned)
show-main #(st/emit! (udh/select-section :main))
show-pinned #(st/emit! (udh/select-section :pinned))]
[:div.document-history.tool-window
[:div.tool-window-bar
[:div.tool-window-icon i/undo-history]
[:span (tr "ds.settings.document-history")]
[:div.tool-window-close {:on-click close} i/close]]
[:div.tool-window-content
[:ul.history-tabs
[:li {:on-click #(reset! section :main)
:class (when main? "selected")}
(tr "ds.history.versions")]
[:li {:on-click #(reset! section :pinned)
:class (when pinned? "selected")}
(tr "ds.history.pinned")]]
(if (= @section :pinned)
[:& history-pinned-list {:history history}]
[:& history-list {:history history}])]]))
;; --- History Dialog
(mf/defc history-dialog
[props]
(let [history nil #_(mf/deref refs/history)
version (:selected history)
on-accept #(st/emit! udh/apply-selected)
on-cancel #(st/emit! udh/deselect)]
(when (or version (:deselecting history))
[:div.message-version
{:class (when (:deselecting history) "hide-message")}
[:span (tr "history.alert-message" (or version "00"))
[:div.message-action
[:a.btn-transparent {:on-click on-accept} (tr "ds.accept")]
[:a.btn-transparent {:on-click on-cancel} (tr "ds.cancel")]]]])))
(mf/defc history-toolbox []
(let [locale (mf/deref i18n/locale)
{:keys [items index]} (mf/deref workspace-undo)
objects (mf/deref refs/workspace-page-objects)]
[:div.history-toolbox
[:div.history-toolbox-title "History"]
(when (> (count items) 0)
[:ul.undo-history
[:*
(when (or (nil? index) (>= index (count items))) [:hr.separator])
(for [[idx-entry {:keys [redo-changes]}] (->> items (map-indexed vector) reverse)]
[:*
(when (= index idx-entry) [:hr.separator {:data-index index}])
[:li.undo-entry {:key (str "entry-" idx-entry)}
(for [[idx-change {:keys [type id operations]}] (map-indexed vector redo-changes)]
[:div.undo-entry-change
[:div.undo-entry-change-data (when type (str type)) " " (when id (str (get-in objects [id :name] (subs (str id) 0 8))))]
(when operations
[:div.undo-entry-change-data (str/join ", " (map (comp name :attr) operations))])])]])
(when (= index -1) [:hr.separator])]])]))