diff --git a/CHANGES.md b/CHANGES.md index 7d44a95b8..acebd9e0d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,5 @@ # CHANGELOG # - ## :rocket: Next ### :sparkles: New features @@ -15,6 +14,25 @@ ### :boom: Breaking changes ### :heart: Community contributions by (Thank you!) +## 1.6.4-alpha + +### :sparkles: Minor improvements + +- Decrease default bulk buffers on storage tasks. +- Reduce file_change preserve interval to 24h. + +### :bug: Bugs fixed + +- Don't allow rename drafts project. +- Fix custom font deletion task. +- Fix custom font rendering on exporting shapes. +- Fix font loading on viewer app. +- Fix problem when moving files with drag & drop. +- Fix unexpected exception on searching without term. +- Properly handle nil values on `update-shapes` function. +- Replace frame term usage by artboard on viewer app. + + ## 1.6.3-alpha ### :bug: Bugs fixed diff --git a/backend/src/app/main.clj b/backend/src/app/main.clj index f0b9f6cc5..06765d5ff 100644 --- a/backend/src/app/main.clj +++ b/backend/src/app/main.clj @@ -245,7 +245,7 @@ :app.tasks.file-xlog-gc/handler {:pool (ig/ref :app.db/pool) - :max-age (dt/duration {:hours 48})} + :max-age (dt/duration {:hours 24})} :app.tasks.telemetry/handler {:pool (ig/ref :app.db/pool) diff --git a/backend/src/app/rpc/queries/files.clj b/backend/src/app/rpc/queries/files.clj index 3fa857892..dd36c6413 100644 --- a/backend/src/app/rpc/queries/files.clj +++ b/backend/src/app/rpc/queries/files.clj @@ -112,14 +112,16 @@ order by f.created_at asc") (s/def ::search-files - (s/keys :req-un [::profile-id ::team-id ::search-term])) + (s/keys :req-un [::profile-id ::team-id] + :opt-un [::search-term])) (sv/defmethod ::search-files [{:keys [pool] :as cfg} {:keys [profile-id team-id search-term] :as params}] - (db/exec! pool [sql:search-files - profile-id team-id - profile-id team-id - search-term])) + (when search-term + (db/exec! pool [sql:search-files + profile-id team-id + profile-id team-id + search-term]))) ;; --- Query: Files diff --git a/backend/src/app/rpc/queries/fonts.clj b/backend/src/app/rpc/queries/fonts.clj index b25c780f5..117de3e91 100644 --- a/backend/src/app/rpc/queries/fonts.clj +++ b/backend/src/app/rpc/queries/fonts.clj @@ -8,12 +8,16 @@ (:require [app.common.spec :as us] [app.db :as db] + [app.rpc.queries.files :as files] + [app.rpc.queries.projects :as projects] [app.rpc.queries.teams :as teams] [app.util.services :as sv] [clojure.spec.alpha :as s])) ;; --- Query: Team Font Variants +;; TODO: deprecated, should be removed on 1.7.x + (s/def ::team-id ::us/uuid) (s/def ::profile-id ::us/uuid) (s/def ::team-font-variants @@ -27,3 +31,43 @@ {:team-id team-id :deleted-at nil}))) +;; --- Query: Font Variants + +(s/def ::file-id ::us/uuid) +(s/def ::project-id ::us/uuid) +(s/def ::font-variants + (s/and + (s/keys :req-un [::profile-id] + :opt-un [::team-id + ::file-id + ::project-id]) + (fn [o] + (or (contains? o :team-id) + (contains? o :file-id) + (contains? o :project-id))))) + +(sv/defmethod ::font-variants + [{:keys [pool] :as cfg} {:keys [profile-id team-id file-id project-id] :as params}] + (with-open [conn (db/open pool)] + (cond + (uuid? team-id) + (do + (teams/check-read-permissions! conn profile-id team-id) + (db/query conn :team-font-variant + {:team-id team-id + :deleted-at nil})) + + (uuid? project-id) + (let [project (db/get-by-id conn :project project-id {:columns [:id :team-id]})] + (projects/check-read-permissions! conn profile-id project-id) + (db/query conn :team-font-variant + {:team-id (:team-id project) + :deleted-at nil})) + + (uuid? file-id) + (let [file (db/get-by-id conn :file file-id {:columns [:id :project-id]}) + project (db/get-by-id conn :project (:project-id file) {:columns [:id :team-id]})] + (files/check-read-permissions! conn profile-id file-id) + (db/query conn :team-font-variant + {:team-id (:team-id project) + :deleted-at nil}))))) diff --git a/backend/src/app/rpc/queries/viewer.clj b/backend/src/app/rpc/queries/viewer.clj index 3ed2bbbc5..f346e53ef 100644 --- a/backend/src/app/rpc/queries/viewer.clj +++ b/backend/src/app/rpc/queries/viewer.clj @@ -50,9 +50,14 @@ libs (files/retrieve-file-libraries conn false file-id) users (teams/retrieve-users conn (:team-id project)) + fonts (db/query conn :team-font-variant + {:team-id (:team-id project) + :deleted-at nil}) + bundle {:file file :page page :users users + :fonts fonts :project project :libraries libs}] diff --git a/backend/src/app/storage.clj b/backend/src/app/storage.clj index b67c2b215..0b1c1ffe1 100644 --- a/backend/src/app/storage.clj +++ b/backend/src/app/storage.clj @@ -319,7 +319,7 @@ where s.deleted_at is not null and s.deleted_at < (now() - ?::interval) order by s.deleted_at - limit 500 + limit 100 ) delete from storage_object where id in (select id from items_part) @@ -396,7 +396,7 @@ from storage_object as so where so.touched_at is not null order by so.touched_at - limit 500;") + limit 100;") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recheck Stalled Task diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index 3af771a22..cd78e72d9 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -350,8 +350,8 @@ ([shape {:keys [round-coords?] :or {round-coords? true}}] - (let [shape (apply-displacement shape) - center (gco/center-shape shape) + (let [shape (apply-displacement shape) + center (gco/center-shape shape) modifiers (:modifiers shape)] (if (and modifiers center) (let [transform (modifiers->transform center modifiers)] diff --git a/frontend/src/app/main/data/fonts.cljs b/frontend/src/app/main/data/fonts.cljs index e6cbfe815..5acec3b8d 100644 --- a/frontend/src/app/main/data/fonts.cljs +++ b/frontend/src/app/main/data/fonts.cljs @@ -25,7 +25,7 @@ ;; General purpose events & IMPL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defn team-fonts-loaded +(defn fonts-fetched [fonts] (letfn [;; Prepare font to the internal font database format. (prepare-font [[id [item :as items]]] @@ -74,8 +74,8 @@ (ptk/reify ::load-team-fonts ptk/WatchEvent (watch [_ state stream] - (->> (rp/query :team-font-variants {:team-id team-id}) - (rx/map team-fonts-loaded))))) + (->> (rp/query :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/viewer.cljs b/frontend/src/app/main/data/viewer.cljs index 99e42310e..c4eb65292 100644 --- a/frontend/src/app/main/data/viewer.cljs +++ b/frontend/src/app/main/data/viewer.cljs @@ -12,9 +12,10 @@ [app.common.spec :as us] [app.common.uuid :as uuid] [app.main.constants :as c] + [app.main.data.comments :as dcm] + [app.main.data.fonts :as df] [app.main.repo :as rp] [app.main.store :as st] - [app.main.data.comments :as dcm] [app.util.avatars :as avatars] [app.util.router :as rt] [beicon.core :as rx] @@ -97,7 +98,10 @@ :file-id file-id} (string? token) (assoc :token token))] (->> (rp/query :viewer-bundle params) - (rx/map bundle-fetched)))))) + (rx/mapcat + (fn [{:keys [fonts] :as bundle}] + (rx/of (df/fonts-fetched fonts) + (bundle-fetched bundle))))))))) (defn- extract-frames [objects] diff --git a/frontend/src/app/main/exports.cljs b/frontend/src/app/main/exports.cljs index 1496caaa2..760f2b5d4 100644 --- a/frontend/src/app/main/exports.cljs +++ b/frontend/src/app/main/exports.cljs @@ -7,27 +7,27 @@ (ns app.main.exports "The main logic for SVG export functionality." (:require - [rumext.alpha :as mf] - [cuerdas.core :as str] - [app.common.uuid :as uuid] - [app.common.pages :as cp] - [app.common.math :as mth] - [app.common.geom.shapes :as gsh] [app.common.geom.align :as gal] - [app.common.geom.point :as gpt] [app.common.geom.matrix :as gmt] - [app.util.timers :as ts] + [app.common.geom.point :as gpt] + [app.common.geom.shapes :as gsh] + [app.common.math :as mth] + [app.common.pages :as cp] + [app.common.uuid :as uuid] + [app.main.ui.shapes.circle :as circle] + [app.main.ui.shapes.embed :as embed] [app.main.ui.shapes.filters :as filters] [app.main.ui.shapes.frame :as frame] - [app.main.ui.shapes.circle :as circle] + [app.main.ui.shapes.group :as group] [app.main.ui.shapes.image :as image] [app.main.ui.shapes.path :as path] [app.main.ui.shapes.rect :as rect] - [app.main.ui.shapes.text :as text] - [app.main.ui.shapes.group :as group] - [app.main.ui.shapes.svg-raw :as svg-raw] [app.main.ui.shapes.shape :refer [shape-container]] - [app.main.ui.shapes.embed :as embed])) + [app.main.ui.shapes.svg-raw :as svg-raw] + [app.main.ui.shapes.text :as text] + [app.util.timers :as ts] + [cuerdas.core :as str] + [rumext.alpha :as mf])) (def ^:private default-color "#E8E9EA") ;; $color-canvas @@ -231,4 +231,3 @@ :xmlnsXlink "http://www.w3.org/1999/xlink" :xmlns "http://www.w3.org/2000/svg"} [:& wrapper {:shape group :view-box vbox}]])) - diff --git a/frontend/src/app/main/repo.cljs b/frontend/src/app/main/repo.cljs index bb3531d5c..cd79ddef7 100644 --- a/frontend/src/app/main/repo.cljs +++ b/frontend/src/app/main/repo.cljs @@ -19,7 +19,7 @@ (cond (= 204 status) ;; We need to send "something" so the streams listening downstream can act - (rx/of :empty) + (rx/of nil) (= 502 status) (rx/throw {:type :bad-gateway}) diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index b6a8b10d2..3afa25470 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -329,7 +329,7 @@ (fn [e] (reset! dragging? false) (when (not= selected-project project-id) - (let [data {:ids selected-files + (let [data {:ids (into #{} (keys selected-files)) :project-id project-id} mdata {:on-success on-drop-success}] (st/emit! (dd/move-files (with-meta data mdata)))))))] diff --git a/frontend/src/app/main/ui/dashboard/project_menu.cljs b/frontend/src/app/main/ui/dashboard/project_menu.cljs index 946478a09..8ea8b4132 100644 --- a/frontend/src/app/main/ui/dashboard/project_menu.cljs +++ b/frontend/src/app/main/ui/dashboard/project_menu.cljs @@ -79,7 +79,8 @@ :min-width? true :top top :left left - :options [[(tr "labels.rename") on-edit] + :options [(when-not (:is-default project) + [(tr "labels.rename") on-edit]) [(tr "dashboard.duplicate") on-duplicate] [(tr "dashboard.pin-unpin") toggle-pin] (when (seq teams) diff --git a/frontend/src/app/main/ui/render.cljs b/frontend/src/app/main/ui/render.cljs index c6853ecd2..628a8ddb1 100644 --- a/frontend/src/app/main/ui/render.cljs +++ b/frontend/src/app/main/ui/render.cljs @@ -12,8 +12,10 @@ [app.common.math :as mth] [app.common.pages :as cp] [app.common.uuid :as uuid] + [app.main.data.fonts :as df] [app.main.exports :as exports] [app.main.repo :as repo] + [app.main.store :as st] [app.main.ui.shapes.embed :as embed] [app.main.ui.shapes.filters :as filters] [app.main.ui.shapes.shape :refer [shape-container]] @@ -42,7 +44,6 @@ objects (reduce updt-fn objects mod-ids) object (get objects object-id) - {:keys [width height]} (gsh/points->selrect (:points object)) ;; We need to get the shadows/blurs paddings to create the viewbox properly @@ -80,6 +81,7 @@ :xmlnsXlink "http://www.w3.org/1999/xlink" :xmlns "http://www.w3.org/2000/svg" :xmlns:penpot "https://penpot.app/xmlns"} + (case (:type object) :frame [:& frame-wrapper {:shape object :view-box vbox}] :group [:> shape-container {:shape object} @@ -107,12 +109,19 @@ [{:keys [file-id page-id object-id] :as props}] (let [objects (mf/use-state nil)] (mf/use-effect - #(let [subs (->> (repo/query! :file {:id file-id}) - (rx/subs (fn [{:keys [data]}] - (let [objs (get-in data [:pages-index page-id :objects]) - objs (adapt-root-frame objs object-id)] - (reset! objects objs)))))] - (fn [] (rx/dispose! subs)))) + (mf/deps file-id page-id object-id) + (fn [] + (->> (rx/zip + (repo/query! :font-variants {:file-id file-id}) + (repo/query! :file {:id file-id})) + (rx/subs + (fn [[fonts {:keys [data]} :as kaka]] + (when (seq fonts) + (st/emit! (df/fonts-fetched fonts))) + (let [objs (get-in data [:pages-index page-id :objects]) + objs (adapt-root-frame objs object-id)] + (reset! objects objs))))) + (constantly nil))) (when @objects [:& object-svg {:objects @objects diff --git a/frontend/src/app/main/ui/viewer/thumbnails.cljs b/frontend/src/app/main/ui/viewer/thumbnails.cljs index f2942eae8..66bf403b0 100644 --- a/frontend/src/app/main/ui/viewer/thumbnails.cljs +++ b/frontend/src/app/main/ui/viewer/thumbnails.cljs @@ -75,7 +75,7 @@ (mf/defc thumbnails-summary [{:keys [on-toggle-expand on-close total] :as props}] [:div.thumbnails-summary - [:span.counter (str total " frames")] + [:span.counter (tr "labels.num-of-frames" (i18n/c total))] [:span.buttons [:span.btn-expand {:on-click on-toggle-expand} i/arrow-down] [:span.btn-close {:on-click on-close} i/close]]]) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 31d41d091..5434901e7 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -981,6 +981,11 @@ msgid_plural "labels.num-of-files" msgstr[0] "1 file" msgstr[1] "%s files" +msgid "labels.num-of-frames" +msgid_plural "labels.num-of-frames" +msgstr[0] "1 artboard" +msgstr[1] "%s artboards" + #: src/app/main/ui/dashboard/team.cljs msgid "labels.num-of-projects" msgid_plural "labels.num-of-projects" @@ -1438,11 +1443,11 @@ msgstr "%s - Penpot" #: src/app/main/ui/handoff.cljs, src/app/main/ui/viewer.cljs msgid "viewer.empty-state" -msgstr "No frames found on the page." +msgstr "No artboards found on the page." #: src/app/main/ui/handoff.cljs, src/app/main/ui/viewer.cljs msgid "viewer.frame-not-found" -msgstr "Frame not found." +msgstr "Artboard not found." #: src/app/main/ui/viewer/header.cljs msgid "viewer.header.dont-show-interactions" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index fd651a7cb..e1a658885 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -983,6 +983,11 @@ msgid_plural "labels.num-of-files" msgstr[0] "1 archivo" msgstr[1] "%s archivos" +msgid "labels.num-of-frames" +msgid_plural "labels.num-of-frames" +msgstr[0] "1 tablero" +msgstr[1] "%s tableros" + #: src/app/main/ui/dashboard/team.cljs msgid "labels.num-of-projects" msgid_plural "labels.num-of-projects"