diff --git a/CHANGES.md b/CHANGES.md index 3ff0053c81..028b7b55fe 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -111,6 +111,9 @@ example. It's still usable as before, we just removed the example. - Fix copy/pasting application/transit+json [Taiga #12721](https://tree.taiga.io/project/penpot/issue/12721) - Fix problem with plugins content attribute [Plugins #209](https://github.com/penpot/penpot-plugins/issues/209) - Fix U and E icon displayed in project list [Taiga #12806](https://tree.taiga.io/project/penpot/issue/12806) +- Fix unpublish library modal not scrolling a long file list [Taiga #12285](https://tree.taiga.io/project/penpot/issue/12285) +- Fix incorrect interaction betwen hower and scroll on assets sidebar [Taiga #12389](https://tree.taiga.io/project/penpot/issue/12389) +- Fix switch variants with paths [Taiga #12841](https://tree.taiga.io/project/penpot/issue/12841) ## 2.11.1 diff --git a/backend/src/app/email.clj b/backend/src/app/email.clj index 91563b4d95..43361039d9 100644 --- a/backend/src/app/email.clj +++ b/backend/src/app/email.clj @@ -106,17 +106,17 @@ (let [content-part (MimeBodyPart.) alternative-mpart (MimeMultipart. "alternative")] + (when-let [content (get body "text/plain")] + (let [text-part (MimeBodyPart.)] + (.setText text-part ^String content ^String charset) + (.addBodyPart alternative-mpart text-part))) + (when-let [content (get body "text/html")] (let [html-part (MimeBodyPart.)] (.setContent html-part ^String content (str "text/html; charset=" charset)) (.addBodyPart alternative-mpart html-part))) - (when-let [content (get body "text/plain")] - (let [text-part (MimeBodyPart.)] - (.setText text-part ^String content ^String charset) - (.addBodyPart alternative-mpart text-part))) - (.setContent content-part alternative-mpart) (.addBodyPart mixed-mpart content-part)) diff --git a/backend/src/app/loggers/audit.clj b/backend/src/app/loggers/audit.clj index 9471f5dad4..7d64b768b0 100644 --- a/backend/src/app/loggers/audit.clj +++ b/backend/src/app/loggers/audit.clj @@ -79,18 +79,6 @@ (remove #(contains? reserved-props (key %)))) props)) -(defn event-from-rpc-params - "Create a base event skeleton with pre-filled some important - data that can be extracted from RPC params object" - [params] - (let [context {:external-session-id (::rpc/external-session-id params) - :external-event-origin (::rpc/external-event-origin params) - :triggered-by (::rpc/handler-name params)}] - {::type "action" - ::profile-id (::rpc/profile-id params) - ::ip-addr (::rpc/ip-addr params) - ::context (d/without-nils context)})) - (defn get-external-session-id [request] (when-let [session-id (yreq/get-header request "x-external-session-id")] @@ -99,13 +87,24 @@ (str/blank? session-id)) session-id))) -(defn- get-external-event-origin +(defn- get-client-event-origin [request] (when-let [origin (yreq/get-header request "x-event-origin")] - (when-not (or (> (count origin) 256) - (= origin "null") + (when-not (or (= origin "null") (str/blank? origin)) - origin))) + (str/prune origin 200)))) + +(defn get-client-user-agent + [request] + (when-let [user-agent (yreq/get-header request "user-agent")] + (str/prune user-agent 500))) + +(defn- get-client-version + [request] + (when-let [origin (yreq/get-header request "x-frontend-version")] + (when-not (or (= origin "null") + (str/blank? origin)) + (str/prune origin 100)))) ;; --- SPECS @@ -134,6 +133,33 @@ (def ^:private check-event (sm/check-fn schema:event)) +(defn- prepare-context-from-request + [request] + (let [client-event-origin (get-client-event-origin request) + client-version (get-client-version request) + client-user-agent (get-client-user-agent request) + session-id (get-external-session-id request) + token-id (::actoken/id request)] + (d/without-nils + {:external-session-id session-id + :access-token-id (some-> token-id str) + :client-event-origin client-event-origin + :client-user-agent client-user-agent + :client-version client-version + :version (:full cf/version)}))) + +(defn event-from-rpc-params + "Create a base event skeleton with pre-filled some important + data that can be extracted from RPC params object" + [params] + (let [context (some-> params meta ::http/request prepare-context-from-request) + event {::type "action" + ::profile-id (or (::rpc/profile-id params) uuid/zero) + ::ip-addr (::rpc/ip-addr params)}] + (cond-> event + (some? context) + (assoc ::context context)))) + (defn prepare-event [cfg mdata params result] (let [resultm (meta result) @@ -148,18 +174,10 @@ (merge (::props resultm)) (dissoc :profile-id) (dissoc :type))) - (clean-props)) - token-id (::actoken/id request) - context (-> (::context resultm) - (assoc :external-session-id - (get-external-session-id request)) - (assoc :external-event-origin - (get-external-event-origin request)) - (assoc :access-token-id (some-> token-id str)) - (d/without-nils)) - + context (merge (::context resultm) + (prepare-context-from-request request)) ip-addr (inet/parse-request request)] {::type (or (::type resultm) diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index 364099b37b..0d291a94f4 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -12,8 +12,11 @@ [app.common.files.changes-builder :as pcb] [app.common.files.helpers :as cfh] [app.common.files.variant :as cfv] + [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] + [app.common.geom.rect :as grc] [app.common.geom.shapes :as gsh] + [app.common.geom.shapes.common :as gco] [app.common.logging :as log] [app.common.logic.shapes :as cls] [app.common.logic.variant-properties :as clvp] @@ -25,6 +28,7 @@ [app.common.types.library :as ctl] [app.common.types.page :as ctp] [app.common.types.pages-list :as ctpl] + [app.common.types.path.segment :as segment] [app.common.types.shape :as cts] [app.common.types.shape-tree :as ctst] [app.common.types.shape.interactions :as ctsi] @@ -1874,6 +1878,44 @@ roperations' uoperations'))))))) +(defn- set-path-new-values + [current-shape prev-shape transform] + (let [new-content (segment/transform-content + (:content current-shape) + (gmt/transform-in (gpt/point 0 0) transform)) + new-points (-> (segment/content->selrect new-content) + (grc/rect->points)) + points-center (gco/points->center new-points) + new-selrect (gsh/calculate-selrect new-points points-center) + shape (assoc current-shape + :content new-content + :points new-points + :selrect new-selrect) + + prev-center (segment/content-center (:content prev-shape)) + delta (gpt/subtract points-center (first new-points)) + new-pos (gpt/subtract prev-center delta)] + (gsh/absolute-move shape new-pos))) + +(defn- switch-path-change-value + [prev-shape ;; The shape before the switch + current-shape ;; The shape after the switch (a clean copy) + ref-shape ;; The referenced shape on the main component + ;; before the switch + attr] + (let [old-width (-> ref-shape :selrect :width) + new-width (-> prev-shape :selrect :width) + + old-height (-> ref-shape :selrect :height) + new-height (-> prev-shape :selrect :height) + + transform (-> (gpt/point (/ new-width old-width) + (/ new-height old-height)) + (gmt/scale-matrix)) + + shape (set-path-new-values current-shape prev-shape transform)] + (get shape attr))) + (defn- switch-text-change-value [prev-content ;; The :content of the text before the switch @@ -2025,6 +2067,10 @@ (= :content attr) (touched attr-group)) + path-change? + (and (= :path (:type current-shape)) + (contains? #{:points :selrect :content} attr)) + ;; position-data is a special case because can be affected by :geometry-group and :content-group ;; so, if the position-data changes but the geometry is touched we need to reset the position-data ;; so it's calculated again @@ -2053,6 +2099,12 @@ (:content origin-ref-shape) touched) + path-change? + (switch-path-change-value previous-shape + current-shape + origin-ref-shape + attr) + :else (get previous-shape attr))) diff --git a/common/src/app/common/schema.cljc b/common/src/app/common/schema.cljc index a5a9828ad3..6c4ecb6ef1 100644 --- a/common/src/app/common/schema.cljc +++ b/common/src/app/common/schema.cljc @@ -284,9 +284,22 @@ (defn check-fn "Create a predefined check function" [s & {:keys [hint type code]}] - (let [s (delay (schema s)) - validator* (delay (m/validator @s)) - explainer* (delay (m/explainer @s)) + (let [s #?(:clj + (schema s) + :cljs + (try + (schema s) + (catch :default cause + (let [data (ex-data cause)] + (if (= :malli.core/invalid-schema (:type data)) + (throw (ex-info + (str "Invalid schema\n" + (pp/pprint-str (:data data))) + {})) + (throw cause)))))) + + validator* (delay (m/validator s)) + explainer* (delay (m/explainer s)) hint (or ^boolean hint "check error") type (or ^boolean type :assertion) code (or ^boolean code :data-validation)] diff --git a/exporter/scripts/wait-and-start.sh b/exporter/scripts/wait-and-start.sh index f9638eb06d..c3848228dc 100755 --- a/exporter/scripts/wait-and-start.sh +++ b/exporter/scripts/wait-and-start.sh @@ -7,4 +7,5 @@ bb -i '(babashka.wait/wait-for-port "localhost" 9630)'; bb -i '(babashka.wait/wait-for-path "target/app.js")'; sleep 2; +export NODE_TLS_REJECT_UNAUTHORIZED=0 exec node target/app.js diff --git a/exporter/src/app/browser.cljs b/exporter/src/app/browser.cljs index 816fb1c954..526ae77380 100644 --- a/exporter/src/app/browser.cljs +++ b/exporter/src/app/browser.cljs @@ -100,7 +100,7 @@ (def browser-pool-factory (letfn [(create [] - (p/let [opts #js {:args #js ["--font-render-hinting=none"]} + (p/let [opts #js {:args #js ["--allow-insecure-localhost" "--font-render-hinting=none"]} browser (.launch pw/chromium opts) id (swap! pool-browser-id inc)] (l/info :origin "factory" :action "create" :browser-id id) diff --git a/exporter/src/app/handlers/export_shapes.cljs b/exporter/src/app/handlers/export_shapes.cljs index c254aba5b5..82f1d78855 100644 --- a/exporter/src/app/handlers/export_shapes.cljs +++ b/exporter/src/app/handlers/export_shapes.cljs @@ -74,7 +74,7 @@ (p/fmap (fn [resource] (assoc exchange :response/body resource))) (p/merr (fn [cause] - (l/error :hint "unexpected error on export multiple" + (l/error :hint "unexpected error on single export" :cause cause) (p/rejected cause)))))) @@ -94,7 +94,7 @@ (redis/pub! topic data)))) on-error (fn [cause] - (l/error :hint "unexpected error on multiple exportation" :cause cause) + (l/error :hint "unexpected error on multiple export" :cause cause) (if wait (p/rejected cause) (redis/pub! topic {:type :export-update diff --git a/frontend/src/app/main/data/event.cljs b/frontend/src/app/main/data/event.cljs index 0e6ac46b4a..7f7551544a 100644 --- a/frontend/src/app/main/data/event.cljs +++ b/frontend/src/app/main/data/event.cljs @@ -67,7 +67,7 @@ [] (let [uagent (new ua/UAParser)] (merge - {:app-version (:full cf/version) + {:version (:full cf/version) :locale i18n/*current-locale*} (let [browser (.getBrowser uagent)] {:browser (obj/get browser "name") diff --git a/frontend/src/app/main/data/team.cljs b/frontend/src/app/main/data/team.cljs index e05cf81748..8c0a35b8e0 100644 --- a/frontend/src/app/main/data/team.cljs +++ b/frontend/src/app/main/data/team.cljs @@ -351,19 +351,31 @@ (on-success)))) (rx/catch on-error)))))) + +(def ^:private schema:create-invitation + [:and + [:map + [:emails {:optional true} [::sm/set ::sm/email]] + [:invitations {:optional true} + [:vector + [:map + [:email ::sm/email] + [:role [::sm/one-of ctt/valid-roles]]]]] + [:team-id ::sm/uuid] + [:resend? {:optional true} ::sm/boolean]] + [:fn (fn [attrs] + (or (contains? attrs :emails) + (contains? attrs :invitations)))]]) + +(def ^:private check-create-invitations-params + (sm/check-fn schema:create-invitation)) + (defn create-invitations "Unified function to create invitations. Supports two parameter formats: 1. {:emails #{...} :role :admin :team-id uuid} - single role for all emails 2. {:invitations [{:email ... :role ...}] :team-id uuid} - individual roles per email" [{:keys [emails role team-id invitations resend?] :as params}] - - (assert (uuid? team-id)) - ;; Validate input format - must have either emails+role OR invitations - (assert (or (and emails role (sm/check-set-of-emails emails) (keyword? role)) - (and invitations - (sm/check-set-of-emails (map :email invitations)) - (every? #(contains? ctt/valid-roles (:role %)) invitations))) - "Must provide either emails+role or invitations with individual roles") + (check-create-invitations-params params) (ptk/reify ::create-invitations ev/Event diff --git a/frontend/src/app/main/ui/delete_shared.cljs b/frontend/src/app/main/ui/delete_shared.cljs index 43a2a2425b..51fcb8225e 100644 --- a/frontend/src/app/main/ui/delete_shared.cljs +++ b/frontend/src/app/main/ui/delete_shared.cljs @@ -106,14 +106,14 @@ (when (not= 0 count-libraries) (if (pos? (count references)) [:* - [:div - (when (and (string? scd-msg) (not= scd-msg "")) - [:h3 {:class (stl/css :modal-scd-msg)} scd-msg]) - [:ul {:class (stl/css :element-list)} - (for [[file-id file-name] references] - [:li {:class (stl/css :list-item) - :key (dm/str file-id)} - [:span "- " file-name]])]] + (when (and (string? scd-msg) (not= scd-msg "")) + [:p {:class (stl/css :modal-scd-msg)} scd-msg]) + + [:ul {:class (stl/css :element-list)} + (for [[file-id file-name] references] + [:li {:class (stl/css :list-item) + :key (dm/str file-id)} + [:span "- " file-name]])] (when (and (string? hint) (not= hint "")) [:> context-notification* {:level :info :appearance :ghost} diff --git a/frontend/src/app/main/ui/delete_shared.scss b/frontend/src/app/main/ui/delete_shared.scss index ff842933da..8e06bb4720 100644 --- a/frontend/src/app/main/ui/delete_shared.scss +++ b/frontend/src/app/main/ui/delete_shared.scss @@ -4,7 +4,8 @@ // // Copyright (c) KALEIDOS INC -@use "refactor/common-refactor.scss" as deprecated; +@use "refactor/basic-rules.scss" as *; +@use "ds/typography.scss" as t; .modal-overlay { @extend .modal-overlay-base; @@ -15,14 +16,19 @@ .modal-container { @extend .modal-container-base; + display: grid; + gap: var(--sp-xxl); + grid-template-rows: auto minmax(0, 1fr) auto; } -.modal-header { - margin-bottom: deprecated.$s-24; +.list-wrapper { + display: grid; + grid-template-rows: auto 1fr auto; + max-height: 100%; } .modal-title { - @include deprecated.headlineMediumTypography; + @include t.use-typography("headline-medium"); color: var(--modal-title-foreground-color); } @@ -31,13 +37,16 @@ } .modal-content { - @include deprecated.bodySmallTypography; - margin-bottom: deprecated.$s-24; + @include t.use-typography("body-small"); + display: grid; + gap: var(--sp-s); } .element-list { - @include deprecated.bodyLargeTypography; + @include t.use-typography("body-large"); color: var(--modal-text-foreground-color); + overflow-y: scroll; + margin-block: 0; } .action-buttons { @@ -55,10 +64,14 @@ } } +.modal-scd-msg { + margin-block: 0; +} + .modal-scd-msg, .modal-subtitle, .modal-msg { - @include deprecated.bodyLargeTypography; + @include t.use-typography("body-large"); color: var(--modal-text-foreground-color); line-height: 1.5; } diff --git a/frontend/src/app/main/ui/inspect/attributes.cljs b/frontend/src/app/main/ui/inspect/attributes.cljs index 2eb274d4d5..8255782af5 100644 --- a/frontend/src/app/main/ui/inspect/attributes.cljs +++ b/frontend/src/app/main/ui/inspect/attributes.cljs @@ -36,7 +36,7 @@ :text [:visibility :geometry :text :shadow :blur :stroke :layout-element] :variant [:variant :geometry :fill :stroke :shadow :blur :layout :layout-element]}) -(mf/defc attributes +(mf/defc attributes* [{:keys [page-id file-id shapes frame from libraries share-id objects color-space]}] (let [shapes (hooks/use-equal-memo shapes) first-shape (first shapes) diff --git a/frontend/src/app/main/ui/inspect/code.cljs b/frontend/src/app/main/ui/inspect/code.cljs index 3e93b2898a..661bee9075 100644 --- a/frontend/src/app/main/ui/inspect/code.cljs +++ b/frontend/src/app/main/ui/inspect/code.cljs @@ -96,7 +96,7 @@ embed-images? (replace-map images-data))] (str/format page-template style-code markup-code))) -(mf/defc code +(mf/defc code* [{:keys [shapes frame on-expand from]}] (let [style-type* (mf/use-state "css") markup-type* (mf/use-state "html") diff --git a/frontend/src/app/main/ui/inspect/right_sidebar.cljs b/frontend/src/app/main/ui/inspect/right_sidebar.cljs index cc260316c9..bcee180956 100644 --- a/frontend/src/app/main/ui/inspect/right_sidebar.cljs +++ b/frontend/src/app/main/ui/inspect/right_sidebar.cljs @@ -17,8 +17,8 @@ [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]] [app.main.ui.ds.product.empty-state :refer [empty-state*]] - [app.main.ui.inspect.attributes :refer [attributes]] - [app.main.ui.inspect.code :refer [code]] + [app.main.ui.inspect.attributes :refer [attributes*]] + [app.main.ui.inspect.code :refer [code*]] [app.main.ui.inspect.selection-feedback :refer [resolve-shapes]] [app.main.ui.inspect.styles :refer [styles-tab*]] [app.util.dom :as dom] @@ -123,8 +123,7 @@ (fn [] (if (seq shapes) (st/emit! (ptk/event ::ev/event {::ev/name "inspect-mode-click-element"})) - (handle-change-tab (if (contains? cf/flags :inspect-styles) :styles :info))) - (reset! color-space* "hex"))) + (handle-change-tab (if (contains? cf/flags :inspect-styles) :styles :info))))) [:aside {:class (stl/css-case :settings-bar-right true :viewer-code (= from :viewer))} @@ -190,41 +189,41 @@ :libraries libraries :file-id file-id}] :computed - [:& attributes {:color-space color-space - :page-id page-id - :objects objects - :file-id file-id - :frame frame - :shapes shapes - :from from - :libraries libraries - :share-id share-id}] + [:> attributes* {:color-space color-space + :page-id page-id + :objects objects + :file-id file-id + :frame frame + :shapes shapes + :from from + :libraries libraries + :share-id share-id}] :code - [:& code {:frame frame - :shapes shapes - :on-expand handle-expand - :from from}])] + [:> code* {:frame frame + :shapes shapes + :on-expand handle-expand + :from from}])] [:> tab-switcher* {:tabs tabs :selected (name @section) :on-change handle-change-tab :class (stl/css :viewer-tab-switcher)} (case @section :info - [:& attributes {:page-id page-id - :objects objects - :file-id file-id - :frame frame - :shapes shapes - :from from - :libraries libraries - :share-id share-id}] + [:> attributes* {:page-id page-id + :objects objects + :file-id file-id + :frame frame + :shapes shapes + :from from + :libraries libraries + :share-id share-id}] :code - [:& code {:frame frame - :shapes shapes - :on-expand handle-expand - :from from}])])]] + [:> code* {:frame frame + :shapes shapes + :on-expand handle-expand + :from from}])])]] [:* [:div {:class (stl/css :empty)} diff --git a/frontend/src/app/main/ui/inspect/styles.cljs b/frontend/src/app/main/ui/inspect/styles.cljs index fc9b9fa17d..4c46bf393a 100644 --- a/frontend/src/app/main/ui/inspect/styles.cljs +++ b/frontend/src/app/main/ui/inspect/styles.cljs @@ -133,7 +133,7 @@ (swap! shorthands* assoc (:panel shorthand) (:property shorthand))))] [:ol {:class (stl/css :styles-tab) :aria-label (tr "labels.styles")} ;; TOKENS PANEL - (when (or active-themes active-sets) + (when (or (seq active-themes) (seq active-sets)) [:li [:> style-box* {:panel :token} [:> tokens-panel* {:theme-paths active-themes :set-names active-sets}]]]) diff --git a/frontend/src/app/main/ui/inspect/styles/style_box.scss b/frontend/src/app/main/ui/inspect/styles/style_box.scss index 846d3ca5ad..fcb9ac73b7 100644 --- a/frontend/src/app/main/ui/inspect/styles/style_box.scss +++ b/frontend/src/app/main/ui/inspect/styles/style_box.scss @@ -6,6 +6,15 @@ @use "ds/typography.scss" as *; +// TODO: this must be a custom property in the design system +:global(.light) { + --low-emphasis-background: #fafafa; +} + +:global(.default) { + --low-emphasis-background: #121214; +} + .style-box { --title-gap: var(--sp-xs); --title-padding: var(--sp-s); @@ -13,12 +22,9 @@ --arrow-color: var(--color-foreground-secondary); --box-border-color: var(--color-background-primary); - // TODO: this must be a custom property in the design system - --lowEmphasis-background: #121214; - padding-block: var(--sp-s); padding-inline: var(--sp-m); - background-color: var(--lowEmphasis-background); + background-color: var(--low-emphasis-background); border-block-end: 2px solid var(--box-border-color); } diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index a2d74157b5..0b44af4511 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -27,7 +27,7 @@ [app.main.ui.workspace.coordinates :as coordinates] [app.main.ui.workspace.libraries] [app.main.ui.workspace.nudge] - [app.main.ui.workspace.palette :refer [palette]] + [app.main.ui.workspace.palette :refer [palette*]] [app.main.ui.workspace.plugins] [app.main.ui.workspace.sidebar :refer [sidebar*]] [app.main.ui.workspace.sidebar.history :refer [history-toolbox*]] @@ -84,8 +84,8 @@ node-ref (use-resize-observer on-resize)] [:* (when (not ^boolean hide-ui?) - [:& palette {:layout layout - :on-change-palette-size on-resize-palette}]) + [:> palette* {:layout layout + :on-change-size on-resize-palette}]) [:section {:key (dm/str "workspace-" page-id) diff --git a/frontend/src/app/main/ui/workspace/colorpicker/color_tokens.cljs b/frontend/src/app/main/ui/workspace/colorpicker/color_tokens.cljs index 78c9d7d884..61871dfcdd 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker/color_tokens.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker/color_tokens.cljs @@ -156,7 +156,7 @@ (let [{:keys [modal title]} (get dwta/token-properties :color) window-size (dom/get-window-size) left-sidebar (dom/get-element "left-sidebar-aside") - x-size (dom/get-data left-sidebar "left-sidebar-width") + x-size (dom/get-data left-sidebar "width") modal-height 392 x (- (int x-size) 30) y (- (/ (:height window-size) 2) (/ modal-height 2))] diff --git a/frontend/src/app/main/ui/workspace/palette.cljs b/frontend/src/app/main/ui/workspace/palette.cljs index 43f7b5e4e4..80c396989e 100644 --- a/frontend/src/app/main/ui/workspace/palette.cljs +++ b/frontend/src/app/main/ui/workspace/palette.cljs @@ -33,12 +33,13 @@ [okulary.core :as l] [rumext.v2 :as mf])) -(def viewport +(def ^:private ref:viewport (l/derived :vport refs/workspace-local)) -(defn calculate-palette-padding [rulers?] +(defn- calculate-palette-style + [rulers?] (let [left-sidebar (dom/get-element "left-sidebar-aside") - left-sidebar-size (-> (dom/get-data left-sidebar "left-sidebar-width") + left-sidebar-size (-> (dom/get-data left-sidebar "width") (d/parse-integer)) rulers-width (if rulers? 22 0) min-left-sidebar-width left-sidebar-default-width @@ -48,36 +49,46 @@ #js {"paddingLeft" (dm/str calculate-padding-left "px") "paddingRight" "322px"})) -(mf/defc palette - [{:keys [layout on-change-palette-size]}] - (let [color-palette? (:colorpalette layout) - text-palette? (:textpalette layout) - hide-palettes? (:hide-palettes layout) - workspace-read-only? (mf/use-ctx ctx/workspace-read-only?) - container (mf/use-ref nil) - state* (mf/use-state {:show-menu false}) - state (deref state*) - show-menu? (:show-menu state) - selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent) - selected-text* (mf/use-state :file) - selected-text (deref selected-text*) - on-select (mf/use-fn #(reset! selected %)) - rulers? (mf/deref refs/rulers?) - {:keys [on-pointer-down on-lost-pointer-capture on-pointer-move parent-ref size]} - (r/use-resize-hook :palette 72 54 80 :y true :bottom on-change-palette-size) +(mf/defc palette* + [{:keys [layout on-change-size]}] + (let [color-palette? (:colorpalette layout) + text-palette? (:textpalette layout) + hide-palettes? (:hide-palettes layout) - vport (mf/deref viewport) - vport-width (:width vport) + read-only? (mf/use-ctx ctx/workspace-read-only?) + container (mf/use-ref nil) + + state* (mf/use-state #(-> {:show-menu false})) + state (deref state*) + show-menu? (:show-menu state) + + selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent) + + selected-text* (mf/use-state :file) + selected-text (deref selected-text*) + + on-select (mf/use-fn #(reset! selected %)) + + rulers? (mf/deref refs/rulers?) + vport (mf/deref ref:viewport) + vport-width (get vport :width) + + {:keys [on-pointer-down + on-lost-pointer-capture + on-pointer-move + parent-ref + size]} + (r/use-resize-hook :palette 72 54 80 :y true :bottom on-change-size) on-resize - (mf/use-callback + (mf/use-fn (fn [_] (let [dom (mf/ref-val container) width (obj/get dom "clientWidth")] (swap! state* assoc :width width)))) on-close-menu - (mf/use-callback + (mf/use-fn (fn [_] (swap! state* assoc :show-menu false))) @@ -100,7 +111,7 @@ (reset! selected-text* (:id lib))))) toggle-palettes - (mf/use-callback + (mf/use-fn (fn [_] (r/set-resize-type! :top) (dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down") @@ -131,7 +142,9 @@ (vary-meta assoc ::ev/origin "workspace-left-toolbar")))) (dom/blur! node)))) - any-palette? (or color-palette? text-palette?) + any-palette? + (or color-palette? text-palette?) + size-classname (cond (<= size 64) (stl/css :small-palette) @@ -142,16 +155,16 @@ (let [key1 (events/listen js/window "resize" on-resize)] #(events/unlistenByKey key1))) - (mf/use-layout-effect - #(let [dom (mf/ref-val parent-ref) + (mf/with-layout-effect [] + (let [dom (mf/ref-val parent-ref) width (obj/get dom "clientWidth")] (swap! state* assoc :width width))) [:div {:class (stl/css :palette-wrapper) :id "palette-wrapper" - :style (calculate-palette-padding rulers?) + :style (calculate-palette-style rulers?) :data-testid "palette"} - (when-not workspace-read-only? + (when-not ^boolean read-only? [:div {:ref parent-ref :class (dm/str size-classname " " (stl/css-case :palettes true :wide any-palette? diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index a9733567d7..58f299f666 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -27,7 +27,6 @@ [app.main.ui.workspace.left-header :refer [left-header*]] [app.main.ui.workspace.right-header :refer [right-header*]] [app.main.ui.workspace.sidebar.assets :refer [assets-toolbox*]] - [app.main.ui.workspace.sidebar.collapsable-button :refer [collapsed-button*]] [app.main.ui.workspace.sidebar.debug :refer [debug-panel*]] [app.main.ui.workspace.sidebar.debug-shape-info :refer [debug-shape-info*]] [app.main.ui.workspace.sidebar.history :refer [history-toolbox*]] @@ -44,19 +43,34 @@ ;; --- Left Sidebar (Component) -(defn- on-collapse-left-sidebar - [] - (st/emit! (dw/toggle-layout-flag :collapse-left-sidebar))) +(def ^:private toggle-collapse-left-sidebar + (partial st/emit! (dw/toggle-layout-flag :collapse-left-sidebar))) (mf/defc collapse-button* + {::mf/private true} [] ;; NOTE: This custom button may be replace by an action button when this variant is designed [:button {:class (stl/css :collapse-sidebar-button) - :on-click on-collapse-left-sidebar} + :on-click toggle-collapse-left-sidebar} [:> icon* {:icon-id i/arrow :size "s" :aria-label (tr "workspace.sidebar.collapse")}]]) +(mf/defc collapsed-button* + {::mf/memo true + ::mf/private true} + [] + [:div {:id "left-sidebar-aside" + :data-width "0" + :class (stl/css :collapsed-sidebar)} + [:div {:class (stl/css :collapsed-title)} + [:button {:class (stl/css :collapsed-button) + :title (tr "workspace.sidebar.expand") + :on-click toggle-collapse-left-sidebar} + [:> icon* {:icon-id i/arrow + :size "s" + :aria-label (tr "workspace.sidebar.expand")}]]]]) + (mf/defc layers-content* {::mf/private true ::mf/memo true} @@ -97,6 +111,7 @@ [:> layers-toolbox* {:size-parent width}]])) + (mf/defc left-sidebar* {::mf/memo true} [{:keys [layout file page-id tokens-lib active-tokens resolved-active-tokens]}] @@ -161,7 +176,7 @@ [:aside {:ref parent-ref :id "left-sidebar-aside" :data-testid "left-sidebar" - :data-left-sidebar-width (str width) + :data-width (str width) :class aside-class :style {:--left-sidebar-width (dm/str width "px")}} diff --git a/frontend/src/app/main/ui/workspace/sidebar.scss b/frontend/src/app/main/ui/workspace/sidebar.scss index 3c6871e784..acceaf4f7d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.scss +++ b/frontend/src/app/main/ui/workspace/sidebar.scss @@ -116,6 +116,44 @@ } } +.collapsed-sidebar { + @include deprecated.flexCenter; + position: absolute; + top: deprecated.$s-48; + left: 0; + padding: deprecated.$s-4; + border-radius: deprecated.$br-8; + background: var(--color-background-primary); + margin-inline-start: var(--sp-m); +} +.collapsed-title { + @include deprecated.flexCenter; + height: deprecated.$s-36; + width: deprecated.$s-24; + border-radius: deprecated.$br-8; + background: var(--color-background-secondary); +} +.collapsed-button { + @include deprecated.buttonStyle; + height: deprecated.$s-24; + width: deprecated.$s-16; + padding: 0; + border-radius: deprecated.$br-5; + svg { + @include deprecated.flexCenter; + height: deprecated.$s-16; + width: deprecated.$s-16; + color: transparent; + fill: none; + stroke: var(--icon-foreground); + } + &:hover { + svg { + stroke: var(--icon-foreground-hover); + } + } +} + .versions-tab { width: 100%; overflow: hidden; diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 2227de25b9..d899f20d67 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -56,9 +56,8 @@ (update file :data dissoc :pages-index)) refs/file)) -(mf/defc assets-local-library - {::mf/wrap [mf/memo] - ::mf/wrap-props false} +(mf/defc assets-local-library* + {::mf/private true} [{:keys [filters]}] (let [file (mf/deref ref:local-library)] [:> file-library* @@ -68,7 +67,7 @@ :filters filters}])) (defn- toggle-values - [v [a b]] + [v a b] (if (= v a) b a)) (mf/defc assets-toolbox* @@ -97,7 +96,7 @@ (mf/use-fn (mf/deps ordering) (fn [] - (let [new-value (toggle-values ordering [:asc :desc])] + (let [new-value (toggle-values ordering :asc :desc)] (swap! filters* assoc :ordering new-value) (dwa/set-current-assets-ordering! new-value)))) @@ -105,7 +104,7 @@ (mf/use-fn (mf/deps list-style) (fn [] - (let [new-value (toggle-values list-style [:thumbs :list])] + (let [new-value (toggle-values list-style :thumbs :list)] (swap! filters* assoc :list-style new-value) (dwa/set-current-assets-list-style! new-value)))) @@ -209,5 +208,5 @@ [:& (mf/provider cmm/assets-toggle-ordering) {:value toggle-ordering} [:& (mf/provider cmm/assets-toggle-list-style) {:value toggle-list-style} [:* - [:& assets-local-library {:filters filters}] + [:> assets-local-library* {:filters filters}] [:> assets-libraries* {:filters filters}]]]]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss index 223a6d920e..1237c53323 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss @@ -15,7 +15,7 @@ cursor: pointer; .title-menu { - display: block; + visibility: visible; } } } @@ -25,7 +25,7 @@ } .title-menu { - display: none; + visibility: hidden; } .group-title { diff --git a/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.cljs b/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.cljs deleted file mode 100644 index 8d6160c147..0000000000 --- a/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.cljs +++ /dev/null @@ -1,29 +0,0 @@ -;; 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 - -(ns app.main.ui.workspace.sidebar.collapsable-button - (:require-macros [app.main.style :as stl]) - (:require - [app.main.data.workspace :as dw] - [app.main.store :as st] - [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] - [app.util.i18n :refer [tr]] - [rumext.v2 :as mf])) - -(mf/defc collapsed-button* - {::mf/memo true} - [] - (let [on-click (mf/use-fn #(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar)))] - [:div {:id "left-sidebar-aside" - :data-size "0" - :class (stl/css :collapsed-sidebar)} - [:div {:class (stl/css :collapsed-title)} - [:button {:class (stl/css :collapsed-button) - :title (tr "workspace.sidebar.expand") - :on-click on-click} - [:> icon* {:icon-id i/arrow - :size "s" - :aria-label (tr "workspace.sidebar.expand")}]]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.scss b/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.scss deleted file mode 100644 index 9d2f6156f5..0000000000 --- a/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.scss +++ /dev/null @@ -1,45 +0,0 @@ -// 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 "refactor/common-refactor.scss" as deprecated; - -.collapsed-sidebar { - @include deprecated.flexCenter; - position: absolute; - top: deprecated.$s-48; - left: 0; - padding: deprecated.$s-4; - border-radius: deprecated.$br-8; - background: var(--color-background-primary); - margin-inline-start: var(--sp-m); -} -.collapsed-title { - @include deprecated.flexCenter; - height: deprecated.$s-36; - width: deprecated.$s-24; - border-radius: deprecated.$br-8; - background: var(--color-background-secondary); -} -.collapsed-button { - @include deprecated.buttonStyle; - height: deprecated.$s-24; - width: deprecated.$s-16; - padding: 0; - border-radius: deprecated.$br-5; - svg { - @include deprecated.flexCenter; - height: deprecated.$s-16; - width: deprecated.$s-16; - color: transparent; - fill: none; - stroke: var(--icon-foreground); - } - &:hover { - svg { - stroke: var(--icon-foreground-hover); - } - } -} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index 0098eea40e..e016bc354f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -686,7 +686,7 @@ (str/upper (tr "workspace.assets.local-library")) (dm/get-in libraries [current-library-id :name])) - current-lib-data (mf/with-memo [libraries] + current-lib-data (mf/with-memo [libraries current-library-id] (get-in libraries [current-library-id :data])) current-lib-counts (mf/with-memo [current-lib-data] diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index f27ca272e5..7d08054fb4 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -149,9 +149,9 @@ canvas-ref (mf/use-ref nil) - ;; VARS - disable-paste (mf/use-var false) - in-viewport? (mf/use-var false) + ;; STATE REFS + disable-paste-ref (mf/use-ref false) + in-viewport-ref (mf/use-ref false) ;; STREAMS move-stream (mf/use-memo #(rx/subject)) @@ -210,10 +210,10 @@ on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? path-editing? grid-editing? path-drawing? create-comment? space? panning z? read-only?) - on-pointer-up (actions/on-pointer-up disable-paste) + on-pointer-up (actions/on-pointer-up disable-paste-ref) - on-pointer-enter (actions/on-pointer-enter in-viewport?) - on-pointer-leave (actions/on-pointer-leave in-viewport?) + on-pointer-enter (actions/on-pointer-enter in-viewport-ref) + on-pointer-leave (actions/on-pointer-leave in-viewport-ref) on-pointer-move (actions/on-pointer-move move-stream) on-move-selected (actions/on-move-selected hover hover-ids selected space? z? read-only?) on-menu-selected (actions/on-menu-selected hover hover-ids selected read-only?) @@ -304,7 +304,7 @@ #(st/emit! (dwv/add-new-variant (:id first-shape))))] - (hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool path-drawing?) + (hooks/setup-dom-events zoom disable-paste-ref in-viewport-ref read-only? drawing-tool path-drawing?) (hooks/setup-viewport-size vport viewport-ref) (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool path-drawing? path-editing? z? read-only?) (hooks/setup-keyboard alt? mod? space? z? shift?) diff --git a/frontend/src/app/main/ui/workspace/viewport/actions.cljs b/frontend/src/app/main/ui/workspace/viewport/actions.cljs index 56c70d1748..902c8f860b 100644 --- a/frontend/src/app/main/ui/workspace/viewport/actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/actions.cljs @@ -266,7 +266,7 @@ (st/emit! (dw/show-shape-context-menu {:position position :hover-ids @hover-ids}))))))) (defn on-pointer-up - [disable-paste] + [disable-paste-ref] (mf/use-callback (fn [event] (dom/stop-propagation event) @@ -291,21 +291,19 @@ (dom/prevent-default event) ;; We store this so in Firefox the middle button won't do a paste of the content - (reset! disable-paste true) - (ts/schedule #(reset! disable-paste false))) + (mf/set-ref-val! disable-paste-ref true) + (ts/schedule #(mf/set-ref-val! disable-paste-ref false))) (st/emit! (dw/finish-panning) (dw/finish-zooming)))))) -(defn on-pointer-enter [in-viewport?] - (mf/use-callback - (fn [] - (reset! in-viewport? true)))) +(defn on-pointer-enter + [in-viewport-ref] + (mf/use-fn #(mf/set-ref-val! in-viewport-ref true))) -(defn on-pointer-leave [in-viewport?] - (mf/use-callback - (fn [] - (reset! in-viewport? false)))) +(defn on-pointer-leave + [in-viewport-ref] + (mf/use-fn #(mf/set-ref-val! in-viewport-ref false))) (defn on-key-down [] (mf/use-callback @@ -524,15 +522,22 @@ :blobs (seq files)}] (st/emit! (dwm/upload-media-workspace params)))))))) +(def ^:private invalid-paste-targets + #{"INPUT" "TEXTAREA"}) + (defn on-paste - [disable-paste in-viewport? read-only?] + [disable-paste-ref in-viewport-ref read-only?] (mf/use-fn (mf/deps read-only?) (fn [event] - ;; We disable the paste just after mouse-up of a middle button so - ;; when panning won't paste the content into the workspace - (let [tag-name (-> event dom/get-target dom/get-tag-name)] - (when (and (not (#{"INPUT" "TEXTAREA"} tag-name)) - (not @disable-paste) + ;; We disable the paste when: 1. just after mouse-up of a middle + ;; button (so when panning won't paste the content into the + ;; workspace); 2. when we paste content in an input on the + ;; sidebar + (let [tag-name (-> event dom/get-target dom/get-tag-name) + disable-paste? (mf/ref-val disable-paste-ref) + in-viewport? (mf/ref-val in-viewport-ref)] + (when (and (not (contains? invalid-paste-targets tag-name)) + (not disable-paste?) (not read-only?)) - (st/emit! (dw/paste-from-event event @in-viewport?))))))) + (st/emit! (dw/paste-from-event event in-viewport?))))))) diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index 230abf8a28..922e18057d 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -42,11 +42,12 @@ [rumext.v2 :as mf]) (:import goog.events.EventType)) -(defn setup-dom-events [zoom disable-paste in-viewport? workspace-read-only? drawing-tool drawing-path?] +(defn setup-dom-events + [zoom disable-paste-ref in-viewport-ref workspace-read-only? drawing-tool drawing-path?] (let [on-key-down (actions/on-key-down) on-key-up (actions/on-key-up) on-mouse-wheel (actions/on-mouse-wheel zoom) - on-paste (actions/on-paste disable-paste in-viewport? workspace-read-only?) + on-paste (actions/on-paste disable-paste-ref in-viewport-ref workspace-read-only?) on-pointer-down (mf/use-fn (mf/deps drawing-tool drawing-path?) (fn [e] @@ -56,27 +57,27 @@ (st/emit! (dwe/clear-edition-mode)))))) on-blur (mf/use-fn #(st/emit! (mse/->BlurEvent)))] - (mf/use-effect - (mf/deps drawing-tool drawing-path?) - (fn [] - (let [keys [(events/listen js/window EventType.POINTERDOWN on-pointer-down)]] - (fn [] - (doseq [key keys] - (events/unlistenByKey key)))))) + (mf/with-effect [drawing-tool drawing-path?] + (let [key (events/listen js/window EventType.POINTERDOWN on-pointer-down)] - (mf/use-layout-effect - (mf/deps on-key-down on-key-up on-mouse-wheel on-paste workspace-read-only?) - (fn [] - (let [keys [(events/listen js/document EventType.KEYDOWN on-key-down) - (events/listen js/document EventType.KEYUP on-key-up) - ;; bind with passive=false to allow the event to be cancelled - ;; https://stackoverflow.com/a/57582286/3219895 - (events/listen js/window EventType.WHEEL on-mouse-wheel #js {:passive false}) - (events/listen js/window EventType.PASTE on-paste) - (events/listen js/window EventType.BLUR on-blur)]] - (fn [] - (doseq [key keys] - (events/unlistenByKey key)))))))) + ;; We need to disable workspace paste when we on comments + (if (= drawing-tool :comments) + (mf/set-ref-val! disable-paste-ref true) + (mf/set-ref-val! disable-paste-ref false)) + + #(events/unlistenByKey key))) + + (mf/with-layout-effect [on-key-down on-key-up on-mouse-wheel on-paste workspace-read-only?] + (let [keys [(events/listen js/document EventType.KEYDOWN on-key-down) + (events/listen js/document EventType.KEYUP on-key-up) + ;; bind with passive=false to allow the event to be cancelled + ;; https://stackoverflow.com/a/57582286/3219895 + (events/listen js/window EventType.WHEEL on-mouse-wheel #js {:passive false}) + (events/listen js/window EventType.PASTE on-paste) + (events/listen js/window EventType.BLUR on-blur)]] + (fn [] + (doseq [key keys] + (events/unlistenByKey key))))))) (defn setup-viewport-size [vport viewport-ref] (mf/with-effect [vport] diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index 54dde7688d..acb1f51de0 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -142,9 +142,9 @@ canvas-ref (mf/use-ref nil) text-editor-ref (mf/use-ref nil) - ;; VARS - disable-paste (mf/use-var false) - in-viewport? (mf/use-var false) + ;; STATE REFS + disable-paste-ref (mf/use-ref false) + in-viewport-ref (mf/use-ref false) ;; STREAMS move-stream (mf/use-memo #(rx/subject)) @@ -204,10 +204,10 @@ on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? path-editing? grid-editing? path-drawing? create-comment? space? panning z? read-only?) - on-pointer-up (actions/on-pointer-up disable-paste) + on-pointer-up (actions/on-pointer-up disable-paste-ref) - on-pointer-enter (actions/on-pointer-enter in-viewport?) - on-pointer-leave (actions/on-pointer-leave in-viewport?) + on-pointer-enter (actions/on-pointer-enter in-viewport-ref) + on-pointer-leave (actions/on-pointer-leave in-viewport-ref) on-pointer-move (actions/on-pointer-move move-stream) on-move-selected (actions/on-move-selected hover hover-ids selected space? z? read-only?) on-menu-selected (actions/on-menu-selected hover hover-ids selected read-only?) @@ -349,7 +349,7 @@ (wasm.api/show-grid @hover-top-frame-id) (wasm.api/clear-grid)))) - (hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool path-drawing?) + (hooks/setup-dom-events zoom disable-paste-ref in-viewport-ref read-only? drawing-tool path-drawing?) (hooks/setup-viewport-size vport viewport-ref) (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool path-drawing? path-editing? z? read-only?) (hooks/setup-keyboard alt? mod? space? z? shift?) diff --git a/frontend/src/app/util/clipboard.cljs b/frontend/src/app/util/clipboard.cljs index e70c567881..92729e5ec4 100644 --- a/frontend/src/app/util/clipboard.cljs +++ b/frontend/src/app/util/clipboard.cljs @@ -57,10 +57,11 @@ (= (dom/get-tag-name target) "INPUT")] ;; ignore when pasting into an editable control - (when-not (or content-editable? is-input?) + (if-not (or content-editable? is-input?) (-> event (dom/event->browser-event) - (from-clipboard-event options)))))) + (from-clipboard-event options)) + (rx/empty))))) (defn from-drop-event "Get clipboard stream from drop event" diff --git a/frontend/translations/ca.po b/frontend/translations/ca.po index a1b1add7bb..986f9364d5 100644 --- a/frontend/translations/ca.po +++ b/frontend/translations/ca.po @@ -392,7 +392,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"els fitxers amb biblioteques compartides s’inclouran a l’exportació, " +"Els fitxers amb biblioteques compartides s’inclouran a l’exportació, " "mantenint la vinculació." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/cs.po b/frontend/translations/cs.po index a6385aa048..7ba4527bd7 100644 --- a/frontend/translations/cs.po +++ b/frontend/translations/cs.po @@ -542,7 +542,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"soubory se sdílenými knihovnami budou zahrnuty do exportu, čímž se zachová " +"Soubory se sdílenými knihovnami budou zahrnuty do exportu, čímž se zachová " "jejich propojení." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 029bfd98c2..0a61de53b0 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -576,7 +576,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"files with shared libraries will be included in the export, maintaining " +"Files with shared libraries will be included in the export, maintaining " "their linkage." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 46106f4a89..6a7d06f23f 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -585,7 +585,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"ficheros con librerias compartidas se inclurán en el paquete de exportación " +"Ficheros con librerias compartidas se inclurán en el paquete de exportación " "y mantendrán los enlaces." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/eu.po b/frontend/translations/eu.po index fc8c7c1d7b..2287cf419d 100644 --- a/frontend/translations/eu.po +++ b/frontend/translations/eu.po @@ -370,7 +370,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"partekatutako liburutegiak dituzten fitxategiak esportazio paketean sartuko " +"Partekatutako liburutegiak dituzten fitxategiak esportazio paketean sartuko " "dira eta loturak mantenduko dituzte." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/gl.po b/frontend/translations/gl.po index c80223a5fa..6aa59619a0 100644 --- a/frontend/translations/gl.po +++ b/frontend/translations/gl.po @@ -368,7 +368,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"os ficheiros con bibliotecas compartidas incluiranse na exportación " +"Os ficheiros con bibliotecas compartidas incluiranse na exportación " "mantendo os vínculos." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/ha.po b/frontend/translations/ha.po index 32066e0f0d..64c8ff41d6 100644 --- a/frontend/translations/ha.po +++ b/frontend/translations/ha.po @@ -430,7 +430,7 @@ msgstr "za ka iya fitar da kundi daya ko fiye ta hanyar tura taska. \"me \"*?" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" -msgstr "manhajar tura kundi ta kunshi fitarwa, tattali mahaxarsu." +msgstr "Manhajar tura kundi ta kunshi fitarwa, tattali mahaxarsu." #: src/app/main/ui/exports/files.cljs:165 msgid "dashboard.export.options.all.title" diff --git a/frontend/translations/hr.po b/frontend/translations/hr.po index 9480cca8c3..7da4caaa2f 100644 --- a/frontend/translations/hr.po +++ b/frontend/translations/hr.po @@ -541,7 +541,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"datoteke sa zajedničkim bibliotekama bit će uključene u izvoz, održavajući " +"Datoteke sa zajedničkim bibliotekama bit će uključene u izvoz, održavajući " "njihovu poveznicu." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/id.po b/frontend/translations/id.po index 8a4035cae7..fd479185d1 100644 --- a/frontend/translations/id.po +++ b/frontend/translations/id.po @@ -573,7 +573,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" -msgstr "berkas dengan pustaka bersama akan dimasukkan dalam hasil ekspor." +msgstr "Berkas dengan pustaka bersama akan dimasukkan dalam hasil ekspor." #: src/app/main/ui/exports/files.cljs:165 msgid "dashboard.export.options.all.title" diff --git a/frontend/translations/lt.po b/frontend/translations/lt.po index e6aeaf46e6..133777fb19 100644 --- a/frontend/translations/lt.po +++ b/frontend/translations/lt.po @@ -346,7 +346,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"failai su bendromis bibliotekomis bus įtraukti į eksportą, išlaikant jų " +"Failai su bendromis bibliotekomis bus įtraukti į eksportą, išlaikant jų " "susiejimą." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/lv.po b/frontend/translations/lv.po index ebe6191634..8cb32beadc 100644 --- a/frontend/translations/lv.po +++ b/frontend/translations/lv.po @@ -584,7 +584,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"izguvē tiks iekļautas datnes ar koplietojamām bibliotēkām, saglabājot to " +"Izguvē tiks iekļautas datnes ar koplietojamām bibliotēkām, saglabājot to " "sasaisti." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/ms.po b/frontend/translations/ms.po index 1ffbaae2ae..6f4170622e 100644 --- a/frontend/translations/ms.po +++ b/frontend/translations/ms.po @@ -438,7 +438,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"fail dengan perpustakaan kongsi akan disertakan dalam eksport, mengekalkan " +"Fail dengan perpustakaan kongsi akan disertakan dalam eksport, mengekalkan " "hubungannya." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/pl.po b/frontend/translations/pl.po index ffb9ae9a3d..99f73dea19 100644 --- a/frontend/translations/pl.po +++ b/frontend/translations/pl.po @@ -372,7 +372,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"pliki z bibliotekami współdzielonymi zostaną uwzględnione w eksporcie, z " +"Pliki z bibliotekami współdzielonymi zostaną uwzględnione w eksporcie, z " "zachowaniem ich powiązania." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/pt_BR.po b/frontend/translations/pt_BR.po index 2e3fbe5e08..71ca2086c4 100644 --- a/frontend/translations/pt_BR.po +++ b/frontend/translations/pt_BR.po @@ -581,7 +581,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"arquivos com bibliotecas compartilhadas serão incluídos na exportação, " +"Arquivos com bibliotecas compartilhadas serão incluídos na exportação, " "mantendo seu vínculo." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/pt_PT.po b/frontend/translations/pt_PT.po index 29bd74b418..403f522460 100644 --- a/frontend/translations/pt_PT.po +++ b/frontend/translations/pt_PT.po @@ -555,7 +555,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"ficheiros com bibliotecas partilhadas serão incluídos na exportação, " +"Ficheiros com bibliotecas partilhadas serão incluídos na exportação, " "mantendo as ligações." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/ro.po b/frontend/translations/ro.po index b46d16e098..2f91d64376 100644 --- a/frontend/translations/ro.po +++ b/frontend/translations/ro.po @@ -590,7 +590,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"fișierele cu biblioteci partajate vor fi incluse în export, menținându-le " +"Fișierele cu biblioteci partajate vor fi incluse în export, menținându-le " "legătura." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/sr.po b/frontend/translations/sr.po index 816e57dcfe..7c306486c2 100644 --- a/frontend/translations/sr.po +++ b/frontend/translations/sr.po @@ -491,7 +491,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"датотеке са дељеним библиотекама ће бити укључене у извоз, одржавајући " +"Датотеке са дељеним библиотекама ће бити укључене у извоз, одржавајући " "њихову повезаност." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/sv.po b/frontend/translations/sv.po index e5a55008c1..1c5fb8ddef 100644 --- a/frontend/translations/sv.po +++ b/frontend/translations/sv.po @@ -582,7 +582,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"filer med delade bibliotek kommer att ingå i exporten, bibehåller deras " +"Filer med delade bibliotek kommer att ingå i exporten, bibehåller deras " "koppling." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/tr.po b/frontend/translations/tr.po index 9292c86732..3299351b93 100644 --- a/frontend/translations/tr.po +++ b/frontend/translations/tr.po @@ -583,7 +583,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"paylaşılan kütüphanelere sahip dosyalar, bağlantılarını koruyarak dışarı " +"Paylaşılan kütüphanelere sahip dosyalar, bağlantılarını koruyarak dışarı " "aktarmaya dahil edilecek." #: src/app/main/ui/exports/files.cljs:165 diff --git a/frontend/translations/ukr_UA.po b/frontend/translations/ukr_UA.po index 87e685a6d8..502f8f0b4b 100644 --- a/frontend/translations/ukr_UA.po +++ b/frontend/translations/ukr_UA.po @@ -577,7 +577,7 @@ msgstr "" #: src/app/main/ui/exports/files.cljs:164 msgid "dashboard.export.options.all.message" msgstr "" -"файли з спільними бібліотеками буде додано до експорту зі збереженням " +"Файли з спільними бібліотеками буде додано до експорту зі збереженням " "зв'язків між ними." #: src/app/main/ui/exports/files.cljs:165