diff --git a/CHANGES.md b/CHANGES.md index 2c2c7675a9..42896bf5c9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,29 +24,31 @@ - The plugin list in the navigation menu lacks scrolling, some plugins are not visible when a large number are installed [Taiga #9360](https://tree.taiga.io/project/penpot/us/9360) - Fix hidden toolbar click event still available [Taiga #10437](https://tree.taiga.io/project/penpot/us/10437) -## 2.5.3 -### :rocket: Epics and highlights - -### :boom: Breaking changes & Deprecations - -### :heart: Community contributions (Thank you!) +## 2.5.4 (Unreleased) ### :sparkles: New features +- Add support for WEBP format on shape export [Github #6053](https://github.com/penpot/penpot/pull/6053) and [Github #6074](https://github.com/penpot/penpot/pull/6074) + +### :bug: Bugs fixed + +- Fix feature loading on workspace when opening a file in a background + tab [Taiga #10377](https://tree.taiga.io/project/penpot/issue/10377) +- Fix minor inconsistencies on RPC `get-file-libraries` and `get-file` + methods (add missing team-id prop) + + +## 2.5.3 + ### :bug: Bugs fixed - Component sync issues with multiple tabs [Taiga #10471](https://tree.taiga.io/project/penpot/issue/10471) ## 2.5.2 -### :rocket: Epics and highlights - -### :boom: Breaking changes & Deprecations - -### :heart: Community contributions (Thank you!) - ### :sparkles: New features + - When the workspace is empty, set default the board creation tool [Taiga #9425](https://tree.taiga.io/project/penpot/us/9425) ### :bug: Bugs fixed @@ -58,22 +60,12 @@ ## 2.5.1 -### :rocket: Epics and highlights - -### :boom: Breaking changes & Deprecations - -### :heart: Community contributions (Thank you!) - ### :sparkles: New features - Improve Nginx entryponit to get the resolvers dinamically by default -### :bug: Bugs fixed - ## 2.5.0 -### :rocket: Epics and highlights - ### :boom: Breaking changes & Deprecations Although this is not a breaking change, we believe it’s important to highlight it in this @@ -102,9 +94,6 @@ If you have a big database and many cores available, you can reduce the time of all files by increasing paralelizacion changing the `max-jobs` value from 1 to N (where N is a number of cores) - -### :heart: Community contributions (Thank you!) - ### :sparkles: New features - [GRADIENTS] New gradients UI with multi-stop support. [Taiga #3418](https://tree.taiga.io/project/penpot/epic/3418) diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index 1c4b27c649..f409b0bc74 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -323,6 +323,7 @@ file (-> (get-file cfg id :project-id project-id) (assoc :permissions perms) + (assoc :team-id (:id team)) (check-version!))] (-> (cfeat/get-team-enabled-features cf/flags team) @@ -613,6 +614,7 @@ SELECT l.id, l.features, l.project_id, + p.team_id, l.created_at, l.modified_at, l.deleted_at, @@ -622,6 +624,7 @@ l.synced_at, l.is_shared FROM libs AS l + INNER JOIN project AS p ON (p.id = l.project_id) WHERE l.deleted_at IS NULL OR l.deleted_at > now();") (defn get-file-libraries diff --git a/common/src/app/common/types/shape/export.cljc b/common/src/app/common/types/shape/export.cljc index bd2bee0a51..feb7f8dec6 100644 --- a/common/src/app/common/types/shape/export.cljc +++ b/common/src/app/common/types/shape/export.cljc @@ -8,7 +8,7 @@ (:require [app.common.schema :as sm])) -(def types #{:png :jpeg :svg :pdf}) +(def types #{:png :jpeg :webp :svg :pdf}) (def schema:export [:map {:title "ShapeExport"} diff --git a/docs/user-guide/exporting/index.njk b/docs/user-guide/exporting/index.njk index 63f9d9fb24..d685a66834 100644 --- a/docs/user-guide/exporting/index.njk +++ b/docs/user-guide/exporting/index.njk @@ -27,7 +27,7 @@ title: 07· Exporting objects

Exporting multiple elements

diff --git a/exporter/src/app/renderer.cljs b/exporter/src/app/renderer.cljs index b4abaca4bc..4a7cf8af73 100644 --- a/exporter/src/app/renderer.cljs +++ b/exporter/src/app/renderer.cljs @@ -15,7 +15,7 @@ (s/def ::name ::us/string) (s/def ::suffix ::us/string) -(s/def ::type #{:jpeg :png :pdf :svg}) +(s/def ::type #{:png :jpeg :webp :pdf :svg}) (s/def ::page-id ::us/uuid) (s/def ::file-id ::us/uuid) (s/def ::share-id ::us/uuid) @@ -40,6 +40,7 @@ (case type :png (rb/render params on-object) :jpeg (rb/render params on-object) + :webp (rb/render params on-object) :pdf (rp/render params on-object) :svg (rs/render params on-object))) diff --git a/exporter/src/app/renderer/bitmap.cljs b/exporter/src/app/renderer/bitmap.cljs index 38022db739..750102af79 100644 --- a/exporter/src/app/renderer/bitmap.cljs +++ b/exporter/src/app/renderer/bitmap.cljs @@ -34,7 +34,11 @@ (bw/wait-for node) (case type :png (bw/screenshot node {:omit-background? true :type type :path path}) - :jpeg (bw/screenshot node {:omit-background? false :type type :path path})) + :jpeg (bw/screenshot node {:omit-background? false :type type :path path}) + :webp (p/let [png-path (sh/tempfile :prefix "penpot.tmp.render.bitmap." :suffix ".png")] + ;; playwright only supports jpg and png, we need to convert it afterwards + (bw/screenshot node {:omit-background? true :type :png :path png-path}) + (sh/run-cmd! (str "convert " png-path " -quality 100 WEBP:" path)))) (on-object (assoc object :path path)))) (render [uri page] diff --git a/exporter/src/app/util/mime.cljs b/exporter/src/app/util/mime.cljs index 18601cbd07..7bb0ce77c7 100644 --- a/exporter/src/app/util/mime.cljs +++ b/exporter/src/app/util/mime.cljs @@ -15,6 +15,7 @@ (case type :png ".png" :jpeg ".jpg" + :webp ".webp" :svg ".svg" :pdf ".pdf" :zip ".zip")) @@ -26,6 +27,7 @@ :pdf "application/pdf" :svg "image/svg+xml" :jpeg "image/jpeg" - :png "image/png")) + :png "image/png" + :webp "image/webp")) diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index 4494037f9d..f74c834e34 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -39,7 +39,9 @@ (declare process-message) (defn initialize - [] + [team-id] + (assert (uuid? team-id) "expected uuid instance for `team-id`") + (ptk/reify ::initialize ptk/WatchEvent (watch [_ state stream] @@ -47,8 +49,8 @@ profile-id (:profile-id state)] (->> (rx/merge - (rx/of (fetch-projects) - (df/fetch-fonts)) + (rx/of (fetch-projects team-id) + (df/fetch-fonts team-id)) (->> stream (rx/filter (ptk/type? ::dws/message)) (rx/map deref) @@ -61,8 +63,8 @@ (rx/take-until stopper)))))) (defn finalize - [] - (ptk/data-event ::finalize {})) + [team-id] + (ptk/data-event ::finalize {:team-id team-id})) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data Fetching (context aware: current team) @@ -70,7 +72,7 @@ ;; --- EVENT: fetch-projects -(defn projects-fetched +(defn- projects-fetched [projects] (ptk/reify ::projects-fetched ptk/UpdateEvent @@ -81,13 +83,12 @@ projects)))) (defn fetch-projects - [] + [team-id] (ptk/reify ::fetch-projects ptk/WatchEvent - (watch [_ state _] - (let [team-id (:current-team-id state)] - (->> (rp/cmd! :get-projects {:team-id team-id}) - (rx/map projects-fetched)))))) + (watch [_ _ _] + (->> (rp/cmd! :get-projects {:team-id team-id}) + (rx/map projects-fetched))))) ;; --- EVENT: search @@ -116,7 +117,7 @@ ;; --- EVENT: recent-files -(defn recent-files-fetched +(defn- recent-files-fetched [files] (ptk/reify ::recent-files-fetched ptk/UpdateEvent @@ -127,13 +128,14 @@ (update :files d/merge files)))))) (defn fetch-recent-files - [] - (ptk/reify ::fetch-recent-files - ptk/WatchEvent - (watch [_ state _] - (let [team-id (:current-team-id state)] - (->> (rp/cmd! :get-team-recent-files {:team-id team-id}) - (rx/map recent-files-fetched)))))) + ([] (fetch-recent-files nil)) + ([team-id] + (ptk/reify ::fetch-recent-files + ptk/WatchEvent + (watch [_ state _] + (when-let [team-id (or team-id (:current-team-id state))] + (->> (rp/cmd! :get-team-recent-files {:team-id team-id}) + (rx/map recent-files-fetched))))))) ;; --- EVENT: fetch-template-files diff --git a/frontend/src/app/main/data/exports/assets.cljs b/frontend/src/app/main/data/exports/assets.cljs index 1e800aee6d..b1f0293993 100644 --- a/frontend/src/app/main/data/exports/assets.cljs +++ b/frontend/src/app/main/data/exports/assets.cljs @@ -266,10 +266,10 @@ (defn export-shapes-event [exports origin] (let [types (reduce (fn [counts {:keys [type]}] - (if (#{:png :pdf :svg :jpeg} type) + (if (#{:png :jpeg :webp :svg :pdf} type) (update counts type inc) counts)) - {:png 0, :pdf 0, :svg 0, :jpeg 0} + {:png 0, :jpeg 0, :webp 0, :pdf 0, :svg 0} exports)] (ptk/event ::ev/event (merge types diff --git a/frontend/src/app/main/data/fonts.cljs b/frontend/src/app/main/data/fonts.cljs index a1aba3d671..4706e7c5c3 100644 --- a/frontend/src/app/main/data/fonts.cljs +++ b/frontend/src/app/main/data/fonts.cljs @@ -73,13 +73,12 @@ (fonts/register! :custom fonts)))))) (defn fetch-fonts - [] - (ptk/reify ::load-team-fonts + [team-id] + (ptk/reify ::fetch-fonts ptk/WatchEvent - (watch [_ state _] - (let [team-id (:current-team-id state)] - (->> (rp/cmd! :get-font-variants {:team-id team-id}) - (rx/map fonts-fetched)))))) + (watch [_ _ _] + (->> (rp/cmd! :get-font-variants {:team-id team-id}) + (rx/map fonts-fetched))))) (defn process-upload "Given a seq of blobs and the team id, creates a ready-to-use fonts diff --git a/frontend/src/app/main/data/team.cljs b/frontend/src/app/main/data/team.cljs index 50af94a444..43e1690257 100644 --- a/frontend/src/app/main/data/team.cljs +++ b/frontend/src/app/main/data/team.cljs @@ -64,13 +64,14 @@ (update :profiles merge (d/index-by :id members)))))) (defn fetch-members - [] - (ptk/reify ::fetch-members - ptk/WatchEvent - (watch [_ state _] - (let [team-id (:current-team-id state)] - (->> (rp/cmd! :get-team-members {:team-id team-id}) - (rx/map (partial members-fetched team-id))))))) + ([] (fetch-members nil)) + ([team-id] + (ptk/reify ::fetch-members + ptk/WatchEvent + (watch [_ state _] + (when-let [team-id (or team-id (:current-team-id state))] + (->> (rp/cmd! :get-team-members {:team-id team-id}) + (rx/map (partial members-fetched team-id)))))))) (defn- invitations-fetched [team-id invitations] @@ -88,41 +89,20 @@ (->> (rp/cmd! :get-team-invitations {:team-id team-id}) (rx/map (partial invitations-fetched team-id))))))) -(defn set-current-team - [{:keys [id permissions features] :as team}] - (ptk/reify ::set-current-team - ptk/UpdateEvent - (update [_ state] - (-> state - ;; FIXME: redundant operation, only necessary on workspace - ;; until workspace initialization is refactored - (update-in [:teams id] merge team) - (assoc :permissions permissions) - ;; FIXME: this is a redundant operation that only needed by - ;; workspace; ti will not be needed after workspace - ;; bootstrap & urls refactor - (assoc :current-team-id id))) - - ptk/WatchEvent - (watch [_ _ _] - (rx/of (features/initialize (or features #{})))) - - ptk/EffectEvent - (effect [_ _ _] - (swap! storage/global assoc ::current-team-id id)))) - (defn- team-initialized - [] + [team-id] (ptk/reify ::team-initialized ptk/WatchEvent (watch [_ state _] - (let [team-id (:current-team-id state) - teams (get state :teams) - team (get teams team-id)] + (let [teams (get state :teams) + team (get teams team-id)] (if (not team) (rx/throw (ex/error :type :authentication)) - (rx/of (set-current-team team) - (fetch-members))))))) + (let [permissions (get team :permissions) + features (get team :features)] + (rx/of #(assoc % :permissions permissions) + (features/initialize (or features #{})) + (fetch-members team-id)))))))) (defn initialize-team [team-id] @@ -138,8 +118,7 @@ (rx/of (fetch-teams)) (->> stream (rx/filter (ptk/type? ::teams-fetched)) - (rx/observe-on :async) - (rx/map team-initialized))) + (rx/map (partial team-initialized team-id)))) (rx/take-until stopper)))))) (defn finalize-team @@ -169,7 +148,7 @@ params (assoc params :team-id team-id)] (->> (rp/cmd! :update-team-member-role params) (rx/mapcat (fn [_] - (rx/of (fetch-members) + (rx/of (fetch-members team-id) (fetch-teams) (ptk/data-event ::ev/event {::ev/name "update-team-member-role" @@ -187,7 +166,7 @@ params (assoc params :team-id team-id)] (->> (rp/cmd! :delete-team-member params) (rx/mapcat (fn [_] - (rx/of (fetch-members) + (rx/of (fetch-members team-id) (fetch-teams) (ptk/data-event ::ev/event {::ev/name "delete-team-member" diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 3428ddd0ab..b676dc8d9e 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -291,7 +291,8 @@ (watch [_ state stream] (let [features (features/get-team-enabled-features state) render-wasm? (contains? features "render-wasm/v1") - stopper-s (rx/filter (ptk/type? ::finalize-workspace) stream)] + stopper-s (rx/filter (ptk/type? ::finalize-workspace) stream) + team-id (:current-team-id state)] (->> (rx/concat ;; Firstly load wasm module if it is enabled and fonts @@ -305,7 +306,7 @@ (rx/filter (ptk/type? ::df/fonts-loaded)) (rx/take 1) (rx/ignore)) - (rx/of (df/fetch-fonts))) + (rx/of (df/fetch-fonts team-id))) ;; Then fetch file and thumbnails (->> (rx/zip (rp/cmd! :get-file {:id file-id :features features}) @@ -335,7 +336,7 @@ ptk/WatchEvent (watch [_ state stream] - (log/debug :hint "initialize-workspace" :file-id file-id) + (log/debug :hint "initialize-workspace" :file-id (dm/str file-id)) (let [stoper-s (rx/filter (ptk/type? ::finalize-workspace) stream) rparams (rt/get-params state)] diff --git a/frontend/src/app/main/ui/dashboard.cljs b/frontend/src/app/main/ui/dashboard.cljs index d0d7bafdee..9dbe96ae0a 100644 --- a/frontend/src/app/main/ui/dashboard.cljs +++ b/frontend/src/app/main/ui/dashboard.cljs @@ -210,42 +210,45 @@ (swap! storage/session dissoc :plugin-url)))))) (defn use-templates-import - [can-edit? template-url default-project-id] - (mf/with-layout-effect - [can-edit? template-url default-project-id] - (when (and (some? template-url) (some? default-project-id)) - (if can-edit? - (let [valid-url? (and (str/ends-with? template-url ".penpot") - (str/starts-with? template-url cf/templates-uri)) - template-name (when valid-url? (subs template-url (count cf/templates-uri))) - on-import #(st/emit! (dpj/fetch-files default-project-id) - (dd/fetch-recent-files) - (dd/fetch-projects) - (dd/clear-selected-files) - (ptk/event ::ev/event {::ev/name "install-template-from-link-finished" - :name template-name - :url template-url}))] - (if valid-url? - (do - (st/emit! (ptk/event ::ev/event {::ev/name "install-template-from-link" :name template-name :url template-url})) - (->> (http/send! {:method :get - :uri template-url - :response-type :blob - :omit-default-headers true}) - (rx/subs! - (fn [result] - (if (or (< (:status result) 200) (>= (:status result) 300)) - (st/emit! (notif/error (tr "dashboard.import.error"))) - (st/emit! (modal/show - {:type :import - :project-id default-project-id - :entries [{:name template-name :uri (wapi/create-uri (:body result))}] - :on-finish-import on-import}))))))) - (st/emit! (notif/error (tr "dashboard.import.bad-url"))))) - (st/emit! (notif/error (tr "dashboard.import.no-perms")))) + [can-edit? template-url project] + (let [project-id (get project :id) + team-id (get project :team-id)] + (mf/with-layout-effect [can-edit? template-url project-id team-id] + (when (and (some? template-url) + (some? project-id) + (some? team-id)) + (if can-edit? + (let [valid-url? (and (str/ends-with? template-url ".penpot") + (str/starts-with? template-url cf/templates-uri)) + template-name (when valid-url? (subs template-url (count cf/templates-uri))) + on-import #(st/emit! (dpj/fetch-files project-id) + (dd/fetch-recent-files team-id) + (dd/fetch-projects team-id) + (dd/clear-selected-files) + (ptk/event ::ev/event {::ev/name "install-template-from-link-finished" + :name template-name + :url template-url}))] + (if valid-url? + (do + (st/emit! (ptk/event ::ev/event {::ev/name "install-template-from-link" :name template-name :url template-url})) + (->> (http/send! {:method :get + :uri template-url + :response-type :blob + :omit-default-headers true}) + (rx/subs! + (fn [result] + (if (or (< (:status result) 200) (>= (:status result) 300)) + (st/emit! (notif/error (tr "dashboard.import.error"))) + (st/emit! (modal/show + {:type :import + :project-id project-id + :entries [{:name template-name :uri (wapi/create-uri (:body result))}] + :on-finish-import on-import}))))))) + (st/emit! (notif/error (tr "dashboard.import.bad-url"))))) + (st/emit! (notif/error (tr "dashboard.import.no-perms")))) - (binding [storage/*sync* true] - (swap! storage/session dissoc :template-url))))) + (binding [storage/*sync* true] + (swap! storage/session dissoc :template-url)))))) (mf/defc dashboard* {::mf/props :obj} @@ -270,10 +273,10 @@ (hooks/use-shortcuts ::dashboard sc/shortcuts) - (mf/with-effect [] - (st/emit! (dd/initialize)) + (mf/with-effect [team-id] + (st/emit! (dd/initialize team-id)) (fn [] - (st/emit! (dd/finalize)))) + (st/emit! (dd/finalize team-id)))) (mf/with-effect [] (let [key (events/listen goog/global "keydown" @@ -285,7 +288,7 @@ (events/unlistenByKey key)))) (use-plugin-register plugin-url team-id (:id default-project)) - (use-templates-import can-edit? template-url (:id default-project)) + (use-templates-import can-edit? template-url default-project) [:& (mf/provider ctx/current-project-id) {:value project-id} [:> modal-container*] diff --git a/frontend/src/app/main/ui/dashboard/file_menu.cljs b/frontend/src/app/main/ui/dashboard/file_menu.cljs index f882c2179c..6e10ede276 100644 --- a/frontend/src/app/main/ui/dashboard/file_menu.cljs +++ b/frontend/src/app/main/ui/dashboard/file_menu.cljs @@ -133,7 +133,7 @@ (st/emit! (dcm/go-to-dashboard-files {:project-id project-id :team-id team-id})) - (st/emit! (dd/fetch-recent-files) + (st/emit! (dd/fetch-recent-files team-id) (dd/clear-selected-files)))) on-move-accept diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index 4a3112ca2c..2a2bf20f76 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -566,8 +566,9 @@ on-finish-import (mf/use-fn + (mf/deps team-id) (fn [] - (st/emit! (dd/fetch-recent-files) + (st/emit! (dd/fetch-recent-files team-id) (dd/clear-selected-files)))) import-files (use-import-file project-id on-finish-import) @@ -608,9 +609,10 @@ on-drop-success (mf/use-fn + (mf/deps team-id) (fn [] (st/emit! (ntf/success (tr "dashboard.success-move-file")) - (dd/fetch-recent-files) + (dd/fetch-recent-files team-id) (dd/clear-selected-files)))) on-drop diff --git a/frontend/src/app/main/ui/dashboard/import.cljs b/frontend/src/app/main/ui/dashboard/import.cljs index c9fb7df2b0..ce6b83afb4 100644 --- a/frontend/src/app/main/ui/dashboard/import.cljs +++ b/frontend/src/app/main/ui/dashboard/import.cljs @@ -344,11 +344,13 @@ continue-template (mf/use-fn + (mf/deps on-finish-import) (fn [template] (let [on-success (fn [_event] (reset! status* :import-success) - (st/emit! (dd/fetch-recent-files))) + (when (fn? on-finish-import) + (on-finish-import))) on-error (fn [cause] @@ -479,8 +481,6 @@ [:> import-entry* {:entry (assoc template :status status) :can-be-deleted false}])] - ;; (prn "import-dialog" status) - [:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :action-buttons)} (when (= :analyze status) diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index 12f22309b7..3aaa590f81 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -105,7 +105,8 @@ [{:keys [project is-first team files can-edit]}] (let [locale (mf/deref i18n/locale) - project-id (:id project) + project-id (get project :id) + team-id (get team :id) file-count (or (:count project) 0) is-draft? (:is-default project) @@ -191,11 +192,11 @@ on-import (mf/use-fn - (mf/deps project-id) + (mf/deps project-id team-id) (fn [] (st/emit! (dpj/fetch-files project-id) - (dd/fetch-recent-files) - (dd/fetch-projects) + (dd/fetch-recent-files team-id) + (dd/fetch-projects team-id) (dd/clear-selected-files)))) handle-create-click @@ -317,6 +318,8 @@ (sort-by :modified-at) (reverse))) + team-id (get team :id) + recent-map (mf/deref ref:recent-files) permisions (:permissions team) @@ -327,7 +330,7 @@ show-team-hero* (mf/use-state #(get storage/global ::show-team-hero true)) show-team-hero? (deref show-team-hero*) - is-my-penpot (= (:default-team-id profile) (:id team)) + is-my-penpot (= (:default-team-id profile) team-id) is-defalt-team? (:is-default team) on-close @@ -346,8 +349,8 @@ (:name team))] (dom/set-html-title (tr "title.dashboard.projects" tname)))) - (mf/with-effect [] - (st/emit! (dd/fetch-recent-files) + (mf/with-effect [team-id] + (st/emit! (dd/fetch-recent-files team-id) (dd/clear-selected-files))) (when (seq projects) diff --git a/frontend/src/app/main/ui/dashboard/templates.cljs b/frontend/src/app/main/ui/dashboard/templates.cljs index a69b21910a..ae2df1b08d 100644 --- a/frontend/src/app/main/ui/dashboard/templates.cljs +++ b/frontend/src/app/main/ui/dashboard/templates.cljs @@ -37,6 +37,7 @@ [template team-id project-id default-project-id section] (letfn [(on-finish [] (st/emit! + (dd/fetch-recent-files team-id) (ptk/event ::ev/event {::ev/name "import-template-finish" ::ev/origin "dashboard" :template (:name template) diff --git a/frontend/src/app/main/ui/inspect/exports.cljs b/frontend/src/app/main/ui/inspect/exports.cljs index 8c5495ad1e..5f1aa2118e 100644 --- a/frontend/src/app/main/ui/inspect/exports.cljs +++ b/frontend/src/app/main/ui/inspect/exports.cljs @@ -37,7 +37,7 @@ scale-enabled? (mf/use-callback (fn [export] - (#{:png :jpeg} (:type export)))) + (#{:png :jpeg :webp} (:type export)))) in-progress? (:in-progress xstate) @@ -123,6 +123,7 @@ format-options [{:value "png" :label "PNG"} {:value "jpeg" :label "JPG"} + {:value "webp" :label "WEBP"} {:value "svg" :label "SVG"} {:value "pdf" :label "PDF"}]] diff --git a/frontend/src/app/main/ui/inspect/exports.scss b/frontend/src/app/main/ui/inspect/exports.scss index 8244d9e23f..f7365067c8 100644 --- a/frontend/src/app/main/ui/inspect/exports.scss +++ b/frontend/src/app/main/ui/inspect/exports.scss @@ -51,7 +51,7 @@ .element-group { display: grid; - grid-template-columns: repeat(8, 1fr); + grid-template-columns: repeat(9, 1fr); column-gap: $s-4; .action-btn { @extend .button-tertiary; @@ -64,13 +64,13 @@ } .input-wrapper { - grid-column: span 7; + grid-column: span 8; display: grid; grid-template-columns: subgrid; } .format-select { - grid-column: span 2; + grid-column: span 3; padding: 0; .dropdown-upwards { diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index 90d9111b25..0c6a8b8feb 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -568,7 +568,6 @@ [{:keys [starting-tab file-id] :as props :or {starting-tab :libraries}}] (let [files (mf/deref refs/files) file (get files file-id) - team-id (:team-id file) shared? (:is-shared file) linked-libraries @@ -616,8 +615,8 @@ :id "updates" :content updates-tab}]] - (mf/with-effect [team-id] - (st/emit! (dtm/fetch-shared-files team-id))) + (mf/with-effect [] + (st/emit! (dtm/fetch-shared-files))) [:div {:class (stl/css :modal-overlay) :on-click close-dialog-outside diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs index dd8908d76d..415d0295a1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs @@ -53,7 +53,7 @@ scale-enabled? (mf/use-fn (fn [export] - (#{:png :jpeg} (:type export)))) + (#{:png :jpeg :webp} (:type export)))) on-download (mf/use-fn @@ -173,6 +173,7 @@ format-options [{:value "png" :label "PNG"} {:value "jpeg" :label "JPG"} + {:value "webp" :label "WEBP"} {:value "svg" :label "SVG"} {:value "pdf" :label "PDF"}]] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss index 6bf3152dd4..0f9aae670e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss @@ -32,18 +32,18 @@ .element-group { display: grid; - grid-template-columns: repeat(8, 1fr); + grid-template-columns: repeat(9, 1fr); column-gap: $s-4; } .input-wrapper { - grid-column: span 7; + grid-column: span 8; display: grid; grid-template-columns: subgrid; } .format-select { - grid-column: span 2; + grid-column: span 3; padding: 0; .dropdown-upwards { diff --git a/frontend/src/app/plugins/format.cljs b/frontend/src/app/plugins/format.cljs index 829476da0b..6555f6a367 100644 --- a/frontend/src/app/plugins/format.cljs +++ b/frontend/src/app/plugins/format.cljs @@ -261,7 +261,7 @@ :hidden hidden}))) ;; export interface Export { -;; type: 'png' | 'jpeg' | 'svg' | 'pdf'; +;; type: 'png' | 'jpeg' | 'webp' | 'svg' | 'pdf'; ;; scale: number; ;; suffix: string; ;; } diff --git a/frontend/src/app/plugins/parser.cljs b/frontend/src/app/plugins/parser.cljs index 8d884350dd..0ce6aad418 100644 --- a/frontend/src/app/plugins/parser.cljs +++ b/frontend/src/app/plugins/parser.cljs @@ -243,7 +243,7 @@ ;; export interface Export { -;; type: 'png' | 'jpeg' | 'svg' | 'pdf'; +;; type: 'png' | 'jpeg' | 'webp' | 'svg' | 'pdf'; ;; scale: number; ;; suffix: string; ;; } diff --git a/frontend/src/app/render.cljs b/frontend/src/app/render.cljs index d8a3d86505..258c988128 100644 --- a/frontend/src/app/render.cljs +++ b/frontend/src/app/render.cljs @@ -14,7 +14,6 @@ [app.common.types.components-list :as ctkl] [app.common.uri :as u] [app.main.data.fonts :as df] - [app.main.data.team :as dtm] [app.main.features :as features] [app.main.render :as render] [app.main.repo :as repo] @@ -30,6 +29,20 @@ (log/setup! {:app :info}) +(defn set-current-team + [{:keys [id permissions features] :as team}] + (ptk/reify ::set-current-team + ptk/UpdateEvent + (update [_ state] + (-> state + (assoc :permissions permissions) + (update :teams assoc id team) + (assoc :current-team-id id))) + + ptk/WatchEvent + (watch [_ _ _] + (rx/of (features/initialize (or features #{})))))) + (defn- fetch-team [& {:keys [file-id]}] (ptk/reify ::fetch-team @@ -37,7 +50,7 @@ (watch [_ _ _] (->> (repo/cmd! :get-team {:file-id file-id}) (rx/mapcat (fn [team] - (rx/of (dtm/set-current-team team) + (rx/of (set-current-team team) (ptk/data-event ::team-fetched team)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;