From 3cce47094eef50990e018f457284d03c9c869429 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 28 May 2026 15:51:46 +0200 Subject: [PATCH] :recycle: Refactor font upload to process variants sequentially (#9921) * :recycle: Refactor font upload to process variants sequentially Change the batch upload handler so fonts are uploaded one at a time instead of all concurrently, preventing excessive simultaneous upload requests. Previously `on-upload-all` used `run!` which fired all font variant uploads simultaneously. Now it uses `rx/from` combined with `rx/mapcat` to process each font sequentially. As part of this change, extract the upload logic into a standalone `handle-font-upload` helper for reuse between single and batch upload paths, and remove the separately memoized `on-upload*` hook. Also fix error logging to use `js/console.error` instead of `js/console.log` for consistency with project conventions. Signed-off-by: Andrey Antukh * :paperclip: Add code comment Signed-off-by: Andrey Antukh --------- Signed-off-by: Andrey Antukh --- frontend/src/app/main/ui/dashboard/fonts.cljs | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/frontend/src/app/main/ui/dashboard/fonts.cljs b/frontend/src/app/main/ui/dashboard/fonts.cljs index 68ce4d57c6..2174f1e712 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.cljs +++ b/frontend/src/app/main/ui/dashboard/fonts.cljs @@ -51,6 +51,16 @@ (and (contains? font :font-family-tmp) (str/blank? (:font-family-tmp font)))) +(defn- handle-font-upload + [{:keys [id] :as item}] + (->> (df/upload-font-variant item) + ;; This delay fixes the UI problem. When the font is uploaded quickly, + ;; the user only sees a flicker on the button. With a small delay we + ;; have a clear transition from uploading state to uploaded + (rx/delay-at-least 2000) + (rx/map (fn [font] + [id font])))) + (mf/defc header* {::mf/props :obj ::mf/memo true @@ -107,30 +117,23 @@ (fn [error] (js/console.error "error" error)))))) - on-upload* - (mf/use-fn - (fn [{:keys [id] :as item}] - (swap! uploading* conj id) - (->> (df/upload-font-variant item) - (rx/delay-at-least 2000) - (rx/subs! (fn [font] - (swap! fonts* dissoc id) - (swap! uploading* disj id) - (st/emit! (df/add-font font))) - (fn [error] - (st/emit! (ntf/error (tr "errors.bad-font" (first (:names item))))) - (swap! fonts* dissoc id) - (js/console.log "error" error)))))) - on-upload (mf/use-fn - (mf/deps fonts on-upload*) + (mf/deps fonts) (fn [event] (let [id (-> (dom/get-current-target event) (dom/get-data "id") (uuid/parse)) item (get fonts id)] - (on-upload* item)))) + (swap! uploading* conj id) + (->> (handle-font-upload item) + (rx/subs! (fn [[previous-id font]] + (swap! fonts* dissoc previous-id) + (swap! uploading* disj previous-id) + (st/emit! (df/add-font font))) + (fn [cause] + (st/emit! (ntf/error (tr "errors.bad-font" (first (:names item))))) + (js/console.error "Unexpected error on uploading font" cause))))))) on-blur-name (mf/use-fn @@ -168,7 +171,20 @@ (mf/use-fn (mf/deps font-vals) (fn [_] - (run! on-upload* font-vals))) + (->> (rx/from font-vals) + (rx/tap #(swap! uploading* conj (:id %))) + (rx/mapcat (fn [{:keys [id] :as item}] + (->> (handle-font-upload item) + (rx/catch (fn [cause] + (st/emit! (ntf/error (tr "errors.bad-font" (first (:names item))))) + (js/console.error "Unexpected error on uploading font" cause) + (rx/of [id nil])))))) + + (rx/subs! (fn [[previous-id font]] + (swap! fonts* dissoc previous-id) + (swap! uploading* disj previous-id) + (when font + (st/emit! (df/add-font font)))))))) on-dismis-all (mf/use-fn