diff --git a/CHANGES.md b/CHANGES.md index 3aa38d215c..28bb73c8bf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -68,6 +68,8 @@ - Fix problem when changing between flex/grid layout [Taiga #11625](https://tree.taiga.io/project/penpot/issue/11625) - Fix opacity on stroke gradients [Taiga #11646](https://tree.taiga.io/project/penpot/issue/11646) - Fix change from gradient to solid color [Taiga #11648](https://tree.taiga.io/project/penpot/issue/11648) +- Fix the context menu always closes after any action [Taiga #11624](https://tree.taiga.io/project/penpot/issue/11624) +- Fix font selector highlight inconsistency when using keyboard navigation [Taiga #11668](https://tree.taiga.io/project/penpot/issue/11668) ## 2.8.1 (Unreleased) @@ -75,6 +77,7 @@ - Fix unexpected exception on processing old texts [Github #6889](https://github.com/penpot/penpot/pull/6889) - Fix UI theme selection from main menu [Taiga #11567](https://tree.taiga.io/project/penpot/issue/11567) +- Add missing migration information to file snapshots [Github #686](https://github.com/penpot/penpot/pull/6864) ## 2.8.0 diff --git a/backend/src/app/features/logical_deletion.clj b/backend/src/app/features/logical_deletion.clj index 8a06f3f30f..a8407cdf62 100644 --- a/backend/src/app/features/logical_deletion.clj +++ b/backend/src/app/features/logical_deletion.clj @@ -10,18 +10,19 @@ [app.config :as cf] [app.util.time :as dt])) +(def ^:private canceled-status + #{"canceled" "unpaid"}) + (defn get-deletion-delay "Calculate the next deleted-at for a resource (file, team, etc) in function of team settings" [team] - (if-let [subscription (get team :subscription)] + (if-let [{:keys [type status]} (get team :subscription)] (cond - (and (= (:type subscription) "unlimited") - (= (:status subscription) "active")) + (and (= "unlimited" type) (not (contains? canceled-status status))) (dt/duration {:days 30}) - (and (= (:type subscription) "enterprise") - (= (:status subscription) "active")) + (and (= "enterprise" type) (not (contains? canceled-status status))) (dt/duration {:days 90}) :else diff --git a/backend/src/app/migrations.clj b/backend/src/app/migrations.clj index 795a9bea5c..1c51365a9c 100644 --- a/backend/src/app/migrations.clj +++ b/backend/src/app/migrations.clj @@ -438,7 +438,10 @@ :fn (mg/resource "app/migrations/sql/0138-mod-file-data-fragment-table.sql")} {:name "0139-mod-file-change-table.sql" - :fn (mg/resource "app/migrations/sql/0139-mod-file-change-table.sql")}]) + :fn (mg/resource "app/migrations/sql/0139-mod-file-change-table.sql")} + + {:name "0140-mod-file-change-table.sql" + :fn (mg/resource "app/migrations/sql/0140-mod-file-change-table.sql")}]) (defn apply-migrations! [pool name migrations] diff --git a/backend/src/app/migrations/sql/0140-mod-file-change-table.sql b/backend/src/app/migrations/sql/0140-mod-file-change-table.sql new file mode 100644 index 0000000000..6189edb140 --- /dev/null +++ b/backend/src/app/migrations/sql/0140-mod-file-change-table.sql @@ -0,0 +1,2 @@ +ALTER TABLE file_change + ADD COLUMN migrations text[]; diff --git a/backend/src/app/rpc/commands/files_snapshot.clj b/backend/src/app/rpc/commands/files_snapshot.clj index 71689560a5..bcfbad9428 100644 --- a/backend/src/app/rpc/commands/files_snapshot.clj +++ b/backend/src/app/rpc/commands/files_snapshot.clj @@ -8,6 +8,7 @@ (:require [app.binfile.common :as bfc] [app.common.exceptions :as ex] + [app.common.files.migrations :as fmg] [app.common.logging :as l] [app.common.schema :as sm] [app.common.uuid :as uuid] @@ -15,6 +16,7 @@ [app.db :as db] [app.db.sql :as-alias sql] [app.features.fdata :as feat.fdata] + [app.features.file-migrations :refer [reset-migrations!]] [app.main :as-alias main] [app.msgbus :as mbus] [app.rpc :as-alias rpc] @@ -27,6 +29,13 @@ [app.util.time :as dt] [cuerdas.core :as str])) +(defn decode-row + [{:keys [migrations] :as row}] + (when row + (cond-> row + (some? migrations) + (assoc :migrations (db/decode-pgarray migrations))))) + (def sql:get-file-snapshots "WITH changes AS ( SELECT id, label, revn, created_at, created_by, profile_id @@ -74,10 +83,7 @@ (assert (#{:system :user :admin} created-by) "expected valid keyword for created-by") - (let [conn - (db/get-connection cfg) - - created-by + (let [created-by (name created-by) deleted-at @@ -101,12 +107,15 @@ (blob/encode (:data file)) features - (db/encode-pgarray (:features file) conn "text")] + (into-array (:features file)) - (l/debug :hint "creating file snapshot" - :file-id (str (:id file)) - :id (str snapshot-id) - :label label) + migrations + (into-array (:migrations file))] + + (l/dbg :hint "creating file snapshot" + :file-id (str (:id file)) + :id (str snapshot-id) + :label label) (db/insert! cfg :file-change {:id snapshot-id @@ -114,6 +123,7 @@ :data data :version (:version file) :features features + :migrations migrations :profile-id profile-id :file-id (:id file) :label label @@ -159,7 +169,17 @@ {:file-id file-id :id snapshot-id} {::db/for-share true}) - (feat.fdata/resolve-file-data cfg))] + (feat.fdata/resolve-file-data cfg) + (decode-row)) + + ;; If snapshot has tracked applied migrations, we reuse them, + ;; if not we take a safest set of migrations as starting + ;; point. This is because, at the time of implementing + ;; snapshots, migrations were not taken into account so we + ;; need to make this backward compatible in some way. + file (assoc file :migrations + (or (:migrations snapshot) + (fmg/generate-migrations-from-version 67)))] (when-not snapshot (ex/raise :type :not-found @@ -180,12 +200,16 @@ :label (:label snapshot) :snapshot-id (str (:id snapshot))) - ;; If the file was already offloaded, on restring the snapshot - ;; we are going to replace the file data, so we need to touch - ;; the old referenced storage object and avoid possible leaks + ;; If the file was already offloaded, on restoring the snapshot we + ;; are going to replace the file data, so we need to touch the old + ;; referenced storage object and avoid possible leaks (when (feat.fdata/offloaded? file) (sto/touch-object! storage (:data-ref-id file))) + ;; In the same way, on reseting the file data, we need to restore + ;; the applied migrations on the moment of taking the snapshot + (reset-migrations! conn file) + (db/update! conn :file {:data (:data snapshot) :revn (inc (:revn file)) @@ -253,7 +277,7 @@ :deleted-at nil} {:id snapshot-id} {::db/return-keys true}) - (dissoc :data :features))) + (dissoc :data :features :migrations))) (defn- get-snapshot "Get a minimal snapshot from database and lock for update" diff --git a/common/src/app/common/files/migrations.cljc b/common/src/app/common/files/migrations.cljc index 9bff98e6d1..2af7b31f4d 100644 --- a/common/src/app/common/files/migrations.cljc +++ b/common/src/app/common/files/migrations.cljc @@ -80,7 +80,7 @@ (update :migrations set/union diff) (vary-meta assoc ::migrated (not-empty diff))))) -(defn- generate-migrations-from-version +(defn generate-migrations-from-version "A function that generates new format migration from the old, version based migration system" [version] diff --git a/common/src/app/common/logic/shapes.cljc b/common/src/app/common/logic/shapes.cljc index 4e3e0e3924..281d2b8e55 100644 --- a/common/src/app/common/logic/shapes.cljc +++ b/common/src/app/common/logic/shapes.cljc @@ -11,6 +11,7 @@ [app.common.files.helpers :as cfh] [app.common.geom.shapes :as gsh] [app.common.logic.variant-properties :as clvp] + [app.common.text :as ct] [app.common.types.component :as ctk] [app.common.types.container :as ctn] [app.common.types.pages-list :as ctpl] diff --git a/docker/images/Dockerfile.backend b/docker/images/Dockerfile.backend index b8d59818e9..3535cffd0c 100644 --- a/docker/images/Dockerfile.backend +++ b/docker/images/Dockerfile.backend @@ -125,7 +125,7 @@ RUN set -ex; \ COPY --from=build /opt/jre /opt/jre COPY --from=build /opt/node /opt/node -COPY --from=penpotapp/imagemagick:7.1.1-47 /opt/imagick /opt/imagick +COPY --from=penpotapp/imagemagick:7.1.2-0 /opt/imagick /opt/imagick COPY --chown=penpot:penpot ./bundle-backend/ /opt/penpot/backend/ USER penpot:penpot diff --git a/docs/user-guide/design-tokens/index.njk b/docs/user-guide/design-tokens/index.njk index 3de6a9dbae..186de28280 100644 --- a/docs/user-guide/design-tokens/index.njk +++ b/docs/user-guide/design-tokens/index.njk @@ -205,6 +205,10 @@ title: 10· Design Tokens

Y Position (dimension)

The Y property specifies the position of the element on the Y axis of the canvas.

+

Font Size

+

Font size tokens allow you to define and standardize font-size values across your design system. These tokens can be applied to the font-size property in text layers, ensuring consistent typography throughout your designs.

+

Font size token values are always computed as px (pixels).

+

Opacity

Opacity tokens allow you to define the opacity of a layer, ranging from fully opaque to fully transparent.

Opacity tokens can be applied to any design element that supports transparency. You can use any decimal value between 0 and 1 to set varying levels of opacity or you can use any value between 0 and 100 with `%` sign at the end of the value. For example, you can use 45% which would resolve to .45.

@@ -378,7 +382,15 @@ title: 10· Design Tokens

Import Options

-

Single file

+ +

ZIP file

+

You can import tokens from a .zip file. This file can either contain a single JSON file or a folder structure with multiple files. The ZIP import option provides flexibility for organizing your tokens before importing them into Penpot.

+ + +

Single JSON file

You can import a JSON file comprising all tokens, token sets and token themes.

When importing a single file, the first-level keys of the json file will be interpreted as the set name.

diff --git a/docs/user-guide/layer-basics/index.njk b/docs/user-guide/layer-basics/index.njk index 317857423c..1667d8886e 100644 --- a/docs/user-guide/layer-basics/index.njk +++ b/docs/user-guide/layer-basics/index.njk @@ -34,7 +34,13 @@ desc: Master layer basics with Penpot's user guide! Learn to create, manipulate,

Layers are displayed from the bottom to the top of the layer stack, with layers above on the stack being shown on top in the image.

Hide and lock layers

-

Click on the eye icon to change the visibility of a layer. Click on the lock icon to lock or unlock a layer. A locked layer can not be modified.

+ +

Hide and show layers

+

You can control the visibility of any layer by clicking the eye icon next to it in the Layers panel. When a layer is hidden, it will not appear on the canvas, but you can still select it in the Layers panel, move its order, or modify its properties. The eye icon always indicates whether a layer is visible or hidden, making it easy to manage complex designs.

+ +

Lock and unlock layers

+

Locking a layer helps prevent accidental changes or movement on the canvas. When a layer is locked, it cannot be moved or edited directly in the canvas area. However, you can still select a locked layer in the Layers panel and adjust its properties, such as color, effects, or name. The lock icon next to the layer’s name shows its locked status, helping you keep your design organized and protected.

+
+

Tips for resizing

+

Edit and style text content

Press Enter with a text layer selected to start editing the text content. You can style parts of the text content as rich text.

diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index a3a2d1da8c..ee71a3e73b 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -1098,15 +1098,24 @@ (when (seq (:redo-changes changes)) (rx/of (dch/commit-changes changes))) (when-not (empty? updated-frames) - (rx/merge - (rx/of (ptk/data-event :layout/update {:ids (map :id updated-frames) :undo-group undo-group})) - (->> (rx/from updated-frames) - (rx/mapcat - (fn [shape] - (rx/of - (dwt/clear-thumbnail file-id (:page-id shape) (:id shape) "frame") - (when-not (= (:frame-id shape) uuid/zero) - (dwt/clear-thumbnail file-id (:page-id shape) (:frame-id shape) "frame")))))))) + (let [frames-by-page (->> updated-frames + (group-by :page-id))] + (rx/merge + ;; Emit one layout/update event for each page + (rx/from + (map (fn [[page-id frames]] + (ptk/data-event :layout/update + {:page-id page-id + :ids (map :id frames) + :undo-group undo-group})) + frames-by-page)) + (->> (rx/from updated-frames) + (rx/mapcat + (fn [shape] + (rx/of + (dwt/clear-thumbnail file-id (:page-id shape) (:id shape) "frame") + (when-not (= (:frame-id shape) uuid/zero) + (dwt/clear-thumbnail file-id (:page-id shape) (:frame-id shape) "frame"))))))))) (when (not= file-id library-id) ;; When we have just updated the library file, give some time for the diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 187a307341..908c5fc107 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -131,11 +131,12 @@ ;; they are process together. It will get a better performance. (rx/buffer-time 100) (rx/filter #(d/not-empty? %)) - (rx/map + (rx/mapcat (fn [data] - (let [page-id (->> data (keep :page-id) first) - ids (reduce #(into %1 (:ids %2)) #{} data)] - (update-layout-positions {:page-id page-id :ids ids})))) + (->> (group-by :page-id data) + (map (fn [[page-id items]] + (let [ids (reduce #(into %1 (:ids %2)) #{} items)] + (update-layout-positions {:page-id page-id :ids ids}))))))) (rx/take-until stopper)))))) (defn finalize-shape-layout diff --git a/frontend/src/app/main/data/workspace/tokens/application.cljs b/frontend/src/app/main/data/workspace/tokens/application.cljs index 55e14cc4ff..78eb5da27b 100644 --- a/frontend/src/app/main/data/workspace/tokens/application.cljs +++ b/frontend/src/app/main/data/workspace/tokens/application.cljs @@ -304,7 +304,6 @@ (when (string? value) (generate-text-shape-update {:text-transform value} shape-ids page-id)))) - ;; Events to apply / unapply tokens to shapes ------------------------------------------------------------ (defn apply-token diff --git a/frontend/src/app/main/ui/dashboard/subscription.cljs b/frontend/src/app/main/ui/dashboard/subscription.cljs index e751e27443..d320a687e4 100644 --- a/frontend/src/app/main/ui/dashboard/subscription.cljs +++ b/frontend/src/app/main/ui/dashboard/subscription.cljs @@ -75,7 +75,7 @@ [:> cta-power-up* {:top-title (tr "subscription.dashboard.power-up.your-subscription") :top-description (tr "subscription.dashboard.power-up.unlimited-plan") - :bottom-description (tr "subscription.dashboard.power-up.unlimited.bottom", subscription-href) + :bottom-description (tr "subscription.dashboard.power-up.unlimited.bottom-text", subscription-href) :has-dropdown true}]) "enterprise" diff --git a/frontend/src/app/main/ui/settings/subscription.cljs b/frontend/src/app/main/ui/settings/subscription.cljs index e72c4f9b86..e693da8f33 100644 --- a/frontend/src/app/main/ui/settings/subscription.cljs +++ b/frontend/src/app/main/ui/settings/subscription.cljs @@ -365,17 +365,17 @@ [:> plan-card* {:card-title (tr "subscription.settings.enterprise-trial") :card-title-icon i/character-e :benefits-title (tr "subscription.settings.benefits.all-professional-benefits") - :benefits [(tr "subscription.settings.enterprise.security"), + :benefits [(tr "subscription.settings.enterprise.unlimited-storage"), (tr "subscription.settings.enterprise.capped-bill"), - (tr "subscription.settings.enterprise.unlimited-storage")] + (tr "subscription.settings.enterprise.autosave")] :cta-text (tr "subscription.settings.manage-your-subscription") :cta-link go-to-payments}] [:> plan-card* {:card-title (tr "subscription.settings.enterprise") :card-title-icon i/character-e :benefits-title (tr "subscription.settings.benefits.all-professional-benefits") - :benefits [(tr "subscription.settings.enterprise.security"), + :benefits [(tr "subscription.settings.enterprise.unlimited-storage"), (tr "subscription.settings.enterprise.capped-bill"), - (tr "subscription.settings.enterprise.unlimited-storage")] + (tr "subscription.settings.enterprise.autosave")] :cta-text (tr "subscription.settings.manage-your-subscription") :cta-link go-to-payments}])) @@ -425,9 +425,9 @@ :price-value "$950" :price-period (tr "subscription.settings.price-organization-month") :benefits-title (tr "subscription.settings.benefits.all-unlimited-benefits") - :benefits [(tr "subscription.settings.enterprise.security"), + :benefits [(tr "subscription.settings.enterprise.unlimited-storage"), (tr "subscription.settings.enterprise.capped-bill"), - (tr "subscription.settings.enterprise.unlimited-storage")] + (tr "subscription.settings.enterprise.autosave")] :cta-text (if subscription (tr "subscription.settings.subscribe") (tr "subscription.settings.try-it-free")) :cta-link #(open-subscription-modal "enterprise" subscription) :cta-text-with-icon (tr "subscription.settings.more-information") diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index 1914b6c2ad..b663d12fd5 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -275,10 +275,8 @@ handle-gradient-remove-stop (mf/use-fn - (mf/deps state) (fn [index] - (when (> (count (:stops state)) 2) - (st/emit! (dc/remove-gradient-stop index))))) + (st/emit! (dc/remove-gradient-stop index)))) handle-stop-edit-start (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index dc86ee4764..99e81678cc 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -59,6 +59,14 @@ on-unmount children is-selected icon disabled value]}] (let [submenu-ref (mf/use-ref nil) hovering? (mf/use-ref false) + + on-click' + (mf/use-fn + (mf/deps on-click) + (fn [event] + (st/emit! dw/hide-context-menu) + (when on-click (on-click event)))) + on-pointer-enter (mf/use-fn (fn [] @@ -96,7 +104,7 @@ :disabled disabled :data-value value :ref set-dom-node - :on-click on-click + :on-click on-click' :on-pointer-enter on-pointer-enter :on-pointer-leave on-pointer-leave} [:span @@ -110,7 +118,7 @@ :disabled disabled :ref set-dom-node :data-value value - :on-click on-click + :on-click on-click' :on-pointer-enter on-pointer-enter :on-pointer-leave on-pointer-leave} [:span {:class (stl/css :title)} title] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs index 2faae0ddca..94bb1b3c92 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs @@ -41,25 +41,9 @@ "" (ust/format-precision value 2))) -(defn- get-next-font - [{:keys [id] :as current} fonts] - (if (seq fonts) - (let [index (d/index-of-pred fonts #(= (:id %) id)) - index (or index -1) - next (ex/ignoring (nth fonts (inc index)))] - (or next (first fonts))) - current)) - -(defn- get-prev-font - [{:keys [id] :as current} fonts] - (if (seq fonts) - (let [index (d/index-of-pred fonts #(= (:id %) id)) - next (ex/ignoring (nth fonts (dec index)))] - (or next (peek fonts))) - current)) - (mf/defc font-item* - {::mf/wrap [mf/memo]} + {::mf/wrap [mf/memo] + ::mf/private true} [{:keys [font is-current on-click style]}] (let [item-ref (mf/use-ref) on-click (mf/use-fn (mf/deps font) #(on-click font))] @@ -83,7 +67,7 @@ (declare row-renderer) -(defn filter-fonts +(defn- filter-fonts [{:keys [term backends]} fonts] (let [term (str/lower term) xform (cond-> (map identity) @@ -96,8 +80,7 @@ (mf/defc font-selector* [{:keys [on-select on-close current-font show-recent full-size]}] - (let [selected (mf/use-state current-font) - state* (mf/use-state + (let [state* (mf/use-state #(do {:term "" :backends #{}})) state (deref state*) @@ -112,23 +95,41 @@ recent-fonts (mf/with-memo [state recent-fonts] (filter-fonts state recent-fonts)) - full-size? (boolean (and full-size show-recent)) + ;; Combine recent fonts with filtered fonts, avoiding duplicates + combined-fonts + (mf/with-memo [recent-fonts fonts] + (let [recent-ids (into #{} d/xf:map-id recent-fonts)] + (into recent-fonts (remove #(contains? recent-ids (:id %))) fonts))) + + ;; Initialize selected with current font index + selected-index + (mf/use-state + (fn [] + (or (some (fn [[idx font]] + (when (= (:id current-font) (:id font)) idx)) + (map-indexed vector combined-fonts)) + 0))) + + full-size? + (boolean (and full-size show-recent)) select-next (mf/use-fn - (mf/deps fonts) + (mf/deps combined-fonts) (fn [event] (dom/stop-propagation event) (dom/prevent-default event) - (swap! selected get-next-font fonts))) + (let [next-idx (mod (inc @selected-index) (count combined-fonts))] + (reset! selected-index next-idx)))) select-prev (mf/use-fn - (mf/deps fonts) + (mf/deps combined-fonts) (fn [event] (dom/stop-propagation event) (dom/prevent-default event) - (swap! selected get-prev-font fonts))) + (let [prev-idx (mod (dec @selected-index) (count combined-fonts))] + (reset! selected-index prev-idx)))) on-select-and-close (mf/use-fn @@ -139,35 +140,32 @@ on-key-down (mf/use-fn - (mf/deps fonts) + (mf/deps combined-fonts) (fn [event] (cond (kbd/up-arrow? event) (select-prev event) (kbd/down-arrow? event) (select-next event) (kbd/esc? event) (on-close) - (kbd/enter? event) (do (on-select-and-close @selected)) + (kbd/enter? event) (do + (let [selected-font (nth combined-fonts @selected-index)] + (on-select-and-close selected-font))) :else (dom/focus! (mf/ref-val input))))) on-filter-change (mf/use-fn (fn [event] - (swap! state* assoc :term event))) - - on-select-and-close - (mf/use-fn - (mf/deps on-select on-close) - (fn [font] - (on-select font) - (on-close)))] + (swap! state* assoc :term event) + ;; Reset selection to first item when filter changes + (reset! selected-index 0)))] (mf/with-effect [fonts] (let [key (events/listen js/document "keydown" on-key-down)] #(events/unlistenByKey key))) - (mf/with-effect [@selected] + (mf/with-effect [@selected-index] (when-let [inst (mf/ref-val flist)] - (when-let [index (:index @selected)] - (.scrollToRow ^js inst index)))) + (when (and (>= @selected-index 0) (< @selected-index (count combined-fonts))) + (.scrollToRow ^js inst @selected-index)))) (mf/with-effect [] (st/emit! (dsc/push-shortcuts :typography {})) @@ -175,15 +173,12 @@ (st/emit! (dsc/pop-shortcuts :typography)))) (mf/with-effect [] - (let [index (d/index-of-pred fonts #(= (:id %) (:id current-font))) + (let [index (d/index-of-pred combined-fonts #(= (:id %) (:id current-font))) inst (mf/ref-val flist)] - (tm/schedule - #(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})] - (.scrollToPosition ^js inst offset))))) - - (mf/with-effect [(:term state) fonts] - (when (and (seq fonts) (not= (:id @selected) (:id (first fonts)))) - (reset! selected (first fonts)))) + (when (and index (>= index 0)) + (tm/schedule + #(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})] + (.scrollToPosition ^js inst offset)))))) [:div {:class (stl/css :font-selector)} [:div {:class (stl/css-case :font-selector-dropdown true :font-selector-dropdown-full-size full-size?)} @@ -200,7 +195,7 @@ :font font :style {} :on-click on-select-and-close - :is-current (= (:id font) (:id @selected))}])])] + :is-current (= idx @selected-index)}])])] [:div {:class (stl/css-case :fonts-list true :fonts-list-full-size full-size?)} @@ -208,17 +203,17 @@ (fn [props] (let [width (unchecked-get props "width") height (unchecked-get props "height") - render #(row-renderer fonts @selected on-select-and-close %)] + render #(row-renderer combined-fonts @selected-index on-select-and-close %)] (mf/html [:> rvt/List #js {:height height :ref flist :width width - :rowCount (count fonts) + :rowCount (count combined-fonts) :rowHeight 36 :rowRenderer render}])))]]]])) (defn row-renderer - [fonts selected on-select props] + [fonts selected-index on-select props] (let [index (unchecked-get props "index") key (unchecked-get props "key") style (unchecked-get props "style") @@ -228,7 +223,7 @@ :font font :style style :on-click on-select - :is-current (= (:id font) (:id selected))}]))) + :is-current (= index selected-index)}]))) (mf/defc font-options {::mf/wrap-props false} diff --git a/frontend/translations/en.po b/frontend/translations/en.po index b87261613b..dec86d9dab 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -4313,11 +4313,6 @@ msgstr "Please upgrade to match your usage. Contact with the team owner: %s" msgid "subscription.dashboard.power-up.enterprise-plan" msgstr "Enterprise plan" -#: src/app/main/ui/dashboard/subscription.cljs:77 -#, unused -msgid "subscription.dashboard.power-up.enterprise.description" -msgstr "Advanced security, activity logs, dedicated support and more." - #: src/app/main/ui/dashboard/subscription.cljs:60 #, markdown msgid "subscription.dashboard.power-up.professional.bottom" @@ -4357,9 +4352,9 @@ msgstr "Enterprise plan (trial)" #: src/app/main/ui/dashboard/subscription.cljs:74 #, markdown -msgid "subscription.dashboard.power-up.unlimited.bottom" +msgid "subscription.dashboard.power-up.unlimited.bottom-text" msgstr "" -"Get extra editors, more storage and backup, advanced security and more. " +"Get extra editors, more backup, unlimited storage and more. " "[Take a look to the Enterprise plan.|target:self](%s)" #: src/app/main/ui/dashboard/subscription.cljs:70 @@ -4417,9 +4412,8 @@ msgstr "Enterprise (trial)" msgid "subscription.settings.enterprise.unlimited-storage" msgstr "Unlimited storage and 90-day autosave versions and file recovery" -#: src/app/main/ui/settings/subscription.cljs:270, src/app/main/ui/settings/subscription.cljs:319 -msgid "subscription.settings.enterprise.security" -msgstr "Advanced security" +msgid "subscription.settings.enterprise.autosave" +msgstr "90-day autosave versions and file recovery" #: src/app/main/ui/settings/subscription.cljs:269, src/app/main/ui/settings/subscription.cljs:318 msgid "subscription.settings.enterprise.capped-bill" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 81a0621e99..3821c05bed 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -4340,11 +4340,6 @@ msgstr "Por favor, mejóralo para adaptarlo a tu uso. Contacta con el " msgid "subscription.dashboard.power-up.enterprise-plan" msgstr "Plan Enterprise" -#: src/app/main/ui/dashboard/subscription.cljs:77 -#, unused -msgid "subscription.dashboard.power-up.enterprise.description" -msgstr "Seguridad avanzada, registros de actividad, asistencia dedicada y mucho más." - #: src/app/main/ui/dashboard/subscription.cljs:60 #, markdown msgid "subscription.dashboard.power-up.professional.bottom" @@ -4388,9 +4383,9 @@ msgstr "Plan Unlimited" #: src/app/main/ui/dashboard/subscription.cljs:74 #, markdown -msgid "subscription.dashboard.power-up.unlimited.bottom" +msgid "subscription.dashboard.power-up.unlimited.bottom-text" msgstr "" -"Consigue editores adicionales, más almacenamiento y copias de seguridad, seguridad avanzada y mucho más. " +"Consigue editores adicionales, copias de seguridad, almacenamiento ilimitado y mucho más. " "[Echa un ojo al Plan Enterprise|target:self](%s)" #: src/app/main/ui/dashboard/subscription.cljs:70 @@ -4445,9 +4440,8 @@ msgstr "Enterprise (prueba)" msgid "subscription.settings.enterprise.unlimited-storage" msgstr "Almacenamiento ilimitado y versiones de autoguardado de 90 días y recuperación de archivos" -#: src/app/main/ui/settings/subscription.cljs:270, src/app/main/ui/settings/subscription.cljs:319 -msgid "subscription.settings.enterprise.security" -msgstr "Seguridad avanzada" +msgid "subscription.settings.enterprise.autosave" +msgstr "Versiones guardadas automáticamente cada 90 días y recuperación de archivos" #: src/app/main/ui/settings/subscription.cljs:269, src/app/main/ui/settings/subscription.cljs:318 msgid "subscription.settings.enterprise.capped-bill" diff --git a/manage.sh b/manage.sh index 90f69239b9..32b348ffe7 100755 --- a/manage.sh +++ b/manage.sh @@ -7,7 +7,7 @@ export DEVENV_PNAME="penpotdev"; export CURRENT_USER_ID=$(id -u); export CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD); -export IMAGEMAGICK_VERSION=7.1.1-47 +export IMAGEMAGICK_VERSION=7.1.2-0 # Safe directory to avoid ownership errors with Git git config --global --add safe.directory /home/penpot/penpot || true