diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index a3b181a28a..c3d0990d6e 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -654,6 +654,59 @@ (ptk/data-event :layout/update {:ids selected-ids}) (dwu/commit-undo-transaction undo-id)))))) +(defn set-shape-index + [file-id page-id id new-index] + (ptk/reify ::set-shape-index + ptk/WatchEvent + (watch [it state _] + (let [file-id (or file-id (:current-file-id state)) + page-id (or page-id (:current-page-id state)) + + objects (dsh/lookup-page-objects state file-id page-id) + + undo-id (js/Symbol) + + shape (get objects id) + parent (get objects (:parent-id shape)) + + current-index (d/index-of (:shapes parent) id) + + new-index + (if (> new-index current-index) + (inc new-index) + new-index) + + changes + (-> (pcb/empty-changes it page-id) + (pcb/with-objects objects) + (pcb/change-parent (:id parent) [shape] new-index))] + + (rx/of (dwu/start-undo-transaction undo-id) + (dch/commit-changes changes) + (ptk/data-event :layout/update {:ids [id]}) + (dwu/commit-undo-transaction undo-id)))))) + +(defn reorder-children + [file-id page-id parent-id children] + + (ptk/reify ::reorder-children + ptk/WatchEvent + (watch [it state _] + (let [file-id (or file-id (:current-file-id state)) + page-id (or page-id (:current-page-id state)) + objects (dsh/lookup-page-objects state file-id page-id) + undo-id (js/Symbol) + + changes + (-> (pcb/empty-changes it page-id) + (pcb/with-objects objects) + (pcb/reorder-children parent-id children))] + + (rx/of (dwu/start-undo-transaction undo-id) + (dch/commit-changes changes) + (ptk/data-event :layout/update {:ids [parent-id]}) + (dwu/commit-undo-transaction undo-id)))))) + ;; --- Change Shape Order (D&D Ordering) (defn relocate-selected-shapes diff --git a/frontend/src/app/plugins/format.cljs b/frontend/src/app/plugins/format.cljs index 0ea3832406..2b892a65e1 100644 --- a/frontend/src/app/plugins/format.cljs +++ b/frontend/src/app/plugins/format.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.plugins.image-data :refer [create-image-data]] [app.util.object :as obj])) (def shape-proxy nil) @@ -106,15 +107,9 @@ ;; keepAspectRatio?: boolean; ;; }; (defn format-image - [{:keys [name width height mtype id keep-aspect-ratio] :as image}] + [image] (when (some? image) - (obj/without-empty - #js {:name name - :width width - :height height - :mtype mtype - :id (format-id id) - :keepAspectRatio keep-aspect-ratio}))) + (create-image-data image))) ;; export interface Color { ;; id?: string; diff --git a/frontend/src/app/plugins/image_data.cljs b/frontend/src/app/plugins/image_data.cljs new file mode 100644 index 0000000000..f3bfb84080 --- /dev/null +++ b/frontend/src/app/plugins/image_data.cljs @@ -0,0 +1,37 @@ +;; 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.plugins.image-data + (:require + [app.common.data.macros :as dm] + [app.config :as cf] + [app.util.http :as http] + [app.util.object :as obj] + [beicon.v2.core :as rx])) + +(defn create-image-data + [{:keys [name width height mtype id keep-aspect-ratio] :as entry}] + (obj/reify {:name "ImageData"} + :name {:get (constantly name)} + :width {:get (constantly width)} + :height {:get (constantly height)} + :mtype {:get (constantly mtype)} + :id {:get #(when id (dm/str id))} + :keepAspectRatio {:get (constantly keep-aspect-ratio)} + + :data + (fn [] + (let [url (cf/resolve-file-media entry)] + (js/Promise. + (fn [resolve reject] + (->> (http/send! + {:method :get + :uri url + :response-type :blob}) + (rx/map :body) + (rx/mapcat #(.arrayBuffer %)) + (rx/map #(js/Uint8Array. %)) + (rx/subs! resolve reject)))))))) diff --git a/frontend/src/app/plugins/shape.cljs b/frontend/src/app/plugins/shape.cljs index 6224920783..6c3e60a32d 100644 --- a/frontend/src/app/plugins/shape.cljs +++ b/frontend/src/app/plugins/shape.cljs @@ -531,6 +531,19 @@ (let [parent-id (:parent-id shape)] (shape-proxy plugin-id (obj/get self "$file") (obj/get self "$page") parent-id)))))} + :parentIndex + {:this true + :get + (fn [self] + (let [shape (u/proxy->shape self)] + (if (cfh/root? shape) + 0 + (let [file-id (obj/get self "$file") + page-id (obj/get self "$page") + parent (u/locate-shape file-id page-id (:parent-id shape)) + index (d/index-of (:shapes parent) id)] + index))))} + :parentX {:this true :get (fn [self] @@ -1061,6 +1074,35 @@ (let [typography (u/proxy->library-typography typography)] (st/emit! (dwt/apply-typography #{id} typography file-id)))))) + ;; Change index method + :setParentIndex + (fn [index] + (cond + (not (us/safe-int? index)) + (u/display-not-valid :setParentIndex index) + + (not (r/check-permission plugin-id "content:write")) + (u/display-not-valid :setParentIndex "Plugin doesn't have 'content:write' permission") + + :else + (st/emit! (dw/set-shape-index file-id page-id id index)))) + + :bringForward + (fn [] + (st/emit! (dw/vertical-order-selected :up))) + + :sendBackward + (fn [] + (st/emit! (dw/vertical-order-selected :down))) + + :bringToFront + (fn [] + (st/emit! (dw/vertical-order-selected :top))) + + :sendToBack + (fn [] + (st/emit! (dw/vertical-order-selected :bottom))) + ;; COMPONENTS :isComponentInstance (fn [] @@ -1294,9 +1336,34 @@ (cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data)) (crc/add-properties! - {:name "children" + {:this true + :name "children" :enumerable false - :get #(.getChildren ^js %)})) + :get + (fn [^js self] + (.getChildren self)) + + :set + (fn [^js self children] + (cond + (not (r/check-permission plugin-id "content:write")) + (u/display-not-valid :children "Plugin doesn't have 'content:write' permission") + + (not (every? shape-proxy? children)) + (u/display-not-valid :children "Every children needs to be shape proxies") + + :else + (let [shape (u/proxy->shape self) + file-id (obj/get self "$file") + page-id (obj/get self "$page") + ids (->> children (map #(obj/get % "$id")))] + + (cond + (not= (set ids) (set (:shapes shape))) + (u/display-not-valid :children "Not all children are present in the input") + + :else + (st/emit! (dw/reorder-children file-id page-id (:id shape) ids))))))})) (cond-> (cfh/frame-shape? data) (-> (crc/add-properties!