0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 00:40:30 -05:00

Add proper history loading and history state management.

This commit is contained in:
Andrey Antukh 2016-03-28 18:49:09 +03:00
parent 95263402b7
commit 6ef76673e8
4 changed files with 83 additions and 44 deletions

View file

@ -26,7 +26,9 @@
(defrecord PagesFetched [pages] (defrecord PagesFetched [pages]
rs/UpdateEvent rs/UpdateEvent
(-apply-update [_ state] (-apply-update [_ state]
(reduce stpr/unpack-page state pages))) (as-> state $
(reduce stpr/unpack-page $ pages)
(reduce stpr/assoc-page $ pages))))
(defn pages-fetched? (defn pages-fetched?
[v] [v]
@ -56,14 +58,16 @@
rs/WatchEvent rs/WatchEvent
(-apply-watch [this state s] (-apply-watch [this state s]
(letfn [(on-created [{page :payload}] (letfn [(on-created [{page :payload}]
#(stpr/unpack-page % page)) (rx/of
#(stpr/unpack-page % page)
#(stpr/assoc-page % page)))
(on-failed [page] (on-failed [page]
(uum/error (tr "errors.auth")) (uum/error (tr "errors.auth"))
(rx/empty))] (rx/empty))]
(let [params (-> (into {} this) (let [params (-> (into {} this)
(assoc :data {}))] (assoc :data {}))]
(->> (rp/do :create/page params) (->> (rp/do :create/page params)
(rx/map on-created) (rx/mapcat on-created)
(rx/catch on-failed)))))) (rx/catch on-failed))))))
(def ^:static +create-page-schema+ (def ^:static +create-page-schema+
@ -80,12 +84,11 @@
;; --- Update Page ;; --- Update Page
(defrecord UpdatePage [id name width height layout data] (defrecord UpdatePage [id name width height layout]
rs/UpdateEvent rs/UpdateEvent
(-apply-update [_ state] (-apply-update [_ state]
(letfn [(updater [page] (letfn [(updater [page]
(merge page (merge page
(when data {:data data})
(when width {:width width}) (when width {:width width})
(when height {:height height}) (when height {:height height})
(when name {:name name})))] (when name {:name name})))]
@ -94,13 +97,16 @@
rs/WatchEvent rs/WatchEvent
(-apply-watch [this state s] (-apply-watch [this state s]
(letfn [(on-success [{page :payload}] (letfn [(on-success [{page :payload}]
#(assoc-in % [:pages-by-id id :version] (:version page))) (rx/of
#(assoc-in % [:pages-by-id id :version] (:version page))
#(stpr/assoc-page % page)))
(on-failure [e] (on-failure [e]
(uum/error (tr "errors.page-update")) (uum/error (tr "errors.page-update"))
(rx/empty))] (rx/empty))]
(->> (rp/do :update/page (into {} this)) (let [page (stpr/pack-page state id)]
(rx/map on-success) (->> (rp/do :update/page page)
(rx/catch on-failure))))) (rx/mapcat on-success)
(rx/catch on-failure))))))
(def ^:const +update-page-schema+ (def ^:const +update-page-schema+
{:name [sc/required sc/string] {:name [sc/required sc/string]
@ -181,37 +187,67 @@
[id] [id]
(DeletePage. id)) (DeletePage. id))
;; --- Page History Fetched ;; --- Pinned Page History Fetched
(defrecord PageHistoryFetched [history] (defrecord PinnedPageHistoryFetched [history]
rs/UpdateEvent rs/UpdateEvent
(-apply-update [_ state] (-apply-update [_ state]
(-> state (assoc-in state [:workspace :history :pinned-items] history)))
(assoc-in [:workspace :history :items] history))))
;; (assoc-in [:workspace :history :selected] nil)))) ;; --- Fetch Pinned Page History
(defrecord FetchPinnedPageHistory [id]
rs/WatchEvent
(-apply-watch [_ state s]
(println "FetchPinnedPageHistory" id)
(letfn [(on-success [{history :payload}]
(->PinnedPageHistoryFetched history))
(on-failure [e]
(uum/error (tr "errors.fetch-page-history"))
(rx/empty))]
(let [params {:page id :pinned true}]
(->> (rp/do :fetch/page-history params)
(rx/map on-success)
(rx/catch on-failure))))))
(defn fetch-pinned-page-history
[id]
(->FetchPinnedPageHistory id))
;; --- Page History Fetched
(defrecord PageHistoryFetched [history append?]
rs/UpdateEvent
(-apply-update [_ state]
(println "PageHistoryFetched" "append=" append?)
(let [items (into [] history)
minv (apply min (map :version history))
state (assoc-in state [:workspace :history :min-version] minv)]
(if-not append?
(assoc-in state [:workspace :history :items] items)
(update-in state [:workspace :history :items] #(reduce conj % items))))))
;; --- Fetch Page History ;; --- Fetch Page History
(defrecord FetchPageHistory [id] (defrecord FetchPageHistory [id since max]
rs/WatchEvent rs/WatchEvent
(-apply-watch [_ state s] (-apply-watch [_ state s]
(println "FetchPageHistory" id) (println "FetchPageHistory" id)
(letfn [(on-success [{history :payload}] (letfn [(on-success [{history :payload}]
(->PageHistoryFetched history)) (->PageHistoryFetched history (not (nil? since))))
(on-failure [e] (on-failure [e]
(uum/error (tr "errors.fetch-page-history")) (uum/error (tr "errors.fetch-page-history"))
(rx/empty))] (rx/empty))]
(->> (rp/do :fetch/page-history {:page id :max 15}) (let [params {:page id :max (or max 15)}]
(rx/map on-success) (->> (rp/do :fetch/page-history params)
(rx/catch on-failure)))) (rx/map on-success)
(rx/catch on-failure))))))
rs/EffectEvent
(-apply-effect [_ state]
))
(defn fetch-page-history (defn fetch-page-history
[id] ([id]
(FetchPageHistory. id)) (fetch-page-history id nil))
([id params]
(map->FetchPageHistory (assoc params :id id))))
;; --- Clean Page History ;; --- Clean Page History
@ -229,30 +265,22 @@
;; --- Select Page History ;; --- Select Page History
;; TODO: seems like it is inefficient packing the current
;; page every time, but a this moment it works. Maybe in
;; future it will need some refactor.
(defrecord SelectPageHistory [id history] (defrecord SelectPageHistory [id history]
rs/UpdateEvent rs/UpdateEvent
(-apply-update [_ state] (-apply-update [_ state]
(if (nil? history) (if (nil? history)
(let [packed (get-in state [:workspace :history :current])] (let [packed (get-in state [:pagedata-by-id id])]
(-> state (-> state
(stpr/unpack-page packed) (stpr/unpack-page packed)
(assoc-in [:workspace :history :selected] nil) (assoc-in [:workspace :history :selected] nil)))
(assoc-in [:workspace :history :current] nil))) (let [page (get-in state [:pages-by-id id])
(let [packed (stpr/pack-page state id)
page (get-in state [:pages-by-id id])
page' (assoc page page' (assoc page
:history true :history true
:data (:data history) :data (:data history)
:version (:version history))] :version (:version history))]
(-> state (-> state
(stpr/unpack-page page') (stpr/unpack-page page')
(assoc-in [:workspace :history :selected] (:id history)) (assoc-in [:workspace :history :selected] (:id history)))))))
(update-in [:workspace :history :current] (fnil identity packed)))))))
(defn select-page-history (defn select-page-history
[id history] [id history]

View file

@ -26,7 +26,7 @@
(defmethod -do :fetch/page-history (defmethod -do :fetch/page-history
[type {:keys [page] :as params}] [type {:keys [page] :as params}]
(let [url (str url "/pages/" page "/history") (let [url (str url "/pages/" page "/history")
query (select-keys params [:max :since])] query (select-keys params [:max :since :pinned])]
(send! {:method :get :url url :query query }))) (send! {:method :get :url url :query query })))
(defmethod -do :delete/page (defmethod -do :delete/page

View file

@ -23,10 +23,19 @@
acc)) acc))
shapes shapes
shapes)))) shapes))))
(defn assoc-page
[state {:keys [id] :as page}]
(assoc-in state [:pagedata-by-id id] page))
(defn dissoc-page
[state id]
(update state :pagedata-by-id dissoc id))
(defn pack-page (defn pack-page
"Return a packed version of page object ready "Return a packed version of page object ready
for send to remore storage service." for send to remore storage service."
[state id] [state id]
(time
(let [page (get-in state [:pages-by-id id]) (let [page (get-in state [:pages-by-id id])
xf (filter #(= (:page (second %)) id)) xf (filter #(= (:page (second %)) id))
shapes (into {} xf (:shapes-by-id state))] shapes (into {} xf (:shapes-by-id state))]
@ -34,7 +43,7 @@
(assoc-in [:data :shapes] (into [] (:shapes page))) (assoc-in [:data :shapes] (into [] (:shapes page)))
(assoc-in [:data :shapes-by-id] shapes) (assoc-in [:data :shapes-by-id] shapes)
(update-in [:data] dissoc :items) (update-in [:data] dissoc :items)
(dissoc :shapes)))) (dissoc :shapes)))))
(defn unpack-page (defn unpack-page
"Unpacks packed page object and assocs it to the "Unpacks packed page object and assocs it to the

View file

@ -39,7 +39,8 @@
(defn- history-toolbox-will-mount (defn- history-toolbox-will-mount
[own] [own]
(let [page @wb/page-l] (let [page @wb/page-l]
(rs/emit! (dpg/fetch-page-history (:id page))) (rs/emit! (dpg/fetch-page-history (:id page))
(dpg/fetch-pinned-page-history (:id page)))
(add-watch wb/page-l ::key (fn [_ _ ov nv] (add-watch wb/page-l ::key (fn [_ _ ov nv]
(when (and (> (:version nv) (:version ov)) (when (and (> (:version nv) (:version ov))
(not (:history nv))) (not (:history nv)))
@ -54,7 +55,8 @@
(defn history-list-render (defn history-list-render
[own page history] [own page history]
(let [select #(rs/emit! (dpg/select-page-history (:id page) %))] (let [select #(rs/emit! (dpg/select-page-history (:id page) %))
show-more? (> (count (:items history)) 15)]
(html (html
[:ul.history-content [:ul.history-content
[:li {:class (when-not (:selected history) "current") [:li {:class (when-not (:selected history) "current")
@ -68,9 +70,9 @@
[:div.pin-icon i/pin] [:div.pin-icon i/pin]
[:span (str "Version " (:version item) [:span (str "Version " (:version item)
" (" (dt/timeago (:created-at item)) ")")]]) " (" (dt/timeago (:created-at item)) ")")]])
(if show-more?
[:li [:li
[:a.btn-primary.btn-small "view more"]]]))) [:a.btn-primary.btn-small "view more"]])])))
(def history-list (def history-list
(mx/component (mx/component