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
- Size - Options for the most common sizing scales.
- Suffix - Especially useful if you are exporting at different scales.
- - File format - PNG, SVG, JPEG, PDF.
+ - File format - PNG, JPEG, WEBP, SVG, PDF.
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))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;