From fbf1c10077bf86e51d22ef5447323b990cf3c8c2 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 18 Jun 2021 14:49:14 +0200 Subject: [PATCH] :sparkles: Export library data (images, typographies, colors) --- common/src/app/common/data.cljc | 4 + frontend/src/app/worker/export.cljs | 126 +++++++++++++++++++++++----- frontend/src/app/worker/import.cljs | 7 +- 3 files changed, 113 insertions(+), 24 deletions(-) diff --git a/common/src/app/common/data.cljc b/common/src/app/common/data.cljc index bdf35dc00..39abab9d4 100644 --- a/common/src/app/common/data.cljc +++ b/common/src/app/common/data.cljc @@ -556,3 +556,7 @@ :else m))) + +(defn not-empty? + [coll] + (boolean (seq coll))) diff --git a/frontend/src/app/worker/export.cljs b/frontend/src/app/worker/export.cljs index 5c2d485a0..abd5e2753 100644 --- a/frontend/src/app/worker/export.cljs +++ b/frontend/src/app/worker/export.cljs @@ -6,36 +6,57 @@ (ns app.worker.export (:require + [app.common.data :as d] + [app.config :as cfg] [app.main.render :as r] [app.main.repo :as rp] [app.util.dom :as dom] - [app.util.zip :as uz] + [app.util.http :as http] [app.util.json :as json] + [app.util.zip :as uz] [app.worker.impl :as impl] - [beicon.core :as rx])) + [beicon.core :as rx] + [cuerdas.core :as str])) (defn create-manifest "Creates a manifest entry for the given files" - [team-id files] + [team-id file-id files] (letfn [(format-page [manifest page] (-> manifest (assoc (str (:id page)) {:name (:name page)}))) (format-file [manifest file] - (let [name (:name file) - pages (->> (get-in file [:data :pages]) (mapv str)) - index (->> (get-in file [:data :pages-index]) (vals) - (reduce format-page {}))] + (let [name (:name file) + is-shared (:is-shared file) + pages (->> (get-in file [:data :pages]) + (mapv str)) + index (->> (get-in file [:data :pages-index]) + (vals) + (reduce format-page {}))] (-> manifest (assoc (str (:id file)) - {:name name - :pages pages - :pagesIndex index}))))] + {:name name + :shared is-shared + :pages pages + :pagesIndex index + :hasComponents (d/not-empty? (get-in file [:data :components])) + :hasImages (d/not-empty? (get-in file [:data :media])) + :hasColors (d/not-empty? (get-in file [:data :colors])) + :hasTypographies (d/not-empty? (get-in file [:data :typographies]))}))))] (let [manifest {:teamId (str team-id) + :fileId (str file-id) :files (->> (vals files) (reduce format-file {}))}] (json/encode manifest)))) +(defn process-pages [file] + (let [pages (get-in file [:data :pages]) + pages-index (get-in file [:data :pages-index])] + (->> pages + (map #(hash-map + :file-id (:id file) + :data (get pages-index %)))))) + (defn get-page-data [{file-id :file-id {:keys [id name] :as data} :data}] (->> (r/render-page data) @@ -45,30 +66,45 @@ :file-id file-id :markup markup})))) -(defn process-pages [file] - (let [pages (get-in file [:data :pages]) - pages-index (get-in file [:data :pages-index])] - (->> pages - (map #(hash-map - :file-id (:id file) - :data (get pages-index %)))))) - (defn collect-page [{:keys [id file-id markup] :as page}] [(str file-id "/" id ".svg") markup]) +(defn collect-color + [result color] + (-> result + (assoc (str (:id color)) + (->> (select-keys color [:name :color :opacity :gradient]) + (d/deep-mapm + (fn [[k v]] + [(-> k str/camel) v])))))) + +(def ^:const typography-keys [:name :font-family :font-id :font-size + :font-style :font-variant-id :font-weight + :letter-spacing :line-height :text-transform]) +(defn collect-typography + [result typography] + (-> result + (assoc (str (:id typography)) + (->> (select-keys typography typography-keys) + (d/deep-mapm + (fn [[k v]] + [(-> k str/camel) v])))))) (defn export-file [team-id file-id] (let [files-stream - (->> (rp/query :file {:id file-id}) + (->> (rx/merge (rp/query :file {:id file-id}) + (->> (rp/query :file-libraries {:file-id file-id}) + (rx/flat-map identity) + (rx/map #(assoc % :is-shared true)))) (rx/reduce #(assoc %1 (:id %2) %2) {}) (rx/share)) manifest-stream (->> files-stream - (rx/map #(create-manifest team-id %)) + (rx/map #(create-manifest team-id file-id %)) (rx/map #(vector "manifest.json" %))) render-stream @@ -79,6 +115,48 @@ (rx/flat-map get-page-data) (rx/share)) + colors-stream + (->> files-stream + (rx/flat-map vals) + (rx/map #(vector (:id %) (get-in % [:data :colors]))) + (rx/filter #(d/not-empty? (second %))) + (rx/map (fn [[file-id colors]] + (let [markup + (->> (vals colors) + (reduce collect-color {}) + (json/encode))] + [(str file-id "/colors.json") markup])))) + + typographies-stream + (->> files-stream + (rx/flat-map vals) + (rx/map #(vector (:id %) (get-in % [:data :typographies]))) + (rx/filter #(d/not-empty? (second %))) + (rx/map (fn [[file-id typographies]] + (let [markup + (->> (vals typographies) + (reduce collect-typography {}) + (json/encode))] + [(str file-id "/typographies.json") markup])))) + + media-stream + (->> files-stream + (rx/flat-map vals) + (rx/map #(vector (:id %) (get-in % [:data :media]))) + (rx/filter #(d/not-empty? (second %))) + (rx/flat-map + (fn [[file-id media]] + (->> media vals (mapv #(assoc % :file-id file-id))))) + + (rx/flat-map + (fn [media] + (->> (http/send! + {:uri (cfg/resolve-file-media media) + :response-type :blob + :method :get}) + (rx/map :body) + (rx/map #(vector (str file-id "/images/" (:id media)) %)))))) + pages-stream (->> render-stream (rx/map collect-page))] @@ -90,7 +168,13 @@ :file file-id :data (str "Render " (:file-name %) " - " (:name %))))) - (->> (rx/merge manifest-stream pages-stream) + (->> (rx/merge + manifest-stream + pages-stream + #_components-stream + media-stream + colors-stream + typographies-stream) (rx/reduce conj []) (rx/with-latest-from files-stream) (rx/flat-map (fn [[data files]] diff --git a/frontend/src/app/worker/import.cljs b/frontend/src/app/worker/import.cljs index e54098b43..0be111877 100644 --- a/frontend/src/app/worker/import.cljs +++ b/frontend/src/app/worker/import.cljs @@ -25,12 +25,13 @@ (defn create-file "Create a new file on the back-end" - [project-id name] + [project-id file-desc] (let [file-id (uuid/next)] (rp/mutation :create-temp-file {:id file-id - :name name + :name (:name file-desc) + :is-shared (:shared file-desc) :project-id project-id :data (-> cp/empty-file-data (assoc :id file-id))}))) @@ -203,7 +204,7 @@ (rx/flat-map (comp :files json/decode :content)) (rx/flat-map (fn [[file-id file-desc]] - (->> (create-file project-id (:name file-desc)) + (->> (create-file project-id file-desc) (rx/flat-map #(process-file % file-id file-desc zip-file))))))) (defmethod impl/handler :import-file