diff --git a/.github/workflows/build-tag.yml b/.github/workflows/build-tag.yml index 80ef7bcaeb..c32e363888 100644 --- a/.github/workflows/build-tag.yml +++ b/.github/workflows/build-tag.yml @@ -33,7 +33,7 @@ jobs: MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK }} MATTERMOST_CHANNEL: bot-alerts-cicd TEXT: | - 🐳 *[PENPOT] Docker image available: {{ github.ref_name }}* + 🐳 *[PENPOT] Docker image available: ${{ github.ref_name }}* 🔗 Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} @infra diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0d1e008d21..c4e715e55a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ concurrency: jobs: lint: name: "Linter" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest steps: @@ -34,7 +34,7 @@ jobs: test-common: name: "Common Tests" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest steps: @@ -53,7 +53,8 @@ jobs: test-plugins: name: Plugins Runtime Linter & Tests - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 + container: penpotapp/devenv:latest steps: - uses: actions/checkout@v4 @@ -98,7 +99,7 @@ jobs: test-frontend: name: "Frontend Tests" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest steps: @@ -119,7 +120,7 @@ jobs: test-render-wasm: name: "Render WASM Tests" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest steps: @@ -143,7 +144,7 @@ jobs: test-backend: name: "Backend Tests" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest services: @@ -182,7 +183,7 @@ jobs: test-library: name: "Library Tests" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest steps: @@ -196,7 +197,7 @@ jobs: build-integration: name: "Build Integration Bundle" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest steps: @@ -217,7 +218,7 @@ jobs: test-integration-1: name: "Integration Tests 1/4" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest needs: build-integration @@ -247,7 +248,7 @@ jobs: test-integration-2: name: "Integration Tests 2/4" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest needs: build-integration @@ -277,7 +278,7 @@ jobs: test-integration-3: name: "Integration Tests 3/4" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest needs: build-integration @@ -307,7 +308,7 @@ jobs: test-integration-4: name: "Integration Tests 4/4" - runs-on: ubuntu-24.04 + runs-on: penpot-runner-02 container: penpotapp/devenv:latest needs: build-integration diff --git a/CHANGES.md b/CHANGES.md index bca9e9f17b..3cefb829b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -33,6 +33,11 @@ - Fix unhandled exception tokens creation dialog [Github #8110](https://github.com/penpot/penpot/issues/8110) - Fix allow negative spread values on shadow token creation [Taiga #13167](https://tree.taiga.io/project/penpot/issue/13167) - Fix spanish translations on import export token modal [Taiga #13171](https://tree.taiga.io/project/penpot/issue/13171) +- Remove whitespaces from asset export filename [Github #8133](https://github.com/penpot/penpot/pull/8133) +- Fix exception on uploading large fonts [Github #8135](https://github.com/penpot/penpot/pull/8135) +- Fix unhandled exception on open-new-window helper [Github #7787](https://github.com/penpot/penpot/issues/7787) +- Fix incorrect handling of input values on layout gap and padding inputs [Github #8113](https://github.com/penpot/penpot/issues/8113) + ## 2.12.1 diff --git a/backend/src/app/rpc/commands/fonts.clj b/backend/src/app/rpc/commands/fonts.clj index 05454d6698..8ca20eac49 100644 --- a/backend/src/app/rpc/commands/fonts.clj +++ b/backend/src/app/rpc/commands/fonts.clj @@ -27,7 +27,17 @@ [app.rpc.helpers :as rph] [app.rpc.quotes :as quotes] [app.storage :as sto] - [app.util.services :as sv])) + [app.storage.tmp :as tmp] + [app.util.services :as sv] + [datoteka.io :as io]) + (:import + java.io.InputStream + java.io.OutputStream + java.io.SequenceInputStream + java.util.Collections)) + +(set! *warn-on-reflection* true) + (def valid-weight #{100 200 300 400 500 600 700 800 900 950}) (def valid-style #{"normal" "italic"}) @@ -105,7 +115,7 @@ (defn create-font-variant [{:keys [::sto/storage ::db/conn]} {:keys [data] :as params}] - (letfn [(generate-missing! [data] + (letfn [(generate-missing [data] (let [data (media/run {:cmd :generate-fonts :input data})] (when (and (not (contains? data "font/otf")) (not (contains? data "font/ttf")) @@ -116,8 +126,26 @@ :hint "invalid font upload, unable to generate missing font assets")) data)) + (process-chunks [chunks] + (let [tmp (tmp/tempfile :prefix "penpot.tempfont." :suffix "") + streams (map io/input-stream chunks) + streams (Collections/enumeration streams)] + (with-open [^OutputStream output (io/output-stream tmp) + ^InputStream input (SequenceInputStream. streams)] + (io/copy input output)) + tmp)) + + (join-chunks [data] + (reduce-kv (fn [data mtype content] + (if (vector? content) + (assoc data mtype (process-chunks content)) + data)) + data + data)) + (prepare-font [data mtype] (when-let [resource (get data mtype)] + (let [hash (sto/calculate-hash resource) content (-> (sto/content resource) (sto/wrap-with-hash hash))] @@ -156,7 +184,8 @@ :otf-file-id (:id otf) :ttf-file-id (:id ttf)}))] - (let [data (generate-missing! data) + (let [data (join-chunks data) + data (generate-missing data) assets (persist-fonts-files! data) result (insert-font-variant! assets)] (vary-meta result assoc ::audit/replace-props (update params :data (comp vec keys)))))) diff --git a/exporter/src/app/handlers/resources.cljs b/exporter/src/app/handlers/resources.cljs index 8b0a55ba35..5394e673a8 100644 --- a/exporter/src/app/handlers/resources.cljs +++ b/exporter/src/app/handlers/resources.cljs @@ -36,7 +36,7 @@ {:path path :mtype (mime/get type) :name name - :filename (str/concat name (mime/get-extension type)) + :filename (str/concat (str/slug name) (mime/get-extension type)) :id task-id})) (defn create-zip diff --git a/frontend/src/app/main/data/fonts.cljs b/frontend/src/app/main/data/fonts.cljs index 4706e7c5c3..4efa40718f 100644 --- a/frontend/src/app/main/data/fonts.cljs +++ b/frontend/src/app/main/data/fonts.cljs @@ -24,6 +24,20 @@ [cuerdas.core :as str] [potok.v2.core :as ptk])) +(def ^:const default-chunk-size + (* 1024 1024 4)) ;; 4MiB + +(defn- chunk-array + [data chunk-size] + (let [total-size (alength data)] + (loop [offset 0 + chunks []] + (if (< offset total-size) + (let [end (min (+ offset chunk-size) total-size) + chunk (.subarray ^js data offset end)] + (recur end (conj chunks chunk))) + chunks)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; General purpose events & IMPL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -116,9 +130,9 @@ (not= hhea-descender win-descent) (and f-selection (or (not= hhea-ascender os2-ascent) - (not= hhea-descender os2-descent))))] - - {:content {:data (js/Uint8Array. data) + (not= hhea-descender os2-descent)))) + data (js/Uint8Array. data)] + {:content {:data (chunk-array data default-chunk-size) :name name :type type} :font-family (or family "") diff --git a/frontend/src/app/main/ui/dashboard/team.scss b/frontend/src/app/main/ui/dashboard/team.scss index 90e33f5cca..259fdeb565 100644 --- a/frontend/src/app/main/ui/dashboard/team.scss +++ b/frontend/src/app/main/ui/dashboard/team.scss @@ -628,6 +628,7 @@ width: $sz-400; padding: var(--sp-xxxl); background-color: var(--color-background-primary); + z-index: var(--z-index-set); &.hero { top: px2rem(216); diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index 320abd7d18..e89033964d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -375,7 +375,7 @@ (mf/use-fn (mf/deps on-change ids) (fn [value attr event] - (if (or (string? value) (int? value)) + (if (or (string? value) (number? value)) (on-change :simple attr value event) (do (let [resolved-value (:resolved-value (first value)) @@ -489,7 +489,7 @@ (mf/use-fn (mf/deps on-change ids) (fn [value attr event] - (if (or (string? value) (int? value)) + (if (or (string? value) (number? value)) (on-change :multiple attr value event) (do (let [resolved-value (:resolved-value (first value))] @@ -724,7 +724,7 @@ (mf/use-fn (mf/deps on-change wrap-type ids) (fn [value event attr] - (if (or (string? value) (int? value)) + (if (or (string? value) (number? value)) (on-change (= "nowrap" wrap-type) attr value event) (do (let [resolved-value (:resolved-value (first value))] diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index 2faa6cc1c0..e22de0dbba 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -802,9 +802,10 @@ ([uri name] (open-new-window uri name "noopener,noreferrer")) ([uri name features] - (let [new-window (.open js/window (str uri) name features)] + (when-let [new-window (.open js/window (str uri) name features)] (when (not= name "_blank") - (.reload (.-location new-window)))))) + (when-let [location (.-location new-window)] + (.reload location)))))) (defn browser-back []