Merge remote-tracking branch 'origin/main' into develop

This commit is contained in:
alonso.torres 2022-05-27 09:25:22 +02:00
commit 3d8c41cd69
52 changed files with 625 additions and 568 deletions

View file

@ -10,17 +10,34 @@
[beicon.core :as rx]))
(defonce cache (atom {}))
(defonce pending (atom {}))
(defn with-cache
[{:keys [key max-age]} observable]
(let [entry (get @cache key)
pending-entry (get @pending key)
age (when entry
(dt/diff (dt/now)
(:created-at entry)))]
(if (and (some? entry) (< age max-age))
(cond
(and (some? entry) (< age max-age))
(rx/of (:data entry))
(->> observable
(rx/tap
(fn [data]
(let [entry {:created-at (dt/now) :data data}]
(swap! cache assoc key entry))))))))
(some? pending-entry)
pending-entry
:else
(let [subject (rx/subject)]
(swap! pending assoc key subject)
(->> observable
(rx/catch #(do (rx/error! subject %)
(swap! pending dissoc key)
(rx/throw %)))
(rx/tap
(fn [data]
(let [entry {:created-at (dt/now) :data data}]
(swap! cache assoc key entry))
(rx/push! subject data)
(rx/end! subject)
(swap! pending dissoc key))))))))

View file

@ -558,3 +558,11 @@
(seq (.-children node)))]
(->> root-node
(tree-seq branch? get-children))))
(defn check-font? [font]
(let [fonts (.-fonts globals/document)]
(.check fonts font)))
(defn load-font [font]
(let [fonts (.-fonts globals/document)]
(.load fonts font)))

View file

@ -173,32 +173,34 @@
(fetch-data-uri uri false))
([uri throw-err?]
(c/with-cache {:key uri :max-age (dt/duration {:hours 4})}
(let [request-stream
(send! {:method :get
:uri uri
:response-type :blob
:omit-default-headers true})
(let [request-str
(->> (send! {:method :get
:uri uri
:response-type :blob
:omit-default-headers true})
(rx/tap
(fn [resp]
(when (or (< (:status resp) 200) (>= (:status resp) 300))
(rx/throw (js/Error. "Error fetching data uri" #js {:cause (clj->js resp)})))))
request-stream
(if throw-err?
(rx/tap #(when-not (and (>= (:status %) 200) (< (:status %) 300))
;; HTTP ERRROR
(throw (js/Error. "Error fetching data uri" #js {:cause (clj->js %)})))
request-stream)
(rx/filter #(= 200 (:status %))
request-stream))]
(->> request-stream
(rx/map :body)
(rx/mapcat wapi/read-file-as-data-url)
(rx/map #(hash-map uri %)))))))
(rx/map :body)
(rx/mapcat wapi/read-file-as-data-url)
(rx/map #(hash-map uri %))
(c/with-cache {:key uri :max-age (dt/duration {:hours 4})}))]
;; We need to check `throw-err?` after the cache is resolved otherwise we cannot cache request
;; with different values of throw-err. By default we throw always the exception and then we just
;; ignore when `throw-err?` is `true`
(if (not throw-err?)
(->> request-str (rx/catch #(rx/empty)))
request-str))))
(defn fetch-text [url]
(c/with-cache {:key url :max-age (dt/duration {:hours 4})}
(->> (send!
{:method :get
:mode :cors
:omit-default-headers true
:uri url
:response-type :text})
(rx/map :body))))
(->> (send!
{:method :get
:mode :cors
:omit-default-headers true
:uri url
:response-type :text})
(rx/map :body)
(c/with-cache {:key url :max-age (dt/duration {:hours 4})})))

View file

@ -23,14 +23,18 @@
{:label "Français (community)" :value "fr"}
{:label "Deutsch (community)" :value "de"}
;; {:label "Italiano (community)" :value "it"}
{:label "Norsk - Bokmål (community)" :value "nb_no"}
{:label "Portuguese - Brazil (community)" :value "pt_br"}
{:label "Polski (community)" :value "pl"}
{:label "Русский (community)" :value "ru"}
{:label "Rumanian (community)" :value "ro"}
{:label "Türkçe (community)" :value "tr"}
{:label "Rumanian (communit)" :value "ro"}
{:label "Portuguese (Brazil, community)" :value "pt_br"}
{:label "Ελληνική γλώσσα (community)" :value "el"}
{:label "עִבְרִית (community)" :value "he"}
{:label "عربي/عربى (community)" :value "ar"}
{:label "简体中文 (community)" :value "zh_cn"}])
{:label "فارسی (community)" :value "fa"}
{:label "简体中文 (community)" :value "zh_cn"}
{:label "中国传统的 (community)" :value "zh_hant"}])
(defn- parse-locale
[locale]

View file

@ -7,6 +7,7 @@
(ns app.util.import.parser
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.spec.interactions :as cti]
@ -213,16 +214,29 @@
(reduce add-attrs node-attrs))
(= type :frame)
(let [;; The nodes with the "frame-background" class can have some anidation depending on the strokes they have
(let [;; Old .penpot files doesn't have "g" nodes. They have a clipPath reference as a node attribute
to-url #(dm/str "url(#" % ")")
frame-clip-rect-node (->> (find-all-nodes node :defs)
(mapcat #(find-all-nodes % :clipPath))
(filter #(= (to-url (:id (:attrs %))) (:clip-path node-attrs)))
(mapcat #(find-all-nodes % #{:rect :path}))
(first))
;; The nodes with the "frame-background" class can have some anidation depending on the strokes they have
g-nodes (find-all-nodes node :g)
defs-nodes (flatten (map #(find-all-nodes % :defs) g-nodes))
gg-nodes (flatten (map #(find-all-nodes % :g) g-nodes))
rect-nodes (flatten [[(find-all-nodes node :rect)]
(map #(find-all-nodes % #{:rect :path}) defs-nodes)
(map #(find-all-nodes % #{:rect :path}) g-nodes)
(map #(find-all-nodes % #{:rect :path}) gg-nodes)])
svg-node (d/seek #(= "frame-background" (get-in % [:attrs :class])) rect-nodes)]
(merge (add-attrs {} (:attrs svg-node)) node-attrs))
(merge
(add-attrs {} (:attrs frame-clip-rect-node))
(add-attrs {} (:attrs svg-node))
node-attrs))
(= type :svg-raw)
(let [svg-content (get-data node :penpot:svg-content)

View file

@ -9,9 +9,11 @@
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.transit :as transit]
[app.main.fonts :as fonts]
[app.main.store :as st]
[app.util.dom :as dom]
[app.util.text-position-data :as tpd]))
[app.util.text-position-data :as tpd]
[promesa.core :as p]))
(defn parse-text-nodes
"Given a text node retrieves the rectangles for everyone of its paragraphs and its text."
@ -27,6 +29,27 @@
(map parse-entry)
(tpd/parse-text-nodes parent-node text-node))))
(def load-promises (atom {}))
(defn load-font
[font]
(if (contains? @load-promises font)
(get @load-promises font)
(let [load-promise (dom/load-font font)]
(swap! load-promises assoc font load-promise)
load-promise)))
(defn resolve-font
[^js node]
(let [styles (js/getComputedStyle node)
font (.getPropertyValue styles "font")]
(if (dom/check-font? font)
(p/resolved font)
(let [font-id (.getPropertyValue styles "--font-id")]
(-> (fonts/ensure-loaded! font-id)
(p/then #(when (not (dom/check-font? font))
(load-font font))))))))
(defn calc-text-node-positions
[base-node viewport zoom]
@ -58,22 +81,25 @@
:width (- (:x p2) (:x p1))
:height (- (:y p2) (:y p1)))))
text-nodes (dom/query-all base-node ".text-node, span[data-text]")]
(->> text-nodes
(mapcat
(fn [parent-node]
(let [direction (.-direction (js/getComputedStyle parent-node))]
(->> (.-childNodes parent-node)
(mapcat #(parse-text-nodes parent-node direction %))))))
(mapv #(update % :position translate-rect))))))
text-nodes (dom/query-all base-node ".text-node, span[data-text]")
load-fonts (->> text-nodes (map resolve-font))]
(-> (p/all load-fonts)
(p/then
(fn []
(->> text-nodes
(mapcat
(fn [parent-node]
(let [direction (.-direction (js/getComputedStyle parent-node))]
(->> (.-childNodes parent-node)
(mapcat #(parse-text-nodes parent-node direction %))))))
(mapv #(update % :position translate-rect)))))))))
(defn calc-position-data
[base-node]
(let [viewport (dom/get-element "render")
zoom (or (get-in @st/state [:workspace-local :zoom]) 1)]
(when (and (some? base-node) (some? viewport))
(let [text-data (calc-text-node-positions base-node viewport zoom)]
(p/let [text-data (calc-text-node-positions base-node viewport zoom)]
(when (d/not-empty? text-data)
(->> text-data
(mapv (fn [{:keys [node position text direction]}]