diff --git a/frontend/src/uxbox/main/data/pages.cljs b/frontend/src/uxbox/main/data/pages.cljs index db7fd304c5..6cc7c3e593 100644 --- a/frontend/src/uxbox/main/data/pages.cljs +++ b/frontend/src/uxbox/main/data/pages.cljs @@ -144,22 +144,47 @@ [state id] (update state :packed-pages dissoc id)) +;; --- Update Project main page +;; +;; A event that handles the project main page +;; update based on the user selected page ordering. + +(deftype UpdateProjectMainPage [id] + ptk/UpdateEvent + (update [_ state] + (let [get-order #(get-in % [:metadata :order]) + page-id (->> (vals (:pages state)) + (filter #(= id (:project %))) + (sort-by get-order) + (map :id) + (first))] + (assoc-in state [:projects id :page-id] page-id)))) + +(defn update-project-main-page + [id] + {:pre [(uuid? id)]} + (UpdateProjectMainPage. id)) + ;; --- Pages Fetched -(deftype PagesFetched [pages] +(deftype PagesFetched [id pages] IDeref - (-deref [_] pages) + (-deref [_] (list id pages)) ptk/UpdateEvent (update [_ state] (as-> state $ (reduce assoc-page $ pages) - (reduce assoc-packed-page $ pages)))) + (reduce assoc-packed-page $ pages))) + + ptk/WatchEvent + (watch [_ state stream] + (rx/of (update-project-main-page id)))) (defn pages-fetched - [pages] - {:pre [(coll? pages)]} - (PagesFetched. pages)) + [id pages] + {:pre [(uuid? id) (coll? pages)]} + (PagesFetched. id pages)) (defn pages-fetched? [v] @@ -172,7 +197,7 @@ (watch [_ state s] (->> (rp/req :fetch/pages-by-project {:project id}) (rx/map :payload) - (rx/map pages-fetched)))) + (rx/map #(pages-fetched id %))))) (defn fetch-pages [id] @@ -181,25 +206,32 @@ ;; --- Page Created +(declare reorder-pages) + (deftype PageCreated [data] ptk/UpdateEvent (update [_ state] (-> state (assoc-page data) - (assoc-packed-page data)))) + (assoc-packed-page data))) -(s/def ::page-created-event - (s/keys :req-un [::id ::name ::project ::metadata])) + ptk/WatchEvent + (watch [_ state stream] + (rx/of (reorder-pages (:id data))))) + +(s/def ::page-created + (s/keys :req-un [::id + ::name + ::project + ::metadata])) (defn page-created [data] - {:pre [(us/valid? ::page-created-event data)]} + {:pre [(us/valid? ::page-created data)]} (PageCreated. data)) ;; --- Create Page -(declare reorder-pages) - (deftype CreatePage [name project width height layout] ptk/WatchEvent (watch [this state s] @@ -210,13 +242,11 @@ :height height :layout layout :order -100}}] - (rx/concat - (->> (rp/req :create/page params) - (rx/map :payload) - (rx/map page-created)) - (rx/of (reorder-pages)))))) + (->> (rp/req :create/page params) + (rx/map :payload) + (rx/map page-created))))) -(s/def ::create-page-event +(s/def ::create-page (s/keys :req-un [::name ::project ::width @@ -225,7 +255,7 @@ (defn create-page [{:keys [name project width height layout] :as data}] - {:pre [(us/valid? ::create-page-event data)]} + {:pre [(us/valid? ::create-page data)]} (CreatePage. name project width height layout)) ;; --- Page Persisted @@ -309,21 +339,21 @@ {:pre [(uuid? id)]} (PersistMetadata. id)) -(deftype PersistPagesMetadata [] +(deftype PersistPagesMetadata [project-id] ptk/WatchEvent (watch [_ state stream] - (let [project (get-in state [:workspace :project]) - xform (comp + (let [xform (comp (map second) - (filter #(= project (:project %))) + (filter #(= project-id (:project %))) (map :id))] (->> (sequence xform (:pages state)) (rx/from-coll) (rx/map persist-metadata))))) (defn persist-pages-metadata - [] - (PersistPagesMetadata.)) + [project-id] + {:pre [(uuid? project-id)]} + (PersistPagesMetadata. project-id)) ;; --- Update Page @@ -355,29 +385,31 @@ ;; ;; A post processing event that normalizes the ;; page order numbers after a user sorting -;; operation. +;; operation for a concrete project. -(deftype ReorderPages [] +(deftype ReorderPages [project-id] ptk/UpdateEvent (update [this state] - (let [project (get-in state [:workspace :project]) + (let [get-order #(get-in % [:metadata :order]) pages (->> (vals (:pages state)) - (filter #(= project (:project %))) - (sort-by #(get-in % [:metadata :order])) + (filter #(= project-id (:project %))) + (sort-by get-order) (map :id) (map-indexed vector))] - (reduce (fn [state [i page]] - (assoc-in state [:pages page :metadata :order] (* 10 i))) + (reduce (fn [state [order id]] + (assoc-in state [:pages id :metadata :order] (* order 10))) state pages))) ptk/WatchEvent (watch [_ state stream] - (rx/of (persist-pages-metadata)))) + (rx/of (update-project-main-page project-id) + (persist-pages-metadata project-id)))) (defn reorder-pages - [] - (ReorderPages.)) + [id] + {:pre [(uuid? id)]} + (ReorderPages. id)) ;; --- Update Order ;; @@ -391,7 +423,8 @@ ptk/WatchEvent (watch [_ state stream] - (rx/of (reorder-pages)))) + (let [project (get-in state [:pages id :project])] + (rx/of (reorder-pages project))))) (defn update-order [id order] diff --git a/frontend/src/uxbox/main/data/projects.cljs b/frontend/src/uxbox/main/data/projects.cljs index b73a7ed1cf..7262115a7f 100644 --- a/frontend/src/uxbox/main/data/projects.cljs +++ b/frontend/src/uxbox/main/data/projects.cljs @@ -35,31 +35,11 @@ ;; --- Helpers -(defn assoc-project-page - "Assoc to the state the project's embedded page." - [state project] - {:pre [(us/valid? ::project-entity project)]} - (let [page {:id (:page-id project) - :name (:page-name project) - :version (:page-version project) - :project (:id project) - :data (:page-data project) - :created-at (:page-created-at project) - :modified-at (:page-modified-at project) - :metadata (:page-metadata project)}] - (-> state - (udp/assoc-page page) - (udp/assoc-packed-page page)))) - (defn assoc-project "A reduce function for assoc the project to the state map." [state {:keys [id] :as project}] {:pre [(us/valid? ::project-entity project)]} - (let [project (dissoc project - :page-name :page-version - :page-data :page-metadata - :page-created-at :page-modified-at)] - (update-in state [:projects id] merge project))) + (update-in state [:projects id] merge project)) (defn dissoc-project "A reduce function for dissoc the project from the state map." @@ -89,9 +69,12 @@ (defrecord ProjectsFetched [projects] ptk/UpdateEvent (update [_ state] - (as-> state $ - (reduce assoc-project-page $ projects) - (reduce assoc-project $ projects)))) + (reduce assoc-project state projects)) + + ptk/WatchEvent + (watch [_ state stream] + (->> (rx/from-coll (map :id projects)) + (rx/map udp/fetch-pages)))) (defn projects-fetched [projects] @@ -106,7 +89,7 @@ (defrecord FetchProjects [] ptk/WatchEvent - (watch [_ state s] + (watch [_ state stream] (->> (rp/req :fetch/projects) (rx/map :payload) (rx/map projects-fetched)))) @@ -220,16 +203,12 @@ (defrecord GoTo [project-id] ptk/WatchEvent (watch [_ state stream] - (let [page-id (get-in state [:projects project-id :page-id]) - params {:project project-id - :page page-id}] - (rx/merge - (rx/of (udp/fetch-pages project-id)) - (->> stream - (rx/filter udp/pages-fetched?) - (rx/take 1) - (rx/map deref) - (rx/map go-to-first-page)))))) + (let [page-id (get-in state [:projects project-id :page-id])] + (if-not page-id + (rx/empty) + (let [params {:project project-id + :page page-id}] + (rx/of (rt/navigate :workspace/page params))))))) (defrecord GoToPage [project-id page-id] ptk/WatchEvent diff --git a/frontend/src/uxbox/main/ui/dashboard/projects.cljs b/frontend/src/uxbox/main/ui/dashboard/projects.cljs index 842f78b076..f8c391f69c 100644 --- a/frontend/src/uxbox/main/ui/dashboard/projects.cljs +++ b/frontend/src/uxbox/main/ui/dashboard/projects.cljs @@ -134,10 +134,17 @@ (when url (blob/revoke-uri url)) own)) +(defn- grid-item-thumbnail-did-remount + [oldown own] + (when-let [url (::url oldown)] + (blob/revoke-uri url)) + (grid-item-thumbnail-will-mount own)) + (mx/defcs grid-item-thumbnail {:mixins [mx/static] :will-mount grid-item-thumbnail-will-mount - :will-unmount grid-item-thumbnail-will-unmount} + :will-unmount grid-item-thumbnail-will-unmount + :did-remount grid-item-thumbnail-did-remount} [own project] (if-let [url (::url own)] [:div.grid-item-th diff --git a/frontend/src/uxbox/main/ui/dashboard/projects_createform.cljs b/frontend/src/uxbox/main/ui/dashboard/projects_createform.cljs index feaac3b969..143dfb1a58 100644 --- a/frontend/src/uxbox/main/ui/dashboard/projects_createform.cljs +++ b/frontend/src/uxbox/main/ui/dashboard/projects_createform.cljs @@ -75,8 +75,6 @@ (let [data (merge c/project-defaults (mx/react form-data)) errors (mx/react form-errors) valid? (fm/valid? ::project-form data)] - (println data) - (println valid?) (letfn [(on-submit [event] (dom/prevent-default event) (when valid? diff --git a/frontend/src/uxbox/main/ui/workspace/ruler.cljs b/frontend/src/uxbox/main/ui/workspace/ruler.cljs index 9e22175dec..12e4c6591f 100644 --- a/frontend/src/uxbox/main/ui/workspace/ruler.cljs +++ b/frontend/src/uxbox/main/ui/workspace/ruler.cljs @@ -83,7 +83,6 @@ :width c/viewport-width :height c/viewport-height}] (when-let [points (mx/react ruler-points-ref)] - (println points) [:g (ruler-line zoom points) (ruler-text zoom points)])])) diff --git a/frontend/src/uxbox/view/data/viewer.cljs b/frontend/src/uxbox/view/data/viewer.cljs index 736143d9c6..6007b93730 100644 --- a/frontend/src/uxbox/view/data/viewer.cljs +++ b/frontend/src/uxbox/view/data/viewer.cljs @@ -47,7 +47,8 @@ ptk/UpdateEvent (update [_ state] (let [project (dissoc data :pages) - pages (sort-by :created-at (:pages data))] + get-order #(get-in % [:metadata :order]) + pages (sort-by get-order (:pages data))] (as-> state $ (assoc $ :project project) (assoc $ :pages []) @@ -76,7 +77,7 @@ ptk/WatchEvent (watch [_ state stream] (let [token (get-in state [:route :params :token])] - (rx/of (rt/navigate :view/viewer {:token token :id index}))))) + (rx/of (rt/navigate :view/viewer {:token token :index index}))))) (defn select-page [index] diff --git a/frontend/src/uxbox/view/ui.cljs b/frontend/src/uxbox/view/ui.cljs index fb6d9066cd..aa70c72434 100644 --- a/frontend/src/uxbox/view/ui.cljs +++ b/frontend/src/uxbox/view/ui.cljs @@ -14,13 +14,14 @@ [uxbox.view.ui.viewer :refer [viewer-page]] [uxbox.util.router :as rt] [uxbox.util.i18n :refer [tr]] + [uxbox.util.data :refer [parse-int]] [uxbox.util.messages :as uum] [uxbox.util.mixins :as mx :include-macros true] [uxbox.util.dom :as dom])) -(def route-id-ref - (-> (l/in [:route :id]) +(def route-ref + (-> (l/key :route) (l/derive st/state))) (defn- on-error @@ -46,16 +47,17 @@ (mx/defc app {:mixins [mx/static mx/reactive]} [] - (let [location (mx/react route-id-ref)] - (case location + (let [{loc :id params :params} (mx/react route-ref)] + (case loc :view/notfound (notfound-page) - :view/viewer (viewer-page) + :view/viewer (let [{:keys [index token]} params] + (viewer-page token (parse-int index 0))) nil))) ;; --- Routes (def routes - [["/:token/:id" :view/viewer] + [["/:token/:index" :view/viewer] ["/:token" :view/viewer] ["/not-found" :view/notfound]]) diff --git a/frontend/src/uxbox/view/ui/viewer.cljs b/frontend/src/uxbox/view/ui/viewer.cljs index a3464a1ab6..e5d8fdb914 100644 --- a/frontend/src/uxbox/view/ui/viewer.cljs +++ b/frontend/src/uxbox/view/ui/viewer.cljs @@ -2,21 +2,19 @@ ;; 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) 2016 Andrey Antukh -;; Copyright (c) 2016 Juan de la Cruz +;; Copyright (c) 2016-2017 Andrey Antukh +;; Copyright (c) 2016-2017 Juan de la Cruz (ns uxbox.view.ui.viewer (:require [lentes.core :as l] - [uxbox.util.i18n :refer (tr)] - [potok.core :as ptk] - [uxbox.util.router :as rt] - [uxbox.util.mixins :as mx :include-macros true] [uxbox.builtins.icons :as i] + [uxbox.util.i18n :refer [tr]] + [uxbox.util.mixins :as mx :include-macros true] [uxbox.view.store :as st] [uxbox.view.data.viewer :as dv] - [uxbox.view.ui.viewer.nav :refer (nav)] - [uxbox.view.ui.viewer.canvas :refer (canvas)] - [uxbox.view.ui.viewer.sitemap :refer (sitemap)])) + [uxbox.view.ui.viewer.nav :refer [nav]] + [uxbox.view.ui.viewer.canvas :refer [canvas]] + [uxbox.view.ui.viewer.sitemap :refer [sitemap]])) ;; --- Refs @@ -24,34 +22,37 @@ (-> (l/key :flags) (l/derive st/state))) -(def token-ref - (-> (l/in [:route :params :token]) +(def pages-ref + (-> (l/key :pages) (l/derive st/state))) ;; --- Component (defn- viewer-page-will-mount [own] - (letfn [(on-change [token] - (st/emit! (dv/initialize token)))] - (add-watch token-ref ::wkey #(on-change %4)) - (on-change @token-ref) + (let [[token] (:rum/args own)] + (st/emit! (dv/initialize token)) own)) -(defn- viewer-page-will-unmount - [own] - (remove-watch token-ref ::wkey) - own) +(defn- viewer-page-did-remount + [oldown own] + (let [[old-token] (:rum/args oldown) + [new-token] (:rum/args own)] + (when (not= old-token new-token) + (st/emit! (dv/initialize old-token))) + own)) (mx/defc viewer-page {:mixins [mx/static mx/reactive] - :will-unmount viewer-page-will-unmount - :will-mount viewer-page-will-mount} - [own] + :will-mount viewer-page-will-mount + :did-remount viewer-page-did-remount} + [token index] (let [flags (mx/react flags-ref) - sitemap? (contains? flags :sitemap)] + sitemap? (contains? flags :sitemap) + get-order #(get-in % [:metadata :order]) + pages (mx/react pages-ref)] [:section.view-content (when sitemap? - (sitemap)) + (sitemap pages index)) (nav flags) - (canvas)])) + (canvas (nth pages index))])) diff --git a/frontend/src/uxbox/view/ui/viewer/canvas.cljs b/frontend/src/uxbox/view/ui/viewer/canvas.cljs index 42f8ad4f70..9ee73c5751 100644 --- a/frontend/src/uxbox/view/ui/viewer/canvas.cljs +++ b/frontend/src/uxbox/view/ui/viewer/canvas.cljs @@ -2,32 +2,13 @@ ;; 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) 2016 Andrey Antukh -;; Copyright (c) 2016 Juan de la Cruz +;; Copyright (c) 2016-2017 Andrey Antukh +;; Copyright (c) 2016-2017 Juan de la Cruz (ns uxbox.view.ui.viewer.canvas - (:require [sablono.core :refer-macros [html]] - [lentes.core :as l] - [rum.core :as rum] - [uxbox.util.mixins :as mx :include-macros true] - [uxbox.util.data :refer (parse-int)] - [uxbox.view.store :as st] - [uxbox.main.ui.shapes :as uus] - [uxbox.builtins.icons :as i] + (:require [uxbox.util.mixins :as mx :include-macros true] [uxbox.view.ui.viewer.shapes :as shapes])) -;; --- Refs - -(defn- resolve-selected-page - [state] - (let [index (get-in state [:route :params :id]) - index (parse-int index 0)] - (get-in state [:pages index]))) - -(def page-ref - (-> (l/lens resolve-selected-page) - (l/derive st/state))) - ;; --- Background (Component) (mx/defc background @@ -43,16 +24,14 @@ (declare shape) (mx/defc canvas - {:mixins [mx/static mx/reactive]} - [] - (let [page (rum/react page-ref) - metadata (:metadata page) - width (:width metadata) - height (:height metadata)] + {:mixins [mx/static]} + [{:keys [metadata] :as page}] + (let [{:keys [width height]} metadata] [:div.view-canvas - [:svg.page-layout {:width width :height height} + [:svg.page-layout {:width width + :height height} (background) (for [id (reverse (:shapes page))] (-> (shapes/shape id) - (rum/with-key (str id))))]])) + (mx/with-key (str id))))]])) diff --git a/frontend/src/uxbox/view/ui/viewer/nav.cljs b/frontend/src/uxbox/view/ui/viewer/nav.cljs index bc29f2c0b8..3ebd0e2cc4 100644 --- a/frontend/src/uxbox/view/ui/viewer/nav.cljs +++ b/frontend/src/uxbox/view/ui/viewer/nav.cljs @@ -2,14 +2,14 @@ ;; 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) 2016 Andrey Antukh -;; Copyright (c) 2016 Juan de la Cruz +;; Copyright (c) 2016-2017 Andrey Antukh +;; Copyright (c) 2016-2017 Juan de la Cruz (ns uxbox.view.ui.viewer.nav - (:require [uxbox.util.mixins :as mx :include-macros true] - [potok.core :as ptk] - [uxbox.view.store :as st] + (:require [potok.core :as ptk] [uxbox.builtins.icons :as i] + [uxbox.util.mixins :as mx :include-macros true] + [uxbox.view.store :as st] [uxbox.view.data.viewer :as dv])) (mx/defc nav diff --git a/frontend/src/uxbox/view/ui/viewer/sitemap.cljs b/frontend/src/uxbox/view/ui/viewer/sitemap.cljs index 8cc45293d5..15b888d456 100644 --- a/frontend/src/uxbox/view/ui/viewer/sitemap.cljs +++ b/frontend/src/uxbox/view/ui/viewer/sitemap.cljs @@ -8,38 +8,26 @@ (ns uxbox.view.ui.viewer.sitemap (:require [sablono.core :refer-macros (html)] [lentes.core :as l] + [potok.core :as ptk] + [uxbox.builtins.icons :as i] [uxbox.util.i18n :refer [tr]] [uxbox.util.mixins :as mx :include-macros true] [uxbox.util.data :refer [parse-int]] - [potok.core :as ptk] - [uxbox.view.store :as st] - [uxbox.builtins.icons :as i] - [uxbox.view.data.viewer :as dv])) + [uxbox.view.data.viewer :as dv] + [uxbox.view.store :as st])) ;; --- Refs -(def pages-ref - (-> (l/key :pages) - (l/derive st/state))) - (def project-name-ref (-> (l/in [:project :name]) (l/derive st/state))) -(def selected-ref - (-> (comp (l/in [:route :params :id]) - (l/lens #(parse-int % 0))) - (l/derive st/state))) - ;; --- Component (mx/defc sitemap {:mixins [mx/static mx/reactive]} - [] + [pages selected] (let [project-name (mx/react project-name-ref) - pages (->> (mx/react pages-ref) - (sort-by #(get-in % [:metadata :order]))) - selected (mx/react selected-ref) on-click #(st/emit! (dv/select-page %))] [:div.view-sitemap [:span.sitemap-title project-name] @@ -51,4 +39,3 @@ :key (str i)} [:div.page-icon i/page] [:span (:name page)]])]])) -