0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-10 00:58:26 -05:00

Merge pull request #988 from penpot/alotor/small-improvements

Small improvements
This commit is contained in:
Andrey Antukh 2021-05-27 14:51:28 +02:00 committed by GitHub
commit 53cb36dd8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 207 additions and 105 deletions

View file

@ -40,6 +40,7 @@
"draft-js": "^0.11.7",
"highlight.js": "^10.6.0",
"js-beautify": "^1.13.5",
"jszip": "^3.6.0",
"luxon": "^1.26.0",
"mousetrap": "^1.6.5",
"opentype.js": "^1.3.3",

View file

@ -148,8 +148,10 @@
:version "1.1"
:xmlnsXlink "http://www.w3.org/1999/xlink"
:xmlns "http://www.w3.org/2000/svg"
:xmlns:penpot "https://penpot.app/xmlns"}
[:& background {:vbox dim :color background-color}]
:xmlns:penpot "https://penpot.app/xmlns"
:style {:width "100%"
:height "100%"
:background background-color}}
(for [item shapes]
(let [frame? (= (:type item) :frame)]
(cond

View file

@ -34,7 +34,7 @@
(fn [{:keys [status body] :as response}]
(js/console.log status body)
(if (= status 200)
(we/trigger-download (:name shape) body)
(dom/trigger-download (:name shape) body)
(st/emit! (dm/error (t locale "errors.unexpected-error")))))
(constantly nil)
(fn []

View file

@ -75,7 +75,7 @@
:y y
:width width
:height height
:style {:fill "transparent"
:style {:fill "none"
:stroke select-color
:stroke-width selection-rect-width}}]]))

View file

@ -177,7 +177,7 @@
:y y
:width width
:height height
:style {:fill "transparent"
:style {:fill "none"
:stroke hover-color
:stroke-width selection-rect-width}}]]))

View file

@ -89,7 +89,7 @@
;; we setup the default fill as transparent (instead of black)
(and (not (contains? shape :svg-attrs))
(not (#{ :svg-raw :group } (:type shape))))
{:fill "transparent"}
{:fill "none"}
:else
{})

View file

@ -28,8 +28,8 @@
#js {:d pdata}))]
(if background?
[:g
[:path {:stroke "transparent"
:fill "transparent"
[:path {:stroke "none"
:fill "none"
:stroke-width "20px"
:d pdata}]
[:& shape-custom-stroke {:shape shape

View file

@ -42,7 +42,7 @@
:height height
:transform (or transform "none")
:style {:stroke color
:fill "transparent"
:fill "none"
:stroke-width "1px"
:pointer-events "none"}}])

View file

@ -86,10 +86,11 @@
:on-mouse-down on-mouse-down
:on-mouse-enter on-enter
:on-mouse-leave on-leave
:pointer-events (when-not preview? "visible")
:style {:cursor (cond
(= edit-mode :draw) cur/pen-node
(= edit-mode :move) cur/pointer-node)
:fill "transparent"}}]]))
:fill "none"}}]]))
(mf/defc path-handler [{:keys [index prefix point handler zoom selected? hover? edit-mode snap-angle?]}]
(when (and point handler)
@ -111,7 +112,7 @@
(= edit-mode :move)
(st/emit! (drp/start-move-handler index prefix))))]
[:g.handler {:pointer-events (when (= edit-mode :draw))}
[:g.handler {:pointer-events (if (= edit-mode :draw) "none" "visible")}
[:line
{:x1 (:x point)
:y1 (:y point)
@ -147,12 +148,12 @@
:on-mouse-enter on-enter
:on-mouse-leave on-leave
:style {:cursor (when (= edit-mode :move) cur/pointer-move)
:fill "transparent"}}]])))
:fill "none"}}]])))
(mf/defc path-preview [{:keys [zoom command from]}]
[:g.preview {:style {:pointer-events "none"}}
(when (not= :move-to (:command command))
[:path {:style {:fill "transparent"
[:path {:style {:fill "none"
:stroke pc/black-color
:stroke-width (/ 1 zoom)
:stroke-dasharray (/ 4 zoom)}
@ -274,6 +275,7 @@
[:g.drag-handler {:pointer-events "none"}
[:& path-handler {:point last-p
:handler drag-handler
:edit-mode edit-mode
:zoom zoom}]])
(when @hover-point
@ -325,6 +327,7 @@
(when prev-handler
[:g.prev-handler {:pointer-events "none"}
[:& path-handler {:point last-p
:edit-mode edit-mode
:handler prev-handler
:zoom zoom}]])

View file

@ -29,21 +29,6 @@
:name (:name shape)
:exports exports}))
(defn- trigger-download
[filename blob]
(let [link (dom/create-element "a")
uri (dom/create-uri blob)
extension (dom/mtype->extension (.-type ^js blob))
filename (if extension
(str filename "." extension)
filename)]
(obj/set! link "href" uri)
(obj/set! link "download" filename)
(obj/set! (.-style ^js link) "display" "none")
(.appendChild (.-body ^js js/document) link)
(.click link)
(.remove link)))
(mf/defc exports-menu
[{:keys [shape page-id file-id] :as props}]
(let [locale (mf/deref i18n/locale)
@ -64,7 +49,7 @@
(->> (request-export (assoc shape :page-id page-id :file-id file-id) exports)
(rx/subs
(fn [body]
(trigger-download filename body))
(dom/trigger-download filename body))
(fn [error]
(swap! loading? not)
(st/emit! (dm/error (tr "errors.unexpected-error"))))

View file

@ -45,6 +45,6 @@
:width width
:height height
:style {:stroke "#1FDEA7"
:fill "transparent"
:fill "none"
:stroke-width (/ 1 zoom)}}])))

View file

@ -55,7 +55,7 @@
:opacity color-opacity}
#js {:stroke color-value
:strokeOpacity color-opacity
:fill "transparent"})]
:fill "none"})]
[:g.grid
(for [{:keys [x y width height]} (gg/grid-areas frame grid)]
(do

View file

@ -109,7 +109,7 @@
"translate(" (* zoom x) ", " (* zoom y) ")")}]
(when arrow-dir
[:path {:stroke "#31EFB8"
:fill "transparent"
:fill "none"
:stroke-width 2
:d arrow-pdata
:transform (str
@ -134,14 +134,16 @@
(if-not selected?
[:path {:stroke "#B1B2B5"
:fill "transparent"
:fill "none"
:pointer-events "visible"
:stroke-width (/ 2 zoom)
:d pdata
:on-mouse-down #(on-mouse-down % orig-shape selected)}]
[:g {:on-mouse-down #(on-mouse-down % orig-shape selected)}
[:path {:stroke "#31EFB8"
:fill "transparent"
:fill "none"
:pointer-events "visible"
:stroke-width (/ 2 zoom)
:d pdata}]
[:& interaction-marker {:x orig-x

View file

@ -36,7 +36,7 @@
:path "path"
"rect")
common {:fill "transparent"
common {:fill "none"
:stroke color
:strokeWidth (/ 1 zoom)
:pointerEvents "none"

View file

@ -53,7 +53,7 @@
:on-mouse-down on-move-selected
:style {:stroke color
:stroke-width (/ selection-rect-width zoom)
:fill "transparent"}}])))
:fill "none"}}])))
(defn- handlers-for-selection [{:keys [x y width height]} {:keys [type]} zoom]
(let [zoom-width (* width zoom)
@ -142,7 +142,7 @@
:y y
:width size
:height size
:fill (if (debug? :rotation-handler) "blue" "transparent")
:fill (if (debug? :rotation-handler) "blue" "none")
:transform transform
:on-mouse-down on-rotate}]))
@ -174,7 +174,7 @@
:width resize-point-circle-radius
:height resize-point-circle-radius
:transform (when rotation (str/fmt "rotate(%s, %s, %s)" rotation cx' cy'))
:style {:fill (if (debug? :resize-handler) "red" "transparent")
:style {:fill (if (debug? :resize-handler) "red" "none")
:cursor cursor}
:on-mouse-down #(on-resize {:x cx' :y cy'} %)}])
@ -187,7 +187,7 @@
:r (/ resize-point-circle-radius zoom)
:cx cx'
:cy cy'
:style {:fill (if (debug? :resize-handler) "red" "transparent")
:style {:fill (if (debug? :resize-handler) "red" "none")
:cursor cursor}}])
)]))
@ -214,7 +214,7 @@
:transform (gmt/multiply transform
(gmt/rotate-matrix angle (gpt/point x y)))
:on-mouse-down #(on-resize res-point %)
:style {:fill (if (debug? :resize-handler) "yellow" "transparent")
:style {:fill (if (debug? :resize-handler) "yellow" "none")
:cursor (if (#{:left :right} position)
(cur/resize-ew rotation)
(cur/resize-ns rotation)) }}]))
@ -245,7 +245,7 @@
transform (geom/transform-matrix shape {:no-flip true})]
(when (not (#{:move :rotate} current-transform))
[:g.controls {:pointer-events (when disable-handlers "none")}
[:g.controls {:pointer-events (if disable-handlers "none" "visible")}
;; Selection rect
[:& selection-rect {:rect selrect
@ -282,10 +282,11 @@
:transform (geom/transform-matrix shape)
:width width
:height height
:pointer-events "visible"
:style {:stroke color
:stroke-width "0.5"
:stroke-opacity "1"
:fill "transparent"}}]]))
:fill "none"}}]]))
(mf/defc multiple-selection-handlers
[{:keys [shapes selected zoom color disable-handlers on-move-selected] :as props}]

View file

@ -26,3 +26,7 @@
(defn ask-buffered!
[message]
(uw/ask-buffered! instance message))
(defn ask-many!
[message]
(uw/ask-many! instance message))

View file

@ -54,6 +54,10 @@
[id]
(dom/getElement id))
(defn get-elements-by-tag
[node tag]
(.getElementsByTagName node tag))
(defn stop-propagation
[e]
(when e
@ -279,13 +283,14 @@
(defn mtype->extension [mtype]
;; https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
(case mtype
"image/apng" "apng"
"image/avif" "avif"
"image/gif" "gif"
"image/jpeg" "jpg"
"image/png" "png"
"image/svg+xml" "svg"
"image/webp" "webp"
"image/apng" "apng"
"image/avif" "avif"
"image/gif" "gif"
"image/jpeg" "jpg"
"image/png" "png"
"image/svg+xml" "svg"
"image/webp" "webp"
"application/zip" "zip"
nil))
(defn set-attribute [^js node ^string attr value]
@ -311,3 +316,21 @@
(>= (.-left rect) 0)
(<= (.-bottom rect) height)
(<= (.-right rect) width))))
(defn trigger-download-uri
[filename mtype uri]
(let [link (create-element "a")
extension (mtype->extension mtype)
filename (if extension
(str filename "." extension)
filename)]
(obj/set! link "href" uri)
(obj/set! link "download" filename)
(obj/set! (.-style ^js link) "display" "none")
(.appendChild (.-body ^js js/document) link)
(.click link)
(.remove link)))
(defn trigger-download
[filename blob]
(trigger-download-uri filename (.-type ^js blob) (dom/create-uri blob)))

View file

@ -14,14 +14,25 @@
(declare handle-response)
(defrecord Worker [instance stream])
(defn- send-message! [worker {sender-id :sender-id :as message}]
(let [data (t/encode message)
instance (:instance worker)]
(.postMessage instance data)
(->> (:stream worker)
(rx/filter #(= (:reply-to %) sender-id))
(rx/take 1)
(rx/map handle-response))))
(defn- send-message!
([worker message]
(send-message! worker message nil))
([worker {sender-id :sender-id :as message} {:keys [many?] :or {many? false}}]
(let [take-messages
(fn [ob]
(if many?
(rx/take-while #(not (:completed %)) ob)
(rx/take 1 ob)))
data (t/encode message)
instance (:instance worker)]
(.postMessage instance data)
(->> (:stream worker)
(rx/filter #(= (:reply-to %) sender-id))
(take-messages)
(rx/map handle-response)))))
(defn ask!
[worker message]
@ -30,6 +41,14 @@
{:sender-id (uuid/next)
:payload message}))
(defn ask-many!
[worker message]
(send-message!
worker
{:sender-id (uuid/next)
:payload message}
{:many? true}))
(defn ask-buffered!
[worker message]
(send-message!

View file

@ -6,14 +6,47 @@
(ns app.util.zip
"Helpers for make zip file (using jszip)."
(:require [vendor.jszip]
[beicon.core :as rx]))
(:require
["jszip" :as zip]
[app.common.data :as d]
[beicon.core :as rx]
[promesa.core :as p]))
(defn build
(defn compress-files
[files]
(letfn [(attach-file [zobj [name content]]
(.file zobj name content))]
(let [zobj (js/JSZip.)]
(let [zobj (zip.)]
(run! (partial attach-file zobj) files)
(->> (.generateAsync zobj #js {:type "blob"})
(rx/from)))))
(defn extract-files
"Creates a stream that will emit values for every file in the zip"
[file]
(rx/create
(fn [subs]
(let [process-entry
(fn [path entry]
(if (.-dir entry)
(rx/push! subs {:dir path})
(p/then
(.async entry "text")
(fn [content]
(rx/push! subs
{:path path
:content content})))))]
(p/let [response (js/fetch file)
data (.blob response)
content (zip/loadAsync data)]
(let [promises (atom [])]
(.forEach content
(fn [path entry]
(let [current (process-entry path entry)]
(swap! promises conj current))))
(p/then (p/all @promises)
#(rx/end! subs))))
nil))))

View file

@ -43,35 +43,42 @@
"Process the message and returns to the client"
[{:keys [sender-id payload] :as message}]
(us/assert ::message message)
(try
(let [result (impl/handler payload)]
(cond
(p/promise? result)
(p/handle result
(fn [msg]
(.postMessage js/self (t/encode
{:reply-to sender-id
:payload msg})))
(fn [err]
(.postMessage js/self (t/encode
{:reply-to sender-id
:error {:data (ex-data err)
:message (ex-message err)}}))))
(letfn [(post [msg]
(let [msg (-> msg (assoc :reply-to sender-id) (t/encode))]
(.postMessage js/self msg)))
(or (rx/observable? result)
(rx/subject? result))
(throw (ex-info "not implemented" {}))
(reply [result]
(post {:payload result}))
:else
(.postMessage js/self (t/encode
{:reply-to sender-id
:payload result}))))
(catch :default e
(.error js/console "error" e)
(let [message {:reply-to sender-id
:error {:data (ex-data e)
:message (ex-message e)}}]
(.postMessage js/self (t/encode message))))))
(reply-error [err]
(.error js/console "error" err)
(post {:error {:data (ex-data err)
:message (ex-message err)}}))
(reply-completed
([] (reply-completed nil))
([msg] (post {:payload msg
:completed true})))]
(try
(let [result (impl/handler payload)
promise? (p/promise? result)
stream? (or (rx/observable? result) (rx/subject? result))]
(cond
promise?
(-> result
(p/then reply-completed)
(p/catch reply-error))
stream?
(rx/subscribe result reply reply-error reply-completed)
:else
(reply result)))
(catch :default err
(reply-error err)))))
(defn- drop-message
"Sends to the client a notifiction that its messages have been dropped"

View file

@ -31,17 +31,12 @@
(defn- request-page
[file-id page-id]
(let [uri "/api/rpc/query/page"]
(p/create
(fn [resolve reject]
(->> (http/send! {:uri uri
:query {:file-id file-id :id page-id :strip-thumbnails true}
:method :get})
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response)
(rx/subs (fn [body]
(resolve body))
(fn [error]
(reject error))))))))
(->> (http/send!
{:uri uri
:query {:file-id file-id :id page-id :strip-thumbnails true}
:method :get})
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response))))
(defonce cache (atom {}))
@ -57,8 +52,8 @@
(defmethod impl/handler :thumbnails/generate
[{:keys [file-id page-id] :as message}]
(p/then
(request-page file-id page-id)
(fn [data]
{:svg (render-page data #{file-id page-id})
:fonts @fonts/loaded})))
(->> (request-page file-id page-id)
(rx/map
(fn [data]
{:svg (render-page data #{file-id page-id})
:fonts @fonts/loaded}))))

View file

@ -2375,6 +2375,11 @@ ieee754@^1.1.4:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
immutable@~3.7.4:
version "3.7.6"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b"
@ -2838,6 +2843,16 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
jszip@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.6.0.tgz#839b72812e3f97819cc13ac4134ffced95dd6af9"
integrity sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==
dependencies:
lie "~3.3.0"
pako "~1.0.2"
readable-stream "~2.3.6"
set-immediate-shim "~1.0.1"
just-debounce@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf"
@ -2920,6 +2935,13 @@ lead@^1.0.0:
dependencies:
flush-write-stream "^1.0.2"
lie@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
dependencies:
immediate "~3.0.5"
liftoff@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3"
@ -3762,7 +3784,7 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pako@~1.0.5:
pako@~1.0.2, pako@~1.0.5:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
@ -4521,6 +4543,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
set-immediate-shim@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=
set-value@^2.0.0, set-value@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"