From 24715a85e59915331f8fde5149dafe67b0f370ca Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 13 Jun 2023 09:57:05 +0200 Subject: [PATCH] :sparkles: Deleted fonts auto match --- frontend/src/app/main/data/workspace.cljs | 2 + .../data/workspace/fix_deleted_fonts.cljs | 129 ++++++++++++++++++ frontend/translations/en.po | 2 +- frontend/translations/es.po | 2 +- 4 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 792288feb..4ce4dc2ee 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -44,6 +44,7 @@ [app.main.data.workspace.drawing.common :as dwdc] [app.main.data.workspace.edition :as dwe] [app.main.data.workspace.fix-bool-contents :as fbc] + [app.main.data.workspace.fix-deleted-fonts :as fdf] [app.main.data.workspace.groups :as dwg] [app.main.data.workspace.guides :as dwgu] [app.main.data.workspace.highlight :as dwh] @@ -131,6 +132,7 @@ components-v2 (features/active-feature? state :components-v2)] (rx/merge (rx/of (fbc/fix-bool-contents)) + (rx/of (fdf/fix-deleted-fonts)) (if (and has-graphics? components-v2) (rx/of (remove-graphics (:id file) (:name file))) (rx/empty))))))) diff --git a/frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs b/frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs new file mode 100644 index 000000000..05b4a13da --- /dev/null +++ b/frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs @@ -0,0 +1,129 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.data.workspace.fix-deleted-fonts + (:require + [app.common.data :as d] + [app.common.pages.helpers :as cph] + [app.common.text :as txt] + [app.main.data.workspace.changes :as dch] + [app.main.data.workspace.state-helpers :as wsh] + [app.main.fonts :as fonts] + [beicon.core :as rx] + [potok.core :as ptk])) + +;; This event will update the file so the texts with non existing custom fonts try to be fixed. +;; This can happen when: +;; - Exporting/importing files to different teams or penpot instances +;; - Moving files from one team to another in the same instance +;; - Custom fonts are explicitly deleted in the team area + +(defn has-invalid-font-family + [node] + (let [fonts (deref fonts/fontsdb)] + (and + (some? (:font-family node)) + (nil? (get fonts (:font-id node)))))) + +(defn calculate-alternative-font-id + [value] + (let [fonts (deref fonts/fontsdb)] + (->> (vals fonts) + (filter #(= (:family %) value)) + (first) + :id))) + +(defn should-fix-deleted-font-shape? + [shape] + (let [text-nodes (txt/node-seq txt/is-text-node? (:content shape))] + (and (cph/text-shape? shape) (some has-invalid-font-family text-nodes)))) + +(defn should-fix-deleted-font-component? + [component] + (->> (:objects component) + (vals) + (d/seek should-fix-deleted-font-shape?))) + +(defn should-fix-deleted-font-typography? + [typography] + (let [fonts (deref fonts/fontsdb)] + (nil? (get fonts (:font-id typography))))) + +(defn fix-deleted-font + [node] + (let [alternative-font-id (calculate-alternative-font-id (:font-family node))] + (cond-> node + (some? alternative-font-id) (assoc :font-id alternative-font-id)))) + +(defn fix-deleted-font-shape + [shape] + (let [transform (partial txt/transform-nodes has-invalid-font-family fix-deleted-font)] + (update shape :content transform))) + +(defn fix-deleted-font-component + [component] + (update component + :objects + (fn [objects] + (d/mapm #(fix-deleted-font-shape %2) objects)))) + +(defn fix-deleted-font-typography + [typography] + (let [alternative-font-id (calculate-alternative-font-id (:font-family typography))] + (cond-> typography + (some? alternative-font-id) (assoc :font-id alternative-font-id)))) + +(defn fix-deleted-fonts + [] + (ptk/reify ::fix-deleted-fonts + ptk/WatchEvent + (watch [it state _] + (let [objects (wsh/lookup-page-objects state) + + ids (into #{} + (comp (filter should-fix-deleted-font-shape?) (map :id)) + (vals objects)) + + components (->> (wsh/lookup-local-components state) + (vals) + (filter should-fix-deleted-font-component?)) + + component-changes + (into [] + (map (fn [component] + {:type :mod-component + :id (:id component) + :objects (-> (fix-deleted-font-component component) :objects)})) + components) + + typographies (->> (get-in state [:workspace-data :typographies]) + (vals) + (filter should-fix-deleted-font-typography?)) + + typography-changes + (into [] + (map (fn [typography] + {:type :mod-typography + :typography (fix-deleted-font-typography typography)})) + typographies)] + + (rx/concat + (rx/of (dch/update-shapes ids #(fix-deleted-font-shape %) {:reg-objects? false + :save-undo? false + :ignore-tree true})) + (if (empty? component-changes) + (rx/empty) + (rx/of (dch/commit-changes {:origin it + :redo-changes component-changes + :undo-changes [] + :save-undo? false}))) + + (if (empty? typography-changes) + (rx/empty) + (rx/of (dch/commit-changes {:origin it + :redo-changes typography-changes + :undo-changes [] + :save-undo? false})))))))) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 3b81dae37..7376e687f 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -387,7 +387,7 @@ msgid "dashboard.export.title" msgstr "Export files" msgid "dashboard.fonts.deleted-placeholder" -msgstr "Font deleted" +msgstr "Missing font" #: src/app/main/ui/dashboard/fonts.cljs msgid "dashboard.fonts.dismiss-all" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index a694a16f3..f201c633d 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -393,7 +393,7 @@ msgid "dashboard.export.title" msgstr "Exportar ficheros" msgid "dashboard.fonts.deleted-placeholder" -msgstr "Fuente eliminada" +msgstr "Fuente no encontrada" #: src/app/main/ui/dashboard/fonts.cljs msgid "dashboard.fonts.dismiss-all"