mirror of
https://github.com/penpot/penpot.git
synced 2025-05-22 06:26:13 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
4fad2ab619
59 changed files with 608 additions and 325 deletions
|
@ -279,15 +279,19 @@
|
|||
(->
|
||||
(assoc-in (conj path :position) (:position comment-thread))
|
||||
(assoc-in (conj path :frame-id) (:frame-id comment-thread))))))
|
||||
(fetched [data state]
|
||||
(let [state (assoc state :comment-threads (d/index-by :id data))]
|
||||
(reduce set-comment-threds state data)))]
|
||||
(fetched [[users comments] state]
|
||||
(let [state (-> state
|
||||
(assoc :comment-threads (d/index-by :id comments))
|
||||
(assoc :current-file-comments-users (d/index-by :id users)))]
|
||||
(reduce set-comment-threds state comments)))]
|
||||
|
||||
(ptk/reify ::retrieve-comment-threads
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [share-id (-> state :viewer-local :share-id)]
|
||||
(->> (rp/cmd! :get-comment-threads {:file-id file-id :share-id share-id})
|
||||
(->> (rx/zip (rp/cmd! :get-team-users {:file-id file-id})
|
||||
(rp/cmd! :get-comment-threads {:file-id file-id :share-id share-id}))
|
||||
(rx/take 1)
|
||||
(rx/map #(partial fetched %))
|
||||
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.main.data.shortcuts
|
||||
(:refer-clojure :exclude [meta reset!])
|
||||
(:require
|
||||
["mousetrap" :as mousetrap]
|
||||
["./shortcuts_impl.js$default" :as mousetrap]
|
||||
[app.common.logging :as log]
|
||||
[app.common.spec :as us]
|
||||
[app.config :as cf]
|
||||
|
@ -32,6 +32,7 @@
|
|||
(def up-arrow "\u2191")
|
||||
(def right-arrow "\u2192")
|
||||
(def down-arrow "\u2193")
|
||||
(def tab "tab")
|
||||
|
||||
(defn c-mod
|
||||
"Adds the control/command modifier to a shortcuts depending on the
|
||||
|
|
27
frontend/src/app/main/data/shortcuts_impl.js
Normal file
27
frontend/src/app/main/data/shortcuts_impl.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* 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/.
|
||||
*
|
||||
* Copyright (c) KALEIDOS INC
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
import Mousetrap from 'mousetrap'
|
||||
|
||||
const target = Mousetrap.prototype || Mousetrap;
|
||||
target.stopCallback = function(e, element, combo) {
|
||||
// if the element has the class "mousetrap" then no need to stop
|
||||
if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// stop for input, select, textarea and button
|
||||
return element.tagName == 'INPUT' ||
|
||||
element.tagName == 'SELECT' ||
|
||||
element.tagName == 'TEXTAREA' ||
|
||||
element.tagName == 'BUTTON' ||
|
||||
(element.contentEditable && element.contentEditable == 'true');
|
||||
}
|
||||
|
||||
export default Mousetrap;
|
|
@ -37,7 +37,7 @@
|
|||
(s/def ::created-at ::us/inst)
|
||||
(s/def ::password-1 ::us/string)
|
||||
(s/def ::password-2 ::us/string)
|
||||
(s/def ::password-old ::us/string)
|
||||
(s/def ::password-old (s/nilable ::us/string))
|
||||
|
||||
(s/def ::profile
|
||||
(s/keys :req-un [::id]
|
||||
|
|
|
@ -300,6 +300,13 @@
|
|||
(update [_ state]
|
||||
(update-in state [:viewer-local :fullscreen?] not))))
|
||||
|
||||
(defn exit-fullscreen
|
||||
[]
|
||||
(ptk/reify ::exit-fullscreen
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:viewer-local :fullscreen?] false))))
|
||||
|
||||
(defn set-viewport-size
|
||||
[{:keys [size]}]
|
||||
(ptk/reify ::set-viewport-size
|
||||
|
|
|
@ -2043,6 +2043,8 @@
|
|||
(dm/export dws/select-all)
|
||||
(dm/export dws/select-inside-group)
|
||||
(dm/export dws/select-shape)
|
||||
(dm/export dws/select-prev-shape)
|
||||
(dm/export dws/select-next-shape)
|
||||
(dm/export dws/shift-select-shapes)
|
||||
|
||||
;; Highlight
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require
|
||||
[app.common.colors :as colors]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.broadcast :as mbc]
|
||||
[app.main.data.modal :as md]
|
||||
|
@ -81,6 +82,8 @@
|
|||
text-ids (filter is-text? ids)
|
||||
shape-ids (remove is-text? ids)
|
||||
|
||||
undo-id (js/Symbol)
|
||||
|
||||
attrs
|
||||
(cond-> {}
|
||||
(contains? color :color)
|
||||
|
@ -104,8 +107,10 @@
|
|||
transform-attrs #(transform % attrs)]
|
||||
|
||||
(rx/concat
|
||||
(rx/of (dwu/start-undo-transaction undo-id))
|
||||
(rx/from (map #(dwt/update-text-with-function % transform-attrs) text-ids))
|
||||
(rx/of (dch/update-shapes shape-ids transform-attrs)))))
|
||||
(rx/of (dch/update-shapes shape-ids transform-attrs))
|
||||
(rx/of (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
(defn swap-attrs [shape attr index new-index]
|
||||
(let [first (get-in shape [attr index])
|
||||
|
@ -339,7 +344,8 @@
|
|||
(defn change-text-color
|
||||
[old-color new-color index node]
|
||||
(let [fills (map #(dissoc % :fill-color-ref-id :fill-color-ref-file) (:fills node))
|
||||
parsed-color (d/without-nils (color-att->text old-color))
|
||||
parsed-color (-> (d/without-nils (color-att->text old-color))
|
||||
(dissoc :fill-color-ref-id :fill-color-ref-file))
|
||||
parsed-new-color (d/without-nils (color-att->text new-color))
|
||||
has-color? (d/index-of fills parsed-color)]
|
||||
(cond-> node
|
||||
|
@ -365,23 +371,33 @@
|
|||
(rx/of (dwu/commit-undo-transaction undo-id)))))))
|
||||
|
||||
(defn apply-color-from-palette
|
||||
[color is-alt?]
|
||||
[color stroke?]
|
||||
(ptk/reify ::apply-color-from-palette
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (->> (wsh/lookup-selected state)
|
||||
(cph/clean-loops objects))
|
||||
selected-obj (keep (d/getf objects) selected)
|
||||
select-shapes-for-color (fn [shape objects]
|
||||
(let [shapes (case (:type shape)
|
||||
:group (cph/get-children objects (:id shape))
|
||||
[shape])]
|
||||
(->> shapes
|
||||
(remove cph/group-shape?)
|
||||
(map :id))))
|
||||
ids (mapcat #(select-shapes-for-color % objects) selected-obj)]
|
||||
(if is-alt?
|
||||
|
||||
ids
|
||||
(loop [pending (seq selected)
|
||||
result []]
|
||||
(if (empty? pending)
|
||||
result
|
||||
(let [cur (first pending)
|
||||
;; We treat frames with no fill the same as groups
|
||||
group? (or (cph/group-shape? objects cur)
|
||||
(and (cph/frame-shape? objects cur)
|
||||
(empty? (dm/get-in objects [cur :fills]))))
|
||||
|
||||
pending
|
||||
(if group?
|
||||
(concat pending (dm/get-in objects [cur :shapes]))
|
||||
pending)
|
||||
|
||||
result (cond-> result (not group?) (conj cur))]
|
||||
(recur (rest pending) result))))]
|
||||
(if stroke?
|
||||
(rx/of (change-stroke ids (merge uc/empty-color color) 0))
|
||||
(rx/of (change-fill ids (merge uc/empty-color color) 0)))))))
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.main.data.workspace.groups
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
|
@ -195,6 +196,11 @@
|
|||
(keep :id))
|
||||
selected)
|
||||
|
||||
child-ids
|
||||
(into (d/ordered-set)
|
||||
(mapcat #(dm/get-in objects [% :shapes]))
|
||||
selected)
|
||||
|
||||
changes {:redo-changes (vec (mapcat :redo-changes changes-list))
|
||||
:undo-changes (vec (mapcat :undo-changes changes-list))
|
||||
:origin it}
|
||||
|
@ -203,7 +209,8 @@
|
|||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(ptk/data-event :layout/update parents)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
(dwu/commit-undo-transaction undo-id)
|
||||
(dws/select-shapes child-ids))))))
|
||||
|
||||
(def mask-group
|
||||
(ptk/reify ::mask-group
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
(watch [_ state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
frame (cph/get-frame objects shape)
|
||||
frame (cph/get-root-frame objects (:id shape))
|
||||
flows (get-in state [:workspace-data
|
||||
:pages-index
|
||||
page-id
|
||||
|
|
|
@ -176,10 +176,11 @@
|
|||
(ptk/reify ::rename-color
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (get state :workspace-data)
|
||||
object (get-in data [:colors id])
|
||||
new-object (assoc object :name new-name)]
|
||||
(do-update-color it state new-object file-id)))))
|
||||
(when (and (some? new-name) (not= "" new-name))
|
||||
(let [data (get state :workspace-data)
|
||||
object (get-in data [:colors id])
|
||||
new-object (assoc object :name new-name)]
|
||||
(do-update-color it state new-object file-id))))))
|
||||
|
||||
(defn delete-color
|
||||
[{:keys [id] :as params}]
|
||||
|
@ -211,14 +212,15 @@
|
|||
(ptk/reify ::rename-media
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (get state :workspace-data)
|
||||
[path name] (cph/parse-path-name new-name)
|
||||
object (get-in data [:media id])
|
||||
new-object (assoc object :path path :name name)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/update-media new-object))]
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
(when (and (some? new-name) (not= "" new-name))
|
||||
(let [data (get state :workspace-data)
|
||||
[path name] (cph/parse-path-name new-name)
|
||||
object (get-in data [:media id])
|
||||
new-object (assoc object :path path :name name)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/update-media new-object))]
|
||||
(rx/of (dch/commit-changes changes)))))))
|
||||
|
||||
|
||||
(defn delete-media
|
||||
|
@ -281,11 +283,12 @@
|
|||
(ptk/reify ::rename-typography
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (get state :workspace-data)
|
||||
[path name] (cph/parse-path-name new-name)
|
||||
object (get-in data [:typographies id])
|
||||
new-object (assoc object :path path :name name)]
|
||||
(do-update-tipography it state new-object file-id)))))
|
||||
(when (and (some? new-name) (not= "" new-name))
|
||||
(let [data (get state :workspace-data)
|
||||
[path name] (cph/parse-path-name new-name)
|
||||
object (get-in data [:typographies id])
|
||||
new-object (assoc object :path path :name name)]
|
||||
(do-update-tipography it state new-object file-id))))))
|
||||
|
||||
(defn delete-typography
|
||||
[id]
|
||||
|
@ -342,27 +345,28 @@
|
|||
(ptk/reify ::rename-component
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (get state :workspace-data)
|
||||
[path name] (cph/parse-path-name new-name)
|
||||
(when (and (some? new-name) (not= "" new-name))
|
||||
(let [data (get state :workspace-data)
|
||||
[path name] (cph/parse-path-name new-name)
|
||||
|
||||
update-fn
|
||||
(fn [component]
|
||||
;; NOTE: we need to ensure the component exists,
|
||||
;; because there are small possibilities of race
|
||||
;; conditions with component deletion.
|
||||
(when component
|
||||
(-> component
|
||||
(assoc :path path)
|
||||
(assoc :name name)
|
||||
(update :objects
|
||||
;; Give the same name to the root shape
|
||||
#(assoc-in % [id :name] name)))))
|
||||
update-fn
|
||||
(fn [component]
|
||||
;; NOTE: we need to ensure the component exists,
|
||||
;; because there are small possibilities of race
|
||||
;; conditions with component deletion.
|
||||
(when component
|
||||
(-> component
|
||||
(assoc :path path)
|
||||
(assoc :name name)
|
||||
(update :objects
|
||||
;; Give the same name to the root shape
|
||||
#(assoc-in % [id :name] name)))))
|
||||
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/update-component id update-fn))]
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/update-component id update-fn))]
|
||||
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
(rx/of (dch/commit-changes changes)))))))
|
||||
|
||||
(defn duplicate-component
|
||||
"Create a new component copied from the one with the given id."
|
||||
|
|
|
@ -131,6 +131,55 @@
|
|||
objects (wsh/lookup-page-objects state page-id)]
|
||||
(rx/of (dwc/expand-all-parents [id] objects)))))))
|
||||
|
||||
(defn select-prev-shape
|
||||
([]
|
||||
(ptk/reify ::select-prev-shape
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [selected (wsh/lookup-selected state)
|
||||
count-selected (count selected)
|
||||
first-selected (first selected)
|
||||
page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
current (get objects first-selected)
|
||||
parent (get objects (:parent-id current))
|
||||
sibling-ids (:shapes parent)
|
||||
current-index (d/index-of sibling-ids first-selected)
|
||||
sibling (if (= (dec (count sibling-ids)) current-index)
|
||||
(first sibling-ids)
|
||||
(nth sibling-ids (inc current-index)))]
|
||||
|
||||
(cond
|
||||
(= 1 count-selected)
|
||||
(rx/of (select-shape sibling))
|
||||
|
||||
(> count-selected 1)
|
||||
(rx/of (select-shape first-selected))))))))
|
||||
|
||||
(defn select-next-shape
|
||||
([]
|
||||
(ptk/reify ::select-next-shape
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [selected (wsh/lookup-selected state)
|
||||
count-selected (count selected)
|
||||
first-selected (first selected)
|
||||
page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
current (get objects first-selected)
|
||||
parent (get objects (:parent-id current))
|
||||
sibling-ids (:shapes parent)
|
||||
current-index (d/index-of sibling-ids first-selected)
|
||||
sibling (if (= 0 current-index)
|
||||
(last sibling-ids)
|
||||
(nth sibling-ids (dec current-index)))]
|
||||
(cond
|
||||
(= 1 count-selected)
|
||||
(rx/of (select-shape sibling))
|
||||
|
||||
(> count-selected 1)
|
||||
(rx/of (select-shape first-selected))))))))
|
||||
|
||||
(defn deselect-shape
|
||||
[id]
|
||||
(us/verify ::us/uuid id)
|
||||
|
@ -140,13 +189,14 @@
|
|||
(update-in state [:workspace-local :selected] disj id))))
|
||||
|
||||
(defn shift-select-shapes
|
||||
([id] (shift-select-shapes id nil))
|
||||
([id]
|
||||
(shift-select-shapes id nil))
|
||||
|
||||
([id objects]
|
||||
(ptk/reify ::shift-select-shapes
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (or objects (wsh/lookup-page-objects state page-id))
|
||||
(let [objects (or objects (wsh/lookup-page-objects state))
|
||||
selection (-> state
|
||||
wsh/lookup-selected
|
||||
(conj id))]
|
||||
|
|
|
@ -67,8 +67,8 @@
|
|||
:cut {:tooltip (ds/meta "X")
|
||||
:command (ds/c-mod "x")
|
||||
:subsections [:edit]
|
||||
:fn #(emit-when-no-readonly (dw/copy-selected)
|
||||
(dw/delete-selected))}
|
||||
:fn #(emit-when-no-readonly (dw/copy-selected)
|
||||
(dw/delete-selected))}
|
||||
|
||||
:paste {:tooltip (ds/meta "V")
|
||||
:disabled true
|
||||
|
@ -110,7 +110,7 @@
|
|||
|
||||
|
||||
;; MODIFY LAYERS
|
||||
|
||||
|
||||
|
||||
:group {:tooltip (ds/meta "G")
|
||||
:command (ds/c-mod "g")
|
||||
|
@ -222,7 +222,7 @@
|
|||
:fn #(emit-when-no-readonly (dwsl/toggle-layout-flex))}
|
||||
|
||||
;; TOOLS
|
||||
|
||||
|
||||
:draw-frame {:tooltip "B"
|
||||
:command ["b" "a"]
|
||||
:subsections [:tools :basics]
|
||||
|
@ -247,7 +247,7 @@
|
|||
:command "t"
|
||||
:subsections [:tools]
|
||||
:fn #(emit-when-no-readonly dwtxt/start-edit-if-selected
|
||||
(dwd/select-for-drawing :text))}
|
||||
(dwd/select-for-drawing :text))}
|
||||
|
||||
:draw-path {:tooltip "P"
|
||||
:command "p"
|
||||
|
@ -300,7 +300,7 @@
|
|||
:fn #(emit-when-no-readonly (dw/toggle-focus-mode))}
|
||||
|
||||
;; ITEM ALIGNMENT
|
||||
|
||||
|
||||
:align-left {:tooltip (ds/alt "A")
|
||||
:command "alt+a"
|
||||
:subsections [:alignment]
|
||||
|
@ -342,7 +342,7 @@
|
|||
:fn #(emit-when-no-readonly (dw/distribute-objects :vertical))}
|
||||
|
||||
;; MAIN MENU
|
||||
|
||||
|
||||
:toggle-rules {:tooltip (ds/meta-shift "R")
|
||||
:command (ds/c-mod "shift+r")
|
||||
:subsections [:main-menu]
|
||||
|
@ -387,7 +387,7 @@
|
|||
:command (ds/c-mod "shift+e")
|
||||
:subsections [:basics :main-menu]
|
||||
:fn #(st/emit!
|
||||
(de/show-workspace-export-dialog))}
|
||||
(de/show-workspace-export-dialog))}
|
||||
|
||||
:toggle-snap-guide {:tooltip (ds/meta-shift "G")
|
||||
:command (ds/c-mod "shift+g")
|
||||
|
@ -400,7 +400,7 @@
|
|||
:fn #(st/emit! (toggle-layout-flag :shortcuts))}
|
||||
|
||||
;; PANELS
|
||||
|
||||
|
||||
:toggle-layers {:tooltip (ds/alt "L")
|
||||
:command (ds/a-mod "l")
|
||||
:subsections [:panels]
|
||||
|
@ -420,15 +420,15 @@
|
|||
:command (ds/a-mod "p")
|
||||
:subsections [:panels]
|
||||
:fn #(do (r/set-resize-type! :bottom)
|
||||
(emit-when-no-readonly (dw/remove-layout-flag :textpalette)
|
||||
(toggle-layout-flag :colorpalette)))}
|
||||
(emit-when-no-readonly (dw/remove-layout-flag :textpalette)
|
||||
(toggle-layout-flag :colorpalette)))}
|
||||
|
||||
:toggle-textpalette {:tooltip (ds/alt "T")
|
||||
:command (ds/a-mod "t")
|
||||
:subsections [:panels]
|
||||
:fn #(do (r/set-resize-type! :bottom)
|
||||
(emit-when-no-readonly (dw/remove-layout-flag :colorpalette)
|
||||
(toggle-layout-flag :textpalette)))}
|
||||
(emit-when-no-readonly (dw/remove-layout-flag :colorpalette)
|
||||
(toggle-layout-flag :textpalette)))}
|
||||
|
||||
:hide-ui {:tooltip "\\"
|
||||
:command "\\"
|
||||
|
@ -436,7 +436,7 @@
|
|||
:fn #(st/emit! (toggle-layout-flag :hide-ui))}
|
||||
|
||||
;; ZOOM-WORKSPACE
|
||||
|
||||
|
||||
:increase-zoom {:tooltip "+"
|
||||
:command ["+" "="]
|
||||
:subsections [:zoom-workspace]
|
||||
|
@ -473,7 +473,7 @@
|
|||
:fn identity}
|
||||
|
||||
;; NAVIGATION
|
||||
|
||||
|
||||
|
||||
:open-viewer {:tooltip "G V"
|
||||
:command "g v"
|
||||
|
@ -495,7 +495,18 @@
|
|||
:subsections [:navigation-workspace]
|
||||
:fn #(st/emit! (dw/go-to-dashboard))}
|
||||
|
||||
:select-prev {:tooltip (ds/shift "tab")
|
||||
:command "shift+tab"
|
||||
:subsections [:navigation-workspace]
|
||||
:fn #(st/emit! (dw/select-prev-shape))}
|
||||
|
||||
:select-next {:tooltip ds/tab
|
||||
:command "tab"
|
||||
:subsections [:navigation-workspace]
|
||||
:fn #(st/emit! (dw/select-next-shape))}
|
||||
|
||||
;; SHAPE
|
||||
|
||||
|
||||
:bool-union {:tooltip (ds/meta (ds/alt "U"))
|
||||
:command (ds/c-mod "alt+u")
|
||||
|
|
|
@ -202,22 +202,22 @@
|
|||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
(def shortcuts
|
||||
{:align-left {:tooltip (ds/meta (ds/alt "l"))
|
||||
:command (ds/c-mod "alt+l")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "left"})}
|
||||
:align-right {:tooltip (ds/meta (ds/alt "r"))
|
||||
:command (ds/c-mod "alt+r")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "right"})}
|
||||
:align-center {:tooltip (ds/meta (ds/alt "t"))
|
||||
:command (ds/c-mod "alt+t")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "center"})}
|
||||
:align-justify {:tooltip (ds/meta (ds/alt "j"))
|
||||
:command (ds/c-mod "alt+j")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "justify"})}
|
||||
{:text-align-left {:tooltip (ds/meta (ds/alt "l"))
|
||||
:command (ds/c-mod "alt+l")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "left"})}
|
||||
:text-align-right {:tooltip (ds/meta (ds/alt "r"))
|
||||
:command (ds/c-mod "alt+r")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "right"})}
|
||||
:text-align-center {:tooltip (ds/meta (ds/alt "t"))
|
||||
:command (ds/c-mod "alt+t")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "center"})}
|
||||
:text-align-justify {:tooltip (ds/meta (ds/alt "j"))
|
||||
:command (ds/c-mod "alt+j")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-align "justify"})}
|
||||
|
||||
:underline {:tooltip (ds/meta "u")
|
||||
:command (ds/c-mod "u")
|
||||
|
|
|
@ -251,7 +251,7 @@
|
|||
(into [] (distinct) (conj coll item)))
|
||||
|
||||
(mf/defc multi-input
|
||||
[{:keys [form label class name trim valid-item-fn on-submit] :as props}]
|
||||
[{:keys [form label class name trim valid-item-fn caution-item-fn on-submit] :as props}]
|
||||
(let [form (or form (mf/use-ctx form-ctx))
|
||||
input-name (get props :name)
|
||||
touched? (get-in @form [:touched input-name])
|
||||
|
@ -309,7 +309,9 @@
|
|||
(on-submit form))
|
||||
(when (not (str/empty? @value))
|
||||
(reset! value "")
|
||||
(swap! items conj-dedup {:text val :valid (valid-item-fn val)}))))
|
||||
(swap! items conj-dedup {:text val
|
||||
:valid (valid-item-fn val)
|
||||
:caution (caution-item-fn val)}))))
|
||||
|
||||
(and (kbd/backspace? event)
|
||||
(str/empty? @value))
|
||||
|
@ -361,6 +363,7 @@
|
|||
[:div.selected-item {:key (:text item)
|
||||
:tab-index "0"
|
||||
:on-key-down (partial manage-key-down item)}
|
||||
[:span.around {:class (when-not (:valid item) "invalid")}
|
||||
[:span.around {:class (dom/classnames "invalid" (not (:valid item))
|
||||
"caution" (:caution item))}
|
||||
[:span.text (:text item)]
|
||||
[:span.icon {:on-click #(remove-item! item)} i/cross]]])])]))
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
(assert (fn? on-edit) "missing `on-edit` prop")
|
||||
(assert (fn? on-menu-close) "missing `on-menu-close` prop")
|
||||
(assert (boolean? navigate?) "missing `navigate?` prop")
|
||||
(let [is-lib-page? (= :libraries origin)
|
||||
(let [is-lib-page? (= :libraries origin)
|
||||
is-search-page? (= :search origin)
|
||||
top (or top 0)
|
||||
left (or left 0)
|
||||
|
||||
|
@ -264,28 +265,30 @@
|
|||
[{:option-name (tr "dashboard.open-in-new-tab")
|
||||
:id "file-open-new-tab"
|
||||
:option-handler on-new-tab}
|
||||
{:option-name (tr "labels.rename")
|
||||
:id "file-rename"
|
||||
:option-handler on-edit
|
||||
:data-test "file-rename"}
|
||||
{:option-name (tr "dashboard.duplicate")
|
||||
:id "file-duplicate"
|
||||
:option-handler on-duplicate
|
||||
:data-test "file-duplicate"}
|
||||
(when (and (not is-lib-page?) (or (seq current-projects) (seq other-teams)))
|
||||
(when (not is-search-page?)
|
||||
{:option-name (tr "labels.rename")
|
||||
:id "file-rename"
|
||||
:option-handler on-edit
|
||||
:data-test "file-rename"}
|
||||
{:option-name (tr "dashboard.duplicate")
|
||||
:id "file-duplicate"
|
||||
:option-handler on-duplicate
|
||||
:data-test "file-duplicate"})
|
||||
(when (and (not is-lib-page?) (not is-search-page?) (or (seq current-projects) (seq other-teams)))
|
||||
{:option-name (tr "dashboard.move-to")
|
||||
:id "file-move-to"
|
||||
:sub-options sub-options
|
||||
:data-test "file-move-to"})
|
||||
(if (:is-shared file)
|
||||
{:option-name (tr "dashboard.unpublish-shared")
|
||||
:id "file-del-shared"
|
||||
:option-handler on-del-shared
|
||||
:data-test "file-del-shared"}
|
||||
{:option-name (tr "dashboard.add-shared")
|
||||
:id "file-add-shared"
|
||||
:option-handler on-add-shared
|
||||
:data-test "file-add-shared"})
|
||||
(when (not is-search-page?)
|
||||
(if (:is-shared file)
|
||||
{:option-name (tr "dashboard.unpublish-shared")
|
||||
:id "file-del-shared"
|
||||
:option-handler on-del-shared
|
||||
:data-test "file-del-shared"}
|
||||
{:option-name (tr "dashboard.add-shared")
|
||||
:id "file-add-shared"
|
||||
:option-handler on-add-shared
|
||||
:data-test "file-add-shared"}))
|
||||
{:option-name :separator}
|
||||
{:option-name (tr "dashboard.download-binary-file")
|
||||
:id "file-download-binary"
|
||||
|
@ -295,7 +298,7 @@
|
|||
:id "file-download-standard"
|
||||
:option-handler on-export-standard-files
|
||||
:data-test "download-standard-file"}
|
||||
(when (not is-lib-page?)
|
||||
(when (and (not is-lib-page?) (not is-search-page?))
|
||||
{:option-name :separator}
|
||||
{:option-name (tr "labels.delete")
|
||||
:id "file-delete"
|
||||
|
|
|
@ -87,4 +87,5 @@
|
|||
:else
|
||||
[:& grid {:files result
|
||||
:hide-new? true
|
||||
:origin :search
|
||||
:limit limit}])]]))
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
go-webhooks (mf/use-fn #(st/emit! (dd/go-to-team-webhooks)))
|
||||
invite-member (mf/use-fn
|
||||
(mf/deps team)
|
||||
#(st/emit! (modal/show {:type :invite-members :team team :origin :team})))
|
||||
#(st/emit! (modal/show {:type :invite-members
|
||||
:team team
|
||||
:origin :team})))
|
||||
|
||||
members-section? (= section :dashboard-team-members)
|
||||
settings-section? (= section :dashboard-team-settings)
|
||||
|
@ -98,7 +100,10 @@
|
|||
{::mf/register modal/components
|
||||
::mf/register-as :invite-members}
|
||||
[{:keys [team origin]}]
|
||||
(let [perms (:permissions team)
|
||||
(let [members-map (mf/deref refs/dashboard-team-members)
|
||||
|
||||
perms (:permissions team)
|
||||
|
||||
roles (mf/use-memo (mf/deps perms) #(get-available-roles perms))
|
||||
initial (mf/use-memo (constantly {:role "editor" :team-id (:id team)}))
|
||||
form (fm/use-form :spec ::invite-member-form
|
||||
|
@ -111,6 +116,9 @@
|
|||
(modal/hide)
|
||||
(dd/fetch-team-invitations)))
|
||||
|
||||
current-data-emails (into #{} (dm/get-in @form [:clean-data :emails]))
|
||||
current-members-emails (into #{} (map (comp :email second)) members-map)
|
||||
|
||||
on-error
|
||||
(fn [{:keys [type code] :as error}]
|
||||
(cond
|
||||
|
@ -148,17 +156,23 @@
|
|||
[:div.error
|
||||
[:span.icon i/msg-error]
|
||||
[:span.text @error-text]])
|
||||
|
||||
(when (some current-data-emails current-members-emails)
|
||||
[:div.warning
|
||||
[:span.icon i/msg-warning]
|
||||
[:span.text (tr "modals.invite-member.repeated-invitation")]])
|
||||
|
||||
[:div.form-row
|
||||
[:p.label (tr "onboarding.choice.team-up.roles")]
|
||||
[:& fm/select {:name :role :options roles}]]
|
||||
|
||||
[:div.form-row
|
||||
|
||||
|
||||
[:& fm/multi-input {:type "email"
|
||||
:name :emails
|
||||
:auto-focus? true
|
||||
:trim true
|
||||
:valid-item-fn us/parse-email
|
||||
:caution-item-fn current-members-emails
|
||||
:label (tr "modals.invite-member.emails")
|
||||
:on-submit on-submit}]]
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@
|
|||
|
||||
on-pointer-down
|
||||
(mf/use-callback
|
||||
(mf/deps frame-id padding-num)
|
||||
(mf/deps frame-id rect-data padding-num)
|
||||
(fn [event]
|
||||
(dom/capture-pointer event)
|
||||
(reset! resizing? true)
|
||||
|
@ -382,9 +382,9 @@
|
|||
pill-width (/ flex-display-pill-width zoom)
|
||||
pill-height (/ flex-display-pill-height zoom)
|
||||
hover? #(or hover-all?
|
||||
(and (or (= % :p1) (= % :p3)) hover-v?)
|
||||
(and (or (= % :p2) (= % :p4)) hover-h?)
|
||||
(= @hover %))
|
||||
(and (or (= % :p1) (= % :p3)) hover-v?)
|
||||
(and (or (= % :p2) (= % :p4)) hover-h?)
|
||||
(= @hover %))
|
||||
negate {:p1 (if (:flip-y frame) true false)
|
||||
:p2 (if (:flip-x frame) true false)
|
||||
:p3 (if (:flip-y frame) true false)
|
||||
|
@ -854,9 +854,9 @@
|
|||
(mf/defc padding
|
||||
[{:keys [frame zoom alt? shift?]}]
|
||||
(when frame
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& padding-rects {:frame frame :zoom zoom :alt? alt? :shift? shift?}]]]))
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& padding-rects {:frame frame :zoom zoom :alt? alt? :shift? shift?}]]]))
|
||||
|
||||
(mf/defc gap
|
||||
[{:keys [frame zoom]}]
|
||||
|
|
|
@ -32,7 +32,10 @@
|
|||
(defn- on-success
|
||||
[form]
|
||||
(reset! form nil)
|
||||
(let [msg (tr "dashboard.notifications.password-saved")]
|
||||
(let [password-old-node (dom/get-element "password-old")
|
||||
msg (tr "dashboard.notifications.password-saved")]
|
||||
(dom/clean-value! password-old-node)
|
||||
(dom/focus! password-old-node)
|
||||
(st/emit! (dm/success msg))))
|
||||
|
||||
(defn- on-submit
|
||||
|
@ -45,7 +48,7 @@
|
|||
|
||||
(s/def ::password-1 ::us/not-empty-string)
|
||||
(s/def ::password-2 ::us/not-empty-string)
|
||||
(s/def ::password-old ::us/not-empty-string)
|
||||
(s/def ::password-old (s/nilable ::us/string))
|
||||
|
||||
(defn- password-equality
|
||||
[errors data]
|
||||
|
@ -66,9 +69,10 @@
|
|||
|
||||
(mf/defc password-form
|
||||
[{:keys [locale] :as props}]
|
||||
(let [form (fm/use-form :spec ::password-form
|
||||
:validators [password-equality]
|
||||
:initial {})]
|
||||
(let [initial (mf/use-memo (constantly {:password-old nil}))
|
||||
form (fm/use-form :spec ::password-form
|
||||
:validators [password-equality]
|
||||
:initial initial)]
|
||||
[:& fm/form {:class "password-form"
|
||||
:on-submit on-submit
|
||||
:form form}
|
||||
|
@ -77,6 +81,7 @@
|
|||
[:& fm/input
|
||||
{:type "password"
|
||||
:name :password-old
|
||||
:auto-focus? true
|
||||
:label (t locale "labels.old-password")}]]
|
||||
|
||||
[:div.fields-row
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.viewer
|
||||
(:import goog.events.EventType)
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
|
@ -33,6 +34,7 @@
|
|||
[app.main.ui.viewer.thumbnails :refer [thumbnails-panel]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.dom.normalize-wheel :as nw]
|
||||
[app.util.globals :as globals]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.webapi :as wapi]
|
||||
|
@ -328,7 +330,13 @@
|
|||
(dom/stop-propagation event)
|
||||
(if shift?
|
||||
(dom/set-h-scroll-pos! viewer-section new-scroll-pos)
|
||||
(dom/set-scroll-pos! viewer-section new-scroll-pos)))))))]
|
||||
(dom/set-scroll-pos! viewer-section new-scroll-pos)))))))
|
||||
|
||||
on-exit-fullscreen
|
||||
(mf/use-callback
|
||||
(fn []
|
||||
(when (not (dom/fullscreen?))
|
||||
(st/emit! (dv/exit-fullscreen)))))]
|
||||
|
||||
(hooks/use-shortcuts ::viewer sc/shortcuts)
|
||||
(when (nil? page)
|
||||
|
@ -346,11 +354,20 @@
|
|||
(dom/set-html-title (str "\u25b6 " (tr "title.viewer" name))))))
|
||||
|
||||
(mf/with-effect []
|
||||
(let [key1 (events/listen js/window "click" on-click)
|
||||
key2 (events/listen (mf/ref-val viewer-section-ref) "wheel" on-wheel #js {"passive" false})]
|
||||
(dom/set-html-theme-color clr/gray-50 "dark")
|
||||
(let [events
|
||||
[(events/listen globals/window EventType.CLICK on-click)
|
||||
(events/listen (mf/ref-val viewer-section-ref) EventType.WHEEL on-wheel #js {"passive" false})]]
|
||||
|
||||
(doseq [event dom/fullscreen-events]
|
||||
(.addEventListener globals/document event on-exit-fullscreen false))
|
||||
|
||||
(fn []
|
||||
(events/unlistenByKey key1)
|
||||
(events/unlistenByKey key2))))
|
||||
(doseq [key events]
|
||||
(events/unlistenByKey key))
|
||||
|
||||
(doseq [event dom/fullscreen-events]
|
||||
(.removeEventListener globals/document event on-exit-fullscreen)))))
|
||||
|
||||
(mf/use-effect
|
||||
(fn []
|
||||
|
|
|
@ -234,10 +234,11 @@
|
|||
|
||||
;; When we have a text with grow-type :auto-height or :auto-height we need to check the correct height
|
||||
;; otherwise the center alignment will break
|
||||
tr-shape (when text-modifier (dwt/apply-text-modifier shape text-modifier))
|
||||
shape (cond-> shape
|
||||
(and (some? text-modifier) (#{:auto-height :auto-width} (:grow-type shape)))
|
||||
(assoc :width (:width tr-shape) :height (:height tr-shape)))
|
||||
shape
|
||||
(if (some? text-modifier)
|
||||
(let [{:keys [width height]} (dwt/apply-text-modifier shape text-modifier)]
|
||||
(assoc shape :width width :height height))
|
||||
shape)
|
||||
|
||||
shape (hooks/use-equal-memo shape)
|
||||
|
||||
|
|
|
@ -1173,29 +1173,13 @@
|
|||
(:color color) (:color color)
|
||||
:else (:value color))
|
||||
|
||||
;; TODO: looks like the first argument is not necessary
|
||||
;; TODO: this code should be out of this UI component
|
||||
apply-color
|
||||
(fn [_ event]
|
||||
(let [objects (wsh/lookup-page-objects @st/state)
|
||||
selected (->> (wsh/lookup-selected @st/state)
|
||||
(cph/clean-loops objects))
|
||||
selected-obj (keep (d/getf objects) selected)
|
||||
select-shapes-for-color (fn [shape objects]
|
||||
(let [shapes (case (:type shape)
|
||||
:group (cph/get-children objects (:id shape))
|
||||
[shape])]
|
||||
(->> shapes
|
||||
(remove cph/group-shape?)
|
||||
(map :id))))
|
||||
ids (mapcat #(select-shapes-for-color % objects) selected-obj)]
|
||||
(if (kbd/alt? event)
|
||||
(st/emit! (dc/change-stroke ids (merge uc/empty-color color) 0))
|
||||
(st/emit! (dc/change-fill ids (merge uc/empty-color color) 0)))))
|
||||
(fn [event]
|
||||
(st/emit! (dc/apply-color-from-palette (merge uc/empty-color color) (kbd/alt? event))))
|
||||
|
||||
rename-color
|
||||
(fn [name]
|
||||
(st/emit! (dwl/update-color (assoc color :name name) file-id)))
|
||||
(st/emit! (dwl/rename-color file-id (:id color) name)))
|
||||
|
||||
edit-color
|
||||
(fn [new-color]
|
||||
|
@ -1300,8 +1284,7 @@
|
|||
:selected (contains? selected-colors (:id color)))
|
||||
:on-context-menu on-context-menu
|
||||
:on-click (when-not (:editing @state)
|
||||
#(on-asset-click % (:id color)
|
||||
(partial apply-color (:id color))))
|
||||
#(on-asset-click % (:id color) apply-color))
|
||||
:ref item-ref
|
||||
:draggable (and (not workspace-read-only?) (not (:editing @state)))
|
||||
:on-drag-start on-color-drag-start
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.shortcuts :as sc]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.fonts :as fonts]
|
||||
|
@ -25,8 +26,6 @@
|
|||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
||||
|
||||
(mf/defc text-align-options
|
||||
[{:keys [values on-change on-blur] :as props}]
|
||||
(let [{:keys [text-align]} values
|
||||
|
@ -38,22 +37,22 @@
|
|||
;; --- Align
|
||||
[:div.align-icons
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (tr "workspace.options.text-options.align-left")
|
||||
{:alt (tr "workspace.options.text-options.align-left" (sc/get-tooltip :text-align-left))
|
||||
:class (dom/classnames :current (= "left" text-align))
|
||||
:on-click #(handle-change % "left")}
|
||||
i/text-align-left]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (tr "workspace.options.text-options.align-center")
|
||||
{:alt (tr "workspace.options.text-options.align-center" (sc/get-tooltip :text-align-center))
|
||||
:class (dom/classnames :current (= "center" text-align))
|
||||
:on-click #(handle-change % "center")}
|
||||
i/text-align-center]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (tr "workspace.options.text-options.align-right")
|
||||
{:alt (tr "workspace.options.text-options.align-right" (sc/get-tooltip :text-align-right))
|
||||
:class (dom/classnames :current (= "right" text-align))
|
||||
:on-click #(handle-change % "right")}
|
||||
i/text-align-right]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (tr "workspace.options.text-options.align-justify")
|
||||
{:alt (tr "workspace.options.text-options.align-justify" (sc/get-tooltip :text-align-justify))
|
||||
:class (dom/classnames :current (= "justify" text-align))
|
||||
:on-click #(handle-change % "justify")}
|
||||
i/text-align-justify]]))
|
||||
|
@ -149,13 +148,13 @@
|
|||
i/minus]
|
||||
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (tr "workspace.options.text-options.underline")
|
||||
{:alt (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline))
|
||||
:class (dom/classnames :current (= "underline" text-decoration))
|
||||
:on-click #(handle-change % "underline")}
|
||||
i/underline]
|
||||
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (tr "workspace.options.text-options.strikethrough")
|
||||
{:alt (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through))
|
||||
:class (dom/classnames :current (= "line-through" text-decoration))
|
||||
:on-click #(handle-change % "line-through")}
|
||||
i/strikethrough]]))
|
||||
|
|
|
@ -143,6 +143,8 @@
|
|||
;; shortcuts.open-color-picker
|
||||
;; shortcuts.open-comments
|
||||
;; shortcuts.open-dashboard
|
||||
;; shortcuts.select-prev
|
||||
;; shortcuts.select-next
|
||||
;; shortcuts.open-inspect
|
||||
;; shortcuts.open-interactions
|
||||
;; shortcuts.open-viewer
|
||||
|
|
|
@ -134,12 +134,14 @@
|
|||
;; STREAMS
|
||||
move-stream (mf/use-memo #(rx/subject))
|
||||
|
||||
frame-parent (mf/use-memo
|
||||
guide-frame (mf/use-memo
|
||||
(mf/deps @hover-ids base-objects)
|
||||
(fn []
|
||||
(let [parent (get base-objects (last @hover-ids))]
|
||||
(when (= :frame (:type parent))
|
||||
parent))))
|
||||
(let [parent-id
|
||||
(->> @hover-ids
|
||||
(d/seek (partial cph/root-frame? base-objects)))]
|
||||
(when (some? parent-id)
|
||||
(get base-objects parent-id)))))
|
||||
|
||||
zoom (d/check-num zoom 1)
|
||||
drawing-tool (:tool drawing)
|
||||
|
@ -495,7 +497,7 @@
|
|||
[:& guides/viewport-guides
|
||||
{:zoom zoom
|
||||
:vbox vbox
|
||||
:hover-frame frame-parent
|
||||
:hover-frame guide-frame
|
||||
:disabled-guides? disabled-guides?
|
||||
:modifiers modifiers}])
|
||||
|
||||
|
|
|
@ -434,7 +434,15 @@
|
|||
(:id component)
|
||||
(gpt/point final-x final-y))))
|
||||
|
||||
;; Will trigger when the user drags an image from a browser to the viewport
|
||||
;; Will trigger when the user drags an image from a browser to the viewport (firefox and chrome do it a bit different depending on the origin)
|
||||
(dnd/has-type? event "Files")
|
||||
(let [files (dnd/get-files event)
|
||||
params {:file-id (:id file)
|
||||
:position viewport-coord
|
||||
:blobs (seq files)}]
|
||||
(st/emit! (dwm/upload-media-workspace params)))
|
||||
|
||||
;; Will trigger when the user drags an image from a browser to the viewport (firefox and chrome do it a bit different depending on the origin)
|
||||
(dnd/has-type? event "text/uri-list")
|
||||
(let [data (dnd/get-data event "text/uri-list")
|
||||
lines (str/lines data)
|
||||
|
|
|
@ -58,7 +58,8 @@
|
|||
shape (or drawing-obj (-> selected first))]
|
||||
(when (or (and (= (count selected) 1)
|
||||
(= (:id shape) edition)
|
||||
(cph/path-shape? shape))
|
||||
(and (not (cph/text-shape? shape))
|
||||
(not (cph/frame-shape? shape))))
|
||||
(and (some? drawing-obj)
|
||||
(cph/path-shape? drawing-obj)
|
||||
(not= :curve (:tool drawing))))
|
||||
|
|
|
@ -368,12 +368,22 @@
|
|||
(when (some? node)
|
||||
(.blur node)))
|
||||
|
||||
;; List of dom events for different browsers to detect the exit of fullscreen mode
|
||||
(def fullscreen-events
|
||||
["fullscreenchange" "mozfullscreenchange" "MSFullscreenChange" "webkitfullscreenchange"])
|
||||
|
||||
(defn fullscreen?
|
||||
[]
|
||||
(cond
|
||||
(obj/in? globals/document "webkitFullscreenElement")
|
||||
(boolean (.-webkitFullscreenElement globals/document))
|
||||
|
||||
(obj/in? globals/document "mozFullScreen")
|
||||
(boolean (.-mozFullScreen globals/document))
|
||||
|
||||
(obj/in? globals/document "msFullscreenElement")
|
||||
(boolean (.-msFullscreenElement globals/document))
|
||||
|
||||
(obj/in? globals/document "fullscreenElement")
|
||||
(boolean (.-fullscreenElement globals/document))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue