0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-14 16:51:18 -05:00

Improve history handling on frontend.

This commit is contained in:
Andrey Antukh 2017-03-25 19:35:54 +01:00
parent 691c359985
commit 94677f2f7e
No known key found for this signature in database
GPG key ID: 4DFEBCB8316A8B95
11 changed files with 322 additions and 281 deletions

View file

@ -2,160 +2,207 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; 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/. ;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;; ;;
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz> ;; Copyright (c) 2016-2017 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.data.history (ns uxbox.main.data.history
(:require [cuerdas.core :as str] (:require [beicon.core :as rx]
[beicon.core :as rx]
[lentes.core :as l]
[potok.core :as ptk] [potok.core :as ptk]
[uxbox.util.router :as r]
[uxbox.main.repo :as rp]
[uxbox.util.i18n :refer (tr)]
[uxbox.util.forms :as sc]
[uxbox.main.data.pages :as udp] [uxbox.main.data.pages :as udp]
[uxbox.main.store :as st] [uxbox.main.repo :as rp]
[uxbox.util.time :as dt] [uxbox.util.data :refer [replace-by-id
[uxbox.util.data :refer (without-keys index-by]]))
replace-by-id
index-by)]))
;; --- Watch Page Changes ;; --- Initialize History State
(declare fetch-page-history) (declare fetch-history)
(declare fetch-pinned-page-history) (declare fetch-pinned-history)
(deftype Initialize [page-id]
ptk/UpdateEvent
(update [_ state]
(let [data {:section :main
:selected nil
:pinned #{}
:items #{}
:byver {}}]
(assoc-in state [:workspace :history] data)))
(deftype WatchPageChanges [id]
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [stopper (->> stream (let [page-id (get-in state [:workspace :page])
(rx/filter #(= % ::udp/stop-page-watcher)) stopper (->> stream
(rx/filter #(= % ::stop-changes-watcher))
(rx/take 1))] (rx/take 1))]
(->> stream (rx/merge
(rx/take-until stopper) (->> stream
(rx/filter udp/page-persisted?) (rx/take-until stopper)
(rx/debounce 500) (rx/filter udp/page-persisted?)
(rx/flat-map #(rx/of (fetch-page-history id) (rx/flat-map #(rx/of (fetch-history page-id)
(fetch-pinned-page-history id))))))) (fetch-pinned-history page-id))))
(rx/of (fetch-history page-id)
(fetch-pinned-history page-id))))))
(defn watch-page-changes (defn initialize
[id] [page-id]
(WatchPageChanges. id)) {:pre [(uuid? page-id)]}
(Initialize. page-id))
;; --- Pinned Page History Fetched ;; --- Pinned Page History Fetched
(declare update-history-index) (deftype PinnedPageHistoryFetched [items]
(defrecord PinnedPageHistoryFetched [history]
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(-> state (let [items-map (index-by items :version)
(assoc-in [:workspace :history :pinned-items] (mapv :version history)) items-set (into #{} items)]
(update-history-index history true)))) (update-in state [:workspace :history]
(fn [history]
(-> history
(assoc :pinned items-set)
(update :byver merge items-map)))))))
(defn pinned-page-history-fetched
[items]
(PinnedPageHistoryFetched. items))
;; --- Fetch Pinned Page History ;; --- Fetch Pinned Page History
(defrecord FetchPinnedPageHistory [id] (deftype FetchPinnedPageHistory [id]
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state s]
(letfn [(on-success [{history :payload}] (let [params {:page id :pinned true}]
(->PinnedPageHistoryFetched (into [] history)))] (->> (rp/req :fetch/page-history params)
(let [params {:page id :pinned true}] (rx/map :payload)
(->> (rp/req :fetch/page-history params) (rx/map pinned-page-history-fetched)))))
(rx/map on-success))))))
(defn fetch-pinned-page-history (defn fetch-pinned-history
[id] [id]
(->FetchPinnedPageHistory id)) {:pre [(uuid? id)]}
(FetchPinnedPageHistory. id))
;; --- Page History Fetched ;; --- Page History Fetched
(defrecord PageHistoryFetched [history append?] (deftype PageHistoryFetched [items]
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(letfn [(update-counters [state items] (let [versions (into #{} (map :version) items)
(-> (assoc state :min-version (apply min items)) items-map (index-by items :version)
(assoc :max-version (apply max items)))) min-version (apply min versions)
max-version (apply max versions)]
(update-in state [:workspace :history]
(fn [history]
(-> history
(assoc :min-version min-version)
(assoc :max-version max-version)
(update :byver merge items-map)
(update :items #(reduce conj % items))))))))
(update-lists [state items] ;; TODO: add spec to history items
(if append?
(update state :items #(reduce conj %1 items))
(assoc state :items items)))]
(let [items (mapv :version history) (defn page-history-fetched
hstate (-> (get-in state [:workspace :history] {}) [items]
(update-counters items) (PageHistoryFetched. items))
(update-lists items))]
(-> state
(assoc-in [:workspace :history] hstate)
(update-history-index history append?))))))
;; --- Fetch Page History ;; --- Fetch Page History
(defrecord FetchPageHistory [id since max] (deftype FetchPageHistory [page-id since max]
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state s]
(letfn [(on-success [{history :payload}] (let [params (merge {:page page-id
(let [history (into [] history)] :max (or max 15)}
(->PageHistoryFetched history (not (nil? since)))))] (when since
(let [params (merge {:since since}))]
{:page id :max (or max 15)} (->> (rp/req :fetch/page-history params)
(when since {:since since}))] (rx/map :payload)
(->> (rp/req :fetch/page-history params) (rx/map page-history-fetched)))))
(rx/map on-success))))))
(defn fetch-page-history (defn fetch-history
([id] ([id]
(fetch-page-history id nil)) (fetch-history id nil))
([id params] ([id {:keys [since max]}]
(map->FetchPageHistory (assoc params :id id)))) {:pre [(uuid? id)]}
(FetchPageHistory. id since max)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Context Aware Events
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; --- Select Section
(deftype SelectSection [section]
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace :history :section] section)))
(defn select-section
[section]
{:pre [(keyword? section)]}
(SelectSection. section))
;; --- Load More
(deftype LoadMore []
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (get-in state [:workspace :page])
since (get-in state [:workspace :history :min-version])]
(rx/of (fetch-history page-id {:since since})))))
(defn load-more
[]
(LoadMore.))
;; --- Select Page History ;; --- Select Page History
(defrecord SelectPageHistory [version] (deftype SelectPageHistory [version]
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [item (get-in state [:workspace :history :by-version version]) (let [history (get-in state [:workspace :history])
item (get-in history [:byver version])
page (get-in state [:pages (:page item)]) page (get-in state [:pages (:page item)])
page (assoc page
:history true page (-> (get-in state [:pages (:page item)])
:data (:data item))] (assoc :history true
:data (:data item)))]
(-> state (-> state
(udp/assoc-page page) (udp/assoc-page page)
(assoc-in [:workspace :history :selected] version))))) (assoc-in [:workspace :history :selected] version)))))
(defn select-page-history (defn select-page-history
[version] [version]
{:pre [(integer? version)]}
(SelectPageHistory. version)) (SelectPageHistory. version))
;; --- Apply selected history ;; --- Apply Selected History
(defrecord ApplySelectedHistory [id] (deftype ApplySelectedHistory []
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(-> state (let [page-id (get-in state [:workspace :page])]
(update-in [:pages id] dissoc :history) (-> state
(assoc-in [:workspace :history :selected] nil))) (update-in [:pages page-id] dissoc :history)
(assoc-in [:workspace :history :selected] nil))))
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state s]
(rx/of (udp/persist-page id)))) (let [page-id (get-in state [:workspace :page])]
(rx/of (udp/persist-page page-id)))))
(defn apply-selected-history (defn apply-selected-history
[id] []
(ApplySelectedHistory. id)) (ApplySelectedHistory.))
;; --- Deselect Page History ;; --- Deselect Page History
(defrecord DeselectPageHistory [id ^:mutable noop] (deftype DeselectPageHistory [^:mutable noop]
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [selected (get-in state [:workspace :history :selected])] (let [page-id (get-in state [:workspace :page])
selected (get-in state [:workspace :history :selected])]
(if (nil? selected) (if (nil? selected)
(do (do
(set! noop true) (set! noop true)
state) state)
(let [packed (get-in state [:packed-pages id])] (let [packed (get-in state [:packed-pages page-id])]
(-> (udp/assoc-page state packed) (-> (udp/assoc-page state packed)
(assoc-in [:workspace :history :deselecting] true) (assoc-in [:workspace :history :deselecting] true)
(assoc-in [:workspace :history :selected] nil)))))) (assoc-in [:workspace :history :selected] nil))))))
@ -168,18 +215,35 @@
(rx/delay 500))))) (rx/delay 500)))))
(defn deselect-page-history (defn deselect-page-history
[id] []
{:pre [(uuid? id)]} (DeselectPageHistory. false))
(DeselectPageHistory. id false))
;; --- Refresh Page History
(deftype RefreshHistory []
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (get-in state [:workspace :page])
history (get-in state [:workspace :history])
maxitems (count (:items history))]
(rx/of (fetch-history page-id {:max maxitems})
(fetch-pinned-history page-id)))))
(defn refres-history
[]
(RefreshHistory.))
;; --- History Item Updated ;; --- History Item Updated
(defrecord HistoryItemUpdated [item] (deftype HistoryItemUpdated [item]
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(-> state (update-in state [:workspace :history]
(update-in [:workspace :history :items] replace-by-id item) (fn [history]
(update-in [:workspace :history :pinned-items] replace-by-id item)))) (-> history
(update :items #(into #{} (replace-by-id item) %))
(update :pinned #(into #{} (replace-by-id item) %))
(assoc-in [:byver (:id item)] item))))))
(defn history-updated? (defn history-updated?
[item] [item]
@ -189,33 +253,18 @@
[item] [item]
(HistoryItemUpdated. item)) (HistoryItemUpdated. item))
;; --- Refresh Page History
(defrecord RefreshPageHistory [id]
ptk/WatchEvent
(watch [_ state s]
(let [history (get-in state [:workspace :history])
maxitems (count (:items history))]
(rx/of (fetch-page-history id {:max maxitems})
(fetch-pinned-page-history id)))))
(defn refres-page-history
[id]
(RefreshPageHistory. id))
;; --- Update History Item ;; --- Update History Item
(defrecord UpdateHistoryItem [item] (deftype UpdateHistoryItem [item]
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state stream]
(letfn [(on-success [{item :payload}] (rx/concat
(->HistoryItemUpdated item))] (->> (rp/req :update/page-history item)
(rx/merge (rx/map :payload)
(->> (rp/req :update/page-history item) (rx/map history-updated))
(rx/map on-success)) (->> (rx/filter history-updated? stream)
(->> (rx/filter history-updated? s) (rx/take 1)
(rx/take 1) (rx/map refres-history)))))
(rx/map #(refres-page-history (:page item))))))))
(defn update-history-item (defn update-history-item
[item] [item]
@ -223,7 +272,7 @@
;; --- Forward to Next Version ;; --- Forward to Next Version
(defrecord ForwardToNextVersion [] (deftype ForwardToNextVersion []
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state s]
(let [workspace (:workspace state) (let [workspace (:workspace state)
@ -237,7 +286,7 @@
(rx/of (select-page-history (inc version))) (rx/of (select-page-history (inc version)))
(> (inc version) (:max-version history)) (> (inc version) (:max-version history))
(rx/of (deselect-page-history (:page workspace))) (rx/of (deselect-page-history))
:else :else
(rx/empty))))) (rx/empty)))))
@ -248,7 +297,7 @@
;; --- Backwards to Previous Version ;; --- Backwards to Previous Version
(defrecord BackwardsToPreviousVersion [] (deftype BackwardsToPreviousVersion []
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state s]
(let [workspace (:workspace state) (let [workspace (:workspace state)
@ -265,7 +314,7 @@
(let [since (:min-version history) (let [since (:min-version history)
page (:page workspace) page (:page workspace)
params {:since since}] params {:since since}]
(rx/of (fetch-page-history page params) (rx/of (fetch-history page params)
(select-page-history (dec version))))) (select-page-history (dec version)))))
:else :else
@ -274,13 +323,3 @@
(defn backwards-to-previous-version (defn backwards-to-previous-version
[] []
(BackwardsToPreviousVersion.)) (BackwardsToPreviousVersion.))
;; --- Helpers
(defn- update-history-index
[state history append?]
(let [index (index-by history :version)]
(if append?
(update-in state [:workspace :history :by-version] merge index)
(assoc-in state [:workspace :history :by-version] index))))

View file

@ -262,6 +262,9 @@
;; --- Page Persisted ;; --- Page Persisted
(deftype PagePersisted [data] (deftype PagePersisted [data]
IDeref
(-deref [_] data)
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [{:keys [id version]} data] (let [{:keys [id version]} data]

View file

@ -8,7 +8,6 @@
(:require [cljs.spec :as s] (:require [cljs.spec :as s]
[beicon.core :as rx] [beicon.core :as rx]
[potok.core :as ptk] [potok.core :as ptk]
[lentes.core :as l]
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.constants :as c] [uxbox.main.constants :as c]
[uxbox.main.lenses :as ul] [uxbox.main.lenses :as ul]
@ -47,16 +46,17 @@
(declare initialize-alignment) (declare initialize-alignment)
(defrecord InitializeWorkspace [project-id page-id] (defrecord Initialize [project-id page-id]
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [default-flags #{:sitemap :drawtools :layers :element-options :rules}] (let [default-flags #{:sitemap :drawtools :layers :element-options :rules}
default-flags #{:document-history}]
(if (:workspace state) (if (:workspace state)
(update state :workspace merge (update state :workspace merge
{:project project-id {:project project-id
:page page-id :page page-id
:selected #{} :selected #{}
:flags default-flags ;; :flags default-flags
:drawing nil :drawing nil
:drawing-tool nil :drawing-tool nil
:tooltip nil}) :tooltip nil})
@ -77,21 +77,15 @@
;; Activate loaded if page is not fetched. ;; Activate loaded if page is not fetched.
(when-not page (reset! st/loader true)) (when-not page (reset! st/loader true))
(rx/merge (if page
(if page (rx/of (initialize-alignment page-id))
(rx/of (initialize-alignment page-id)) (rx/merge
(rx/merge (rx/of (udp/fetch-pages project-id))
(rx/of (udp/fetch-pages project-id)) (->> stream
(->> (rx/filter udp/pages-fetched? stream) (rx/filter udp/pages-fetched?)
(rx/take 1) (rx/take 1)
(rx/do #(reset! st/loader false)) (rx/do #(reset! st/loader false))
(rx/map #(initialize-alignment page-id))))) (rx/map #(initialize-alignment page-id)))))))
;; Initial history loading
;; FIXME: move this to the history sidebar component
(rx/of
(udh/fetch-page-history page-id)
(udh/fetch-pinned-page-history page-id)))))
ptk/EffectEvent ptk/EffectEvent
(effect [_ state stream] (effect [_ state stream]
@ -104,7 +98,7 @@
[project page] [project page]
{:pre [(uuid? project) {:pre [(uuid? project)
(uuid? page)]} (uuid? page)]}
(InitializeWorkspace. project page)) (Initialize. project page))
;; --- Workspace Tooltips ;; --- Workspace Tooltips
@ -306,8 +300,6 @@
;; --- Grid Alignment ;; --- Grid Alignment
(declare initialize-alignment?)
(defrecord InitializeAlignment [id] (defrecord InitializeAlignment [id]
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
@ -327,6 +319,7 @@
(defn initialize-alignment (defn initialize-alignment
[id] [id]
{:pre [(uuid? id)]}
(InitializeAlignment. id)) (InitializeAlignment. id))
;; --- Update Metadata ;; --- Update Metadata

View file

@ -9,21 +9,20 @@
(:require [lentes.core :as l] (:require [lentes.core :as l]
[beicon.core :as rx] [beicon.core :as rx]
[uxbox.main.constants :as c] [uxbox.main.constants :as c]
[uxbox.main.store :as st] [uxbox.main.store :as st]))
[uxbox.main.lenses :as ul]))
;; --- Helpers ;; --- Helpers
(defn resolve-project (defn resolve-project
"Retrieve the current project." "Retrieve the current project."
[state] [state]
(let [id (l/focus ul/selected-project state)] (let [project-id (get-in state [:workspace :project])]
(get-in state [:projects id]))) (get-in state [:projects project-id])))
(defn resolve-page (defn resolve-page
[state] [state]
(let [id (l/focus ul/selected-page state)] (let [page-id (get-in state [:workspace :page])]
(get-in state [:pages id]))) (get-in state [:pages page-id])))
(defn- resolve-project-pages (defn- resolve-project-pages
[state] [state]
@ -34,13 +33,19 @@
(sort-by get-order)))) (sort-by get-order))))
(def workspace (def workspace
(l/derive ul/workspace st/state)) (-> (l/key :workspace)
(l/derive st/state)))
(def selected-project (def selected-project
"Ref to the current selected project." "Ref to the current selected project."
(-> (l/lens resolve-project) (-> (l/lens resolve-project)
(l/derive st/state))) (l/derive st/state)))
(def selected-project-id
"Ref to the current selected project id."
(-> (l/key :project)
(l/derive selected-project)))
(def selected-project-pages (def selected-project-pages
(-> (l/lens resolve-project-pages) (-> (l/lens resolve-project-pages)
(l/derive st/state))) (l/derive st/state)))

View file

@ -7,7 +7,6 @@
(ns uxbox.main.ui.workspace (ns uxbox.main.ui.workspace
(:require [beicon.core :as rx] (:require [beicon.core :as rx]
[potok.core :as ptk]
[lentes.core :as l] [lentes.core :as l]
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.constants :as c] [uxbox.main.constants :as c]
@ -55,7 +54,7 @@
(st/emit! (udp/watch-page-changes pageid) (st/emit! (udp/watch-page-changes pageid)
(udu/watch-page-changes pageid) (udu/watch-page-changes pageid)
(udh/watch-page-changes pageid)) #_(udh/watch-page-changes pageid))
(assoc own ::sub sub))) (assoc own ::sub sub)))
@ -74,7 +73,7 @@
::udp/stop-page-watcher ::udp/stop-page-watcher
(udp/watch-page-changes pageid) (udp/watch-page-changes pageid)
(udu/watch-page-changes pageid) (udu/watch-page-changes pageid)
(udh/watch-page-changes pageid))) #_(udh/watch-page-changes pageid)))
state)) state))
(defn- on-scroll (defn- on-scroll
@ -110,10 +109,8 @@
:mixins [mx/static :mixins [mx/static
mx/reactive mx/reactive
shortcuts-mixin]} shortcuts-mixin]}
[own] [own project-id page-id]
(let [flags (mx/react refs/flags) (let [flags (mx/react refs/flags)
page (mx/react workspace-page-ref)
left-sidebar? (not (empty? (keep flags [:layers :sitemap left-sidebar? (not (empty? (keep flags [:layers :sitemap
:document-history]))) :document-history])))
right-sidebar? (not (empty? (keep flags [:icons :drawtools right-sidebar? (not (empty? (keep flags [:icons :drawtools
@ -133,8 +130,7 @@
:on-scroll on-scroll :on-scroll on-scroll
:on-wheel (partial on-wheel own)} :on-wheel (partial on-wheel own)}
(history-dialog)
(history-dialog page)
;; Rules ;; Rules
(when (contains? flags :rules) (when (contains? flags :rules)
@ -151,6 +147,6 @@
;; Aside ;; Aside
(when left-sidebar? (when left-sidebar?
(left-sidebar)) (left-sidebar flags page-id))
(when right-sidebar? (when right-sidebar?
(right-sidebar))]])) (right-sidebar flags page-id))]]))

View file

@ -6,46 +6,40 @@
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com> ;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.workspace.sidebar (ns uxbox.main.ui.workspace.sidebar
(:require [lentes.core :as l] (:require [uxbox.main.refs :as refs]
[potok.core :as ptk] [uxbox.main.ui.workspace.sidebar.options :refer [options-toolbox]]
[uxbox.main.store :as st] [uxbox.main.ui.workspace.sidebar.layers :refer [layers-toolbox]]
[uxbox.main.refs :as refs] [uxbox.main.ui.workspace.sidebar.sitemap :refer [sitemap-toolbox]]
[uxbox.main.ui.workspace.sidebar.options :refer (options-toolbox)] [uxbox.main.ui.workspace.sidebar.history :refer [history-toolbox]]
[uxbox.main.ui.workspace.sidebar.layers :refer (layers-toolbox)] [uxbox.main.ui.workspace.sidebar.icons :refer [icons-toolbox]]
[uxbox.main.ui.workspace.sidebar.sitemap :refer (sitemap-toolbox)] [uxbox.main.ui.workspace.sidebar.drawtools :refer [draw-toolbox]]
[uxbox.main.ui.workspace.sidebar.history :refer (history-toolbox)]
[uxbox.main.ui.workspace.sidebar.icons :refer (icons-toolbox)]
[uxbox.main.ui.workspace.sidebar.drawtools :refer (draw-toolbox)]
[uxbox.util.router :as r]
[uxbox.util.mixins :as mx :include-macros true])) [uxbox.util.mixins :as mx :include-macros true]))
;; --- Left Sidebar (Component) ;; --- Left Sidebar (Component)
(mx/defc left-sidebar (mx/defc left-sidebar
{:mixins [mx/reactive mx/static]} {:mixins [mx/static]}
[] [flags page-id]
(let [flags (mx/react refs/flags)] [:aside#settings-bar.settings-bar.settings-bar-left
[:aside#settings-bar.settings-bar.settings-bar-left [:div.settings-bar-inside
[:div.settings-bar-inside (when (contains? flags :sitemap)
(when (contains? flags :sitemap) (sitemap-toolbox page-id))
(sitemap-toolbox)) (when (contains? flags :document-history)
(when (contains? flags :document-history) (history-toolbox page-id))
(history-toolbox)) (when (contains? flags :layers)
(when (contains? flags :layers) (layers-toolbox))]])
(layers-toolbox))]]))
;; --- Right Sidebar (Component) ;; --- Right Sidebar (Component)
(mx/defc right-sidebar (mx/defc right-sidebar
{:mixins [mx/reactive mx/static]} {:mixins [mx/static]}
[] [flags page-id]
(let [flags (mx/react refs/flags)] [:aside#settings-bar.settings-bar
[:aside#settings-bar.settings-bar [:div.settings-bar-inside
[:div.settings-bar-inside (when (contains? flags :drawtools)
(when (contains? flags :drawtools) (draw-toolbox flags))
(draw-toolbox)) (when (contains? flags :element-options)
(when (contains? flags :element-options) (options-toolbox))
(options-toolbox)) (when (contains? flags :icons)
(when (contains? flags :icons) (icons-toolbox))]])
(icons-toolbox))]]))

View file

@ -94,9 +94,8 @@
(mx/defc draw-toolbox (mx/defc draw-toolbox
{:mixins [mx/static mx/reactive]} {:mixins [mx/static mx/reactive]}
[] [flags]
(let [drawing-tool (mx/react refs/selected-drawing-tool) (let [drawing-tool (mx/react refs/selected-drawing-tool)
flags (mx/react refs/flags)
close #(st/emit! (udw/toggle-flag :drawtools)) close #(st/emit! (udw/toggle-flag :drawtools))
tools (->> (into [] +draw-tools+) tools (->> (into [] +draw-tools+)
(sort-by (comp :priority second))) (sort-by (comp :priority second)))

View file

@ -6,28 +6,19 @@
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com> ;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.workspace.sidebar.history (ns uxbox.main.ui.workspace.sidebar.history
(:require [lentes.core :as l] (:require [uxbox.builtins.icons :as i]
[potok.core :as ptk]
[uxbox.main.store :as st]
[uxbox.main.refs :as refs] [uxbox.main.refs :as refs]
[uxbox.main.data.workspace :as dw] [uxbox.main.store :as st]
[uxbox.main.data.pages :as udp]
[uxbox.main.data.history :as udh] [uxbox.main.data.history :as udh]
[uxbox.builtins.icons :as i] [uxbox.main.data.pages :as udp]
[uxbox.util.i18n :refer (tr)] [uxbox.main.data.workspace :as dw]
[uxbox.util.router :as r] [uxbox.util.data :refer [read-string]]
[uxbox.util.data :refer (read-string)]
[uxbox.util.dom :as dom] [uxbox.util.dom :as dom]
[uxbox.util.i18n :refer [tr]]
[uxbox.util.mixins :as mx :include-macros true] [uxbox.util.mixins :as mx :include-macros true]
[uxbox.util.router :as r]
[uxbox.util.time :as dt])) [uxbox.util.time :as dt]))
;; --- Lenses
(def history-ref
(-> (l/key :history)
(l/derive refs/workspace)))
;; --- History Item (Component) ;; --- History Item (Component)
(mx/defc history-item (mx/defc history-item
@ -43,69 +34,83 @@
:label "no label" :label "no label"
:pinned (not (:pinned item)))] :pinned (not (:pinned item)))]
(st/emit! (udh/update-history-item item))))] (st/emit! (udh/update-history-item item))))]
(let [selected? (= (:version item) selected)] [:li {:class (when (= selected (:version item)) "current")
[:li {:class (when selected? "current") :on-click on-select} :on-click on-select}
[:div.pin-icon {:on-click on-pinned [:div.pin-icon {:on-click on-pinned
:class (when (:pinned item) "selected")} :class (when (:pinned item) "selected")}
i/pin] i/pin]
[:span (str "Version " (:version item) [:span (str "Version " (:version item)
" (" (dt/timeago (:created-at item)) ")")]]))) " (" (dt/timeago (:created-at item)) ")")]]))
;; --- History List (Component) ;; --- History List (Component)
(mx/defc history-list (mx/defc history-list
{:mixins [mx/static]} {:mixins [mx/static mx/reactive]}
[page history] [{:keys [selected items min-version] :as history}]
(letfn [(on-select [event] (let [items (reverse (sort-by :version items))
(dom/prevent-default event) page (mx/react refs/selected-page)
(st/emit! (udh/deselect-page-history (:id page)))) show-more? (pos? min-version)
load-more #(st/emit! (udh/load-more))]
(on-load-more [event] (println "selected" selected)
(dom/prevent-default event) [:ul.history-content
(let [since (:min-version history) (for [item items
params {:since since}] :let [current? (= (:version item) (:version page))]]
(st/emit! (udh/fetch-page-history (:id page) params))))] (-> (history-item item selected current?)
(mx/with-key (str (:id item)))))
(let [selected (:selected history) (when show-more?
show-more? (pos? (:min-version history))] [:li {:on-click load-more}
[:ul.history-content [:a.btn-primary.btn-small
[:li {:class (when-not selected "current") "view more"]])]))
:on-click on-select}
[:div.pin-icon i/pin]
[:span (str "Version " (:version page) " (current)")]]
(for [version (:items history)
:let [item (get-in history [:by-version version])]]
(-> (history-item item selected)
(mx/with-key (str (:id item)))))
(if show-more?
[:li {:on-click on-load-more}
[:a.btn-primary.btn-small
"view more"]])])))
;; --- History Pinned List (Component) ;; --- History Pinned List (Component)
(mx/defc history-pinned-list (mx/defc history-pinned-list
{:mixins [mx/static]} {:mixins [mx/static]}
[history] [{:keys [pinned selected] :as history}]
[:ul.history-content [:ul.history-content
(for [version (:pinned-items history) (for [item (reverse (sort-by :version pinned))
:let [item (get-in history [:by-version version])]] :let [selected? (= (:version item) selected)]]
(-> (history-item item (:selected history)) (-> (history-item item selected?)
(mx/with-key (str (:id item)))))]) (mx/with-key (str (:id item)))))])
;; --- History Toolbox (Component) ;; --- History Toolbox (Component)
(mx/defcs history-toolbox
{:mixins [mx/static mx/reactive (mx/local)]} (defn- history-toolbox-will-mount
[{:keys [rum/local] :as own}] [own]
(let [page (mx/react refs/selected-page) (let [[page-id] (:rum/args own)]
history (mx/react refs/history) (st/emit! (udh/initialize page-id))
section (:section @local :main) own))
(defn- history-toolbox-did-remount
[oldown own]
(let [[old-page-id] (:rum/args oldown)
[new-page-id] (:rum/args own)]
(when-not (= old-page-id new-page-id)
(st/emit! ::udh/stop-changes-watcher
(udh/initialize new-page-id)))
own))
(defn- history-toolbox-will-unmount
[own]
(st/emit! ::udh/stop-changes-watcher)
own)
(mx/defc history-toolbox
{:mixins [mx/static mx/reactive]
:will-mount history-toolbox-will-mount
:will-unmount history-toolbox-will-unmount
:did-remount history-toolbox-did-remount}
[_]
(let [history (mx/react refs/history)
section (:section history :main)
close #(st/emit! (dw/toggle-flag :document-history)) close #(st/emit! (dw/toggle-flag :document-history))
main? (= section :main) main? (= section :main)
pinned? (= section :pinned) pinned? (= section :pinned)
show-main #(swap! local assoc :section :main)
show-pinned #(swap! local assoc :section :pinned)] show-main #(st/emit! (udh/select-section :main))
show-pinned #(st/emit! (udh/select-section :pinned))]
[:div.document-history.tool-window [:div.document-history.tool-window
[:div.tool-window-bar [:div.tool-window-bar
[:div.tool-window-icon i/undo-history] [:div.tool-window-icon i/undo-history]
@ -121,17 +126,17 @@
"Pinned"]] "Pinned"]]
(if (= section :pinned) (if (= section :pinned)
(history-pinned-list history) (history-pinned-list history)
(history-list page history))]])) (history-list history))]]))
;; --- History Dialog ;; --- History Dialog
(mx/defc history-dialog (mx/defc history-dialog
{:mixins [mx/static mx/reactive]} {:mixins [mx/static mx/reactive]}
[page] []
(let [history (mx/react refs/history) (let [history (mx/react refs/history)
version (:selected history) version (:selected history)
on-accept #(st/emit! (udh/apply-selected-history page)) on-accept #(st/emit! (udh/apply-selected-history))
on-cancel #(st/emit! (udh/deselect-page-history page))] on-cancel #(st/emit! (udh/deselect-page-history))]
(when (or version (:deselecting history)) (when (or version (:deselecting history))
[:div.message-version [:div.message-version
{:class (when (:deselecting history) "hide-message")} {:class (when (:deselecting history) "hide-message")}

View file

@ -347,8 +347,6 @@
[] []
(let [selected (mx/react refs/selected-shapes) (let [selected (mx/react refs/selected-shapes)
page (mx/react refs/selected-page) page (mx/react refs/selected-page)
;; TODO: dont react to the whole shapes-by-id
shapes-map (mx/react refs/shapes-by-id) shapes-map (mx/react refs/shapes-by-id)
close #(st/emit! (udw/toggle-flag :layers)) close #(st/emit! (udw/toggle-flag :layers))
dragel (volatile! nil)] dragel (volatile! nil)]

View file

@ -103,10 +103,9 @@
(mx/defc sitemap-toolbox (mx/defc sitemap-toolbox
{:mixins [mx/static mx/reactive]} {:mixins [mx/static mx/reactive]}
[] [current]
(let [project (mx/react refs/selected-project) (let [project (mx/react refs/selected-project)
pages (mx/react refs/selected-project-pages) pages (mx/react refs/selected-project-pages)
current (mx/react refs/selected-page)
create #(udl/open! :page-form {:page {:project (:id project)}}) create #(udl/open! :page-form {:page {:project (:id project)}})
close #(st/emit! (dw/toggle-flag :sitemap))] close #(st/emit! (dw/toggle-flag :sitemap))]
[:div.sitemap.tool-window [:div.sitemap.tool-window
@ -120,6 +119,6 @@
[:div.add-page {:on-click create} i/close]] [:div.add-page {:on-click create} i/close]]
[:ul.element-list [:ul.element-list
(for [page pages (for [page pages
:let [active? (= (:id page) (:id current))]] :let [active? (= (:id page) current)]]
(-> (page-item page (count pages) active?) (-> (page-item page (count pages) active?)
(mx/with-key (:id page))))]]])) (mx/with-key (:id page))))]]]))

View file

@ -57,13 +57,13 @@
coll))) coll)))
(defn replace-by-id (defn replace-by-id
[coll value] ([value]
{:pre [(vector? coll)]} (map (fn [item]
(mapv (fn [item]
(if (= (:id item) (:id value)) (if (= (:id item) (:id value))
value value
item)) coll)) item))))
([coll value]
(sequence (replace-by-id value) coll)))
(defn deep-merge (defn deep-merge
"Like merge, but merges maps recursively." "Like merge, but merges maps recursively."
@ -80,6 +80,16 @@
(disj s v) (disj s v)
(conj s v))) (conj s v)))
(defn seek
([pred coll]
(seek pred coll nil))
([pred coll not-found]
(reduce (fn [_ x]
(if (pred x)
(reduced x)
not-found))
not-found coll)))
;; --- String utils ;; --- String utils
(def +uuid-re+ (def +uuid-re+