diff --git a/CHANGES.md b/CHANGES.md index e475213f0..7374f17af 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -58,6 +58,10 @@ - Fix ungroup does not work for typographies [Taiga #4195](https://tree.taiga.io/project/penpot/issue/4195) - Fix inviting to non existing users can fail [Taiga #4108](https://tree.taiga.io/project/penpot/issue/4108) - Fix components marked as touched when moved [Taiga #4061](https://tree.taiga.io/project/penpot/task/4061) +- Fix boards grouped shouldn't show the title [Taiga #4251](https://tree.taiga.io/project/penpot/issue/4251) +- Fix gradient handlers are under resize handlers[Taiga #4298](https://tree.taiga.io/project/penpot/issue/4298) +- Fix grid not syncing immediately in multiuser [Taiga #4339](https://tree.taiga.io/project/penpot/issue/4339) +- Fix custom font upload fails silently for unsupported formats [Taiga #4279](https://tree.taiga.io/project/penpot/issue/4280) ### :arrow_up: Deps updates ### :heart: Community contributions by (Thank you!) @@ -72,6 +76,8 @@ - Fix artboard border radius [Taiga #4291](https://tree.taiga.io/project/penpot/issue/4291) - Fix copied & pasted layer is not visible [Taiga #4283](https://tree.taiga.io/project/penpot/issue/4283) +- Fix notification to newsletter is shown in all cases [Taiga #4367](https://tree.taiga.io/project/penpot/issue/4367) +- Fix comments section is not scrolling by mouse wheel [Taiga #4305](https://tree.taiga.io/project/penpot/issue/4305) ## 1.15.4-beta diff --git a/backend/src/app/rpc/commands/binfile.clj b/backend/src/app/rpc/commands/binfile.clj index 013beac9f..8144b7464 100644 --- a/backend/src/app/rpc/commands/binfile.clj +++ b/backend/src/app/rpc/commands/binfile.clj @@ -634,7 +634,7 @@ params {:id file-id' :project-id project-id - :name (str "Imported: " (:name file)) + :name (:name file) :revn (:revn file) :is-shared (:is-shared file) :data (blob/encode data) diff --git a/frontend/resources/images/icons/actions.svg b/frontend/resources/images/icons/actions.svg index 7e71052a5..30eedf85b 100644 --- a/frontend/resources/images/icons/actions.svg +++ b/frontend/resources/images/icons/actions.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/frontend/resources/styles/main/partials/dashboard-grid.scss b/frontend/resources/styles/main/partials/dashboard-grid.scss index 64341c9bb..367531338 100644 --- a/frontend/resources/styles/main/partials/dashboard-grid.scss +++ b/frontend/resources/styles/main/partials/dashboard-grid.scss @@ -43,6 +43,13 @@ text-align: initial; } + &.dragged { + border-radius: $br-small; + border: 2px solid lighten($color-gray-20, 15%); + text-align: initial; + max-height: 160px; + } + &.placeholder { min-width: 115px; max-width: 115px; @@ -127,6 +134,9 @@ width: 100%; white-space: nowrap; max-width: 260px; + &::first-letter { + text-transform: capitalize; + } @media #{$bp-max-1366} { max-width: 230px; } diff --git a/frontend/resources/styles/main/partials/viewer.scss b/frontend/resources/styles/main/partials/viewer.scss index 784141c4b..97d6c77d0 100644 --- a/frontend/resources/styles/main/partials/viewer.scss +++ b/frontend/resources/styles/main/partials/viewer.scss @@ -25,6 +25,12 @@ } } +.viewer-loader { + svg#loader-pencil { + fill: $color-gray-50; + } +} + .viewer-section { height: calc(100vh - 48px); grid-row: 1 / span 2; diff --git a/frontend/src/app/main/data/fonts.cljs b/frontend/src/app/main/data/fonts.cljs index c46cc6577..b9ac00443 100644 --- a/frontend/src/app/main/data/fonts.cljs +++ b/frontend/src/app/main/data/fonts.cljs @@ -12,8 +12,11 @@ [app.common.media :as cm] [app.common.spec :as us] [app.common.uuid :as uuid] + [app.main.data.messages :as dm] [app.main.fonts :as fonts] [app.main.repo :as rp] + [app.main.store :as st] + [app.util.i18n :refer [tr]] [app.util.storage :refer [storage]] [app.util.webapi :as wa] [beicon.core :as rx] @@ -133,17 +136,35 @@ {:data data :name (.-name blob) :type (parse-mtype data)})) - (rx/mapcat (fn [{:keys [type] :as font}] - (if type + (rx/catch (fn [] + (rx/of {:error (.-name blob)}))) + (rx/mapcat (fn [{:keys [type, error] :as font}] + (if (or type error) (rx/of font) (rx/empty))))))] - (->> (rx/from blobs) - (rx/mapcat read-blob) - (rx/map parse-font) - (rx/filter some?) - (rx/map prepare) - (rx/reduce join {})))) + (let [fonts (->> (rx/from blobs) + (rx/mapcat read-blob)) + errors (->> fonts + (rx/filter #(some? (:error %))) + (rx/reduce (fn [acc font] + (conj acc (str "'" (:error font) "'"))) + []))] + + (rx/subscribe errors + #(when + (not-empty %) + (st/emit! + (dm/error + (if (> (count %) 1) + (tr "errors.bad-font-plural" (str/join ", " %)) + (tr "errors.bad-font" (first %))))))) + (->> fonts + (rx/filter #(nil? (:error %))) + (rx/map parse-font) + (rx/filter some?) + (rx/map prepare) + (rx/reduce join {}))))) (defn- calculate-family-to-id-mapping [existing] diff --git a/frontend/src/app/main/data/workspace/path/edition.cljs b/frontend/src/app/main/data/workspace/path/edition.cljs index 46617ec06..7ecf800c8 100644 --- a/frontend/src/app/main/data/workspace/path/edition.cljs +++ b/frontend/src/app/main/data/workspace/path/edition.cljs @@ -204,7 +204,8 @@ (watch [_ state stream] (let [id (get-in state [:workspace-local :edition]) current-move (get-in state [:workspace-local :edit-path id :current-move])] - (if (= same-event current-move) + ;; id can be null if we just selected the tool but we didn't start drawing + (if (and id (= same-event current-move)) (let [points (get-in state [:workspace-local :edit-path id :selected-points] #{}) move-events (->> stream diff --git a/frontend/src/app/main/data/workspace/persistence.cljs b/frontend/src/app/main/data/workspace/persistence.cljs index 421a5dba2..f5b2ec567 100644 --- a/frontend/src/app/main/data/workspace/persistence.cljs +++ b/frontend/src/app/main/data/workspace/persistence.cljs @@ -12,6 +12,7 @@ [app.common.pages.changes-spec :as pcs] [app.common.spec :as us] [app.common.types.file :as ctf] + [app.common.types.shape-tree :as ctst] [app.common.uuid :as uuid] [app.config :as cf] [app.main.data.dashboard :as dd] @@ -219,14 +220,23 @@ (ptk/reify ::changes-persisted ptk/UpdateEvent (update [_ state] - (if (= file-id (:current-file-id state)) - (-> state - (update-in [:workspace-file :revn] max revn) - (update :workspace-data cp/process-changes changes)) - (-> state - (update-in [:workspace-libraries file-id :revn] max revn) - (update-in [:workspace-libraries file-id :data] - cp/process-changes changes)))))) + (let [changes (group-by :page-id changes)] + (if (= file-id (:current-file-id state)) + (-> state + (update-in [:workspace-file :revn] max revn) + (update :workspace-data (fn [file] + (loop [fdata file + entries (seq changes)] + (if-let [[page-id changes] (first entries)] + (recur (-> fdata + (cp/process-changes changes) + (ctst/update-object-indices page-id)) + (rest entries)) + fdata))))) + (-> state + (update-in [:workspace-libraries file-id :revn] max revn) + (update-in [:workspace-libraries file-id :data] + cp/process-changes changes))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/frontend/src/app/main/ui/dashboard/fonts.cljs b/frontend/src/app/main/ui/dashboard/fonts.cljs index 286224208..80e05287b 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.cljs +++ b/frontend/src/app/main/ui/dashboard/fonts.cljs @@ -303,8 +303,7 @@ [:div.table-field.search-input [:input {:placeholder (tr "labels.search-font") :default-value "" - :on-change on-change - }]]] + :on-change on-change}]]] (cond (seq fonts) diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index 83df57226..0a5c23994 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -163,7 +163,7 @@ (let [locale (mf/deref i18n/locale) time (dt/timeago modified-at {:locale locale})] [:span.date - (str (tr "ds.updated-at" time))])) + time])) (defn create-counter-element [_element file-count] @@ -390,12 +390,13 @@ (mf/defc line-grid-row [{:keys [files selected-files dragging? limit] :as props}] - (let [limit (if dragging? (dec limit) limit)] + (let [elements limit + limit (if dragging? (dec limit) limit)] [:div.grid-row.no-wrap - {:style {:grid-template-columns (dm/str "repeat(" limit ", 1fr)")}} + {:style {:grid-template-columns (dm/str "repeat(" elements ", 1fr)")}} (when dragging? - [:div.grid-item]) + [:div.grid-item.dragged]) (for [item (take limit files)] [:& grid-item {:id (:id item) diff --git a/frontend/src/app/main/ui/onboarding/newsletter.cljs b/frontend/src/app/main/ui/onboarding/newsletter.cljs index 358ab0783..27dd432ae 100644 --- a/frontend/src/app/main/ui/onboarding/newsletter.cljs +++ b/frontend/src/app/main/ui/onboarding/newsletter.cljs @@ -30,9 +30,10 @@ (mf/use-callback (mf/deps @newsletter-updates @newsletter-news) (fn [] - (st/emit! (dm/success message) - (modal/show {:type :onboarding-team}) - (du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))] + (st/emit! (when (or @newsletter-updates @newsletter-news) + (dm/success message)) + (modal/show {:type :onboarding-team}) + (du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))] [:div.modal-overlay [:div.modal-container.onboarding.newsletter.animated.fadeInDown diff --git a/frontend/src/app/main/ui/viewer.cljs b/frontend/src/app/main/ui/viewer.cljs index 99762cf73..ce5eb322a 100644 --- a/frontend/src/app/main/ui/viewer.cljs +++ b/frontend/src/app/main/ui/viewer.cljs @@ -534,9 +534,11 @@ (fn [] (st/emit! (dv/finalize props))))) - (when-let [data (mf/deref refs/viewer-data)] + (if-let [data (mf/deref refs/viewer-data)] (let [key (str (get-in data [:file :id]))] - [:& viewer {:params props :data data :key key}]))) + [:& viewer {:params props :data data :key key}]) + [:div.loader-content.viewer-loader + i/loader-pencil])) (mf/defc breaking-change-notice [] diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 46ad6bdb9..2d2be20f9 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -96,7 +96,6 @@ ;; REFS viewport-ref (mf/use-ref nil) - overlays-ref (mf/use-ref nil) ;; VARS disable-paste (mf/use-var false) @@ -184,7 +183,7 @@ disabled-guides? (or drawing-tool transform)] - (hooks/setup-dom-events viewport-ref overlays-ref zoom disable-paste in-viewport?) + (hooks/setup-dom-events viewport-ref zoom disable-paste in-viewport?) (hooks/setup-viewport-size viewport-ref) (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing?) (hooks/setup-keyboard alt? mod? space?) @@ -194,7 +193,7 @@ (hooks/setup-active-frames base-objects hover-ids selected active-frames zoom transform vbox) [:div.viewport - [:div.viewport-overlays {:ref overlays-ref} + [:div.viewport-overlays ;; The behaviour inside a foreign object is a bit different that in plain HTML so we wrap ;; inside a foreign object "dummy" so this awkward behaviour is take into account [:svg {:style {:top 0 :left 0 :position "fixed" :width "100%" :height "100%" :opacity 0}} @@ -337,11 +336,6 @@ :on-frame-leave on-frame-leave :on-frame-select on-frame-select}]) - (when show-gradient-handlers? - [:& gradients/gradient-handlers - {:id (first selected) - :zoom zoom}]) - (when show-draw-area? [:& drawarea/draw-area {:shape drawing-obj @@ -441,4 +435,9 @@ :zoom zoom :objects objects-modified :current-transform transform - :hover-disabled? hover-disabled?}])])]]])) + :hover-disabled? hover-disabled?}])]) + + (when show-gradient-handlers? + [:& gradients/gradient-handlers + {:id (first selected) + :zoom zoom}])]]])) diff --git a/frontend/src/app/main/ui/workspace/viewport/actions.cljs b/frontend/src/app/main/ui/workspace/viewport/actions.cljs index f0a5658cd..bbf0c740b 100644 --- a/frontend/src/app/main/ui/workspace/viewport/actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/actions.cljs @@ -359,18 +359,16 @@ pt (utils/translate-point-to-viewport viewport zoom raw-pt)] (rx/push! move-stream pt))))) -(defn on-mouse-wheel [viewport-ref overlays-ref zoom] +(defn on-mouse-wheel [viewport-ref zoom] (mf/use-callback (mf/deps zoom) (fn [event] (let [viewport (mf/ref-val viewport-ref) - overlays (mf/ref-val overlays-ref) event (.getBrowserEvent ^js event) target (dom/get-target event) mod? (kbd/mod? event)] - (when (or (dom/is-child? viewport target) - (dom/is-child? overlays target)) + (when (dom/is-child? viewport target) (dom/prevent-default event) (dom/stop-propagation event) (let [pt (->> (dom/get-client-position event) diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index 4d28abb2a..c9071afc8 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -31,11 +31,11 @@ [rumext.v2 :as mf]) (:import goog.events.EventType)) -(defn setup-dom-events [viewport-ref overlays-ref zoom disable-paste in-viewport?] +(defn setup-dom-events [viewport-ref zoom disable-paste in-viewport?] (let [on-key-down (actions/on-key-down) on-key-up (actions/on-key-up) on-mouse-move (actions/on-mouse-move viewport-ref zoom) - on-mouse-wheel (actions/on-mouse-wheel viewport-ref overlays-ref zoom) + on-mouse-wheel (actions/on-mouse-wheel viewport-ref zoom) on-paste (actions/on-paste disable-paste in-viewport?)] (mf/use-layout-effect (mf/deps on-key-down on-key-up on-mouse-move on-mouse-wheel on-paste) diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index 9b0447b0a..1d85295f6 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -167,7 +167,7 @@ [:g.frame-titles (for [frame frames] - (when (= (:frame-id frame) uuid/zero) + (when (= (:parent-id frame) uuid/zero) [:& frame-title {:key (dm/str "frame-title-" (:id frame)) :frame frame :selected? (contains? selected (:id frame)) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 111305408..c60ec067c 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -337,7 +337,7 @@ msgstr "Export Penpot %s files" #: src/app/main/ui/export.cljs msgid "dashboard.export-multiple.selected" -msgstr "%s de %s elements selected" +msgstr "%s of %s elements selected" #: src/app/main/ui/workspace/header.cljs msgid "dashboard.export-shapes" @@ -4563,4 +4563,13 @@ msgid "workspace.updates.update" msgstr "Update" msgid "workspace.viewport.click-to-close-path" -msgstr "Click to close the path" \ No newline at end of file +msgstr "Click to close the path" + +msgid "errors.profile-blocked" +msgstr "The profile is blocked" + +msgid "errors.bad-font" +msgstr "The font %s could not be loaded" + +msgid "errors.bad-font-plural" +msgstr "The fonts %s could not be loaded" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 2fe5b5bbe..9c0c2ea1f 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -4778,4 +4778,13 @@ msgid "workspace.updates.update" msgstr "Actualizar" msgid "workspace.viewport.click-to-close-path" -msgstr "Pulsar para cerrar la ruta" \ No newline at end of file +msgstr "Pulsar para cerrar la ruta" + +msgid "errors.profile-blocked" +msgstr "El perfil esta blockeado" + +msgid "errors.bad-font" +msgstr "No se ha podido cargar la fuente %s" + +msgid "errors.bad-font-plural" +msgstr "No se han podido cargar las fuentes %s"