mirror of
https://github.com/penpot/penpot.git
synced 2025-01-23 23:18:48 -05:00
Merge pull request #4928 from penpot/alotor-plugins-10
Alotor plugins 10
This commit is contained in:
commit
b122db447a
5 changed files with 359 additions and 263 deletions
File diff suppressed because it is too large
Load diff
|
@ -30,6 +30,7 @@
|
||||||
[app.plugins.file :as file]
|
[app.plugins.file :as file]
|
||||||
[app.plugins.fonts :as fonts]
|
[app.plugins.fonts :as fonts]
|
||||||
[app.plugins.format :as format]
|
[app.plugins.format :as format]
|
||||||
|
[app.plugins.history :as history]
|
||||||
[app.plugins.library :as library]
|
[app.plugins.library :as library]
|
||||||
[app.plugins.page :as page]
|
[app.plugins.page :as page]
|
||||||
[app.plugins.parser :as parser]
|
[app.plugins.parser :as parser]
|
||||||
|
@ -394,4 +395,5 @@
|
||||||
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
||||||
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
||||||
{:name "fonts" :get (fn [_] (fonts/fonts-subcontext plugin-id))}
|
{:name "fonts" :get (fn [_] (fonts/fonts-subcontext plugin-id))}
|
||||||
{:name "library" :get (fn [_] (library/library-subcontext plugin-id))}))
|
{:name "library" :get (fn [_] (library/library-subcontext plugin-id))}
|
||||||
|
{:name "history" :get (fn [_] (history/history-subcontext plugin-id))}))
|
||||||
|
|
|
@ -5,17 +5,23 @@
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.plugins.file
|
(ns app.plugins.file
|
||||||
"RPC for plugins runtime."
|
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.record :as crc]
|
[app.common.record :as crc]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
|
[app.main.features :as features]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
[app.main.ui.export :as mue]
|
||||||
|
[app.main.worker :as uw]
|
||||||
[app.plugins.page :as page]
|
[app.plugins.page :as page]
|
||||||
|
[app.plugins.parser :as parser]
|
||||||
[app.plugins.register :as r]
|
[app.plugins.register :as r]
|
||||||
[app.plugins.utils :as u]
|
[app.plugins.utils :as u]
|
||||||
[app.util.object :as obj]))
|
[app.util.http :as http]
|
||||||
|
[app.util.object :as obj]
|
||||||
|
[beicon.v2.core :as rx]
|
||||||
|
[promesa.core :as p]))
|
||||||
|
|
||||||
(deftype FileProxy [$plugin $id]
|
(deftype FileProxy [$plugin $id]
|
||||||
Object
|
Object
|
||||||
|
@ -105,7 +111,47 @@
|
||||||
:else
|
:else
|
||||||
(let [page-id (uuid/next)]
|
(let [page-id (uuid/next)]
|
||||||
(st/emit! (dw/create-page {:page-id page-id :file-id $id}))
|
(st/emit! (dw/create-page {:page-id page-id :file-id $id}))
|
||||||
(page/page-proxy $plugin $id page-id)))))
|
(page/page-proxy $plugin $id page-id))))
|
||||||
|
|
||||||
|
(export
|
||||||
|
[self type export-type]
|
||||||
|
(let [export-type (or (parser/parse-keyword export-type) :all)]
|
||||||
|
(cond
|
||||||
|
(not (contains? #{"penpot" "zip"} type))
|
||||||
|
(u/display-not-valid :export-type type)
|
||||||
|
|
||||||
|
(not (contains? (set mue/export-types) export-type))
|
||||||
|
(u/display-not-valid :export-exportType export-type)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [export-cmd (if (= type "penpot") :export-binary-file :export-standard-file)
|
||||||
|
file (u/proxy->file self)
|
||||||
|
features (features/get-team-enabled-features @st/state)
|
||||||
|
team-id (:current-team-id @st/state)]
|
||||||
|
(p/create
|
||||||
|
(fn [resolve reject]
|
||||||
|
(->> (uw/ask-many!
|
||||||
|
{:cmd export-cmd
|
||||||
|
:team-id team-id
|
||||||
|
:features features
|
||||||
|
:export-type export-type
|
||||||
|
:files [file]})
|
||||||
|
(rx/mapcat #(->> (rx/of %) (rx/delay 1000)))
|
||||||
|
(rx/mapcat
|
||||||
|
(fn [msg]
|
||||||
|
(case (:type msg)
|
||||||
|
:error
|
||||||
|
(rx/throw (ex-info "cannot export file" {:type :export-file}))
|
||||||
|
|
||||||
|
:progress
|
||||||
|
(rx/empty)
|
||||||
|
|
||||||
|
:finish
|
||||||
|
(http/send! {:method :get :uri (:uri msg) :mode :no-cors :response-type :blob}))))
|
||||||
|
(rx/first)
|
||||||
|
(rx/mapcat (fn [{:keys [body]}] (.arrayBuffer ^js body)))
|
||||||
|
(rx/map (fn [data] (js/Uint8Array. data)))
|
||||||
|
(rx/subs! resolve reject)))))))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
FileProxy
|
FileProxy
|
||||||
|
|
52
frontend/src/app/plugins/history.cljs
Normal file
52
frontend/src/app/plugins/history.cljs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
;; 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.history
|
||||||
|
(:require
|
||||||
|
[app.common.record :as crc]
|
||||||
|
[app.main.data.workspace.undo :as dwu]
|
||||||
|
[app.main.store :as st]
|
||||||
|
[app.plugins.register :as r]
|
||||||
|
[app.plugins.utils :as u]))
|
||||||
|
|
||||||
|
(deftype HistorySubcontext [$plugin]
|
||||||
|
Object
|
||||||
|
(undoBlockBegin
|
||||||
|
[_]
|
||||||
|
(cond
|
||||||
|
(not (r/check-permission $plugin "content:write"))
|
||||||
|
(u/display-not-valid :resize "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [id (js/Symbol)]
|
||||||
|
(st/emit! (dwu/start-undo-transaction id))
|
||||||
|
id)))
|
||||||
|
|
||||||
|
(undoBlockFinish
|
||||||
|
[_ block-id]
|
||||||
|
(cond
|
||||||
|
(not (r/check-permission $plugin "content:write"))
|
||||||
|
(u/display-not-valid :resize "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
(not block-id)
|
||||||
|
(u/display-not-valid :undoBlockFinish block-id)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dwu/commit-undo-transaction block-id)))))
|
||||||
|
|
||||||
|
(crc/define-properties!
|
||||||
|
HistorySubcontext
|
||||||
|
{:name js/Symbol.toStringTag
|
||||||
|
:get (fn [] (str "HistorySubcontext"))})
|
||||||
|
|
||||||
|
(defn history-subcontext? [p]
|
||||||
|
(instance? HistorySubcontext p))
|
||||||
|
|
||||||
|
(defn history-subcontext
|
||||||
|
[plugin-id]
|
||||||
|
(HistorySubcontext. plugin-id))
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]
|
||||||
|
[app.util.storage :refer [storage]]))
|
||||||
|
|
||||||
;; Stores the installed plugins information
|
;; Stores the installed plugins information
|
||||||
(defonce ^:private registry (atom {}))
|
(defonce ^:private registry (atom {}))
|
||||||
|
@ -57,32 +58,22 @@
|
||||||
:icon icon
|
:icon icon
|
||||||
:permissions (into #{} (map str) permissions)}))
|
:permissions (into #{} (map str) permissions)}))
|
||||||
|
|
||||||
(defn format-plugin-data
|
;; FIXME: LEGACY version of the load from store
|
||||||
"Format into a JS object the plugin data. This will be used to be stored in the local storage."
|
;; can be removed before deploying plugins to production
|
||||||
[{:keys [plugin-id name description host code icon permissions]}]
|
;; Needs to be preserved for the beta users
|
||||||
#js {:plugin-id plugin-id
|
(defn legacy-load-from-store
|
||||||
:name name
|
|
||||||
:description description
|
|
||||||
:host host
|
|
||||||
:code code
|
|
||||||
:icon icon
|
|
||||||
:permissions (apply array permissions)})
|
|
||||||
|
|
||||||
(defn parse-plugin-data
|
|
||||||
"Parsers the JS plugin data into a CLJS data structure. This will be used primarily when the local storage
|
|
||||||
data is retrieved"
|
|
||||||
[^js data]
|
|
||||||
{:plugin-id (obj/get data "plugin-id")
|
|
||||||
:name (obj/get data "name")
|
|
||||||
:description (obj/get data "description")
|
|
||||||
:host (obj/get data "host")
|
|
||||||
:code (obj/get data "code")
|
|
||||||
:icon (obj/get data "icon")
|
|
||||||
:permissions (into #{} (obj/get data "permissions"))})
|
|
||||||
|
|
||||||
(defn load-from-store
|
|
||||||
[]
|
[]
|
||||||
(let [ls (.-localStorage js/window)
|
(let [parse-plugin-data
|
||||||
|
(fn [^js data]
|
||||||
|
{:plugin-id (obj/get data "plugin-id")
|
||||||
|
:name (obj/get data "name")
|
||||||
|
:description (obj/get data "description")
|
||||||
|
:host (obj/get data "host")
|
||||||
|
:code (obj/get data "code")
|
||||||
|
:icon (obj/get data "icon")
|
||||||
|
:permissions (into #{} (obj/get data "permissions"))})
|
||||||
|
|
||||||
|
ls (.-localStorage js/window)
|
||||||
plugins-val (.getItem ls "plugins")]
|
plugins-val (.getItem ls "plugins")]
|
||||||
(when plugins-val
|
(when plugins-val
|
||||||
(let [stored (->> (.parse js/JSON plugins-val)
|
(let [stored (->> (.parse js/JSON plugins-val)
|
||||||
|
@ -93,12 +84,14 @@
|
||||||
|
|
||||||
(defn save-to-store
|
(defn save-to-store
|
||||||
[]
|
[]
|
||||||
(->> (:ids @registry)
|
(swap! storage assoc :plugins @registry))
|
||||||
(map #(dm/get-in @registry [:data %]))
|
|
||||||
(map format-plugin-data)
|
(defn load-from-store
|
||||||
(apply array)
|
[]
|
||||||
(.stringify js/JSON)
|
(if (:plugins @storage)
|
||||||
(.setItem (.-localStorage js/window) "plugins")))
|
(reset! registry (:plugins @storage))
|
||||||
|
(do (legacy-load-from-store)
|
||||||
|
(save-to-store))))
|
||||||
|
|
||||||
(defn init
|
(defn init
|
||||||
[]
|
[]
|
||||||
|
|
Loading…
Add table
Reference in a new issue