mirror of
https://github.com/penpot/penpot.git
synced 2025-05-27 21:16:13 +02:00
121 lines
3.9 KiB
Clojure
121 lines
3.9 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; 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/.
|
|
;;
|
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
;; defined by the Mozilla Public License, v. 2.0.
|
|
;;
|
|
;; Copyright (c) 2020 UXBOX Labs SL
|
|
|
|
(ns uxbox.main.ui.viewer
|
|
(:require
|
|
[beicon.core :as rx]
|
|
[goog.events :as events]
|
|
[goog.object :as gobj]
|
|
[okulary.core :as l]
|
|
[rumext.alpha :as mf]
|
|
[uxbox.builtins.icons :as i]
|
|
[uxbox.common.exceptions :as ex]
|
|
[uxbox.main.data.viewer :as dv]
|
|
[uxbox.main.refs :as refs]
|
|
[uxbox.main.store :as st]
|
|
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
|
[uxbox.main.ui.hooks :as hooks]
|
|
[uxbox.main.ui.keyboard :as kbd]
|
|
[uxbox.main.ui.messages :refer [messages]]
|
|
[uxbox.main.ui.viewer.header :refer [header]]
|
|
[uxbox.main.ui.viewer.thumbnails :refer [thumbnails-panel]]
|
|
[uxbox.main.ui.viewer.frame-viewer :refer [frame-viewer-svg]]
|
|
[uxbox.util.data :refer [classnames]]
|
|
[uxbox.util.dom :as dom]
|
|
[uxbox.util.i18n :as i18n :refer [t tr]])
|
|
(:import goog.events.EventType))
|
|
|
|
(mf/defc main-panel
|
|
[{:keys [data zoom index]}]
|
|
(let [locale (i18n/use-locale)
|
|
frames (:frames data [])
|
|
objects (:objects data)
|
|
frame (get frames index)]
|
|
[:section.viewer-preview
|
|
(cond
|
|
(empty? frames)
|
|
[:section.empty-state
|
|
[:span (t locale "viewer.empty-state")]]
|
|
|
|
(nil? frame)
|
|
[:section.empty-state
|
|
[:span (t locale "viewer.frame-not-found")]]
|
|
|
|
:else
|
|
[:& frame-viewer-svg {:frame frame
|
|
:zoom zoom
|
|
:objects objects}])]))
|
|
|
|
(mf/defc viewer-content
|
|
[{:keys [data local index] :as props}]
|
|
(let [container (mf/use-ref)
|
|
|
|
[toggle-fullscreen fullscreen?] (hooks/use-fullscreen container)
|
|
|
|
on-click
|
|
(fn [event]
|
|
(dom/stop-propagation event)
|
|
(let [mode (get local :interactions-mode)]
|
|
(when (= mode :show-on-click)
|
|
(st/emit! dv/flash-interactions))))
|
|
|
|
on-mouse-wheel
|
|
(fn [event]
|
|
(when (kbd/ctrl? event)
|
|
(dom/prevent-default event)
|
|
(let [event (.getBrowserEvent event)]
|
|
(if (pos? (.-deltaY event))
|
|
(st/emit! dv/decrease-zoom)
|
|
(st/emit! dv/increase-zoom)))))
|
|
|
|
on-mount
|
|
(fn []
|
|
;; bind with passive=false to allow the event to be cancelled
|
|
;; https://stackoverflow.com/a/57582286/3219895
|
|
(let [key1 (events/listen goog/global EventType.WHEEL
|
|
on-mouse-wheel #js {"passive" false})]
|
|
(fn []
|
|
(events/unlistenByKey key1))))]
|
|
|
|
(mf/use-effect on-mount)
|
|
(hooks/use-shortcuts dv/shortcuts)
|
|
|
|
[:*
|
|
[:& messages]
|
|
[:div.viewer-layout {:class (classnames :fullscreen fullscreen?)
|
|
:ref container}
|
|
|
|
[:& header {:data data
|
|
:toggle-fullscreen toggle-fullscreen
|
|
:fullscreen? fullscreen?
|
|
:local local
|
|
:index index}]
|
|
[:div.viewer-content {:on-click on-click}
|
|
(when (:show-thumbnails local)
|
|
[:& thumbnails-panel {:index index
|
|
:data data}])
|
|
[:& main-panel {:data data
|
|
:zoom (:zoom local)
|
|
:index index}]]]]))
|
|
|
|
|
|
;; --- Component: Viewer Page
|
|
|
|
(mf/defc viewer-page
|
|
[{:keys [page-id index token] :as props}]
|
|
(mf/use-effect
|
|
(mf/deps page-id token)
|
|
#(st/emit! (dv/initialize page-id token)))
|
|
|
|
(let [data (mf/deref refs/viewer-data-ref)
|
|
local (mf/deref refs/viewer-local-ref)]
|
|
(when data
|
|
[:& viewer-content {:index index
|
|
:local local
|
|
:data data}])))
|