0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-17 18:21:23 -05:00

🎉 Add file thumbnails on dashboard.

This commit is contained in:
Andrey Antukh 2020-01-08 10:34:02 +01:00
parent ba2ffb9c0a
commit ab4171b8ec
7 changed files with 86 additions and 70 deletions

View file

@ -29,7 +29,8 @@
"select distinct on (pf.id, pf.created_at)
pf.*,
p.name as project_name,
array_agg(pp.id) over pages_w as pages
array_agg(pp.id) over pages_w as pages,
first_value(pp.data) over pages_w as data
from project_files as pf
inner join projects as p on (pf.project_id = p.id)
inner join project_users as pu on (p.id = pu.project_id)
@ -131,8 +132,9 @@
;; --- Helpers
(defn decode-row
[{:keys [metadata pages] :as row}]
[{:keys [metadata pages data] :as row}]
(when row
(cond-> row
data (assoc :data (blob/decode data))
pages (assoc :pages (vec (remove nil? pages)))
metadata (assoc :metadata (blob/decode metadata)))))

View file

@ -7,18 +7,20 @@
(ns uxbox.main.exports
"The main logic for SVG export functionality."
(:require
[cljsjs.react.dom.server]
[rumext.alpha :as mf]
[uxbox.main.store :as st]
;; [uxbox.main.ui.shapes.circle :refer [circle-shape]]
;; [uxbox.main.ui.shapes.group :refer [group-shape]]
;; [uxbox.main.ui.shapes.icon :refer [icon-shape]]
;; [uxbox.main.ui.shapes.image :refer [image-shape]]
;; [uxbox.main.ui.shapes.path :refer [path-shape]]
;; [uxbox.main.ui.shapes.rect :refer [rect-shape]]
;; [uxbox.main.ui.shapes.text :refer [text-shape]]
[uxbox.util.dom :as dom]))
[uxbox.main.geom :as geom]
[uxbox.main.ui.shapes.canvas :as canvas]
[uxbox.main.ui.shapes.circle :as circle]
[uxbox.main.ui.shapes.icon :as icon]
[uxbox.main.ui.shapes.image :as image]
[uxbox.main.ui.shapes.path :as path]
[uxbox.main.ui.shapes.rect :as rect]
[uxbox.main.ui.shapes.text :as text]))
;; (def ^:dynamic *state* st/state)
(defn- render-html
[component]
(.renderToStaticMarkup js/ReactDOMServer component))
(mf/defc background
[]
@ -26,47 +28,52 @@
{:x 0 :y 0
:width "100%"
:height "100%"
:fill "white"}])
:fill "#b1b2b5"}])
(declare shape-component)
(declare shape-wrapper)
(defn- calculate-width
[data]
(let [shapes (vals (:shapes-by-id data))
shape (geom/shapes->rect-shape shapes)]
{:width (+ (:x shape) (:width shape) 100)
:height (+ (:y shape) (:height shape) 100)}))
(defn- make-shape-element
[state shape]
#_(mf/html
(case (:type shape)
;; :text [:& text-shape {:shape shape}]
:icon [:& icon-shape {:shape shape}]
:rect [:& rect-shape {:shape shape}]
:path [:& path-shape {:shape shape}]
:circle [:& circle-shape {:shape shape}]
:image (let [image-id (:image shape)
image (get-in state [:images image-id])]
[:& image-shape {:shape shape :image image}]))))
(mf/defc shape-wrapper
[{:keys [shape] :as props}]
(when (and shape (not (:hidden shape)))
(case (:type shape)
:canvas [:& rect/rect-shape {:shape shape}]
:curve [:& path/path-shape {:shape shape}]
:text [:& text/text-shape {:shape shape}]
:icon [:& icon/icon-shape {:shape shape}]
:rect [:& rect/rect-shape {:shape shape}]
:path [:& path/path-shape {:shape shape}]
:image [:& image/image-shape {:shape shape}]
:circle [:& circle/circle-shape {:shape shape}])))
(mf/defc page-svg
[{:keys [page state] :as props}]
#_(let [{:keys [width height]} (:metadata page)]
[{:keys [data] :as props}]
(let [shapes-by-id (:shapes-by-id data)
shapes (map #(get shapes-by-id %) (:shapes data []))
canvas (map #(get shapes-by-id %) (:canvas data []))
{:keys [width height]} (calculate-width data)]
[:svg {:width width
:height height
:view-box (str "0 0 " width " " height)
:version "1.1"
:xmlnsXlink "http://www.w3.org/1999/xlink"
:xmlns "http://www.w3.org/2000/svg"}
;; TODO: properly handle background
#_(background)
(for [sid (reverse (:shapes page))]
(when-let [shape (get-in state [:shapes sid])]
[:g {:key sid} (make-shape-element state shape)]))]))
(background)
[:*
(for [item canvas]
[:& shape-wrapper {:shape item :key (:id item)}])
(for [item shapes]
[:& shape-wrapper {:shape item :key (:id item)}])]]))
(defn render-page
[id]
#_(try
(let [state (deref st/state)
page (get-in state [:pages id])]
(when (:shapes page)
(dom/render-to-html
(mf/element page-svg #js {:page page :state state}))))
(defn render
[{:keys [data] :as page}]
(try
(-> (mf/element page-svg #js {:data data})
(render-html))
(catch :default e
(js/console.log e)
nil)))

View file

@ -15,6 +15,7 @@
[uxbox.main.constants :as c]
[uxbox.main.data.projects :as udp]
[uxbox.main.store :as st]
[uxbox.main.exports :as exports]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.confirm :refer [confirm-dialog]]
@ -66,10 +67,27 @@
;; --- Grid Item Thumbnail
;; (mf/defc grid-item-thumbnail
;; [{:keys [file] :as props}]
;; [:div.grid-item-th
;; [:img.img-th {:src "/images/project-placeholder.svg"}]])
;; (defn use-thumbnail
;; [file]
(mf/defc grid-item-thumbnail
[{:keys [project] :as props}]
[:div.grid-item-th
[:img.img-th {:src "/images/project-placeholder.svg"}]])
[{:keys [file] :as props}]
(let [url (mf/use-memo
{:fn #(let [content (exports/render file)
blob (js/Blob. #js [content] #js {:type "image/svg+xml"})]
(js/URL.createObjectURL blob))
:deps (mf/deps (:id file))})]
(mf/use-effect
{:fn (fn []
#(js/URL.revokeObjectURL url))
:deps (mf/deps (:id file))})
[:div.grid-item-th
[:img.img-th {:src url}]]))
;; --- Grid Item

View file

@ -32,16 +32,3 @@
:image [:& image/image-wrapper {:shape shape}]
:circle [:& circle/circle-wrapper {:shape shape}])))
(mf/defc canvas-and-shapes
{:wrap [mf/wrap-memo]}
[{:keys [page] :as props}]
(let [shapes-by-id (mf/deref refs/shapes-by-id)
shapes (map #(get shapes-by-id %) (:shapes page []))
canvas (map #(get shapes-by-id %) (:canvas page []))]
[:*
(for [item canvas]
[:& shape-wrapper {:shape item :key (:id item)}])
(for [item shapes]
[:& shape-wrapper {:shape item :key (:id item)}])]))

View file

@ -20,7 +20,14 @@
[uxbox.util.color :as color]
[uxbox.util.data :refer [classnames normalize-props]]
[uxbox.util.dom :as dom]
[uxbox.util.geom.matrix :as gmt]))
[uxbox.util.geom.matrix :as gmt]
[cljsjs.react.dom.server]))
(defn- render-html
[component]
(.renderToStaticMarkup js/ReactDOMServer component))
;; TODO: this code need a good refactor
@ -150,7 +157,7 @@
(fn [own]
(let [shape (get-in own [::mf/props :shape])
dom (mf/ref-node (::fobject own))
html (dom/render-to-html (text-shape-html shape))]
html (render-html (text-shape-html shape))]
(set! (.-innerHTML dom) html))
own)
@ -204,7 +211,7 @@
(fn [own]
(let [shape (::mf/props own)
dom (mf/ref-node (::fobject own))
html (dom/render-to-html (text-shape-html shape))]
html (render-html (text-shape-html shape))]
(set! (.-innerHTML dom) html))
own)

View file

@ -15,7 +15,7 @@
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]
[uxbox.main.data.lightbox :as udl]
[uxbox.main.exports :as exports]
;; [uxbox.main.exports :as exports]
[uxbox.main.ui.lightbox :as lbx]
[uxbox.util.blob :as blob]
[uxbox.util.data :refer (read-string)]
@ -44,7 +44,7 @@
(defn- download-page-svg
[{:keys [name id] :as page}]
(let [content (or (exports/render-page id) "")
(let [content (or #_(exports/render-page id) "")
blob (blob/create content "image/svg+xml")
uri (blob/create-uri blob)
link (.createElement js/document "a")
@ -64,7 +64,7 @@
(defn- generate-files
[pages]
(reduce (fn [acc {:keys [id name]}]
(let [content (or (exports/render-page id) "")]
(let [content (or #_(exports/render-page id) "")]
(conj acc [(str (str/uslug name) ".svg")
(blob/create content "image/svg+xml")])))
[]

View file

@ -6,8 +6,7 @@
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.util.dom
(:require [goog.dom :as dom]
[cljsjs.react.dom.server]))
(:require [goog.dom :as dom]))
;; --- Deprecated methods
@ -25,10 +24,6 @@
;; --- New methods
(defn render-to-html
[component]
(.renderToStaticMarkup js/ReactDOMServer component))
(defn get-element-by-class
([classname]
(dom/getElementByClass classname))