Merge remote-tracking branch 'origin/staging' into develop
|
@ -6,11 +6,11 @@
|
|||
|
||||
(ns user
|
||||
(:require
|
||||
[app.common.pprint :as pp]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.schema.desc-js-like :as smdj]
|
||||
[app.common.schema.desc-native :as smdn]
|
||||
[app.common.schema.generators :as sg]
|
||||
[app.common.pprint :as pp]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.pprint :refer [pprint print-table]]
|
||||
[clojure.repl :refer :all]
|
||||
|
|
|
@ -13,25 +13,22 @@
|
|||
[cuerdas.core :as str]))
|
||||
|
||||
(def black "#000000")
|
||||
(def canvas "#E8E9EA")
|
||||
|
||||
(def default-layout "#DE4762")
|
||||
(def gray-10 "#E3E3E3")
|
||||
(def gray-20 "#B1B2B5")
|
||||
(def gray-30 "#7B7D85")
|
||||
(def gray-40 "#64666A")
|
||||
(def gray-50 "#303236")
|
||||
(def info "#59B9E2")
|
||||
(def test "#fabada")
|
||||
(def white "#FFFFFF")
|
||||
(def primary "#31EFB8")
|
||||
(def danger "#E65244")
|
||||
(def warning "#FC8802")
|
||||
|
||||
;; new-css-system colors
|
||||
(def new-primary "#91fadb")
|
||||
(def new-danger "#ff4986")
|
||||
(def new-warning "#ff9b49")
|
||||
(def canvas-background "#1d1f20")
|
||||
(def new-primary "#7efff5")
|
||||
(def new-danger "#ff3277")
|
||||
(def new-warning "#fe4811")
|
||||
(def new-primary-light "#6911d4")
|
||||
(def background-quaternary "#2e3434")
|
||||
(def background-quaternary-light "#eef0f2")
|
||||
(def canvas "#E8E9EA")
|
||||
|
||||
(def names
|
||||
{"aliceblue" "#f0f8ff"
|
||||
|
|
|
@ -749,21 +749,23 @@
|
|||
(defmulti components-changed (fn [_ change] (:type change)))
|
||||
|
||||
(defmethod components-changed :mod-obj
|
||||
[file-data {:keys [id page-id _component-id operations]}]
|
||||
(when page-id
|
||||
(let [page (ctpl/get-page file-data page-id)
|
||||
shape-and-parents (map #(ctn/get-shape page %)
|
||||
(cons id (cfh/get-parent-ids (:objects page) id)))
|
||||
need-sync? (fn [operation]
|
||||
; We need to trigger a sync if the shape has changed any
|
||||
; attribute that participates in components synchronization.
|
||||
(and (= (:type operation) :set)
|
||||
(get ctk/sync-attrs (:attr operation))))
|
||||
any-sync? (some need-sync? operations)]
|
||||
(when any-sync?
|
||||
(let [xform (comp (filter :main-instance) ; Select shapes that are main component instances
|
||||
[file-data {:keys [id page-id component-id operations]}]
|
||||
(let [need-sync? (fn [operation]
|
||||
; We need to trigger a sync if the shape has changed any
|
||||
; attribute that participates in components synchronization.
|
||||
(and (= (:type operation) :set)
|
||||
(get ctk/sync-attrs (:attr operation))))
|
||||
any-sync? (some need-sync? operations)]
|
||||
(when any-sync?
|
||||
(if page-id
|
||||
(let [page (ctpl/get-page file-data page-id)
|
||||
shape-and-parents (map #(ctn/get-shape page %)
|
||||
(cons id (cfh/get-parent-ids (:objects page) id)))
|
||||
xform (comp (filter :main-instance) ; Select shapes that are main component instances
|
||||
(map :component-id))]
|
||||
(into #{} xform shape-and-parents))))))
|
||||
(into #{} xform shape-and-parents))
|
||||
(when component-id
|
||||
#{component-id})))))
|
||||
|
||||
(defmethod components-changed :mov-objects
|
||||
[file-data {:keys [page-id _component-id parent-id shapes] :as change}]
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
(:require
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]))
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.points :as gpo]))
|
||||
|
||||
;; --- Alignment
|
||||
|
||||
|
@ -30,6 +31,23 @@
|
|||
(- (:y align-pos) (:y wrapper-rect)))]
|
||||
(gsh/move shape delta)))
|
||||
|
||||
(defn align-to-parent
|
||||
"Does the same calc as align-to-rect but relative to a parent shape."
|
||||
[shape parent axis]
|
||||
(let [parent-bounds (:points parent)
|
||||
wrapper-rect
|
||||
(-> (gsh/transform-points (:points shape) (gsh/shape->center parent) (:transform-inverse parent))
|
||||
(grc/points->rect))
|
||||
|
||||
align-pos (calc-align-pos wrapper-rect (:selrect parent) axis)
|
||||
|
||||
xv #(gpo/start-hv parent-bounds %)
|
||||
yv #(gpo/start-vv parent-bounds %)
|
||||
|
||||
delta (-> (xv (- (:x align-pos) (:x wrapper-rect)))
|
||||
(gpt/add (yv (- (:y align-pos) (:y wrapper-rect)))))]
|
||||
(gsh/move shape delta)))
|
||||
|
||||
(defn calc-align-pos
|
||||
[wrapper-rect rect axis]
|
||||
(case axis
|
||||
|
|
|
@ -211,7 +211,7 @@
|
|||
([{:keys [type metadata] :as shape} objects]
|
||||
(assert (map? objects))
|
||||
(case type
|
||||
:group
|
||||
(:group :frame)
|
||||
(group-to-path shape objects)
|
||||
|
||||
:bool
|
||||
|
|
|
@ -103,6 +103,12 @@
|
|||
(concat (map #(ctn/make-container % :page) (ctpl/pages-seq file-data))
|
||||
(map #(ctn/make-container % :component) (ctkl/components-seq file-data))))
|
||||
|
||||
(defn object-containers-seq
|
||||
"Generate a sequence of all pages and all deleted components (all those components that have :objects), wrapped as containers"
|
||||
[file-data]
|
||||
(concat (map #(ctn/make-container % :page) (ctpl/pages-seq file-data))
|
||||
(map #(ctn/make-container % :component) (ctkl/deleted-components-seq file-data))))
|
||||
|
||||
(defn update-container
|
||||
"Update a container inside the file, it can be a page or a component"
|
||||
[file-data container f]
|
||||
|
|
|
@ -247,6 +247,16 @@ function templatePipeline(options) {
|
|||
|
||||
gulpSass.compiler = sass;
|
||||
|
||||
|
||||
gulp.task("scss:clean", async function (next) {
|
||||
try {
|
||||
await rimraf("./resources/public/.tmp");
|
||||
await rimraf("./resources/public/css");
|
||||
} finally {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task("scss:modules", function () {
|
||||
return gulp
|
||||
.src(["src/**/**.scss"])
|
||||
|
@ -314,7 +324,10 @@ gulp.task("scss:touch:modules", function() {
|
|||
return gulp.src("src/**/**.scss").pipe(touch());
|
||||
});
|
||||
|
||||
gulp.task("scss", gulp.series("scss:main", "scss:modules", "scss:concat", "scss:touch:main"));
|
||||
gulp.task("scss", gulp.series("scss:main",
|
||||
"scss:modules",
|
||||
"scss:concat",
|
||||
"scss:touch:main"));
|
||||
|
||||
gulp.task("svg:sprite:icons", function () {
|
||||
return gulp
|
||||
|
@ -419,9 +432,18 @@ gulp.task("clean:dist", function (next) {
|
|||
});
|
||||
|
||||
gulp.task("build:styles", gulp.parallel("scss"));
|
||||
gulp.task("build:assets", gulp.parallel("polyfills", "templates", "copy:assets"));
|
||||
|
||||
gulp.task("watch", gulp.series("dev:dirs", "build:styles", "build:assets", "watch:main"));
|
||||
gulp.task("build:assets",
|
||||
gulp.parallel("polyfills",
|
||||
"templates",
|
||||
"copy:assets"));
|
||||
|
||||
gulp.task("watch",
|
||||
gulp.series("dev:dirs",
|
||||
"scss:clean",
|
||||
"build:styles",
|
||||
"build:assets",
|
||||
"watch:main"));
|
||||
|
||||
gulp.task("build:copy", function () {
|
||||
return gulp.src("./resources/public/**/*").pipe(gulp.dest("./target/dist/"));
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 .667h12M12 5.5A1.5 1.5 0 0010.5 4h-5A1.5 1.5 0 004 5.5v1A1.5 1.5 0 005.5 8h5A1.5 1.5 0 0012 6.5v-1zm0 7.333a1.5 1.5 0 00-1.5-1.5h-5a1.5 1.5 0 00-1.5 1.5v1a1.5 1.5 0 001.5 1.5h5a1.5 1.5 0 001.5-1.5v-1z"/>
|
||||
<path d="M2 15.333h12M12 10.5a1.5 1.5 0 01-1.5 1.5h-5A1.5 1.5 0 014 10.5v-1A1.5 1.5 0 015.5 8h5A1.5 1.5 0 0112 9.5v1zm0-7.333a1.5 1.5 0 01-1.5 1.5h-5a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h5a1.5 1.5 0 011.5 1.5v1z"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 339 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 15.333h12M12 10.5a1.5 1.5 0 01-1.5 1.5h-5A1.5 1.5 0 014 10.5v-1A1.5 1.5 0 015.5 8h5A1.5 1.5 0 0112 9.5v1zm0-7.333a1.5 1.5 0 01-1.5 1.5h-5a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h5a1.5 1.5 0 011.5 1.5v1z"/>
|
||||
<path d="M2 .667h12M12 5.5A1.5 1.5 0 0010.5 4h-5A1.5 1.5 0 004 5.5v1A1.5 1.5 0 005.5 8h5A1.5 1.5 0 0012 6.5v-1zm0 7.333a1.5 1.5 0 00-1.5-1.5h-5a1.5 1.5 0 00-1.5 1.5v1a1.5 1.5 0 001.5 1.5h5a1.5 1.5 0 001.5-1.5v-1z"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 333 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M15.5 7.617h-14m14 0l-6.008 4.996M15.5 7.617L9.492 2.613"/>
|
||||
</svg>
|
After Width: | Height: | Size: 186 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M5.8 8a4.7 4.7 0 109.4 0 4.7 4.7 0 00-9.4 0zm0 0H1.5m5.643 1.68h.396m1.184 1.677h.395M7.143 6.321h.396m1.184 1.68h.395m1.185 1.678h.394m1.185 1.678h.396M8.723 4.643h.395m1.185 1.678h.394m1.185 1.68h.396m1.184 1.678h.395m-1.974-5.036h.395m1.184 1.678h.395"/>
|
||||
</svg>
|
After Width: | Height: | Size: 384 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M6.888 9.656h.391m1.168 1.656h.39M6.888 6.344h.391M8.447 8h.39m1.168 1.656h.39m1.168 1.656h.391M8.447 4.688h.39m1.168 1.656h.39M11.563 8h.391m1.169 1.656h.389m-1.947-4.968h.389m1.169 1.656h.389M1.5 8H5m-.025.18l5.045 5.045a.254.254 0 00.36 0l5.045-5.045a.255.255 0 00.056-.277.255.255 0 00-.056-.083L10.38 2.775a.253.253 0 00-.36 0L4.975 7.82a.253.253 0 000 .36z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 492 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M7.167 9.667h.393m1.176 1.666h.392m-1.961-5h.393M8.736 8h.392m1.176 1.667h.392m1.176 1.666h.393M8.736 4.667h.392m1.176 1.666h.392M11.872 8h.393m1.176 1.667h.392m-1.96-5h.392m1.176 1.666h.392M1.5 8h5m0-4h8v8h-8V4z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 342 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.833 4h10.098c2.34 0 4.236 1.791 4.236 4s-1.896 4-4.236 4H.833"/>
|
||||
</svg>
|
After Width: | Height: | Size: 193 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.833 4h14.334v8H.833"/>
|
||||
</svg>
|
After Width: | Height: | Size: 153 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M7.633 9.627h.374m1.117 1.627h.372M7.633 6.373h.374M9.124 8h.372m1.117 1.627h.372M9.124 4.746h.372m1.117 1.627h.372M12.102 8h.373M1.5 8l5.5.004m7.88-.225l-7.494-4.74a.246.246 0 00-.256-.006.262.262 0 00-.13.227v9.48c0 .094.05.181.13.227.08.046.178.044.256-.006l7.494-4.74A.26.26 0 0015 8a.26.26 0 00-.12-.221z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 441 B |
|
@ -63,7 +63,7 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [stoper-s (rx/filter (ptk/type? ::finalize) stream)
|
||||
(let [stopper (rx/filter (ptk/type? ::finalize) stream)
|
||||
profile-id (:profile-id state)]
|
||||
|
||||
(->> (rx/merge
|
||||
|
@ -92,7 +92,7 @@
|
|||
(rx/filter #(= id (:id %)))
|
||||
(rx/map du/set-current-team)))
|
||||
|
||||
(rx/take-until stoper-s))))))
|
||||
(rx/take-until stopper))))))
|
||||
|
||||
(defn finalize
|
||||
[params]
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
ptk/EffectEvent
|
||||
(effect [_ _ stream]
|
||||
(let [session (atom nil)
|
||||
stoper (rx/filter (ptk/type? ::initialize) stream)
|
||||
stopper (rx/filter (ptk/type? ::initialize) stream)
|
||||
buffer (atom #queue [])
|
||||
profile (->> (rx/from-atom storage {:emit-current-value? true})
|
||||
(rx/map :profile)
|
||||
|
@ -259,7 +259,7 @@
|
|||
(rx/tap (fn [_]
|
||||
(l/debug :hint "events chunk persisted" :total (count chunk))))
|
||||
(rx/map (constantly chunk))))))
|
||||
(rx/take-until stoper)
|
||||
(rx/take-until stopper)
|
||||
(rx/subs! (fn [chunk]
|
||||
(swap! buffer remove-from-buffer (count chunk)))
|
||||
(fn [cause]
|
||||
|
@ -290,7 +290,7 @@
|
|||
(swap! buffer append-to-buffer event)))
|
||||
|
||||
(rx/switch-map #(rx/timer (inst-ms session-timeout)))
|
||||
(rx/take-until stoper)
|
||||
(rx/take-until stopper)
|
||||
(rx/subs! (fn [_]
|
||||
(l/debug :hint "session reinitialized")
|
||||
(reset! session nil))
|
||||
|
|
|
@ -209,7 +209,7 @@
|
|||
(rx/filter #(= @resource-id (:resource-id %)))
|
||||
(rx/share))
|
||||
|
||||
stoper
|
||||
stopper
|
||||
(rx/filter #(or (= "ended" (:status %))
|
||||
(= "error" (:status %)))
|
||||
progress-stream)]
|
||||
|
@ -228,12 +228,12 @@
|
|||
(initialize-export-status exports cmd resource))))
|
||||
|
||||
;; We proceed to update the export state with incoming
|
||||
;; progress updates. We delay the stoper for give some time
|
||||
;; progress updates. We delay the stopper for give some time
|
||||
;; to update the status with ended or errored status before
|
||||
;; close the stream.
|
||||
(->> progress-stream
|
||||
(rx/map update-export-status)
|
||||
(rx/take-until (rx/delay 500 stoper))
|
||||
(rx/take-until (rx/delay 500 stopper))
|
||||
(rx/finalize (fn []
|
||||
(swap! st/ongoing-tasks disj :export))))
|
||||
|
||||
|
@ -246,7 +246,7 @@
|
|||
(rx/take 1)
|
||||
(rx/delay default-timeout)
|
||||
(rx/map #(clear-export-state @resource-id))
|
||||
(rx/take-until (rx/delay 6000 stoper))))))))
|
||||
(rx/take-until (rx/delay 6000 stopper))))))))
|
||||
|
||||
(defn retry-last-export
|
||||
[]
|
||||
|
|
|
@ -61,16 +61,16 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(rx/merge
|
||||
(let [stoper (rx/filter (ptk/type? ::hide) stream)]
|
||||
(let [stopper (rx/filter (ptk/type? ::hide) stream)]
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? :app.util.router/navigate))
|
||||
(rx/map (constantly hide))
|
||||
(rx/take-until stoper)))
|
||||
(rx/take-until stopper)))
|
||||
(when (:timeout data)
|
||||
(let [stoper (rx/filter (ptk/type? ::show) stream)]
|
||||
(let [stopper (rx/filter (ptk/type? ::show) stream)]
|
||||
(->> (rx/of hide)
|
||||
(rx/delay (:timeout data))
|
||||
(rx/take-until stoper))))))))
|
||||
(rx/take-until stopper))))))))
|
||||
|
||||
(def hide
|
||||
(ptk/reify ::hide
|
||||
|
@ -80,10 +80,10 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stoper (rx/filter (ptk/type? ::show) stream)]
|
||||
(let [stopper (rx/filter (ptk/type? ::show) stream)]
|
||||
(->> (rx/of #(dissoc % :message))
|
||||
(rx/delay default-animation-timeout)
|
||||
(rx/take-until stoper))))))
|
||||
(rx/take-until stopper))))))
|
||||
|
||||
(defn hide-tag
|
||||
[tag]
|
||||
|
|
|
@ -51,9 +51,9 @@
|
|||
|
||||
(vreset! ws-conn ws)
|
||||
|
||||
(let [stoper (rx/merge
|
||||
(rx/filter (ptk/type? ::finalize) stream)
|
||||
(rx/filter (ptk/type? ::initialize) stream))]
|
||||
(let [stopper (rx/merge
|
||||
(rx/filter (ptk/type? ::finalize) stream)
|
||||
(rx/filter (ptk/type? ::initialize) stream))]
|
||||
|
||||
(->> (rx/merge
|
||||
(rx/of #(assoc % :ws-conn ws))
|
||||
|
@ -64,7 +64,7 @@
|
|||
(->> (ws/get-rcv-stream ws)
|
||||
(rx/filter ws/opened-event?)
|
||||
(rx/map (fn [_] (ptk/data-event ::opened {})))))
|
||||
(rx/take-until stoper)))))))
|
||||
(rx/take-until stopper)))))))
|
||||
|
||||
;; --- Finalize Websocket
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.collapse :as dwco]
|
||||
[app.main.data.workspace.drawing :as dwd]
|
||||
[app.main.data.workspace.drawing.common :as dwdc]
|
||||
[app.main.data.workspace.edition :as dwe]
|
||||
[app.main.data.workspace.fix-bool-contents :as fbc]
|
||||
[app.main.data.workspace.fix-broken-shapes :as fbs]
|
||||
|
@ -153,7 +152,7 @@
|
|||
(watch [_ _ stream]
|
||||
(let [team-id (:id team)
|
||||
file-id (:id file)
|
||||
stoper-s (rx/filter (ptk/type? ::bundle-fetched) stream)]
|
||||
stopper (rx/filter (ptk/type? ::bundle-fetched) stream)]
|
||||
|
||||
(->> (rx/concat
|
||||
;; Initialize notifications
|
||||
|
@ -204,7 +203,7 @@
|
|||
|
||||
(rx/of (with-meta (workspace-initialized)
|
||||
{:file-id file-id})))
|
||||
(rx/take-until stoper-s))))))
|
||||
(rx/take-until stopper))))))
|
||||
|
||||
(defn- libraries-fetched
|
||||
[libraries]
|
||||
|
@ -1080,7 +1079,7 @@
|
|||
(let [object (get objects object-id)
|
||||
parent-id (:parent-id (get objects object-id))
|
||||
parent (get objects parent-id)]
|
||||
[(gal/align-to-rect object parent axis)]))
|
||||
[(gal/align-to-parent object parent axis)]))
|
||||
|
||||
(defn align-objects-list
|
||||
[objects selected axis]
|
||||
|
@ -2138,7 +2137,6 @@
|
|||
(watch [_ _ _]
|
||||
(if read-only?
|
||||
(rx/of :interrupt
|
||||
(dwdc/clear-drawing)
|
||||
(remove-layout-flag :colorpalette)
|
||||
(remove-layout-flag :textpalette))
|
||||
(rx/empty)))))
|
||||
|
|
|
@ -526,9 +526,9 @@
|
|||
(ptk/reify ::initialize-colorpicker
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stoper (rx/merge
|
||||
(rx/filter (ptk/type? ::finalize-colorpicker) stream)
|
||||
(rx/filter (ptk/type? ::initialize-colorpicker) stream))]
|
||||
(let [stopper (rx/merge
|
||||
(rx/filter (ptk/type? ::finalize-colorpicker) stream)
|
||||
(rx/filter (ptk/type? ::initialize-colorpicker) stream))]
|
||||
|
||||
(->> (rx/merge
|
||||
(->> stream
|
||||
|
@ -537,7 +537,7 @@
|
|||
(rx/filter (ptk/type? ::update-colorpicker-color) stream)
|
||||
(rx/filter (ptk/type? ::activate-colorpicker-gradient) stream))
|
||||
(rx/map (constantly (colorpicker-onchange-runner on-change)))
|
||||
(rx/take-until stoper))))
|
||||
(rx/take-until stopper))))
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
(ptk/reify ::initialize-comments
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stoper (rx/filter #(= ::finalize %) stream)]
|
||||
(let [stopper (rx/filter #(= ::finalize %) stream)]
|
||||
(rx/merge
|
||||
(rx/of (dcm/retrieve-comment-threads file-id))
|
||||
(->> stream
|
||||
|
@ -45,11 +45,11 @@
|
|||
(rx/filter (fn [[_ space]] (not space)))
|
||||
(rx/map first)
|
||||
(rx/map handle-comment-layer-click)
|
||||
(rx/take-until stoper))
|
||||
(rx/take-until stopper))
|
||||
(->> stream
|
||||
(rx/filter dwco/interrupt?)
|
||||
(rx/map handle-interrupt)
|
||||
(rx/take-until stoper)))))))
|
||||
(rx/take-until stopper)))))))
|
||||
|
||||
(defn- handle-interrupt
|
||||
[]
|
||||
|
|
|
@ -38,8 +38,7 @@
|
|||
(watch [_ _ stream]
|
||||
(rx/merge
|
||||
(when (= tool :path)
|
||||
(rx/of (start-drawing :path)
|
||||
(dwc/hide-toolbar)))
|
||||
(rx/of (start-drawing :path)))
|
||||
|
||||
(when (= tool :curve)
|
||||
(let [stopper (rx/filter dwc/interrupt? stream)]
|
||||
|
|
|
@ -78,12 +78,12 @@
|
|||
(ptk/reify ::handle-drawing
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [stoper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter #(= % :interrupt))))
|
||||
(let [stopper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter #(= % :interrupt))))
|
||||
|
||||
layout (get state :workspace-layout)
|
||||
zoom (dm/get-in state [:workspace-local :zoom] 1)
|
||||
|
@ -131,7 +131,7 @@
|
|||
(rx/filter #(> (gpt/distance % initial) (/ 2 zoom)))
|
||||
;; Take until before the snap calculation otherwise we could cancel the snap in the worker
|
||||
;; and its a problem for fast moving drawing
|
||||
(rx/take-until stoper)
|
||||
(rx/take-until stopper)
|
||||
(rx/with-latest-from ms/mouse-position-shift ms/mouse-position-mod)
|
||||
(rx/switch-map
|
||||
(fn [[point :as current]]
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
(def simplify-tolerance 0.3)
|
||||
|
||||
(defn stoper-event?
|
||||
(defn stopper-event?
|
||||
[{:keys [type] :as event}]
|
||||
(and (mse/mouse-event? event)
|
||||
(= type :up)))
|
||||
|
@ -104,7 +104,7 @@
|
|||
(ptk/reify ::handle-drawing
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stoper (rx/filter stoper-event? stream)
|
||||
(let [stopper (rx/filter stopper-event? stream)
|
||||
mouse (rx/sample 10 ms/mouse-position)
|
||||
shape (cts/setup-shape {:type :path
|
||||
:initialized? true
|
||||
|
@ -115,7 +115,7 @@
|
|||
(rx/of #(update % :workspace-drawing assoc :object shape))
|
||||
(->> mouse
|
||||
(rx/map insert-point)
|
||||
(rx/take-until stoper))
|
||||
(rx/take-until stopper))
|
||||
(rx/of
|
||||
(setup-frame)
|
||||
(finish-drawing)
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
(ns app.main.data.workspace.edition
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.path.common :as dwpc]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
@ -33,25 +32,27 @@
|
|||
state)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [objects (wsh/lookup-page-objects state)]
|
||||
(rx/concat
|
||||
(if (ctl/grid-layout? objects id)
|
||||
(rx/of (dwc/hide-toolbar))
|
||||
(rx/empty))
|
||||
(->> stream
|
||||
(rx/filter interrupt?)
|
||||
(rx/take 1)
|
||||
(rx/map (constantly clear-edition-mode))))))))
|
||||
(watch [_ _ stream]
|
||||
(->> stream
|
||||
(rx/filter interrupt?)
|
||||
(rx/take 1)
|
||||
(rx/map clear-edition-mode)))))
|
||||
|
||||
;; If these event change modules review /src/app/main/data/workspace/path/undo.cljs
|
||||
(def clear-edition-mode
|
||||
(defn clear-edition-mode
|
||||
[]
|
||||
(ptk/reify ::clear-edition-mode
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update :workspace-local dissoc :edition)
|
||||
(update :workspace-drawing dissoc :tool :object :lock)
|
||||
(dissoc :workspace-grid-edition)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [id (get-in state [:workspace-local :edition])]
|
||||
(-> state
|
||||
(update :workspace-local dissoc :edition)
|
||||
(dissoc :workspace-grid-edition)
|
||||
(assoc-in [:workspace-local :hide-toolbar] false)
|
||||
(cond-> (some? id) (update-in [:workspace-local :edit-path] dissoc id)))))))
|
||||
(rx/concat
|
||||
(when (some? id)
|
||||
(dwpc/finish-path)))))))
|
||||
|
||||
|
|
|
@ -317,10 +317,10 @@
|
|||
|
||||
(let [file (wsh/get-file state file-id)
|
||||
components-v2 (get-in file [:options :components-v2])]
|
||||
(loop [pages (vals (get file :pages-index))
|
||||
(loop [containers (ctf/object-containers-seq file)
|
||||
changes (pcb/empty-changes it)]
|
||||
(if-let [page (first pages)]
|
||||
(recur (next pages)
|
||||
(if-let [container (first containers)]
|
||||
(recur (next containers)
|
||||
(pcb/concat-changes
|
||||
changes
|
||||
(generate-sync-container it
|
||||
|
@ -328,7 +328,7 @@
|
|||
asset-id
|
||||
library-id
|
||||
state
|
||||
(cfh/make-container page :page)
|
||||
container
|
||||
components-v2)))
|
||||
changes))))
|
||||
|
||||
|
@ -597,9 +597,7 @@
|
|||
(log/debug :msg "Sync shape direct" :shape (str shape-id) :reset? reset?)
|
||||
(let [shape-inst (ctn/get-shape container shape-id)
|
||||
library (dm/get-in libraries [(:component-file shape-inst) :data])
|
||||
component (or (ctkl/get-component library (:component-id shape-inst))
|
||||
(and reset?
|
||||
(ctkl/get-deleted-component library (:component-id shape-inst))))]
|
||||
component (ctkl/get-component library (:component-id shape-inst) true)]
|
||||
(if (and (ctk/in-component-copy? shape-inst)
|
||||
(or (ctf/direct-copy? shape-inst component container nil libraries) reset?)) ; In a normal sync, we don't want to sync remote mains, only direct/near
|
||||
(let [redirect-shaperef (partial redirect-shaperef container libraries)
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
(ptk/reify ::initialize
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [stoper (rx/filter (ptk/type? ::finalize) stream)
|
||||
(let [stopper (rx/filter (ptk/type? ::finalize) stream)
|
||||
profile-id (:profile-id state)
|
||||
|
||||
initmsg [{:type :subscribe-file
|
||||
|
@ -87,7 +87,7 @@
|
|||
(rx/pipe (rxs/throttle 100))
|
||||
(rx/map #(handle-pointer-send file-id (:pt %)))))
|
||||
|
||||
(rx/take-until stoper))]
|
||||
(rx/take-until stopper))]
|
||||
|
||||
(rx/concat stream (rx/of (dws/send endmsg)))))))
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.drawing.common :as dwdc]
|
||||
[app.main.data.workspace.edition :as dwe]
|
||||
[app.main.data.workspace.path.changes :as changes]
|
||||
|
@ -166,16 +165,16 @@
|
|||
(ptk/reify ::start-path-from-point
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [stoper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
(let [stopper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
|
||||
drag-events (->> (streams/position-stream state)
|
||||
(rx/map #(drag-handler %))
|
||||
(rx/take-until stoper))]
|
||||
(rx/take-until stopper))]
|
||||
(rx/concat
|
||||
(rx/of (add-node position))
|
||||
(streams/drag-stream
|
||||
|
@ -197,16 +196,16 @@
|
|||
"should be a pointer"
|
||||
(gpt/point? down-event))
|
||||
|
||||
(let [stoper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
(let [stopper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
|
||||
drag-events (->> (streams/position-stream state)
|
||||
(rx/map #(drag-handler %))
|
||||
(rx/take-until stoper))]
|
||||
(rx/take-until stopper))]
|
||||
(rx/concat
|
||||
(rx/of (add-node down-event))
|
||||
(streams/drag-stream
|
||||
|
@ -307,10 +306,8 @@
|
|||
(ptk/reify ::handle-new-shape
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [id (st/get-path-id state)
|
||||
shape (cts/setup-shape {:type :path})]
|
||||
(let [shape (cts/setup-shape {:type :path})]
|
||||
(-> state
|
||||
(assoc-in [:workspace-local :edit-path id :snap-toggled] false)
|
||||
(update :workspace-drawing assoc :object shape))))
|
||||
|
||||
ptk/WatchEvent
|
||||
|
@ -357,13 +354,14 @@
|
|||
(let [id (st/get-path-id state)
|
||||
content (st/get-path state :content)
|
||||
old-content (get-in state [:workspace-local :edit-path id :old-content])
|
||||
mode (get-in state [:workspace-local :edit-path id :edit-mode])]
|
||||
|
||||
mode (get-in state [:workspace-local :edit-path id :edit-mode])
|
||||
empty-content? (empty? content)]
|
||||
(cond
|
||||
(not= content old-content) (rx/of (changes/save-path-content)
|
||||
(start-draw-mode))
|
||||
(and (not= content old-content) (not empty-content?)) (rx/of (changes/save-path-content))
|
||||
(= mode :draw) (rx/of :interrupt)
|
||||
:else (rx/of (common/finish-path)))))))
|
||||
:else (rx/of
|
||||
(common/finish-path)
|
||||
(dwdc/clear-drawing)))))))
|
||||
|
||||
(defn change-edit-mode [mode]
|
||||
(ptk/reify ::change-edit-mode
|
||||
|
@ -378,8 +376,7 @@
|
|||
(let [id (st/get-path-id state)]
|
||||
(cond
|
||||
(and id (= :move mode)) (rx/of (common/finish-path))
|
||||
(and id (= :draw mode)) (rx/of (dwc/hide-toolbar)
|
||||
(start-draw-mode))
|
||||
(and id (= :draw mode)) (rx/of (start-draw-mode))
|
||||
:else (rx/empty))))))
|
||||
|
||||
(defn reset-last-handler
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
[app.common.svg.path.shapes-to-path :as upsp]
|
||||
[app.common.svg.path.subpath :as ups]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.edition :as dwe]
|
||||
[app.main.data.workspace.path.changes :as changes]
|
||||
[app.main.data.workspace.path.drawing :as drawing]
|
||||
|
@ -68,7 +67,7 @@
|
|||
(let [changes (changes/generate-path-changes it objects page-id shape (:content shape) new-content)]
|
||||
(if (empty? new-content)
|
||||
(rx/of (dch/commit-changes changes)
|
||||
dwe/clear-edition-mode)
|
||||
(dwe/clear-edition-mode))
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(selection/update-selection point-change)
|
||||
(fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers :moving-nodes :moving-handler))))))))))
|
||||
|
@ -319,8 +318,7 @@
|
|||
(= (ptk/type %) ::start-path-edit))))
|
||||
interrupt (->> stream (rx/filter #(= % :interrupt)) (rx/take 1))]
|
||||
(rx/concat
|
||||
(rx/of (dwc/hide-toolbar)
|
||||
(undo/start-path-undo)
|
||||
(rx/of (undo/start-path-undo)
|
||||
(drawing/change-edit-mode mode))
|
||||
(->> interrupt
|
||||
(rx/map #(stop-path-edit id))
|
||||
|
|
|
@ -120,12 +120,12 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [zoom (get-in state [:workspace-local :zoom] 1)
|
||||
stoper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter dwc/interrupt?)))
|
||||
stopper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter dwc/interrupt?)))
|
||||
|
||||
from-p @ms/mouse-position]
|
||||
(rx/concat
|
||||
|
@ -133,7 +133,7 @@
|
|||
(rx/map #(grc/points->rect [from-p %]))
|
||||
(rx/filter (partial valid-rect? zoom))
|
||||
(rx/map update-area-selection)
|
||||
(rx/take-until stoper))
|
||||
(rx/take-until stopper))
|
||||
|
||||
(rx/of (select-node-area shift?)
|
||||
(clear-area-selection))))))))
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
(:require
|
||||
[app.main.data.shortcuts :as ds]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.path :as drp]
|
||||
[app.main.store :as st]
|
||||
[beicon.v2.core :as rx]
|
||||
|
@ -24,16 +23,12 @@
|
|||
(ptk/reify ::esc-pressed
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
;; Not interrupt when we're editing a path
|
||||
;; Not interrupt when we're editing a path
|
||||
(let [edition-id (or (get-in state [:workspace-drawing :object :id])
|
||||
(get-in state [:workspace-local :edition]))
|
||||
content (get-in state [:workspace-drawing :object :content])
|
||||
path-edit-mode (get-in state [:workspace-local :edit-path edition-id :edit-mode])]
|
||||
(if-not (= :draw path-edit-mode)
|
||||
(rx/of :interrupt)
|
||||
(if (<= (count content) 1)
|
||||
(rx/of (dwc/show-toolbar))
|
||||
(rx/empty)))))))
|
||||
(when-not (= :draw path-edit-mode)
|
||||
(rx/of :interrupt))))))
|
||||
|
||||
(def shortcuts
|
||||
{:move-nodes {:tooltip "M"
|
||||
|
|
|
@ -6,13 +6,48 @@
|
|||
|
||||
(ns app.main.data.workspace.path.state
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cph]
|
||||
[app.common.svg.path.shapes-to-path :as upsp]))
|
||||
|
||||
(defn path-editing?
|
||||
"Returns true if we're editing a path or creating a new one."
|
||||
[{local :workspace-local
|
||||
drawing :workspace-drawing}]
|
||||
(let [selected (:selected local)
|
||||
edition (:edition local)
|
||||
|
||||
drawing-obj (:object drawing)
|
||||
drawing-tool (:tool drawing)
|
||||
|
||||
edit-path? (dm/get-in local [:edit-path edition])
|
||||
|
||||
shape (or drawing-obj (first selected))
|
||||
shape-id (:id shape)
|
||||
|
||||
single? (= (count selected) 1)
|
||||
editing? (and (some? shape-id)
|
||||
(some? edition)
|
||||
(= shape-id edition))
|
||||
|
||||
;; we need to check if we're drawing a new object but we're
|
||||
;; not using the pencil tool.
|
||||
draw-path? (and (some? drawing-obj)
|
||||
(cph/path-shape? drawing-obj)
|
||||
(not= :curve drawing-tool))]
|
||||
|
||||
(or (and ^boolean single?
|
||||
^boolean editing?
|
||||
(and (not (cph/text-shape? shape))
|
||||
(not (cph/frame-shape? shape))))
|
||||
draw-path?
|
||||
edit-path?)))
|
||||
|
||||
(defn get-path-id
|
||||
"Retrieves the currently editing path id"
|
||||
[state]
|
||||
(or (get-in state [:workspace-local :edition])
|
||||
(get-in state [:workspace-drawing :object :id])))
|
||||
(or (dm/get-in state [:workspace-local :edition])
|
||||
(dm/get-in state [:workspace-drawing :object :id])))
|
||||
|
||||
(defn get-path-location
|
||||
[state & ks]
|
||||
|
|
|
@ -52,19 +52,19 @@
|
|||
|
||||
start (-> @ms/mouse-position to-pixel-snap)
|
||||
|
||||
stoper (rx/merge
|
||||
(->> st/stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> st/stream
|
||||
(rx/filter finish-edition?)))
|
||||
stopper (rx/merge
|
||||
(->> st/stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> st/stream
|
||||
(rx/filter finish-edition?)))
|
||||
|
||||
position-stream
|
||||
(->> ms/mouse-position
|
||||
(rx/map to-pixel-snap)
|
||||
(rx/filter (dragging? start zoom))
|
||||
(rx/take 1)
|
||||
(rx/take-until stoper))]
|
||||
(rx/take-until stopper))]
|
||||
|
||||
(rx/merge
|
||||
(->> position-stream
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
(rx/of (dch/update-shapes [id] upsp/convert-to-path))
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(when (empty? new-content)
|
||||
dwe/clear-edition-mode))))))))))
|
||||
(dwe/clear-edition-mode)))))))))))
|
||||
|
||||
(defn make-corner
|
||||
([]
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.undo-stack :as u]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.path.changes :as changes]
|
||||
[app.main.data.workspace.path.common :as common]
|
||||
[app.main.data.workspace.path.state :as st]
|
||||
[app.main.store :as store]
|
||||
[beicon.v2.core :as rx]
|
||||
|
@ -65,8 +67,14 @@
|
|||
undo-stack)))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (changes/save-path-content {:preserve-move-to true})))))
|
||||
(watch [_ state _]
|
||||
(let [id (st/get-path-id state)
|
||||
undo-stack (get-in state [:workspace-local :edit-path id :undo-stack])]
|
||||
(if (> (:index undo-stack) 0)
|
||||
(rx/of (changes/save-path-content {:preserve-move-to true}))
|
||||
(rx/of (changes/save-path-content {:preserve-move-to true})
|
||||
(common/finish-path)
|
||||
(dwc/show-toolbar)))))))
|
||||
|
||||
(defn redo-path []
|
||||
(ptk/reify ::redo-path
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(log/debug :hint "initialize persistence")
|
||||
(let [stoper (rx/filter (ptk/type? ::initialize-persistence) stream)
|
||||
(let [stopper (rx/filter (ptk/type? ::initialize-persistence) stream)
|
||||
commits (l/atom [])
|
||||
saving? (l/atom false)
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
|||
|
||||
on-dirty
|
||||
(fn []
|
||||
;; Enable reload stoper
|
||||
;; Enable reload stopper
|
||||
(swap! st/ongoing-tasks conj :workspace-change)
|
||||
(st/emit! (update-persistence-status {:status :pending})))
|
||||
|
||||
|
@ -64,7 +64,7 @@
|
|||
|
||||
on-saved
|
||||
(fn []
|
||||
;; Disable reload stoper
|
||||
;; Disable reload stopper
|
||||
(swap! st/ongoing-tasks disj :workspace-change)
|
||||
(st/emit! (update-persistence-status {:status :saved}))
|
||||
(reset! saving? false))]
|
||||
|
@ -82,7 +82,7 @@
|
|||
(assoc :file-id file-id))))
|
||||
(rx/observe-on :async)
|
||||
(rx/tap #(swap! commits conj %))
|
||||
(rx/take-until (rx/delay 100 stoper))
|
||||
(rx/take-until (rx/delay 100 stopper))
|
||||
(rx/finalize (fn []
|
||||
(log/debug :hint "finalize persistence: changes watcher"))))
|
||||
|
||||
|
@ -115,7 +115,7 @@
|
|||
(rx/tap on-saved)
|
||||
(rx/ignore)))
|
||||
(rx/empty))))
|
||||
(rx/take-until (rx/delay 100 stoper))
|
||||
(rx/take-until (rx/delay 100 stopper))
|
||||
(rx/finalize (fn []
|
||||
(log/debug :hint "finalize persistence: save loop"))))
|
||||
|
||||
|
@ -126,7 +126,7 @@
|
|||
(rx/filter library-file?)
|
||||
(rx/filter (complement #(empty? (:changes %))))
|
||||
(rx/map persist-synchronous-changes)
|
||||
(rx/take-until (rx/delay 100 stoper))
|
||||
(rx/take-until (rx/delay 100 stopper))
|
||||
(rx/finalize (fn []
|
||||
(log/debug :hint "finalize persistence: synchronous save loop")))))))))
|
||||
|
||||
|
|
|
@ -64,12 +64,12 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [zoom (dm/get-in state [:workspace-local :zoom] 1)
|
||||
stoper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter interrupt?)))
|
||||
stopper (rx/merge
|
||||
(->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(->> stream
|
||||
(rx/filter interrupt?)))
|
||||
|
||||
init-position @ms/mouse-position
|
||||
|
||||
|
@ -99,7 +99,7 @@
|
|||
(rx/scan calculate-selrect init-selrect)
|
||||
(rx/filter #(or (> (dm/get-prop % :width) (/ 10 zoom))
|
||||
(> (dm/get-prop % :height) (/ 10 zoom))))
|
||||
(rx/take-until stoper))]
|
||||
(rx/take-until stopper))]
|
||||
|
||||
(rx/concat
|
||||
(if preserve?
|
||||
|
@ -667,9 +667,9 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stoper (rx/filter (ptk/type? ::memorize-duplicated) stream)]
|
||||
(let [stopper (rx/filter (ptk/type? ::memorize-duplicated) stream)]
|
||||
(->> (rx/timer 10000) ;; This time may be adjusted after some user testing.
|
||||
(rx/take-until stoper)
|
||||
(rx/take-until stopper)
|
||||
(rx/map clear-memorize-duplicated))))))
|
||||
|
||||
(defn calc-duplicate-delta
|
||||
|
|
|
@ -228,13 +228,13 @@
|
|||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:text-decoration "toggle-line-through"})}
|
||||
|
||||
:font-size-inc {:tooltip (ds/meta-shift ds/up-arrow)
|
||||
:command (ds/c-mod "shift+up")
|
||||
:font-size-inc {:tooltip (ds/meta-shift ds/right-arrow)
|
||||
:command (ds/c-mod "shift+right")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:font-size-inc true})}
|
||||
|
||||
:font-size-dec {:tooltip (ds/meta-shift ds/down-arrow)
|
||||
:command (ds/c-mod "shift+down")
|
||||
:font-size-dec {:tooltip (ds/meta-shift ds/left-arrow)
|
||||
:command (ds/c-mod "shift+left")
|
||||
:subsections [:text-editor]
|
||||
:fn #(update-attrs-when-no-readonly {:font-size-dec true})}
|
||||
|
||||
|
|
|
@ -370,9 +370,9 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stoper (->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
(let [stopper (->> stream
|
||||
(rx/filter mse/mouse-event?)
|
||||
(rx/filter mse/mouse-up-event?))
|
||||
|
||||
group (gsh/shapes->rect shapes)
|
||||
group-center (grc/rect->center group)
|
||||
|
@ -399,7 +399,7 @@
|
|||
(fn [[pos mod? shift?]]
|
||||
(let [delta-angle (calculate-angle pos mod? shift?)]
|
||||
(dwm/set-rotation-modifiers delta-angle shapes group-center))))
|
||||
(rx/take-until stoper))
|
||||
(rx/take-until stopper))
|
||||
(rx/of (dwm/apply-modifiers)
|
||||
(finish-transform)))))))
|
||||
|
||||
|
|
|
@ -196,9 +196,6 @@
|
|||
(def context-menu
|
||||
(l/derived :context-menu workspace-local))
|
||||
|
||||
(def toolbar-visibility
|
||||
(l/derived :hide-toolbar workspace-local))
|
||||
|
||||
;; page item that it is being edited
|
||||
(def editing-page-item
|
||||
(l/derived :page-item workspace-local))
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
ref (gobj/get props "container")
|
||||
ids (gobj/get props "ids")
|
||||
list-class (gobj/get props "list-class")
|
||||
ids (filter some? ids)
|
||||
ids (filter some? ids)
|
||||
on-click
|
||||
(fn [event]
|
||||
(let [target (dom/get-target event)
|
||||
|
@ -69,7 +69,7 @@
|
|||
actual-index (d/index-of ids actual-id)
|
||||
previous-id (if (= 0 actual-index)
|
||||
(last ids)
|
||||
(nth ids (- actual-index 1)))]
|
||||
(get ids (- actual-index 1) (last ids)))]
|
||||
(dom/focus! (dom/get-element previous-id))))
|
||||
|
||||
(when (kbd/down-arrow? event)
|
||||
|
@ -78,8 +78,9 @@
|
|||
actual-index (d/index-of ids actual-id)
|
||||
next-id (if (= (- len 1) actual-index)
|
||||
(first ids)
|
||||
(nth ids (+ 1 actual-index)))]
|
||||
(dom/focus! (dom/get-element next-id))))
|
||||
(get ids (+ 1 actual-index) (first ids)))
|
||||
node-item (dom/get-element next-id)]
|
||||
(dom/focus! node-item)))
|
||||
|
||||
(when (kbd/tab? event)
|
||||
(on-close))))]
|
||||
|
@ -100,5 +101,10 @@
|
|||
(assert (fn? (gobj/get props "on-close")) "missing `on-close` prop")
|
||||
(assert (boolean? (gobj/get props "show")) "missing `show` prop")
|
||||
|
||||
(when (gobj/get props "show")
|
||||
(mf/element dropdown-menu' props)))
|
||||
(let [ids (obj/get props "ids")
|
||||
ids (d/nilv ids (->> (obj/get props "children")
|
||||
(keep #(obj/get-in % ["props" "id"]))))]
|
||||
(when (gobj/get props "show")
|
||||
(mf/element
|
||||
dropdown-menu'
|
||||
(mf/spread-props props {:ids ids})))))
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
}
|
||||
|
||||
.radio-icon {
|
||||
--radio-icon-border-color: var(--radio-btn-border-color);
|
||||
|
||||
@include buttonStyle;
|
||||
@include flexCenter;
|
||||
@include focusRadio;
|
||||
|
@ -21,6 +23,8 @@
|
|||
flex-grow: 1;
|
||||
border-radius: $s-8;
|
||||
box-sizing: border-box;
|
||||
border: $br-2 solid var(--radio-icon-border-color);
|
||||
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
|
@ -37,20 +41,31 @@
|
|||
stroke: var(--radio-btn-foreground-color-selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.checked {
|
||||
background-color: var(--radio-btn-background-color-selected);
|
||||
border-color: var(--radio-btn-border-color-selected);
|
||||
svg {
|
||||
stroke: var(--radio-btn-foreground-color-selected);
|
||||
}
|
||||
.title-name {
|
||||
color: var(--radio-btn-foreground-color-selected);
|
||||
}
|
||||
.checked {
|
||||
--radio-icon-border-color: var(--radio-btn-border-color-selected);
|
||||
|
||||
background-color: var(--radio-btn-background-color-selected);
|
||||
svg {
|
||||
stroke: var(--radio-btn-foreground-color-selected);
|
||||
}
|
||||
.title-name {
|
||||
color: var(--radio-btn-foreground-color-selected);
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: default;
|
||||
.disabled {
|
||||
cursor: default;
|
||||
background-color: transparent;
|
||||
border: $s-2 solid transparent;
|
||||
svg {
|
||||
stroke: var(--button-foreground-color-disabled);
|
||||
}
|
||||
.title-name {
|
||||
color: var(--button-foreground-color-disabled);
|
||||
}
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
border: $s-2 solid transparent;
|
||||
svg {
|
||||
|
@ -59,15 +74,5 @@
|
|||
.title-name {
|
||||
color: var(--button-foreground-color-disabled);
|
||||
}
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
border: $s-2 solid transparent;
|
||||
svg {
|
||||
stroke: var(--button-foreground-color-disabled);
|
||||
}
|
||||
.title-name {
|
||||
color: var(--button-foreground-color-disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,57 +196,69 @@
|
|||
|
||||
open-menu? (mf/use-state false)
|
||||
edit? (mf/use-state false)
|
||||
state* (mf/use-var (:font-family font))
|
||||
state* (mf/use-state (:font-family font))
|
||||
font-family (deref state*)
|
||||
|
||||
|
||||
on-change
|
||||
(fn [event]
|
||||
(reset! state* (dom/get-target-val event)))
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(reset! state* (dom/get-target-val event))))
|
||||
|
||||
on-save
|
||||
(fn [_]
|
||||
(let [font-family font-family]
|
||||
(when-not (str/blank? font-family)
|
||||
(st/emit! (df/update-font
|
||||
{:id font-id
|
||||
:name font-family})))
|
||||
(reset! edit? false)))
|
||||
(mf/use-callback
|
||||
(mf/deps font-family)
|
||||
(fn [_]
|
||||
(when-not (str/blank? font-family)
|
||||
(st/emit! (df/update-font {:id font-id :name font-family})))
|
||||
(reset! edit? false)))
|
||||
|
||||
on-key-down
|
||||
(fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(on-save event)))
|
||||
(mf/use-callback
|
||||
(mf/deps on-save)
|
||||
(fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(on-save event))))
|
||||
|
||||
on-cancel
|
||||
(fn [_]
|
||||
(reset! edit? false)
|
||||
(reset! state* (:font-family font)))
|
||||
(mf/use-callback
|
||||
(fn [_]
|
||||
(reset! edit? false)
|
||||
(reset! state* (:font-family font))))
|
||||
|
||||
delete-font-fn
|
||||
(fn [] (st/emit! (df/delete-font font-id)))
|
||||
(mf/use-callback
|
||||
(mf/deps font-id)
|
||||
(fn []
|
||||
(st/emit! (df/delete-font font-id))))
|
||||
|
||||
delete-variant-fn
|
||||
(fn [id] (st/emit! (df/delete-font-variant id)))
|
||||
(mf/use-callback
|
||||
(fn [id]
|
||||
(st/emit! (df/delete-font-variant id))))
|
||||
|
||||
on-delete
|
||||
(fn []
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-font.title")
|
||||
:message (tr "modals.delete-font.message")
|
||||
:accept-label (tr "labels.delete")
|
||||
:on-accept (fn [_props] (delete-font-fn))})))
|
||||
(mf/use-callback
|
||||
(mf/deps delete-font-fn)
|
||||
(fn []
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-font.title")
|
||||
:message (tr "modals.delete-font.message")
|
||||
:accept-label (tr "labels.delete")
|
||||
:on-accept (fn [_props] (delete-font-fn))}))))
|
||||
|
||||
on-delete-variant
|
||||
(fn [id]
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-font-variant.title")
|
||||
:message (tr "modals.delete-font-variant.message")
|
||||
:accept-label (tr "labels.delete")
|
||||
:on-accept (fn [_props]
|
||||
(delete-variant-fn id))})))]
|
||||
(mf/use-callback
|
||||
(mf/deps delete-variant-fn)
|
||||
(fn [id]
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-font-variant.title")
|
||||
:message (tr "modals.delete-font-variant.message")
|
||||
:accept-label (tr "labels.delete")
|
||||
:on-accept (fn [_props]
|
||||
(delete-variant-fn id))}))))]
|
||||
|
||||
[:div {:class (stl/css :font-item :table-row)}
|
||||
[:div {:class (stl/css :table-field :family)}
|
||||
|
|
|
@ -95,6 +95,9 @@
|
|||
|
||||
;; --- Grid Item Library
|
||||
|
||||
(def ^:private menu-icon
|
||||
(i/icon-xref :menu-refactor (stl/css :menu-icon)))
|
||||
|
||||
(mf/defc grid-item-library
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [file] :as props}]
|
||||
|
@ -381,7 +384,7 @@
|
|||
(when (kbd/enter? event)
|
||||
(dom/stop-propagation event)
|
||||
(on-menu-click event)))}
|
||||
i/actions
|
||||
menu-icon
|
||||
(when (and selected? file-menu-open?)
|
||||
[:& file-menu {:files (vals selected-files)
|
||||
:show? (:menu-open dashboard-local)
|
||||
|
|
|
@ -220,40 +220,40 @@ $thumbnail-default-height: $s-168; // Default width
|
|||
span {
|
||||
color: $db-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
.project-th-icon {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-right: $s-8;
|
||||
margin-top: 0;
|
||||
.project-th-icon {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-right: $s-8;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&.menu {
|
||||
align-items: flex-end;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: $s-32;
|
||||
justify-content: center;
|
||||
margin-right: 0;
|
||||
margin-top: $s-20;
|
||||
width: 100%;
|
||||
.menu {
|
||||
align-items: flex-end;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: $s-32;
|
||||
justify-content: center;
|
||||
margin-right: 0;
|
||||
margin-top: $s-20;
|
||||
width: 100%;
|
||||
--menu-icon-color: var(--button-tertiary-foreground-color-rest);
|
||||
|
||||
> svg {
|
||||
fill: $df-secondary;
|
||||
margin-right: 0;
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
> svg {
|
||||
fill: $da-tertiary;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover,
|
||||
&:focus {
|
||||
--menu-icon-color: var(--button-tertiary-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
stroke: var(--menu-icon-color);
|
||||
fill: none;
|
||||
margin-right: 0;
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
}
|
||||
|
||||
.project-th-actions.force-display {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private show-more-icon
|
||||
(i/icon-xref :arrow-refactor (stl/css :show-more-icon)))
|
||||
|
||||
(mf/defc header
|
||||
{::mf/wrap [mf/memo]}
|
||||
[]
|
||||
|
@ -314,7 +317,7 @@
|
|||
:aria-label (tr "dashboard.new-file")
|
||||
:data-test "project-new-file"
|
||||
:on-key-down handle-create-click}
|
||||
i/close]
|
||||
i/add-refactor]
|
||||
|
||||
[:button
|
||||
{:class (stl/css :btn-secondary :btn-small :tooltip :tooltip-bottom)
|
||||
|
@ -323,7 +326,7 @@
|
|||
:aria-label (tr "dashboard.options")
|
||||
:data-test "project-options"
|
||||
:on-key-down handle-menu-click}
|
||||
i/actions]]]]
|
||||
i/menu-refactor]]]]
|
||||
|
||||
[:div {:class (stl/css :grid-container) :ref rowref}
|
||||
[:& line-grid
|
||||
|
@ -343,7 +346,7 @@
|
|||
(when (kbd/enter? event)
|
||||
(on-nav)))}
|
||||
[:div {:class (stl/css :placeholder-label)} (tr "dashboard.show-all-files")]
|
||||
[:div {:class (stl/css :placeholder-icon)} i/arrow-down]])]))
|
||||
show-more-icon])]))
|
||||
|
||||
|
||||
(def recent-files-ref
|
||||
|
|
|
@ -51,31 +51,6 @@
|
|||
min-height: $s-32;
|
||||
margin-left: $s-8;
|
||||
}
|
||||
.show-more {
|
||||
align-items: center;
|
||||
color: $df-secondary;
|
||||
display: flex;
|
||||
font-size: $fs-14;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
.placeholder-icon {
|
||||
transform: rotate(-90deg);
|
||||
margin-left: $s-12;
|
||||
svg {
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
fill: $df-secondary;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
color: $da-tertiary;
|
||||
svg {
|
||||
fill: $da-tertiary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
border: none;
|
||||
|
@ -137,37 +112,35 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.show-more {
|
||||
align-items: center;
|
||||
color: $df-secondary;
|
||||
display: flex;
|
||||
font-size: $fs-14;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: $s-8;
|
||||
right: $s-52;
|
||||
.placeholder-icon {
|
||||
transform: rotate(-90deg);
|
||||
margin-left: $s-8;
|
||||
svg {
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
fill: $df-secondary;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
color: $da-tertiary;
|
||||
svg {
|
||||
fill: $da-tertiary;
|
||||
}
|
||||
}
|
||||
.show-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: $s-12;
|
||||
|
||||
color: $df-secondary;
|
||||
font-size: $fs-14;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: $s-8;
|
||||
right: $s-52;
|
||||
|
||||
&:hover {
|
||||
color: $da-tertiary;
|
||||
}
|
||||
}
|
||||
|
||||
.show-more-icon {
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
}
|
||||
|
||||
.team-hero {
|
||||
background-color: $db-tertiary;
|
||||
border-radius: $br-8;
|
||||
|
|
|
@ -25,6 +25,15 @@
|
|||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private neutral-icon
|
||||
(i/icon-xref :msg-neutral-refactor (stl/css :icon)))
|
||||
|
||||
(def ^:private error-icon
|
||||
(i/icon-xref :delete-text-refactor (stl/css :icon)))
|
||||
|
||||
(def ^:private close-icon
|
||||
(i/icon-xref :close-refactor (stl/css :close-icon)))
|
||||
|
||||
(mf/defc export-multiple-dialog
|
||||
[{:keys [exports title cmd no-selection]}]
|
||||
(let [lstate (mf/deref refs/export)
|
||||
|
@ -198,25 +207,34 @@
|
|||
(mf/defc export-progress-widget
|
||||
{::mf/wrap [mf/memo]}
|
||||
[]
|
||||
(let [state (mf/deref refs/export)
|
||||
error? (:error state)
|
||||
healthy? (:healthy? state)
|
||||
detail-visible? (:detail-visible state)
|
||||
widget-visible? (:widget-visible state)
|
||||
progress (:progress state)
|
||||
exports (:exports state)
|
||||
total (count exports)
|
||||
complete? (= progress total)
|
||||
circ (* 2 Math/PI 12)
|
||||
pct (- circ (* circ (/ progress total)))
|
||||
(let [state (mf/deref refs/export)
|
||||
profile (mf/deref refs/profile)
|
||||
theme (or (:theme profile) "default")
|
||||
is-default-theme? (= "default" theme)
|
||||
error? (:error state)
|
||||
healthy? (:healthy? state)
|
||||
detail-visible? (:detail-visible state)
|
||||
widget-visible? (:widget-visible state)
|
||||
progress (:progress state)
|
||||
exports (:exports state)
|
||||
total (count exports)
|
||||
complete? (= progress total)
|
||||
circ (* 2 Math/PI 12)
|
||||
pct (- circ (* circ (/ progress total)))
|
||||
|
||||
pwidth (if error?
|
||||
280
|
||||
(/ (* progress 280) total))
|
||||
color (cond
|
||||
error? clr/new-danger
|
||||
healthy? clr/new-primary
|
||||
healthy? (if is-default-theme?
|
||||
clr/new-primary
|
||||
clr/new-primary-light)
|
||||
(not healthy?) clr/new-warning)
|
||||
|
||||
background-clr (if is-default-theme?
|
||||
clr/background-quaternary
|
||||
clr/background-quaternary-light)
|
||||
title (cond
|
||||
error? (tr "workspace.options.exporting-object-error")
|
||||
complete? (tr "workspace.options.exporting-complete")
|
||||
|
@ -233,57 +251,60 @@
|
|||
(when widget-visible?
|
||||
[:div {:class (stl/css :export-progress-widget)
|
||||
:on-click toggle-detail-visibility}
|
||||
[:svg {:width "32" :height "32"}
|
||||
[:circle {:r "12"
|
||||
:cx "16"
|
||||
:cy "16"
|
||||
[:svg {:width "24" :height "24"}
|
||||
[:circle {:r "10"
|
||||
:cx "12"
|
||||
:cy "12"
|
||||
:fill "transparent"
|
||||
:stroke clr/gray-40
|
||||
:stroke background-clr
|
||||
:stroke-width "4"}]
|
||||
[:circle {:r "12"
|
||||
:cx "16"
|
||||
:cy "16"
|
||||
[:circle {:r "10"
|
||||
:cx "12"
|
||||
:cy "12"
|
||||
:fill "transparent"
|
||||
:stroke color
|
||||
:stroke-width "4"
|
||||
:stroke-dasharray (dm/str circ " " circ)
|
||||
:stroke-dashoffset pct
|
||||
:transform "rotate(-90 16,16)"
|
||||
:transform "rotate(-90 12,12)"
|
||||
:style {:transition "stroke-dashoffset 1s ease-in-out"}}]]])
|
||||
|
||||
(when detail-visible?
|
||||
[:div {:class (stl/css :export-progress-modal-overlay)}
|
||||
[:div {:class (stl/css :export-progress-modal-container)}
|
||||
[:div {:class (stl/css :export-progress-modal-header)}
|
||||
[:p {:class (stl/css :export-progress-modal-title)}
|
||||
[:span {:class (stl/css :title-text)}
|
||||
title]
|
||||
(if error?
|
||||
[:button {:class (stl/css :retry-btn)
|
||||
:on-click retry-last-export}
|
||||
(tr "workspace.options.retry")]
|
||||
[:div {:class (stl/css-case :export-progress-modal true
|
||||
:has-error error?)}
|
||||
(if error?
|
||||
error-icon
|
||||
neutral-icon)
|
||||
|
||||
[:p {:class (stl/css :progress)}
|
||||
(dm/str progress " / " total)])]
|
||||
[:p {:class (stl/css :export-progress-title)}
|
||||
title
|
||||
(if error?
|
||||
[:button {:class (stl/css :retry-btn)
|
||||
:on-click retry-last-export}
|
||||
(tr "workspace.options.retry")]
|
||||
|
||||
[:button {:class (stl/css :modal-close-button)
|
||||
:on-click toggle-detail-visibility}
|
||||
i/close-refactor]]
|
||||
[:p {:class (stl/css :progress)}
|
||||
(dm/str progress " / " total)])]
|
||||
|
||||
[:svg {:class (stl/css :progress-bar)
|
||||
:height 5
|
||||
:width 280}
|
||||
[:g
|
||||
[:path {:d "M0 0 L280 0"
|
||||
:stroke clr/black
|
||||
:stroke-width 30}]
|
||||
[:path {:d (dm/str "M0 0 L280 0")
|
||||
:stroke color
|
||||
:stroke-width 30
|
||||
:fill "transparent"
|
||||
:stroke-dasharray 280
|
||||
:stroke-dashoffset (- 280 pwidth)
|
||||
:style {:transition "stroke-dashoffset 1s ease-in-out"}}]]]]])]))
|
||||
[:button {:class (stl/css :progress-close-button)
|
||||
:on-click toggle-detail-visibility}
|
||||
close-icon]
|
||||
|
||||
(when-not error?
|
||||
[:svg {:class (stl/css :progress-bar)
|
||||
:height 4
|
||||
:width 280}
|
||||
[:g
|
||||
[:path {:d "M0 0 L280 0"
|
||||
:stroke background-clr
|
||||
:stroke-width 30}]
|
||||
[:path {:d (dm/str "M0 0 L280 0")
|
||||
:stroke color
|
||||
:stroke-width 30
|
||||
:fill "transparent"
|
||||
:stroke-dasharray 280
|
||||
:stroke-dashoffset (- 280 pwidth)
|
||||
:style {:transition "stroke-dashoffset 1s ease-in-out"}}]]])])]))
|
||||
|
||||
(def ^:const options [:all :merge :detach])
|
||||
|
||||
|
|
|
@ -6,69 +6,101 @@
|
|||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.export-progress-modal-overlay {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
// PROGRESS WIDGET
|
||||
.export-progress-widget {
|
||||
@include flexCenter;
|
||||
width: $s-28;
|
||||
height: $s-28;
|
||||
}
|
||||
|
||||
// PROGRESS MODAL
|
||||
.export-progress-modal {
|
||||
--export-modal-bg-color: var(--alert-background-color-default);
|
||||
--export-modal-fg-color: var(--alert-text-foreground-color-default);
|
||||
--export-modal-icon-color: var(--alert-icon-foreground-color-default);
|
||||
--export-modal-border-color: var(--alert-border-color-default);
|
||||
position: absolute;
|
||||
right: $s-16;
|
||||
top: $s-48;
|
||||
background-color: var(--modal-background-color);
|
||||
display: grid;
|
||||
grid-template-columns: $s-24 1fr $s-24;
|
||||
grid-template-areas:
|
||||
"icon text close"
|
||||
"bar bar bar";
|
||||
gap: $s-4 $s-8;
|
||||
padding-block-start: $s-8;
|
||||
background-color: var(--export-modal-bg-color);
|
||||
border: $s-1 solid var(--export-modal-border-color);
|
||||
border-radius: $br-8;
|
||||
z-index: $z-index-20;
|
||||
z-index: $z-index-modal;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.export-progress-modal-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.export-progress-modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: stretch;
|
||||
padding: $s-8;
|
||||
.has-error {
|
||||
--export-modal-bg-color: var(--alert-background-color-error);
|
||||
--export-modal-fg-color: var(--alert-text-foreground-color-error);
|
||||
--export-modal-icon-color: var(--alert-icon-foreground-color-error);
|
||||
--export-modal-border-color: var(--alert-border-color-error);
|
||||
grid-template-areas: "icon text close";
|
||||
gap: $s-8;
|
||||
padding-block: $s-8;
|
||||
}
|
||||
|
||||
.export-progress-modal-title {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
.icon {
|
||||
@extend .button-icon;
|
||||
grid-area: icon;
|
||||
align-self: center;
|
||||
margin-inline-start: $s-8;
|
||||
stroke: var(--export-modal-icon-color);
|
||||
}
|
||||
|
||||
.title-text {
|
||||
@include flexCenter;
|
||||
@include bodyLargeTypography;
|
||||
.export-progress-title {
|
||||
@include bodyMedTipography;
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: $s-8;
|
||||
grid-area: text;
|
||||
align-self: center;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: var(--modal-title-foreground-color);
|
||||
padding-left: $s-4;
|
||||
color: var(--export-modal-fg-color);
|
||||
}
|
||||
|
||||
.progress {
|
||||
@include bodyLargeTypography;
|
||||
@include bodyMedTipography;
|
||||
padding-left: $s-8;
|
||||
margin: 0;
|
||||
align-self: center;
|
||||
color: var(--modal-text-foreground-color);
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
@extend .button-tertiary;
|
||||
@include buttonStyle;
|
||||
@include bodyMedTipography;
|
||||
display: inline;
|
||||
text-align: left;
|
||||
color: var(--modal-link-foreground-color);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.modal-close-button {
|
||||
@extend .button-tertiary;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
.progress-close-button {
|
||||
@include buttonStyle;
|
||||
padding: 0;
|
||||
margin-inline-end: $s-8;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
@extend .button-icon;
|
||||
stroke: var(--export-modal-icon-color);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
margin-top: 0;
|
||||
grid-area: bar;
|
||||
}
|
||||
|
||||
// EXPORT MODAL
|
||||
.modal-overlay {
|
||||
@extend .modal-overlay-base;
|
||||
&.transparent {
|
||||
|
|
|
@ -441,6 +441,13 @@
|
|||
(def ^:icon status-update-refactor (icon-xref :status-update-refactor))
|
||||
(def ^:icon status-tick-refactor (icon-xref :status-tick-refactor))
|
||||
(def ^:icon status-wrong-refactor (icon-xref :status-wrong-refactor))
|
||||
(def ^:icon stroke-arrow-refactor (icon-xref :stroke-arrow-refactor))
|
||||
(def ^:icon stroke-circle-refactor (icon-xref :stroke-circle-refactor))
|
||||
(def ^:icon stroke-diamond-refactor (icon-xref :stroke-diamond-refactor))
|
||||
(def ^:icon stroke-rectangle-refactor (icon-xref :stroke-rectangle-refactor))
|
||||
(def ^:icon stroke-rounded-refactor (icon-xref :stroke-rounded-refactor))
|
||||
(def ^:icon stroke-squared-refactor (icon-xref :stroke-squared-refactor))
|
||||
(def ^:icon stroke-triangle-refactor (icon-xref :stroke-triangle-refactor))
|
||||
(def ^:icon stroke-size-refactor (icon-xref :stroke-size-refactor))
|
||||
(def ^:icon svg-refactor (icon-xref :svg-refactor))
|
||||
(def ^:icon swatches-refactor (icon-xref :swatches-refactor))
|
||||
|
|
|
@ -29,13 +29,12 @@
|
|||
:links (:links message)
|
||||
:content (:content message)}
|
||||
|
||||
context-message {:actions (:actions message)
|
||||
context-message {:type (or (:type message) :info)
|
||||
:links (:links message)
|
||||
:content (:content message)}
|
||||
|
||||
;; TODO review this options
|
||||
is-toast-msg (or (= :toast (:notification-type message)) (some? (:timeout message)))
|
||||
is-inline-msg (or (= :inline (:notification-type message)) (and (some? (:position message)) (= :floating (:position message))))]
|
||||
is-toast-msg (or (= :toast (:notification-type message)) (some? (:timeout message)))
|
||||
is-inline-msg (or (= :inline (:notification-type message)) (and (some? (:position message)) (= :floating (:position message))))]
|
||||
|
||||
(when message
|
||||
(cond
|
||||
|
|
|
@ -56,14 +56,13 @@
|
|||
[:div {:class (stl/css :context-text)
|
||||
:dangerouslySetInnerHTML (when is-html #js {:__html content})}
|
||||
(when-not is-html
|
||||
content)]
|
||||
|
||||
(when (some? links)
|
||||
[:nav {:class (stl/css :link-nav)}
|
||||
(for [[index link] (d/enumerate links)]
|
||||
;; TODO Review this component
|
||||
[:& lb/link-button {:class (stl/css :link)
|
||||
:on-click (:callback link)
|
||||
:value (:label link)
|
||||
:key (dm/str "link-" index)}])])])
|
||||
[:*
|
||||
content
|
||||
(when (some? links)
|
||||
(for [[index link] (d/enumerate links)]
|
||||
;; TODO Review this component
|
||||
[:& lb/link-button {:class (stl/css :link)
|
||||
:on-click (:callback link)
|
||||
:value (:label link)
|
||||
:key (dm/str "link-" index)}]))])]])
|
||||
|
||||
|
|
|
@ -7,16 +7,18 @@
|
|||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.context-notification {
|
||||
---context-notification-bg-color: var(--alert-background-color-default);
|
||||
--context-notification-bg-color: var(--alert-background-color-default);
|
||||
--context-notification-fg-color: var(--alert-text-foreground-color-default);
|
||||
--context-notification-icon-color: var(--alert-icon-foreground-color-default);
|
||||
--context-notification-border-color: var(--alert-border-color-default);
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: $s-16 auto 1fr;
|
||||
grid-template-columns: $s-16 1fr;
|
||||
gap: $s-8;
|
||||
min-height: $s-32;
|
||||
height: fit-content;
|
||||
width: 100%;
|
||||
padding: $s-8 $s-8 $s-8 $s-16;
|
||||
padding: $s-8;
|
||||
border: $s-1 solid var(--context-notification-border-color);
|
||||
border-radius: $br-8;
|
||||
background-color: var(--context-notification-bg-color);
|
||||
|
@ -63,12 +65,6 @@
|
|||
stroke: var(--context-notification-icon-color);
|
||||
}
|
||||
|
||||
.link-nav {
|
||||
align-self: center;
|
||||
height: $s-24;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.context-text {
|
||||
@include bodyMedTipography;
|
||||
align-self: center;
|
||||
|
@ -84,6 +80,8 @@
|
|||
.contain-html .context-text a {
|
||||
@include bodyMedTipography;
|
||||
align-self: center;
|
||||
display: inline;
|
||||
text-align: left;
|
||||
height: $s-16;
|
||||
margin: 0;
|
||||
color: var(--modal-link-foreground-color);
|
||||
|
|
|
@ -11,11 +11,8 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.ui.components.link-button :as lb]
|
||||
[app.main.ui.icons :as i]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private neutral-icon
|
||||
(i/icon-xref :msg-neutral-refactor (stl/css :icon)))
|
||||
|
||||
|
||||
(mf/defc inline-notification
|
||||
|
@ -25,18 +22,17 @@
|
|||
{::mf/props :obj}
|
||||
[{:keys [content actions links] :as props}]
|
||||
[:aside {:class (stl/css :inline-notification)}
|
||||
neutral-icon
|
||||
|
||||
[:div {:class (stl/css :inline-text)}
|
||||
content]
|
||||
|
||||
(when (some? links)
|
||||
[:nav {:class (stl/css :link-nav)}
|
||||
(for [[index link] (d/enumerate links)]
|
||||
[:& lb/link-button {:key (dm/str "link-" index)
|
||||
:class (stl/css :link)
|
||||
:on-click (:callback link)
|
||||
:value (:label link)}])])
|
||||
content
|
||||
|
||||
(when (some? links)
|
||||
[:nav {:class (stl/css :link-nav)}
|
||||
(for [[index link] (d/enumerate links)]
|
||||
[:& lb/link-button {:key (dm/str "link-" index)
|
||||
:class (stl/css :link)
|
||||
:on-click (:callback link)
|
||||
:value (:label link)}])])]
|
||||
|
||||
[:div {:class (stl/css :actions)}
|
||||
(for [action actions]
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
.inline-notification {
|
||||
--inline-notification-bg-color: var(--alert-background-color-default);
|
||||
--inline-notification-fg-color: var(--alert-text-foreground-color-default);
|
||||
--inline-notification-icon-color: var(--alert-icon-foreground-color-default);
|
||||
--inline-notification-border-color: var(--alert-border-color-default);
|
||||
@include alertShadow;
|
||||
position: absolute;
|
||||
|
@ -17,12 +16,13 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
display: grid;
|
||||
grid-template-columns: $s-16 auto 1fr auto;
|
||||
gap: $s-8;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: $s-24;
|
||||
min-height: $s-48;
|
||||
min-width: $s-640;
|
||||
max-width: $s-712;
|
||||
padding: $s-8 $s-8 $s-8 $s-16;
|
||||
width: fit-content;
|
||||
max-width: $s-960;
|
||||
padding: $s-8;
|
||||
margin-inline: auto;
|
||||
border: $s-1 solid var(--inline-notification-border-color);
|
||||
border-radius: $br-8;
|
||||
|
@ -31,17 +31,15 @@
|
|||
color: var(--inline-notification-fg-color);
|
||||
}
|
||||
|
||||
.icon {
|
||||
@extend .button-icon;
|
||||
height: 100%;
|
||||
stroke: var(--inline-notification-icon-color);
|
||||
}
|
||||
|
||||
.inline-text {
|
||||
@include bodyMedTipography;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.link-nav {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.link {
|
||||
@include bodyMedTipography;
|
||||
margin: 0;
|
||||
|
@ -53,15 +51,16 @@
|
|||
display: grid;
|
||||
grid-template-columns: none;
|
||||
grid-auto-flow: column;
|
||||
gap: $s-8;
|
||||
align-self: center;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
@extend .button-tertiary;
|
||||
@extend .button-secondary;
|
||||
@include uppercaseTitleTipography;
|
||||
min-height: $s-32;
|
||||
min-width: $s-32;
|
||||
width: fit-content;
|
||||
padding: $s-8 $s-24;
|
||||
border: $s-1 solid transparent;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
[{:keys [type content on-close links] :as props}]
|
||||
|
||||
[:aside {:class (stl/css-case :toast-notification true
|
||||
:with-links (some? links)
|
||||
:warning (= type :warning)
|
||||
:error (= type :error)
|
||||
:success (= type :success)
|
||||
|
@ -58,15 +57,16 @@
|
|||
(get-icon-by-type type)
|
||||
|
||||
[:div {:class (stl/css :text)}
|
||||
content]
|
||||
content
|
||||
(when (some? links)
|
||||
[:nav {:class (stl/css :link-nav)}
|
||||
(for [[index link] (d/enumerate links)]
|
||||
[:& lb/link-button {:key (dm/str "link-" index)
|
||||
:class (stl/css :link)
|
||||
:on-click (:callback link)
|
||||
:value (:label link)}])])]
|
||||
|
||||
|
||||
(when (some? links)
|
||||
[:nav {:class (stl/css :link-nav)}
|
||||
(for [[index link] (d/enumerate links)]
|
||||
[:& lb/link-button {:key (dm/str "link-" index)
|
||||
:class (stl/css :link)
|
||||
:on-click (:callback link)
|
||||
:value (:label link)}])])
|
||||
|
||||
[:button {:class (stl/css :btn-close)
|
||||
:on-click on-close}
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
grid-template-columns: $s-16 1fr auto;
|
||||
gap: $s-8;
|
||||
min-height: $s-32;
|
||||
min-width: $s-500;
|
||||
max-width: calc(10 * $s-100);
|
||||
padding: $s-8 $s-8 $s-8 $s-16;
|
||||
min-width: $s-228;
|
||||
max-width: $s-400;
|
||||
padding: $s-8;
|
||||
border: $s-1 solid var(--toast-notification-border-color);
|
||||
background-color: var(--toast-notification-bg-color);
|
||||
border-radius: $br-8;
|
||||
|
@ -29,10 +29,6 @@
|
|||
z-index: $z-index-alert;
|
||||
}
|
||||
|
||||
.with-links {
|
||||
grid-template-columns: $s-16 auto 1fr auto;
|
||||
}
|
||||
|
||||
.warning {
|
||||
--toast-notification-bg-color: var(--alert-background-color-warning);
|
||||
--toast-notification-fg-color: var(--alert-text-foreground-color-warning);
|
||||
|
@ -69,7 +65,7 @@
|
|||
}
|
||||
|
||||
.link-nav {
|
||||
height: $s-24;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.link {
|
||||
|
@ -80,7 +76,7 @@
|
|||
|
||||
.icon {
|
||||
@extend .button-icon;
|
||||
height: 100%;
|
||||
align-self: flex-start;
|
||||
stroke: var(--toast-notification-icon-color);
|
||||
}
|
||||
|
||||
|
@ -91,9 +87,10 @@
|
|||
|
||||
.btn-close {
|
||||
@include buttonStyle;
|
||||
@include flexCenter;
|
||||
height: 100%;
|
||||
min-width: $s-32;
|
||||
align-self: flex-start;
|
||||
width: $s-16;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,16 +20,15 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
max-width: $s-368;
|
||||
max-width: $s-500;
|
||||
margin-bottom: $s-32;
|
||||
width: $s-580;
|
||||
margin: $s-80 auto auto $s-120;
|
||||
margin: $s-80 auto $s-120 auto;
|
||||
justify-content: center;
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: $s-500;
|
||||
|
||||
.btn-secondary {
|
||||
width: 100%;
|
||||
|
|
|
@ -97,7 +97,10 @@
|
|||
(obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))}
|
||||
(cond-> browser-props
|
||||
(obj/merge! browser-props)))
|
||||
shape (assoc shape :fills (:fills data))]
|
||||
shape (assoc shape :fills (:fills data))
|
||||
|
||||
;; Need to create new render-id per text-block
|
||||
render-id (dm/str render-id "-" index)]
|
||||
|
||||
[:& (mf/provider muc/render-id) {:key index :value render-id}
|
||||
[:& shape-custom-strokes {:shape shape :position index :render-id render-id}
|
||||
|
|
|
@ -161,6 +161,8 @@
|
|||
#(st/emit! dv/zoom-to-fit))]
|
||||
|
||||
[:div {:class (stl/css :options-zone)}
|
||||
[:& export-progress-widget]
|
||||
|
||||
(case section
|
||||
:interactions [:*
|
||||
(when index
|
||||
|
@ -169,8 +171,6 @@
|
|||
:comments [:& comments-menu]
|
||||
[:div {:class (stl/css :view-options)}])
|
||||
|
||||
[:& export-progress-widget]
|
||||
|
||||
[:& zoom-widget
|
||||
{:zoom zoom
|
||||
:on-increase handle-increase
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[:& title-bar {:collapsable false
|
||||
:title (tr "workspace.options.component.annotation")
|
||||
:class (stl/css :title-spacing-annotation)}
|
||||
[:& copy-button {:data content}]]
|
||||
[:& copy-button {:data content
|
||||
:class (stl/css :copy-btn-title)}]]
|
||||
|
||||
[:div {:class (stl/css :annotation-content)} content]])
|
||||
|
|
|
@ -18,3 +18,7 @@
|
|||
@include bodyMedTipography;
|
||||
color: var(--entry-foreground-color);
|
||||
}
|
||||
|
||||
.copy-btn-title {
|
||||
max-width: $s-28;
|
||||
}
|
||||
|
|
|
@ -109,7 +109,9 @@
|
|||
[:span {:class (stl/css :layer-title)} (:name first-shape)]])]
|
||||
[:div {:class (stl/css :inspect-content)}
|
||||
[:& tab-container {:on-change-tab handle-change-tab
|
||||
:selected @section}
|
||||
:selected @section
|
||||
:content-class (stl/css :tab-content)
|
||||
:header-class (stl/css :tab-header)}
|
||||
[:& tab-element {:id :info :title (tr "inspect.tabs.info")}
|
||||
[:& attributes {:page-id page-id
|
||||
:objects objects
|
||||
|
|
|
@ -96,3 +96,11 @@
|
|||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
margin-right: $s-12;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.active-users-opened {
|
||||
position: absolute;
|
||||
right: calc(-1 * $s-2);
|
||||
|
|
|
@ -171,7 +171,7 @@
|
|||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! :interrupt
|
||||
dw/clear-edition-mode)
|
||||
(dw/clear-edition-mode))
|
||||
;; Delay so anything that launched :interrupt can finish
|
||||
(ts/schedule 100 #(st/emit! (dw/select-for-drawing :comments)))))
|
||||
|
||||
|
@ -203,8 +203,9 @@
|
|||
|
||||
[:& persistence-state-widget]
|
||||
|
||||
[:div {:class (stl/css :separator)}]
|
||||
[:& export-progress-widget]
|
||||
|
||||
[:div {:class (stl/css :separator)}]
|
||||
|
||||
[:div {:class (stl/css :zoom-section)}
|
||||
[:& zoom-widget-workspace
|
||||
|
@ -215,8 +216,6 @@
|
|||
:on-zoom-fit on-zoom-fit
|
||||
:on-zoom-selected on-zoom-selected}]]
|
||||
|
||||
[:& export-progress-widget]
|
||||
|
||||
[:div {:class (stl/css :comments-section)}
|
||||
[:button {:title (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment))
|
||||
:aria-label (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment))
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
border-radius: $br-8;
|
||||
.label {
|
||||
@include bodyMedTipography;
|
||||
height: 100%;
|
||||
padding: $s-8 0;
|
||||
color: var(--button-tertiary-foreground-color-rest);
|
||||
}
|
||||
|
||||
|
@ -180,14 +182,12 @@
|
|||
|
||||
.status-icon {
|
||||
@include flexCenter;
|
||||
width: $s-16;
|
||||
height: $s-16;
|
||||
width: $s-24;
|
||||
height: $s-24;
|
||||
margin: 0;
|
||||
border-radius: $br-circle;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
height: $s-12;
|
||||
width: $s-12;
|
||||
stroke: var(--status-widget-icon-foreground-color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
[okulary.core :as l]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def primary-color "var(--color-accent-tertiary)")
|
||||
(def accent-color "var(--color-accent-tertiary)")
|
||||
(def secondary-color "var(--color-accent-quaternary)")
|
||||
(def black-color "var(--app-black)")
|
||||
(def white-color "var(--app-white)")
|
||||
|
|
|
@ -89,8 +89,8 @@
|
|||
:style {:stroke-width (/ point-radius-stroke-width zoom)
|
||||
:stroke (cond (or selected? hover?) pc/black-color
|
||||
preview? pc/secondary-color
|
||||
:else pc/primary-color)
|
||||
:fill (cond selected? pc/primary-color
|
||||
:else pc/accent-color)
|
||||
:fill (cond selected? pc/accent-color
|
||||
:else pc/white-color)}}]
|
||||
[:circle {:cx x
|
||||
:cy y
|
||||
|
@ -150,8 +150,8 @@
|
|||
|
||||
:style {:stroke-width (/ handler-stroke-width zoom)
|
||||
:stroke (cond (or selected? hover?) pc/black-color
|
||||
:else pc/primary-color)
|
||||
:fill (cond selected? pc/primary-color
|
||||
:else pc/accent-color)
|
||||
:fill (cond selected? pc/accent-color
|
||||
:else pc/white-color)}}]
|
||||
[:circle {:cx x
|
||||
:cy y
|
||||
|
@ -288,7 +288,7 @@
|
|||
[:g.path-editor {:ref editor-ref}
|
||||
[:path {:d (upf/format-path content)
|
||||
:style {:fill "none"
|
||||
:stroke pc/primary-color
|
||||
:stroke pc/accent-color
|
||||
:strokeWidth (/ 1 zoom)}}]
|
||||
(when (and preview (not drag-handler))
|
||||
[:& path-preview {:command preview
|
||||
|
|
|
@ -122,8 +122,7 @@
|
|||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(when (kbd/esc? event)
|
||||
(st/emit! :interrupt)
|
||||
(st/emit! dw/clear-edition-mode)))
|
||||
(st/emit! :interrupt (dw/clear-edition-mode))))
|
||||
|
||||
on-mount
|
||||
(fn []
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
{:on-change-tab on-change-tab
|
||||
:selected section
|
||||
:collapsable false
|
||||
:content-class (stl/css :content-class)
|
||||
:content-class (stl/css-case :content-class true :inspect (= section :inspect))
|
||||
:header-class (stl/css :tab-spacing)}
|
||||
[:& tab-element {:id :design
|
||||
:title (tr "workspace.options.design")}
|
||||
|
|
|
@ -34,3 +34,7 @@
|
|||
gap: $s-8;
|
||||
padding-top: $s-8;
|
||||
}
|
||||
|
||||
.inspect {
|
||||
scrollbar-gutter: unset;
|
||||
}
|
||||
|
|
|
@ -1279,7 +1279,7 @@
|
|||
[:button {:on-click open-grid-help
|
||||
:class (stl/css :help-button)} i/help-refactor]
|
||||
[:button {:class (stl/css :exit-btn)
|
||||
:on-click #(st/emit! udw/clear-edition-mode)}
|
||||
:on-click #(st/emit! (udw/clear-edition-mode))}
|
||||
(tr "workspace.layout_grid.editor.options.exit")]]
|
||||
|
||||
[:div {:class (stl/css :row :first-row)}
|
||||
|
|
|
@ -123,14 +123,14 @@
|
|||
stroke-caps-options
|
||||
[{:value nil :label (tr "workspace.options.stroke-cap.none")}
|
||||
:separator
|
||||
{:value :line-arrow :label (tr "workspace.options.stroke-cap.line-arrow-short") :icon :cap-line-arrow}
|
||||
{:value :triangle-arrow :label (tr "workspace.options.stroke-cap.triangle-arrow-short") :icon :cap-triangle-arrow}
|
||||
{:value :square-marker :label (tr "workspace.options.stroke-cap.square-marker-short") :icon :cap-square-marker}
|
||||
{:value :circle-marker :label (tr "workspace.options.stroke-cap.circle-marker-short") :icon :cap-circle-marker}
|
||||
{:value :diamond-marker :label (tr "workspace.options.stroke-cap.diamond-marker-short") :icon :cap-diamond-marker}
|
||||
{:value :line-arrow :label (tr "workspace.options.stroke-cap.line-arrow-short") :icon :stroke-arrow-refactor}
|
||||
{:value :triangle-arrow :label (tr "workspace.options.stroke-cap.triangle-arrow-short") :icon :stroke-triangle-refactor}
|
||||
{:value :square-marker :label (tr "workspace.options.stroke-cap.square-marker-short") :icon :stroke-rectangle-refactor}
|
||||
{:value :circle-marker :label (tr "workspace.options.stroke-cap.circle-marker-short") :icon :stroke-circle-refactor}
|
||||
{:value :diamond-marker :label (tr "workspace.options.stroke-cap.diamond-marker-short") :icon :stroke-diamond-refactor}
|
||||
:separator
|
||||
{:value :round :label (tr "workspace.options.stroke-cap.round") :icon :cap-round}
|
||||
{:value :square :label (tr "workspace.options.stroke-cap.square") :icon :cap-square}]
|
||||
{:value :round :label (tr "workspace.options.stroke-cap.round") :icon :stroke-rounded-refactor}
|
||||
{:value :square :label (tr "workspace.options.stroke-cap.square") :icon :stroke-squared-refactor}]
|
||||
|
||||
on-cap-switch
|
||||
(mf/use-callback
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
(ns app.main.ui.workspace.top-toolbar
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.media :as cm]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.media :as dwm]
|
||||
[app.main.data.workspace.path.state :as pst]
|
||||
[app.main.data.workspace.shortcuts :as sc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
|
@ -22,6 +24,7 @@
|
|||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.timers :as ts]
|
||||
[okulary.core :as l]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc image-upload
|
||||
|
@ -33,7 +36,7 @@
|
|||
on-click
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! :interrupt dw/clear-edition-mode)
|
||||
(st/emit! :interrupt (dw/clear-edition-mode))
|
||||
(dom/click (mf/ref-val ref))))
|
||||
|
||||
on-selected
|
||||
|
@ -53,7 +56,8 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image))
|
||||
:aria-label (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image))
|
||||
:on-click on-click}
|
||||
:on-click on-click
|
||||
:class (stl/css :main-toolbar-options-button)}
|
||||
i/img-refactor
|
||||
[:& file-uploader
|
||||
{:input-id "image-upload"
|
||||
|
@ -62,6 +66,15 @@
|
|||
:ref ref
|
||||
:on-selected on-selected}]]]))
|
||||
|
||||
(def toolbar-hidden
|
||||
(l/derived
|
||||
(fn [state]
|
||||
(let [visibility (dm/get-in state [:workspace-local :hide-toolbar])
|
||||
editing? (pst/path-editing? state)
|
||||
hidden? (if editing? true visibility)]
|
||||
hidden?))
|
||||
st/state))
|
||||
|
||||
(mf/defc top-toolbar
|
||||
{::mf/wrap [mf/memo]
|
||||
::mf/wrap-props false}
|
||||
|
@ -72,7 +85,7 @@
|
|||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
|
||||
rulers? (mf/deref refs/rulers?)
|
||||
hide-toolbar? (mf/deref refs/toolbar-visibility)
|
||||
hide-toolbar? (mf/deref toolbar-hidden)
|
||||
|
||||
interrupt
|
||||
(mf/use-fn #(st/emit! :interrupt))
|
||||
|
@ -83,8 +96,7 @@
|
|||
(let [tool (-> (dom/get-current-target event)
|
||||
(dom/get-data "tool")
|
||||
(keyword))]
|
||||
(st/emit! :interrupt
|
||||
dw/clear-edition-mode)
|
||||
(st/emit! :interrupt (dw/clear-edition-mode))
|
||||
|
||||
;; Delay so anything that launched :interrupt can finish
|
||||
(ts/schedule 100 #(st/emit! (dw/select-for-drawing tool))))))
|
||||
|
@ -114,7 +126,8 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.move" (sc/get-tooltip :move))
|
||||
:aria-label (tr "workspace.toolbar.move" (sc/get-tooltip :move))
|
||||
:class (stl/css-case :selected (and (nil? selected-drawtool)
|
||||
:class (stl/css-case :main-toolbar-options-button true
|
||||
:selected (and (nil? selected-drawtool)
|
||||
(not edition)))
|
||||
:on-click interrupt}
|
||||
i/move-refactor]]
|
||||
|
@ -123,7 +136,7 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame))
|
||||
:aria-label (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame))
|
||||
:class (stl/css-case :selected (= selected-drawtool :frame))
|
||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :frame))
|
||||
:on-click select-drawtool
|
||||
:data-tool "frame"
|
||||
:data-test "artboard-btn"}
|
||||
|
@ -132,7 +145,7 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
|
||||
:aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
|
||||
:class (stl/css-case :selected (= selected-drawtool :rect))
|
||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :rect))
|
||||
:on-click select-drawtool
|
||||
:data-tool "rect"
|
||||
:data-test "rect-btn"}
|
||||
|
@ -141,7 +154,7 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
|
||||
:aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
|
||||
:class (stl/css-case :selected (= selected-drawtool :circle))
|
||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :circle))
|
||||
:on-click select-drawtool
|
||||
:data-tool "circle"
|
||||
:data-test "ellipse-btn"}
|
||||
|
@ -150,7 +163,7 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
|
||||
:aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
|
||||
:class (stl/css-case :selected (= selected-drawtool :text))
|
||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :text))
|
||||
:on-click select-drawtool
|
||||
:data-tool "text"}
|
||||
i/text-refactor]]
|
||||
|
@ -161,7 +174,7 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
|
||||
:aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
|
||||
:class (stl/css-case :selected (= selected-drawtool :curve))
|
||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :curve))
|
||||
:on-click select-drawtool
|
||||
:data-tool "curve"
|
||||
:data-test "curve-btn"}
|
||||
|
@ -170,7 +183,7 @@
|
|||
[:button
|
||||
{:title (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
|
||||
:aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
|
||||
:class (stl/css-case :selected (= selected-drawtool :path))
|
||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :path))
|
||||
:on-click select-drawtool
|
||||
:data-tool "path"
|
||||
:data-test "path-btn"}
|
||||
|
@ -180,7 +193,7 @@
|
|||
[:li
|
||||
[:button
|
||||
{:title "Debugging tool"
|
||||
:class (stl/css-case :selected (contains? layout :debug-panel))
|
||||
:class (stl/css-case :main-toolbar-options-button true :selected (contains? layout :debug-panel))
|
||||
:on-click toggle-debug-panel}
|
||||
i/bug-refactor]])]]
|
||||
|
||||
|
|
|
@ -48,25 +48,24 @@
|
|||
transition: opacity 0.3s ease;
|
||||
li {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
@extend .button-tertiary;
|
||||
height: $s-36;
|
||||
width: $s-36;
|
||||
flex-shrink: 0;
|
||||
border-radius: $s-8;
|
||||
border: none;
|
||||
margin: 0 $s-2;
|
||||
.main-toolbar-options-button {
|
||||
@extend .button-tertiary;
|
||||
height: $s-36;
|
||||
width: $s-36;
|
||||
flex-shrink: 0;
|
||||
border-radius: $s-8;
|
||||
margin: 0 $s-2;
|
||||
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--color-foreground-secondary);
|
||||
}
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
@extend .button-icon-selected;
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
@extend .button-icon-selected;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
::dwsp/interrupt)
|
||||
|
||||
(when (and (not= edition id) (or text-editing? grid-editing?))
|
||||
(st/emit! dw/clear-edition-mode))
|
||||
(st/emit! (dw/clear-edition-mode)))
|
||||
|
||||
(when (and (not text-editing?)
|
||||
(not blocked)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"Drawing components."
|
||||
(:require
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.main.ui.shapes.path :refer [path-shape]]
|
||||
[app.main.ui.workspace.shapes :as shapes]
|
||||
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
|
||||
|
@ -19,14 +20,16 @@
|
|||
(mf/defc draw-area
|
||||
[{:keys [shape zoom tool] :as props}]
|
||||
|
||||
[:g.draw-area
|
||||
[:g {:style {:pointer-events "none"}}
|
||||
[:& shapes/shape-wrapper {:shape shape}]]
|
||||
;; Prevent rendering something that it's not a shape.
|
||||
(when (cts/shape? shape)
|
||||
[:g.draw-area
|
||||
[:g {:style {:pointer-events "none"}}
|
||||
[:& shapes/shape-wrapper {:shape shape}]]
|
||||
|
||||
(case tool
|
||||
:path [:& path-editor {:shape shape :zoom zoom}]
|
||||
:curve [:& path-shape {:shape shape :zoom zoom}]
|
||||
#_:default [:& generic-draw-area {:shape shape :zoom zoom}])])
|
||||
(case tool
|
||||
:path [:& path-editor {:shape shape :zoom zoom}]
|
||||
:curve [:& path-shape {:shape shape :zoom zoom}]
|
||||
#_:default [:& generic-draw-area {:shape shape :zoom zoom}])]))
|
||||
|
||||
(mf/defc generic-draw-area
|
||||
[{:keys [shape zoom]}]
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
:on-click #(st/emit! (dwge/locate-board (:id shape)))}
|
||||
(tr "workspace.layout_grid.editor.top-bar.locate")]
|
||||
[:button {:class (stl/css :done-btn)
|
||||
:on-click #(st/emit! dw/clear-edition-mode)}
|
||||
:on-click #(st/emit! (dw/clear-edition-mode))}
|
||||
(tr "workspace.layout_grid.editor.top-bar.done")]]])
|
||||
|
||||
(mf/defc grid-editor-frame
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
(def guide-width 1)
|
||||
(def guide-opacity 0.7)
|
||||
(def guide-opacity-hover 1)
|
||||
(def guide-color colors/primary)
|
||||
(def guide-color colors/new-primary)
|
||||
(def guide-pill-width 34)
|
||||
(def guide-pill-height 20)
|
||||
(def guide-pill-corner-radius 4)
|
||||
|
|
|
@ -154,7 +154,9 @@
|
|||
|
||||
;; These extra operations ensure that we are selecting a frame its initial location is rendered in the ruler
|
||||
minv (+ minv (mod offset step))
|
||||
maxv (+ maxv (mod offset step))]
|
||||
maxv (+ maxv (mod offset step))
|
||||
|
||||
rulers-width (* rulers-width zoom-inverse)]
|
||||
|
||||
[:g.rulers {:clipPath (str "url(#" clip-id ")")}
|
||||
[:defs
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
[:& view-only-actions]
|
||||
|
||||
path-edition?
|
||||
[:div.viewport-actions
|
||||
[:div {:class (stl/css :viewport-actions)}
|
||||
[:& path-actions {:shape shape}]]
|
||||
|
||||
grid-edition?
|
||||
|
|
|
@ -149,7 +149,7 @@
|
|||
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(let [stoper (rx/filter (ptk/type? ::initialize-history) stream)
|
||||
(let [stopper (rx/filter (ptk/type? ::initialize-history) stream)
|
||||
history (:history state)
|
||||
router (:router state)]
|
||||
(ts/schedule #(on-change router (.getToken ^js history)))
|
||||
|
@ -158,5 +158,5 @@
|
|||
(fn []
|
||||
(bhistory/disable! history)
|
||||
(e/unlistenByKey key)))))
|
||||
(rx/take-until stoper)
|
||||
(rx/take-until stopper)
|
||||
(rx/subs! #(on-change router %)))))))
|
||||
|
|