From b97dc09e26cd4287f4439bb691f6b409802cad71 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 30 Jun 2020 15:37:02 +0200 Subject: [PATCH] :tada: Add export button to right sidebar (frontend). --- frontend/resources/locales.json | 90 ++++++----- frontend/src/uxbox/main/ui/workspace.cljs | 4 +- .../src/uxbox/main/ui/workspace/sidebar.cljs | 5 +- .../main/ui/workspace/sidebar/options.cljs | 151 ++++++++++++------ frontend/src/uxbox/util/dom.cljs | 21 +++ 5 files changed, 179 insertions(+), 92 deletions(-) diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json index 3f979a5c0..5972e3959 100644 --- a/frontend/resources/locales.json +++ b/frontend/resources/locales.json @@ -16,7 +16,7 @@ } }, "auth.create-demo-profile" : { - "used-in" : [ "src/uxbox/main/ui/auth/register.cljs:116", "src/uxbox/main/ui/auth/login.cljs:115" ], + "used-in" : [ "src/uxbox/main/ui/auth/login.cljs:115", "src/uxbox/main/ui/auth/register.cljs:116" ], "translations" : { "en" : "Create demo account", "fr" : "Créer un compte de démonstration", @@ -24,7 +24,7 @@ } }, "auth.create-demo-profile-label" : { - "used-in" : [ "src/uxbox/main/ui/auth/register.cljs:113", "src/uxbox/main/ui/auth/login.cljs:112" ], + "used-in" : [ "src/uxbox/main/ui/auth/login.cljs:112", "src/uxbox/main/ui/auth/register.cljs:113" ], "translations" : { "en" : "Just wanna try it?", "fr" : "Vous voulez juste essayer?", @@ -40,7 +40,7 @@ } }, "auth.email-label" : { - "used-in" : [ "src/uxbox/main/ui/auth/register.cljs:82", "src/uxbox/main/ui/auth/recovery_request.cljs:46", "src/uxbox/main/ui/auth/login.cljs:73" ], + "used-in" : [ "src/uxbox/main/ui/auth/login.cljs:73", "src/uxbox/main/ui/auth/recovery_request.cljs:46", "src/uxbox/main/ui/auth/register.cljs:82" ], "translations" : { "en" : "Email", "fr" : "Adresse email", @@ -144,7 +144,7 @@ } }, "auth.password-label" : { - "used-in" : [ "src/uxbox/main/ui/auth/register.cljs:86", "src/uxbox/main/ui/auth/login.cljs:79" ], + "used-in" : [ "src/uxbox/main/ui/auth/login.cljs:79", "src/uxbox/main/ui/auth/register.cljs:86" ], "translations" : { "en" : "Password", "fr" : "Mot de passe", @@ -240,7 +240,7 @@ } }, "dashboard.grid.delete" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:62", "src/uxbox/main/ui/dashboard/grid.cljs:103" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:103", "src/uxbox/main/ui/dashboard/project.cljs:62" ], "translations" : { "en" : "Delete", "fr" : "Supprimer", @@ -256,7 +256,7 @@ } }, "dashboard.grid.rename" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:61", "src/uxbox/main/ui/dashboard/grid.cljs:102" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:102", "src/uxbox/main/ui/dashboard/project.cljs:61" ], "translations" : { "en" : "Rename", "fr" : "Renommer", @@ -280,7 +280,7 @@ } }, "dashboard.header.new-project" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/recent_files.cljs:50" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/recent_files.cljs:48" ], "translations" : { "en" : "+ New project", "fr" : "+ Nouveau projet", @@ -416,7 +416,7 @@ } }, "dashboard.sidebar.drafts" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:112" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:128" ], "translations" : { "en" : "Drafts", "fr" : "Brouillons", @@ -424,7 +424,7 @@ } }, "dashboard.sidebar.libraries" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:118" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:134" ], "translations" : { "en" : "Libraries", "fr" : "Librairies", @@ -432,7 +432,7 @@ } }, "dashboard.sidebar.recent" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:105" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:121" ], "translations" : { "en" : "Recent", "fr" : "Récent", @@ -528,7 +528,7 @@ } }, "ds.search.placeholder" : { - "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:171" ], + "used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:187" ], "translations" : { "en" : "Search...", "fr" : "Rechercher...", @@ -560,7 +560,7 @@ } }, "errors.email-already-exists" : { - "used-in" : [ "src/uxbox/main/ui/auth.cljs:87", "src/uxbox/main/ui/settings/change_email.cljs:47" ], + "used-in" : [ "src/uxbox/main/ui/settings/change_email.cljs:47", "src/uxbox/main/ui/auth.cljs:87" ], "translations" : { "en" : "Email already used", "fr" : "Adresse e-mail déjà utilisée", @@ -576,7 +576,7 @@ } }, "errors.generic" : { - "used-in" : [ "src/uxbox/main/ui.cljs:190", "src/uxbox/main/ui/auth.cljs:91", "src/uxbox/main/ui/settings/profile.cljs:38" ], + "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:38", "src/uxbox/main/ui/auth.cljs:91", "src/uxbox/main/ui.cljs:202" ], "translations" : { "en" : "Something wrong has happened.", "fr" : "Quelque chose c'est mal passé.", @@ -584,7 +584,7 @@ } }, "errors.image-format-unsupported" : { - "used-in" : [ "src/uxbox/main/data/images.cljs:376", "src/uxbox/main/data/workspace/persistence.cljs:318", "src/uxbox/main/data/users.cljs:177" ], + "used-in" : [ "src/uxbox/main/data/users.cljs:177", "src/uxbox/main/data/workspace/persistence.cljs:365", "src/uxbox/main/data/images.cljs:376" ], "translations" : { "en" : "The image format is not supported (must be svg, jpg or png).", "fr" : "Le format d'image n'est pas supporté (doit être svg, jpg ou png).", @@ -592,7 +592,7 @@ } }, "errors.image-too-large" : { - "used-in" : [ "src/uxbox/main/data/images.cljs:374", "src/uxbox/main/data/workspace/persistence.cljs:316", "src/uxbox/main/data/users.cljs:175" ], + "used-in" : [ "src/uxbox/main/data/users.cljs:175", "src/uxbox/main/data/workspace/persistence.cljs:363", "src/uxbox/main/data/images.cljs:374" ], "translations" : { "en" : "The image is too large to be inserted (must be under 5mb).", "fr" : "L'image est trop grande (doit être inférieure à 5 Mo).", @@ -600,7 +600,7 @@ } }, "errors.network" : { - "used-in" : [ "src/uxbox/main/ui.cljs:184" ], + "used-in" : [ "src/uxbox/main/ui.cljs:196" ], "translations" : { "en" : "Unable to connect to backend server.", "fr" : "Impossible de se connecter au serveur principal.", @@ -632,7 +632,7 @@ } }, "errors.unexpected-error" : { - "used-in" : [ "src/uxbox/main/data/images.cljs:385", "src/uxbox/main/data/workspace/persistence.cljs:327", "src/uxbox/main/data/users.cljs:185", "src/uxbox/main/ui/auth/register.cljs:54", "src/uxbox/main/ui/settings/change_email.cljs:51" ], + "used-in" : [ "src/uxbox/main/data/users.cljs:185", "src/uxbox/main/data/workspace/persistence.cljs:334", "src/uxbox/main/data/workspace/persistence.cljs:374", "src/uxbox/main/data/images.cljs:385", "src/uxbox/main/ui/settings/change_email.cljs:51", "src/uxbox/main/ui/auth/register.cljs:54" ], "translations" : { "en" : "An unexpected error occurred.", "fr" : "Une erreur inattendue c'est produite", @@ -672,7 +672,7 @@ } }, "image.loading" : { - "used-in" : [ "src/uxbox/main/data/images.cljs:393", "src/uxbox/main/data/workspace/persistence.cljs:335", "src/uxbox/main/data/users.cljs:191" ], + "used-in" : [ "src/uxbox/main/data/users.cljs:191", "src/uxbox/main/data/workspace/persistence.cljs:341", "src/uxbox/main/data/workspace/persistence.cljs:382", "src/uxbox/main/data/images.cljs:393" ], "translations" : { "en" : "Loading image...", "fr" : "Chargement de l'image...", @@ -864,7 +864,7 @@ } }, "settings.notifications.email-not-verified" : { - "used-in" : [ "src/uxbox/main/ui/dashboard.cljs:109" ], + "used-in" : [ "src/uxbox/main/ui/dashboard.cljs:113" ], "translations" : { "en" : "Your email address has not been verified yet. Please check your inbox at “%s” for a confirmation email.", "fr" : "Votre adresse e-mail n'a pas encore été vérifiée. Veuillez vérifier votre boîte de réception à “%s” pour un e-mail de confirmation.", @@ -896,7 +896,7 @@ } }, "settings.notifications.profile-saved" : { - "used-in" : [ "src/uxbox/main/ui/settings/options.cljs:37", "src/uxbox/main/ui/settings/profile.cljs:43" ], + "used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:43", "src/uxbox/main/ui/settings/options.cljs:37" ], "translations" : { "en" : "Profile saved successfully!", "fr" : "Profil enregistré avec succès!", @@ -944,7 +944,7 @@ } }, "settings.profile-submit-label" : { - "used-in" : [ "src/uxbox/main/ui/settings/password.cljs:93", "src/uxbox/main/ui/settings/options.cljs:66", "src/uxbox/main/ui/settings/profile.cljs:90" ], + "used-in" : [ "src/uxbox/main/ui/settings/password.cljs:93", "src/uxbox/main/ui/settings/profile.cljs:90", "src/uxbox/main/ui/settings/options.cljs:66" ], "translations" : { "en" : "Update settings", "fr" : "Mettre à jour les paramètres", @@ -1304,7 +1304,7 @@ } }, "workspace.library.all" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:123" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:128" ], "translations" : { "en" : "All libraries", "fr" : "Toutes les librairies", @@ -1312,7 +1312,7 @@ } }, "workspace.library.icons" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:173" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:178" ], "translations" : { "en" : "Icons", "fr" : "Icônes", @@ -1320,7 +1320,7 @@ } }, "workspace.library.images" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:178" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:183" ], "translations" : { "en" : "Images", "fr" : "Images", @@ -1328,7 +1328,7 @@ } }, "workspace.library.libraries" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:155" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:160" ], "translations" : { "en" : "Libraries", "fr" : "Librairies", @@ -1336,7 +1336,7 @@ } }, "workspace.library.own" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:124" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:129" ], "translations" : { "en" : "My libraries", "fr" : "Mes librairies", @@ -1344,7 +1344,7 @@ } }, "workspace.library.store" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:125" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:130" ], "translations" : { "en" : "Store libraries", "fr" : "Prédéfinies", @@ -1360,15 +1360,27 @@ } }, "workspace.options.design" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:76" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:107" ], "translations" : { "en" : "Design", "fr" : "Conception", "es" : "Diseño" } }, + "workspace.options.export-object" : { + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:78" ], + "translations" : { + "en" : "Export" + } + }, + "workspace.options.exporting-object" : { + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:77" ], + "translations" : { + "en" : "Exporting..." + } + }, "workspace.options.fill" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:41", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:383" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:383", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:41" ], "translations" : { "en" : "Fill", "fr" : "Remplissage", @@ -1696,7 +1708,7 @@ } }, "workspace.options.navigate-to" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:58" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:59" ], "translations" : { "en" : "Navigate to", "fr" : "Naviguer vers", @@ -1704,7 +1716,7 @@ } }, "workspace.options.none" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:71" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:72" ], "translations" : { "en" : "None", "fr" : "Aucun", @@ -1712,7 +1724,7 @@ } }, "workspace.options.position" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:113", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:125" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:125", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:112" ], "translations" : { "en" : "Position", "fr" : "Position", @@ -1720,7 +1732,7 @@ } }, "workspace.options.prototype" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:85" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:115" ], "translations" : { "en" : "Prototype", "fr" : "Prototype", @@ -1728,7 +1740,7 @@ } }, "workspace.options.radius" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:157" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:158" ], "translations" : { "en" : "Radius", "fr" : "Rayon", @@ -1744,7 +1756,7 @@ } }, "workspace.options.select-a-shape" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:52" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:53" ], "translations" : { "en" : "Select a shape, artboard or group to drag a connection to other artboard.", "fr" : "Sélectionnez une forme, un plan de travail ou un groupe pour faire glisser une connexion vers un autre plan de travail.", @@ -1752,7 +1764,7 @@ } }, "workspace.options.select-artboard" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:64" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:65" ], "translations" : { "en" : "Select artboard", "fr" : "Sélectionner un plan de travail", @@ -1760,7 +1772,7 @@ } }, "workspace.options.size" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:83", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:98" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:98", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:82" ], "translations" : { "en" : "Size", "fr" : "Taille", @@ -1840,7 +1852,7 @@ } }, "workspace.options.use-play-button" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:54" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:55" ], "translations" : { "en" : "Use the play button at the header to run the prototype view.", "fr" : "Utilisez le bouton de lecture dans l'en-tête pour exécuter la vue du prototype.", @@ -1856,7 +1868,7 @@ } }, "workspace.sidebar.sitemap" : { - "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:140" ], + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:150" ], "translations" : { "en" : "Pages", "fr" : "Pages", diff --git a/frontend/src/uxbox/main/ui/workspace.cljs b/frontend/src/uxbox/main/ui/workspace.cljs index 3c5cfd545..a3bf31006 100644 --- a/frontend/src/uxbox/main/ui/workspace.cljs +++ b/frontend/src/uxbox/main/ui/workspace.cljs @@ -77,7 +77,9 @@ (when left-sidebar? [:& left-sidebar {:file file :page page :layout layout}]) (when right-sidebar? - [:& right-sidebar {:page page :layout layout}])])) + [:& right-sidebar {:page page + :local local + :layout layout}])])) (mf/defc workspace-page [{:keys [project file layout page-id] :as props}] diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar.cljs index cfeef1275..f78465bea 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar.cljs @@ -39,8 +39,9 @@ ;; --- Right Sidebar (Component) (mf/defc right-sidebar - [{:keys [layout page] :as props}] + [{:keys [layout page local] :as props}] [:aside#settings-bar.settings-bar [:div.settings-bar-inside (when (contains? layout :element-options) - [:& options-toolbox {:page page}])]]) + [:& options-toolbox {:page page + :local local}])]]) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs index 809007cf4..afd564787 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs @@ -9,32 +9,84 @@ (ns uxbox.main.ui.workspace.sidebar.options (:require - [okulary.core :as l] + [beicon.core :as rx] + [cljs.spec.alpha :as s] + [cuerdas.core :as str] [rumext.alpha :as mf] - [uxbox.main.ui.icons :as i] + [uxbox.common.spec :as us] [uxbox.main.data.workspace :as udw] - [uxbox.main.store :as st] [uxbox.main.refs :as refs] + [uxbox.main.store :as st] + [uxbox.main.ui.components.tab-container :refer [tab-container tab-element]] + [uxbox.main.ui.icons :as i] [uxbox.main.ui.workspace.sidebar.align :refer [align-options]] + [uxbox.main.ui.workspace.sidebar.options.circle :as circle] [uxbox.main.ui.workspace.sidebar.options.frame :as frame] [uxbox.main.ui.workspace.sidebar.options.group :as group] - [uxbox.main.ui.workspace.sidebar.options.rect :as rect] [uxbox.main.ui.workspace.sidebar.options.icon :as icon] - [uxbox.main.ui.workspace.sidebar.options.circle :as circle] - [uxbox.main.ui.workspace.sidebar.options.path :as path] [uxbox.main.ui.workspace.sidebar.options.image :as image] - [uxbox.main.ui.workspace.sidebar.options.text :as text] - [uxbox.main.ui.workspace.sidebar.options.page :as page] [uxbox.main.ui.workspace.sidebar.options.interactions :refer [interactions-menu]] - [uxbox.main.ui.components.tab-container :refer [tab-container tab-element]] - [uxbox.util.i18n :refer [tr]])) + [uxbox.main.ui.workspace.sidebar.options.page :as page] + [uxbox.main.ui.workspace.sidebar.options.path :as path] + [uxbox.main.ui.workspace.sidebar.options.rect :as rect] + [uxbox.main.ui.workspace.sidebar.options.text :as text] + [uxbox.util.dom :as dom] + [uxbox.util.http :as http] + [uxbox.util.i18n :as i18n :refer [tr t]] + [uxbox.util.object :as obj])) ;; --- Options +(defn- request-screenshot + [page-id shape-id] + (http/send! {:method :get + :uri "/export/bitmap" + :query {:page-id page-id + :object-id shape-id}} + {:credentials? true + :response-type :blob})) + +(defn- trigger-download + [name blob] + (let [link (dom/create-element "a") + uri (dom/create-uri blob)] + (obj/set! link "href" uri) + (obj/set! link "download" (str/slug name)) + (obj/set! (.-style ^js link) "display" "none") + (.appendChild (.-body ^js js/document) link) + (.click link) + (.remove link))) + +(mf/defc shape-export + {::mf/wrap [mf/memo]} + [{:keys [shape page] :as props}] + (let [loading? (mf/use-state false) + locale (mf/deref i18n/locale) + on-click (fn [event] + (dom/prevent-default event) + (swap! loading? not) + (->> (request-screenshot (:id page) (:id shape)) + (rx/subs + (fn [{:keys [status body]}] + (trigger-download (:name shape) body)) + (constantly nil) + (fn [] + (swap! loading? not)))))] + + [:div.element-set + [:div.btn-large.btn-icon-dark + {:on-click (when-not @loading? on-click) + :class (dom/classnames + :btn-disabled @loading?) + :disabled @loading?} + (if @loading? + (t locale "workspace.options.exporting-object") + (t locale "workspace.options.export-object"))]])) + (mf/defc shape-options {::mf/wrap [#(mf/throttle % 60)]} - [{:keys [shape] :as props}] - [:div + [{:keys [shape page] :as props}] + [:* (case (:type shape) :frame [:& frame/options {:shape shape}] :group [:& group/options {:shape shape}] @@ -45,45 +97,44 @@ :path [:& path/options {:shape shape}] :curve [:& path/options {:shape shape}] :image [:& image/options {:shape shape}] - nil)]) + nil) + [:& shape-export {:shape shape :page page}]]) + + +(mf/defc options-content + {::mf/wrap [mf/memo]} + [{:keys [section selected shape page] :as props}] + (let [locale (mf/deref i18n/locale)] + [:div.tool-window + [:div.tool-window-content + [:& tab-container {:on-change-tab #(st/emit! (udw/set-options-mode %)) + :selected section} + [:& tab-element {:id :design + :title (t locale "workspace.options.design")} + [:div.element-options + [:& align-options] + (if (= (count selected) 1) + [:& shape-options {:shape shape :page page}] + [:& page/options {:page page}])]] + + [:& tab-element {:id :prototype + :title (t locale "workspace.options.prototype")} + [:div.element-options + [:& interactions-menu {:shape shape}]]]]]])) + (mf/defc options-toolbox - {:wrap [mf/memo]} - [{:keys [page selected] :as props}] - (let [close #(st/emit! (udw/toggle-layout-flags :element-options)) - on-change-tab #(st/emit! (udw/set-options-mode %)) - - options-mode (mf/deref refs/options-mode) - - selected (mf/deref refs/selected-shapes) - shape-id (first selected) - page-id (:id page) + {::mf/wrap [mf/memo]} + [{:keys [page local] :as props}] + (let [selected (:selected local) + section (:options-mode local) + shape-id (first selected) + page-id (:id page) shape-iref (-> (mf/deps shape-id page-id) - (mf/use-memo - #(-> (l/in [:objects shape-id]) - (l/derived refs/workspace-data)))) - shape (mf/deref shape-iref)] - - [:div.tool-window - ;; [:div.tool-window-bar - ;; [:div.tool-window-icon i/options] - ;; [:span (tr "ds.settings.element-options")] - ;; [:div.tool-window-close {:on-click close} i/close]] - [:div.tool-window-content - [:& tab-container {:on-change-tab on-change-tab :selected options-mode} - - [:& tab-element - {:id :design :title (tr "workspace.options.design")} - [:div.element-options - [:& align-options] - [:div - (if (= (count selected) 1) - [:& shape-options {:shape shape}] - [:& page/options {:page page}])]]] - - [:& tab-element - {:id :prototype :title (tr "workspace.options.prototype")} - [:div.element-options - [:& interactions-menu {:shape shape}]]]] - ]])) + (mf/use-memo #(refs/object-by-id shape-id))) + shape (mf/deref shape-iref)] + [:& options-content {:selected selected + :shape shape + :page page + :section section}])) diff --git a/frontend/src/uxbox/util/dom.cljs b/frontend/src/uxbox/util/dom.cljs index a5d9947ca..151e2351c 100644 --- a/frontend/src/uxbox/util/dom.cljs +++ b/frontend/src/uxbox/util/dom.cljs @@ -169,3 +169,24 @@ (defn fullscreen? [] (boolean (.-fullscreenElement js/document))) + +(defn ^boolean blob? + [v] + (instance? js/Blob v)) + +(defn create-blob + "Create a blob from content." + ([content] + (create-blob content "application/octet-stream")) + ([content mimetype] + (js/Blob. #js [content] #js {:type mimetype}))) + +(defn revoke-uri + [url] + (js/URL.revokeObjectURL url)) + +(defn create-uri + "Create a url from blob." + [b] + {:pre [(blob? b)]} + (js/URL.createObjectURL b))