diff --git a/CHANGES.md b/CHANGES.md index 098032b96..68aa3d5a3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -63,7 +63,7 @@ - Fix can't collapse groups when searching in the assets tab [Taiga #8125](https://tree.taiga.io/project/penpot/issue/8125) - Fix 'Detach instance' shortcut is not working [Taiga #8102](https://tree.taiga.io/project/penpot/issue/8102) - Fix import file message does not detect 0 as error [Taiga #6824](https://tree.taiga.io/project/penpot/issue/6824) - +- Image Color Library is not persisted when exporting/importing in .zip [Taiga #8131](https://tree.taiga.io/project/penpot/issue/8131) ## 2.0.3 diff --git a/frontend/src/app/main/ui/shapes/custom_stroke.cljs b/frontend/src/app/main/ui/shapes/custom_stroke.cljs index ed317cdbd..3e664412f 100644 --- a/frontend/src/app/main/ui/shapes/custom_stroke.cljs +++ b/frontend/src/app/main/ui/shapes/custom_stroke.cljs @@ -16,6 +16,7 @@ [app.config :as cf] [app.main.ui.context :as muc] [app.main.ui.shapes.attrs :as attrs] + [app.main.ui.shapes.embed :as embed] [app.main.ui.shapes.gradients :as grad] [app.util.object :as obj] [cuerdas.core :as str] @@ -213,6 +214,7 @@ :force-transform (cfh/path-shape? shape)} stroke-image (:stroke-image stroke) uri (when stroke-image (cf/resolve-file-media stroke-image)) + embed (embed/use-data-uris [uri]) stroke-width (case (:stroke-alignment stroke :center) :center (/ (:stroke-width stroke 0) 2) @@ -229,7 +231,7 @@ w (+ (dm/get-prop selrect :width) (* 2 stroke-margin)) h (+ (dm/get-prop selrect :height) (* 2 stroke-margin)) - image-props #js {:href uri + image-props #js {:href (get embed uri uri) :preserveAspectRatio "xMidYMid slice" :width 1 :height 1 diff --git a/frontend/src/app/main/ui/shapes/embed.cljs b/frontend/src/app/main/ui/shapes/embed.cljs index 218b9687b..4283a6314 100644 --- a/frontend/src/app/main/ui/shapes/embed.cljs +++ b/frontend/src/app/main/ui/shapes/embed.cljs @@ -31,7 +31,7 @@ (->> (http/fetch-data-uri uri true) ;; If fetching give an error we store the URI as its `data-uri` (rx/catch #(rx/of (hash-map uri uri))))))) - (rx/map identity obs))) + (rx/map (fn [uri] {uri uri}) obs))) sub (->> (rx/from urls) (rx/filter some?) diff --git a/frontend/src/app/main/ui/shapes/fills.cljs b/frontend/src/app/main/ui/shapes/fills.cljs index 076a662c0..4fb4a2996 100644 --- a/frontend/src/app/main/ui/shapes/fills.cljs +++ b/frontend/src/app/main/ui/shapes/fills.cljs @@ -14,6 +14,7 @@ [app.common.geom.shapes.text :as gst] [app.config :as cf] [app.main.ui.shapes.attrs :as attrs] + [app.main.ui.shapes.embed :as embed] [app.main.ui.shapes.gradients :as grad] [app.util.object :as obj] [rumext.v2 :as mf])) @@ -57,7 +58,7 @@ (keep :fill-image) (map cf/resolve-file-media)) fills) - + embed (embed/use-data-uris uris) transform (gsh/transform-str shape) pat-props #js {:patternUnits "userSpaceOnUse" @@ -119,7 +120,7 @@ (let [uri (cf/resolve-file-media (:fill-image value)) keep-ar? (-> value :fill-image :keep-aspect-ratio) image-props #js {:id (dm/str "fill-image-" render-id "-" fill-index) - :href (get uris uri uri) + :href (get embed uri uri) :preserveAspectRatio (if keep-ar? "xMidYMid slice" "none") :width width :height height diff --git a/frontend/src/app/worker/export.cljs b/frontend/src/app/worker/export.cljs index b43bbbe11..bd1ccd10c 100644 --- a/frontend/src/app/worker/export.cljs +++ b/frontend/src/app/worker/export.cljs @@ -93,6 +93,9 @@ (def ^:const color-keys [:name :color :opacity :gradient :path]) +(def ^:const image-color-keys + [:width :height :mtype :name :keep-aspect-ratio]) + (def ^:const typography-keys [:name :font-family :font-id :font-size :font-style :font-variant-id :font-weight :letter-spacing :line-height :text-transform :path]) @@ -102,7 +105,21 @@ (defn collect-color [result color] - (collect-entries result color color-keys)) + (let [id (str (:id color)) + basic-data (select-keys color color-keys) + image-color-data (when-let [image-color (:image color)] + (->> (select-keys image-color image-color-keys))) + color-data (cond-> basic-data + (some? image-color-data) + (-> + (assoc :image image-color-data) + (assoc-in [:image :id] (str (get-in color [:image :id])))))] + (-> result + (assoc id + (->> color-data + (d/deep-mapm + (fn [[k v]] + [(-> k str/camel) v]))))))) (defn collect-typography [result typography] @@ -114,11 +131,25 @@ (defn parse-library-color [[file-id colors]] - (let [markup - (->> (vals colors) - (reduce collect-color {}) - (json/encode))] - [(str file-id "/colors.json") markup])) + (rx/merge + (let [markup + (->> (vals colors) + (reduce collect-color {}) + (json/encode))] + (rx/of (vector (str file-id "/colors.json") markup))) + + (->> (rx/from (vals colors)) + (rx/map :image) + (rx/filter d/not-empty?) + (rx/merge-map + (fn [image-color] + (let [file-path (str/concat file-id "/colors/" (:id image-color) (cm/mtype->extension (:mtype image-color)))] + (->> (http/send! + {:uri (cfg/resolve-file-media image-color) + :response-type :blob + :method :get}) + (rx/map :body) + (rx/map #(vector file-path %))))))))) (defn parse-library-typographies [[file-id typographies]] @@ -355,7 +386,7 @@ (rx/merge-map vals) (rx/map #(vector (:id %) (get-in % [:data :colors]))) (rx/filter #(d/not-empty? (second %))) - (rx/map parse-library-color)) + (rx/merge-map parse-library-color)) typographies-stream (->> files-stream diff --git a/frontend/src/app/worker/import.cljs b/frontend/src/app/worker/import.cljs index beb6e2b14..89e50c6aa 100644 --- a/frontend/src/app/worker/import.cljs +++ b/frontend/src/app/worker/import.cljs @@ -50,7 +50,9 @@ path (case type :manifest (str "manifest.json") :page (str file-id "/" id ".svg") - :colors (str file-id "/colors.json") + :colors-list (str file-id "/colors.json") + :colors (let [ext (cm/mtype->extension (:mtype media))] + (str/concat file-id "/colors/" id ext)) :typographies (str file-id "/typographies.json") :media-list (str file-id "/media.json") :media (let [ext (cm/mtype->extension (:mtype media))] @@ -560,15 +562,36 @@ (if (:has-colors context) (let [resolve (:resolve context) add-color - (fn [file [id color]] + (fn [file color] (let [color (-> color (d/update-in-when [:gradient :type] keyword) - (assoc :id (resolve id)))] + (d/update-in-when [:image :id] resolve) + (update :id resolve))] (fb/add-library-color file color)))] - (->> (get-file context :colors) + (->> (get-file context :colors-list) (rx/merge-map (comp d/kebab-keys parser/string->uuid)) + (rx/mapcat + (fn [[id color]] + (let [color (assoc color :id id) + color-image (:image color) + upload-image? (some? color-image) + color-image-id (:id color-image)] + (if upload-image? + (->> (get-file context :colors color-image-id color-image) + (rx/map (fn [blob] + (let [content (.slice blob 0 (.-size blob) (:mtype color-image))] + {:name (:name color-image) + :id (resolve color-image-id) + :file-id (:id file) + :content content + :is-local false}))) + (rx/tap #(progress! context :upload-media (:name %))) + (rx/merge-map #(rp/cmd! :upload-file-media-object %)) + (rx/map (constantly color)) + (rx/catch #(do (.error js/console (str "Error uploading color-image: " (:name color-image))) + (rx/empty)))) + (rx/of color))))) (rx/reduce add-color file))) - (rx/of file))) (defn process-library-typographies