diff --git a/frontend/src/uxbox/main/data/pages.cljs b/frontend/src/uxbox/main/data/pages.cljs index 5df8fb24d..ae68a0ae3 100644 --- a/frontend/src/uxbox/main/data/pages.cljs +++ b/frontend/src/uxbox/main/data/pages.cljs @@ -10,7 +10,7 @@ [beicon.core :as rx] [cuerdas.core :as str] [potok.core :as ptk] - [uxbox.main.repo :as rp] + [uxbox.main.repo.core :as rp] [uxbox.util.data :refer [index-by-id concatv]] [uxbox.util.spec :as us] [uxbox.util.timers :as ts] @@ -159,7 +159,7 @@ [id pages] (s/assert ::us/uuid id) (s/assert ::us/coll pages) - (ptk/reify ::page-fetched + (ptk/reify ::pages-fetched IDeref (-deref [_] (list id pages)) @@ -175,7 +175,7 @@ (defn pages-fetched? [v] - (= ::page-fetched (ptk/type v))) + (= ::pages-fetched (ptk/type v))) ;; --- Fetch Pages (by project id) @@ -185,10 +185,41 @@ (reify ptk/WatchEvent (watch [_ state s] - (->> (rp/req :fetch/pages-by-project {:project id}) - (rx/map :payload) + (->> (rp/query :pages-by-project {:project-id id}) (rx/map #(pages-fetched id %)))))) +;; --- Page Fetched + +(defn page-fetched + [data] + (s/assert any? data) ;; TODO: minimal validate + (ptk/reify ::page-fetched + IDeref + (-deref [_] data) + + ptk/UpdateEvent + (update [_ state] + (-> state + (unpack-page data) + (assoc-packed-page data))))) + +(defn page-fetched? + [v] + (= ::page-fetched (ptk/type v))) + + +;; --- Fetch Pages (by project id) + +(defn fetch-page + "Fetch page by id." + [id] + (s/assert ::us/uuid id) + (reify + ptk/WatchEvent + (watch [_ state s] + (->> (rp/query :page {:id id}) + (rx/map page-fetched))))) + ;; --- Page Created (declare rehash-pages) diff --git a/frontend/src/uxbox/main/data/projects.cljs b/frontend/src/uxbox/main/data/projects.cljs index 2bd25af56..865d80176 100644 --- a/frontend/src/uxbox/main/data/projects.cljs +++ b/frontend/src/uxbox/main/data/projects.cljs @@ -67,36 +67,32 @@ ;; --- Projects Fetched -(defrecord ProjectsFetched [projects] - ptk/UpdateEvent - (update [_ state] - (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] - {:pre [(us/valid? (s/every ::project-entity) projects)]} - (ProjectsFetched. projects)) + (s/assert (s/every ::project-entity) projects) + (ptk/reify ::projects-fetched + ptk/UpdateEvent + (update [_ state] + (reduce assoc-project state projects)))) + + ;; ptk/WatchEvent + ;; (watch [_ state stream] + ;; (->> (rx/from-coll (map :id projects)) + ;; (rx/map udp/fetch-pages)))) (defn projects-fetched? [v] - (instance? ProjectsFetched v)) + (= ::projects-fetched (ptk/type v))) ;; --- Fetch Projects -(defrecord FetchProjects [] - ptk/WatchEvent - (watch [_ state stream] - (->> (rp/query :projects) - (rx/map projects-fetched)))) - (defn fetch-projects [] - (FetchProjects.)) + (ptk/reify ::fetch-projects + ptk/WatchEvent + (watch [_ state stream] + (->> (rp/query :projects) + (rx/map projects-fetched))))) ;; --- Project Persisted @@ -177,14 +173,13 @@ (defn go-to [id] - {:pre [(uuid? id)]} - (reify + (s/assert ::us/uuid id) + (ptk/reify ::go-to ptk/WatchEvent (watch [_ state stream] - (let [[page & rest-pages] (get-in state [:projects id :pages])] - (when page - (let [params {:project id :page page}] - (rx/of (rt/nav :workspace/page params)))))))) + (let [page-id (get-in state [:projects id :ref-page-id])] + (let [params {:project id :page page-id}] + (rx/of (rt/nav :workspace/page params))))))) ;; --- Update Opts (Filtering & Ordering) diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 849bb5b12..ab6070894 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -46,6 +46,15 @@ (declare initialize-alignment) +(def workspace-default-data + {:initialized true + :zoom 1 + :flags #{:sitemap :drawtools :layers :element-options :rules} + :selected #{} + :drawing nil + :drawing-tool nil + :tooltip nil}) + (defn initialize "Initialize the workspace state." [project-id page-id] @@ -54,22 +63,15 @@ (ptk/reify ::initialize ptk/UpdateEvent (update [_ state] - (let [default-flags #{:sitemap :drawtools :layers :element-options :rules} - initial-workspace {:project-id project-id - :initialized true - :page-id page-id - :zoom 1 - :flags default-flags - :selected #{} - :drawing nil - :drawing-tool nil - :tooltip nil}] + (let [data (assoc workspace-default-data + :project-id project-id + :page-id page-id)] (-> state (update-in [:workspace page-id] (fn [wsp] (if (:initialized wsp) wsp - (merge wsp initial-workspace)))) + (merge wsp data)))) (assoc-in [:workspace :current] page-id)))) ptk/WatchEvent @@ -77,17 +79,16 @@ (let [page (get-in state [:pages page-id])] ;; Activate loaded if page is not fetched. (when-not page (reset! st/loader true)) - - (if page - (rx/of (initialize-alignment page-id)) - (rx/merge - (rx/of (udp/fetch-pages project-id)) - (->> stream - (rx/filter udp/pages-fetched?) - (rx/take 1) - (rx/do #(reset! st/loader false)) - (rx/map #(initialize-alignment page-id))))))) - + (rx/merge + ;; TODO: the `fetch-pages` should fetch a limited set of attrs + (rx/of (udp/fetch-page page-id)) + (rx/of (udp/fetch-pages project-id)) + (->> stream + (rx/filter udp/page-fetched?) + (rx/take 1) + (rx/mapcat (fn [event] + (reset! st/loader false) + (rx/of (initialize-alignment page-id)))))))) ptk/EffectEvent (effect [_ state stream] ;; Optimistic prefetch of projects if them are not already fetched @@ -307,27 +308,21 @@ ;; --- Grid Alignment -(defrecord InitializeAlignment [id] - ptk/WatchEvent - (watch [_ state stream] - (let [{:keys [metadata] :as page} (get-in state [:pages id]) - params {:width c/viewport-width - :height c/viewport-height - :x-axis (:grid-x-axis metadata c/grid-x-axis) - :y-axis (:grid-y-axis metadata c/grid-y-axis)}] - (rx/concat - (rx/of (deactivate-flag :grid-indexed)) - (->> (uwrk/initialize-alignment params) - (rx/map #(activate-flag :grid-indexed))))))) - -(defn initialize-alignment? - [v] - (instance? InitializeAlignment v)) - (defn initialize-alignment [id] - {:pre [(uuid? id)]} - (InitializeAlignment. id)) + (s/assert ::us/uuid id) + (ptk/reify ::initialize-alignment + ptk/WatchEvent + (watch [_ state stream] + (let [metadata (get-in state [:pages id :metadata]) + params {:width c/viewport-width + :height c/viewport-height + :x-axis (:grid-x-axis metadata c/grid-x-axis) + :y-axis (:grid-y-axis metadata c/grid-y-axis)}] + (rx/concat + (rx/of (deactivate-flag :grid-indexed)) + (->> (uwrk/initialize-alignment params) + (rx/map #(activate-flag :grid-indexed)))))))) ;; --- Duplicate Selected diff --git a/frontend/src/uxbox/main/exports.cljs b/frontend/src/uxbox/main/exports.cljs index 3392566f0..f2cfdebd0 100644 --- a/frontend/src/uxbox/main/exports.cljs +++ b/frontend/src/uxbox/main/exports.cljs @@ -9,16 +9,16 @@ (:require [rumext.alpha :as mf] [uxbox.main.store :as st] - [uxbox.main.ui.shapes.circle :refer [circle-shape]] - [uxbox.main.ui.shapes.group :refer [group-shape]] - [uxbox.main.ui.shapes.icon :refer [icon-shape]] - [uxbox.main.ui.shapes.image :refer [image-shape]] - [uxbox.main.ui.shapes.path :refer [path-shape]] - [uxbox.main.ui.shapes.rect :refer [rect-shape]] - [uxbox.main.ui.shapes.text :refer [text-shape]] + ;; [uxbox.main.ui.shapes.circle :refer [circle-shape]] + ;; [uxbox.main.ui.shapes.group :refer [group-shape]] + ;; [uxbox.main.ui.shapes.icon :refer [icon-shape]] + ;; [uxbox.main.ui.shapes.image :refer [image-shape]] + ;; [uxbox.main.ui.shapes.path :refer [path-shape]] + ;; [uxbox.main.ui.shapes.rect :refer [rect-shape]] + ;; [uxbox.main.ui.shapes.text :refer [text-shape]] [uxbox.util.dom :as dom])) -(def ^:dynamic *state* st/state) +;; (def ^:dynamic *state* st/state) (mf/defc background [] @@ -33,7 +33,7 @@ (defn- make-shape-element [state shape] - (mf/html + #_(mf/html (case (:type shape) ;; :text [:& text-shape {:shape shape}] :icon [:& icon-shape {:shape shape}] @@ -46,7 +46,7 @@ (mf/defc page-svg [{:keys [page state] :as props}] - (let [{:keys [width height]} (:metadata page)] + #_(let [{:keys [width height]} (:metadata page)] [:svg {:width width :height height :view-box (str "0 0 " width " " height) @@ -61,7 +61,7 @@ (defn render-page [id] - (try + #_(try (let [state (deref st/state) page (get-in state [:pages id])] (when (:shapes page) diff --git a/frontend/src/uxbox/main/ui/shapes/group.cljs b/frontend/src/uxbox/main/ui/shapes/group.cljs index 475139c7a..96a933a59 100644 --- a/frontend/src/uxbox/main/ui/shapes/group.cljs +++ b/frontend/src/uxbox/main/ui/shapes/group.cljs @@ -5,7 +5,7 @@ ;; Copyright (c) 2016-2019 Andrey Antukh (ns uxbox.main.ui.shapes.group - (:require + #_(:require [lentes.core :as l] [rumext.core :as mx] [uxbox.main.geom :as geom] @@ -24,64 +24,64 @@ ;; --- Helpers -(declare group-component) +;; (declare group-component) -(defn- focus-shape - [id] - (-> (l/in [:shapes id]) - (l/derive st/state))) +;; (defn- focus-shape +;; [id] +;; (-> (l/in [:shapes id]) +;; (l/derive st/state))) -(defn render-component - [shape] - (case (:type shape) - :group (group-component shape) - :text (text/text-component shape) - :icon (icon/icon-component shape) - :rect (rect/rect-component shape) - :path (path/path-component shape) - :image (image/image-component shape) - :circle (circle/circle-component shape))) +;; (defn render-component +;; [shape] +;; (case (:type shape) +;; :group (group-component shape) +;; :text (text/text-component shape) +;; :icon (icon/icon-component shape) +;; :rect (rect/rect-component shape) +;; :path (path/path-component shape) +;; :image (image/image-component shape) +;; :circle (circle/circle-component shape))) -(mx/defc component-container - {:mixins [mx/reactive mx/static]} - [id] - (when-let [shape (mx/react (focus-shape id))] - (when-not (:hidden shape) - (render-component shape)))) +;; (mx/defc component-container +;; {:mixins [mx/reactive mx/static]} +;; [id] +;; (when-let [shape (mx/react (focus-shape id))] +;; (when-not (:hidden shape) +;; (render-component shape)))) -;; --- Group Component +;; ;; --- Group Component -(declare group-shape) +;; (declare group-shape) -(mx/defc group-component - {:mixins [mx/static mx/reactive]} - [{:keys [id x y width height group] :as shape}] - (let [modifiers (mx/react (refs/selected-modifiers id)) - selected (mx/react refs/selected-shapes) - selected? (contains? selected id) - on-mouse-down #(common/on-mouse-down % shape selected) - shape (assoc shape :modifiers modifiers)] - [:g.shape.group-shape - {:class (when selected? "selected") - :on-mouse-down on-mouse-down} - (group-shape shape component-container)])) +;; (mx/defc group-component +;; {:mixins [mx/static mx/reactive]} +;; [{:keys [id x y width height group] :as shape}] +;; (let [modifiers (mx/react (refs/selected-modifiers id)) +;; selected (mx/react refs/selected-shapes) +;; selected? (contains? selected id) +;; on-mouse-down #(common/on-mouse-down % shape selected) +;; shape (assoc shape :modifiers modifiers)] +;; [:g.shape.group-shape +;; {:class (when selected? "selected") +;; :on-mouse-down on-mouse-down} +;; (group-shape shape component-container)])) -;; --- Group Shape +;; ;; --- Group Shape -(mx/defc group-shape - {:mixins [mx/static mx/reactive]} - [{:keys [id items modifiers] :as shape} factory] - (let [{:keys [resize displacement]} modifiers +;; (mx/defc group-shape +;; {:mixins [mx/static mx/reactive]} +;; [{:keys [id items modifiers] :as shape} factory] +;; (let [{:keys [resize displacement]} modifiers - xfmt (cond-> (gmt/matrix) - resize (gmt/multiply resize) - displacement (gmt/multiply displacement)) +;; xfmt (cond-> (gmt/matrix) +;; resize (gmt/multiply resize) +;; displacement (gmt/multiply displacement)) - moving? (boolean displacement)] - [:g {:id (str "shape-" id) - :class (classnames :move-cursor moving?) - :transform (str xfmt)} - (for [item (reverse items)] - (-> (factory item) - (mx/with-key (str item))))])) +;; moving? (boolean displacement)] +;; [:g {:id (str "shape-" id) +;; :class (classnames :move-cursor moving?) +;; :transform (str xfmt)} +;; (for [item (reverse items)] +;; (-> (factory item) +;; (mx/with-key (str item))))])) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs index 438995fd2..8f6cf98dd 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/sitemap.cljs @@ -2,7 +2,7 @@ ;; 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 +;; Copyright (c) 2015-2019 Andrey Antukh ;; Copyright (c) 2015-2016 Juan de la Cruz (ns uxbox.main.ui.workspace.sidebar.sitemap @@ -78,7 +78,8 @@ (mf/defc pages-list [{:keys [project current-page-id] :as props}] (let [pages-map (mf/deref pages-map-iref) - pages (map #(get pages-map %) (:pages project)) + pages (->> (vals pages-map) + (filter #(= (:project-id %) (:id project)))) deletable? (> (count pages) 1)] [:ul.element-list (for [[index item] (map-indexed vector pages)] diff --git a/frontend/src/uxbox/view/ui/viewer/canvas.cljs b/frontend/src/uxbox/view/ui/viewer/canvas.cljs index 80f3a93ca..4f3409760 100644 --- a/frontend/src/uxbox/view/ui/viewer/canvas.cljs +++ b/frontend/src/uxbox/view/ui/viewer/canvas.cljs @@ -15,7 +15,7 @@ (mf/defc background {:wrap [mf/wrap-memo]} [{:keys [background] :as metadata}] - [:rect + #_[:rect {:x 0 :y 0 :width "100%" :height "100%" @@ -28,7 +28,7 @@ (mf/defc canvas {:wrap [mf/wrap-memo]} [{:keys [page] :as props}] - (let [{:keys [metadata id]} page + #_(let [{:keys [metadata id]} page {:keys [width height]} metadata] [:div.view-canvas [:svg.page-layout {:width width diff --git a/frontend/src/uxbox/view/ui/viewer/shapes.cljs b/frontend/src/uxbox/view/ui/viewer/shapes.cljs index ec69c13de..9d8d1b1fb 100644 --- a/frontend/src/uxbox/view/ui/viewer/shapes.cljs +++ b/frontend/src/uxbox/view/ui/viewer/shapes.cljs @@ -5,7 +5,7 @@ ;; Copyright (c) 2016 Andrey Antukh (ns uxbox.view.ui.viewer.shapes - (:require [goog.events :as events] + #_(:require [goog.events :as events] [lentes.core :as l] [uxbox.builtins.icons :as i] [uxbox.view.store :as st] @@ -15,104 +15,104 @@ [uxbox.main.ui.shapes.rect :refer [rect-shape]] [uxbox.main.ui.shapes.icon :refer [icon-shape]] [uxbox.main.ui.shapes.text :refer [text-shape]] - [uxbox.main.ui.shapes.group :refer [group-shape]] + ;; [uxbox.main.ui.shapes.group :refer [group-shape]] [uxbox.main.ui.shapes.path :refer [path-shape]] [uxbox.main.ui.shapes.circle :refer [circle-shape]] [uxbox.main.ui.shapes.image :refer [image-shape]] [rumext.core :as mx :include-macros true]) - (:import goog.events.EventType)) + #_(:import goog.events.EventType)) -(def itx-flag-ref - (-> (comp (l/key :flags) (l/lens :interactions)) - (l/derive st/state))) +;; (def itx-flag-ref +;; (-> (comp (l/key :flags) (l/lens :interactions)) +;; (l/derive st/state))) -(defn image-ref - [id] - (-> (l/in [:images id]) - (l/derive st/state))) +;; (defn image-ref +;; [id] +;; (-> (l/in [:images id]) +;; (l/derive st/state))) -;; --- Interactions Wrapper +;; ;; --- Interactions Wrapper -(defn- interactions-wrapper-did-mount - [own] - (let [dom (mx/dom-node own) - shape (first (::mx/args own)) - evnts (itx/build-events shape) - keys (reduce (fn [acc [evt callback]] - (conj acc (events/listen dom evt callback))) - [] - evnts)] - (assoc own ::keys keys))) +;; (defn- interactions-wrapper-did-mount +;; [own] +;; (let [dom (mx/dom-node own) +;; shape (first (::mx/args own)) +;; evnts (itx/build-events shape) +;; keys (reduce (fn [acc [evt callback]] +;; (conj acc (events/listen dom evt callback))) +;; [] +;; evnts)] +;; (assoc own ::keys keys))) -(defn- interactions-wrapper-will-unmount - [own] - (let [keys (::keys own)] - (run! #(events/unlistenByKey %) keys) - (dissoc own ::keys))) +;; (defn- interactions-wrapper-will-unmount +;; [own] +;; (let [keys (::keys own)] +;; (run! #(events/unlistenByKey %) keys) +;; (dissoc own ::keys))) -(mx/defc interactions-wrapper - {:did-mount interactions-wrapper-did-mount - :will-unmount interactions-wrapper-will-unmount - :mixins [mx/reactive mx/static]} - [shape factory] - {:pre [(map? shape)]} - (let [show-itx? (and (mx/react itx-flag-ref) - (not (empty? (:interactions shape)))) - rect (geom/shape->rect-shape shape)] - [:g {:id (str "itx-" (:id shape)) - :style {:cursor "pointer"}} - (factory shape) - (when show-itx? - [:circle {:class "interaction-bullet" - :cx (:x1 rect) - :cy (:y1 rect) - :r 5}])])) +;; (mx/defc interactions-wrapper +;; {:did-mount interactions-wrapper-did-mount +;; :will-unmount interactions-wrapper-will-unmount +;; :mixins [mx/reactive mx/static]} +;; [shape factory] +;; {:pre [(map? shape)]} +;; (let [show-itx? (and (mx/react itx-flag-ref) +;; (not (empty? (:interactions shape)))) +;; rect (geom/shape->rect-shape shape)] +;; [:g {:id (str "itx-" (:id shape)) +;; :style {:cursor "pointer"}} +;; (factory shape) +;; (when show-itx? +;; [:circle {:class "interaction-bullet" +;; :cx (:x1 rect) +;; :cy (:y1 rect) +;; :r 5}])])) -;; [:rect {:class "interaction-hightlight" -;; :x (:x1 rect) -;; :y (:y1 rect) -;; :width (:width rect) -;; :height (:height rect)}] +;; ;; [:rect {:class "interaction-hightlight" +;; ;; :x (:x1 rect) +;; ;; :y (:y1 rect) +;; ;; :width (:width rect) +;; ;; :height (:height rect)}] -;; --- Image Shape Wrapper -;; -;; NOTE: This wrapper is needed for preload the referenced -;; image object which is need for properly show the shape. +;; ;; --- Image Shape Wrapper +;; ;; +;; ;; NOTE: This wrapper is needed for preload the referenced +;; ;; image object which is need for properly show the shape. -(mx/defc image-shape-wrapper - {:mixins [mx/static mx/reactive] - :init (fn [own] - (when-let [image-id (-> own ::mx/args first :image)] - (st/emit! (udv/fetch-image image-id))) - own)} - [{:keys [image] :as item}] - (when-let [image (mx/react (image-ref image))] - (image-shape (assoc item :image image)))) +;; (mx/defc image-shape-wrapper +;; {:mixins [mx/static mx/reactive] +;; :init (fn [own] +;; (when-let [image-id (-> own ::mx/args first :image)] +;; (st/emit! (udv/fetch-image image-id))) +;; own)} +;; [{:keys [image] :as item}] +;; (when-let [image (mx/react (image-ref image))] +;; (image-shape (assoc item :image image)))) -;; --- Text Shape Wrapper +;; ;; --- Text Shape Wrapper -(mx/defc text-shape-wrapper - {:mixins [mx/static]} - [item] - (text-shape (assoc item :user-select true))) +;; (mx/defc text-shape-wrapper +;; {:mixins [mx/static]} +;; [item] +;; (text-shape (assoc item :user-select true))) -;; --- Shapes +;; ;; --- Shapes -(declare shape) +;; (declare shape) -(mx/defc shape* - [{:keys [type] :as item}] - (case type - :group (group-shape item shape) - :image (image-shape-wrapper item) - :text (text-shape-wrapper item) - :icon (icon-shape item) - :rect (rect-shape item) - :path (path-shape item) - :circle (circle-shape item))) +;; (mx/defc shape* +;; [{:keys [type] :as item}] +;; (case type +;; ;; :group (group-shape item shape) +;; :image (image-shape-wrapper item) +;; :text (text-shape-wrapper item) +;; :icon (icon-shape item) +;; :rect (rect-shape item) +;; :path (path-shape item) +;; :circle (circle-shape item))) -(mx/defc shape - [sid] - {:pre [(uuid? sid)]} - (let [item (get-in @st/state [:shapes sid])] - (interactions-wrapper item shape*))) +;; (mx/defc shape +;; [sid] +;; {:pre [(uuid? sid)]} +;; (let [item (get-in @st/state [:shapes sid])] +;; (interactions-wrapper item shape*)))