mirror of
https://github.com/penpot/penpot.git
synced 2025-07-25 20:39:31 +02:00
154 lines
5.3 KiB
Clojure
154 lines
5.3 KiB
Clojure
(ns uxbox.ui.workspace
|
|
(:refer-clojure :exclude [dedupe])
|
|
(:require [sablono.core :as html :refer-macros [html]]
|
|
[rum.core :as rum]
|
|
[beicon.core :as rx]
|
|
[lentes.core :as l]
|
|
[uxbox.rstore :as rs]
|
|
[uxbox.state :as st]
|
|
[uxbox.state.project :as stpr]
|
|
[uxbox.data.workspace :as dw]
|
|
[uxbox.data.projects :as dp]
|
|
[uxbox.data.pages :as udp]
|
|
[uxbox.data.history :as udh]
|
|
[uxbox.util.lens :as ul]
|
|
[uxbox.util.geom.point :as gpt]
|
|
[uxbox.util.data :refer (classnames)]
|
|
[uxbox.ui.core :as uuc]
|
|
[uxbox.ui.icons :as i]
|
|
[uxbox.ui.mixins :as mx]
|
|
[uxbox.ui.messages :as uum]
|
|
[uxbox.ui.workspace.base :as uuwb]
|
|
[uxbox.ui.workspace.shortcuts :as wshortcuts]
|
|
[uxbox.ui.workspace.header :refer (header)]
|
|
[uxbox.ui.workspace.rules :refer (horizontal-rule vertical-rule)]
|
|
[uxbox.ui.workspace.sidebar :refer (left-sidebar right-sidebar)]
|
|
[uxbox.ui.workspace.colorpalette :refer (colorpalette)]
|
|
[uxbox.ui.workspace.canvas :refer (viewport)]))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Workspace
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defn- workspace-will-mount
|
|
[own]
|
|
(let [[projectid pageid] (:rum/props own)]
|
|
(rs/emit! (dw/initialize projectid pageid)
|
|
(udp/fetch-pages projectid)
|
|
(udh/fetch-page-history pageid)
|
|
(udh/fetch-pinned-page-history pageid))
|
|
own))
|
|
|
|
(defn- workspace-did-mount
|
|
[own]
|
|
(letfn [(handle-scroll-interaction []
|
|
(let [stoper (->> uuc/actions-s
|
|
(rx/map :type)
|
|
(rx/filter #(empty? %))
|
|
(rx/take 1))
|
|
local (:rum/local own)
|
|
initial @uuwb/mouse-viewport-a]
|
|
(swap! local assoc :scrolling true)
|
|
(as-> uuwb/mouse-viewport-s $
|
|
(rx/take-until stoper $)
|
|
(rx/subscribe $ #(on-scroll % initial) nil on-scroll-end))))
|
|
|
|
(on-scroll-end []
|
|
(let [local (:rum/local own)]
|
|
(swap! local assoc :scrolling false)))
|
|
|
|
(on-scroll [pt initial]
|
|
(let [{:keys [x y]} (gpt/subtract pt initial)
|
|
el (mx/get-ref-dom own "workspace-canvas")
|
|
cx (.-scrollLeft el)
|
|
cy (.-scrollTop el)]
|
|
(set! (.-scrollLeft el) (- cx x))
|
|
(set! (.-scrollTop el) (- cy y))))]
|
|
(let [[projectid pageid] (:rum/props own)
|
|
el (mx/get-ref-dom own "workspace-canvas")
|
|
sub1 (as-> uuc/actions-s $
|
|
(rx/map :type $)
|
|
(rx/dedupe $)
|
|
(rx/filter #(= "ui.workspace.scroll" %) $)
|
|
(rx/on-value $ handle-scroll-interaction))
|
|
sub2 (udp/watch-page-changes pageid)]
|
|
(set! (.-scrollLeft el) uuwb/canvas-start-scroll-x)
|
|
(set! (.-scrollTop el) uuwb/canvas-start-scroll-y)
|
|
(assoc own ::sub1 sub1 ::sub2 sub2))))
|
|
|
|
(defn- workspace-will-unmount
|
|
[own]
|
|
(let [sub1 (::sub1 own)
|
|
sub2 (::sub2 own)]
|
|
(.close sub1)
|
|
(.close sub2)
|
|
(dissoc own ::sub1 ::sub2)))
|
|
|
|
(defn- workspace-transfer-state
|
|
[old-state state]
|
|
(let [[projectid pageid] (:rum/props state)
|
|
[oldprojectid oldpageid] (:rum/props old-state)]
|
|
(if (not= pageid oldpageid)
|
|
(do
|
|
(rs/emit! (dw/initialize projectid pageid))
|
|
(.close (::sub2 old-state))
|
|
(assoc state
|
|
::sub1 (::sub1 old-state)
|
|
::sub2 (udp/watch-page-changes pageid)))
|
|
(assoc state
|
|
::sub1 (::sub1 old-state)
|
|
::sub2 (::sub2 old-state)))))
|
|
|
|
(defn- on-scroll
|
|
[event]
|
|
(let [target (.-target event)
|
|
top (.-scrollTop target)
|
|
left (.-scrollLeft target)]
|
|
(rx/push! uuwb/scroll-b (gpt/point left top))))
|
|
|
|
(defn- workspace-render
|
|
[own projectid]
|
|
(let [{:keys [flags] :as workspace} (rum/react uuwb/workspace-l)
|
|
left-sidebar? (not (empty? (keep flags [:layers :sitemap
|
|
:document-history])))
|
|
right-sidebar? (not (empty? (keep flags [:icons :drawtools
|
|
:element-options])))
|
|
local (:rum/local own)
|
|
classes (classnames
|
|
:no-tool-bar-right (not right-sidebar?)
|
|
:no-tool-bar-left (not left-sidebar?)
|
|
:scrolling (:scrolling @local false))]
|
|
(html
|
|
[:div
|
|
(header)
|
|
(colorpalette)
|
|
(uum/messages)
|
|
|
|
[:main.main-content
|
|
|
|
[:section.workspace-content {:class classes :on-scroll on-scroll}
|
|
;; Rules
|
|
(horizontal-rule)
|
|
(vertical-rule)
|
|
|
|
;; Canvas
|
|
[:section.workspace-canvas {:ref "workspace-canvas"}
|
|
(viewport)]]
|
|
|
|
;; Aside
|
|
(when left-sidebar?
|
|
(left-sidebar))
|
|
(when right-sidebar?
|
|
(right-sidebar))
|
|
]])))
|
|
|
|
(def ^:static workspace
|
|
(mx/component
|
|
{:render workspace-render
|
|
:transfer-state workspace-transfer-state
|
|
:will-mount workspace-will-mount
|
|
:will-unmount workspace-will-unmount
|
|
:did-mount workspace-did-mount
|
|
:name "workspace"
|
|
:mixins [mx/static rum/reactive wshortcuts/mixin
|
|
(mx/local)]}))
|