diff --git a/CHANGES.md b/CHANGES.md index 71cecacf3b..aef519fab0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ ### :sparkles: New features +- Improve usage of file menu [Taiga #2853](https://tree.taiga.io/project/penpot/us/2853) - Rotation to snap to 15ยบ intervals with shift [Taiga #2437](https://tree.taiga.io/project/penpot/issue/2437) - Support border radius and stroke properties for images [Taiga #497](https://tree.taiga.io/project/penpot/us/497) - Disallow using same password as user email [Taiga #2454](https://tree.taiga.io/project/penpot/us/2454) @@ -54,8 +55,7 @@ - Fixed components get "dirty" marker when moved [Taiga #2764](https://tree.taiga.io/project/penpot/issue/2764) - Fixed cannot align objects in a group that is not part of a frame [Taiga #2762](https://tree.taiga.io/project/penpot/issue/2762) - Fix problem with double click on exit path editing [Taiga #2906](https://tree.taiga.io/project/penpot/issue/2906) - -### :arrow_up: Deps updates +- Fixed alignment of layers with children [Taiga #2862](https://tree.taiga.io/project/penpot/issue/2862) ### :heart: Community contributions by (Thank you!) diff --git a/backend/src/app/http/oauth.clj b/backend/src/app/http/oauth.clj index 21347f6881..17b3720686 100644 --- a/backend/src/app/http/oauth.clj +++ b/backend/src/app/http/oauth.clj @@ -24,6 +24,8 @@ [integrant.core :as ig] [promesa.exec :as px])) +;; TODO: make it fully async (?) + (defn- build-redirect-uri [{:keys [provider] :as cfg}] (let [public (u/uri (:public-uri cfg))] @@ -214,9 +216,9 @@ (redirect-response uri)))) (defn- auth-handler - [{:keys [tokens executors] :as cfg} {:keys [params] :as request} respond _] + [{:keys [tokens executor] :as cfg} {:keys [params] :as request} respond _] (px/run! - (:default executors) + executor (fn [] (let [invitation (:invitation-token params) props (extract-utm-props params) @@ -232,9 +234,9 @@ :body {:redirect-uri uri}}))))) (defn- callback-handler - [{:keys [executors] :as cfg} request respond _] + [{:keys [executor] :as cfg} request respond _] (px/run! - (:default executors) + executor (fn [] (try (let [info (retrieve-info cfg request) diff --git a/backend/src/app/main.clj b/backend/src/app/main.clj index 9eb424b6c0..6430a8e4ec 100644 --- a/backend/src/app/main.clj +++ b/backend/src/app/main.clj @@ -143,6 +143,7 @@ :pool (ig/ref :app.db/pool) :tokens (ig/ref :app.tokens/tokens) :audit (ig/ref :app.loggers.audit/collector) + :executor (ig/ref [::default :app.worker/executor]) :public-uri (cf/get :public-uri)} :app.rpc/rpc diff --git a/backend/src/app/storage.clj b/backend/src/app/storage.clj index 4891e338df..e084c46332 100644 --- a/backend/src/app/storage.clj +++ b/backend/src/app/storage.clj @@ -350,14 +350,15 @@ (retrieve-touched-chunk [conn cursor] (let [rows (->> (db/exec! conn [sql:retrieve-touched-objects-chunk cursor]) - (mapv #(d/update-when % :metadata db/decode-transit-pgobject)))] + (mapv #(d/update-when % :metadata db/decode-transit-pgobject))) + kw (fn [o] (if (keyword? o) o (keyword o)))] (when (seq rows) [(-> rows peek :created-at) ;; NOTE: we use the :file-media-object as default value for backward compatibility because when we ;; deploy it we can have old backend instances running in the same time as the new one and we can ;; still have storage-objects created without reference value. And we know that if it does not ;; have value, it means :file-media-object. - (d/group-by' #(or (-> % :metadata :reference) :file-media-object) :id rows)]))) + (d/group-by' #(or (some-> % :metadata :reference kw) :file-media-object) :id rows)]))) (retrieve-touched [conn] (->> (d/iteration (fn [cursor] @@ -391,7 +392,9 @@ (let [[f d] (case reference :file-media-object (process-objects! conn has-file-media-object-nrefs? ids) :team-font-variant (process-objects! conn has-team-font-variant-nrefs? ids) - (ex/raise :type :internal :code :unexpected-unknown-reference))] + (ex/raise :type :internal + :code :unexpected-unknown-reference + :hint (format "unknown reference %s" (pr-str reference))))] (recur (+ to-freeze f) (+ to-delete d) (rest groups))) diff --git a/common/src/app/common/geom/align.cljc b/common/src/app/common/geom/align.cljc index 11c8422c6c..19d91e7b27 100644 --- a/common/src/app/common/geom/align.cljc +++ b/common/src/app/common/geom/align.cljc @@ -6,7 +6,6 @@ (ns app.common.geom.align (:require - [app.common.data :as d] [app.common.geom.shapes :as gsh] [app.common.pages.helpers :refer [get-children]] [clojure.spec.alpha :as s])) @@ -20,8 +19,7 @@ (defn- recursive-move "Move the shape and all its recursive children." [shape dpoint objects] - (->> (get-children (:id shape) objects) - (map (d/getf objects)) + (->> (get-children objects (:id shape)) (cons shape) (map #(gsh/move % dpoint)))) diff --git a/frontend/resources/styles/main/partials/workspace-header.scss b/frontend/resources/styles/main/partials/workspace-header.scss index f2e20d65d6..3a5f1af69d 100644 --- a/frontend/resources/styles/main/partials/workspace-header.scss +++ b/frontend/resources/styles/main/partials/workspace-header.scss @@ -154,12 +154,22 @@ left: 40px; width: 183px; z-index: 12; - @include animation(0, 0.2s, fadeInDown); background-color: $color-white; border-radius: $br-small; box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); + :first-child { + &:hover { + border-radius: $br-small $br-small 0px 0px; + } + } + :last-child { + &:hover { + border-radius: 0px 0px $br-small $br-small; + } + } + li { cursor: pointer; font-size: $fs14; @@ -193,11 +203,21 @@ left: 230px; width: 270px; z-index: 12; - @include animation(0, 0.2s, fadeInDown); background-color: $color-white; border-radius: $br-small; box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); + :first-child { + &:hover { + border-radius: $br-small $br-small 0px 0px; + } + } + :last-child { + &:hover { + border-radius: 0px 0px $br-small $br-small; + } + } + &.file { top: 40px; } diff --git a/frontend/src/app/main/ui/workspace/header.cljs b/frontend/src/app/main/ui/workspace/header.cljs index 81d8a80f33..3d5169fb22 100644 --- a/frontend/src/app/main/ui/workspace/header.cljs +++ b/frontend/src/app/main/ui/workspace/header.cljs @@ -194,6 +194,13 @@ (st/emit! (dm/error (tr "errors.unexpected-error")))) (st/emitf dm/hide))))))) + on-item-hover + (mf/use-callback + (fn [item] + (fn [event] + (dom/stop-propagation event) + (reset! show-sub-menu? item)))) + on-item-click (mf/use-callback (fn [item] @@ -230,18 +237,23 @@ [:& dropdown {:show @show-menu? :on-close #(reset! show-menu? false)} [:ul.menu - [:li {:on-click (on-item-click :file)} + [:li {:on-click (on-item-click :file) + :on-pointer-enter (on-item-hover :file)} [:span (tr "workspace.header.menu.option.file")] [:span i/arrow-slide]] - [:li {:on-click (on-item-click :edit)} + [:li {:on-click (on-item-click :edit) + :on-pointer-enter (on-item-hover :edit)} [:span (tr "workspace.header.menu.option.edit")] [:span i/arrow-slide]] - [:li {:on-click (on-item-click :view)} + [:li {:on-click (on-item-click :view) + :on-pointer-enter (on-item-hover :view)} [:span (tr "workspace.header.menu.option.view")] [:span i/arrow-slide]] - [:li {:on-click (on-item-click :preferences)} + [:li {:on-click (on-item-click :preferences) + :on-pointer-enter (on-item-hover :preferences)} [:span (tr "workspace.header.menu.option.preferences")] [:span i/arrow-slide]] (when (contains? @cf/flags :user-feedback) [:* - [:li.feedback {:on-click (st/emitf (rt/nav :settings-feedback))} + [:li.feedback {:on-click (st/emitf (rt/nav :settings-feedback)) + :on-pointer-enter (st/emitf (rt/nav :settings-feedback))} [:span (tr "labels.give-feedback")]]])]] [:& dropdown {:show (= @show-sub-menu? :file) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index f27f39d9c0..38267e234c 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -2259,7 +2259,7 @@ msgstr "Fit - Scale down to fit" #: src/app/main/ui/workspace/header.cljs msgid "workspace.header.zoom-fit-all" -msgstr "Zoom to fil all" +msgstr "Zoom to fit all" #: src/app/main/ui/workspace/header.cljs msgid "workspace.header.zoom-full-screen"