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

View file

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

View file

@ -15,6 +15,7 @@
[uxbox.main.constants :as c] [uxbox.main.constants :as c]
[uxbox.main.data.projects :as udp] [uxbox.main.data.projects :as udp]
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.exports :as exports]
[uxbox.main.ui.modal :as modal] [uxbox.main.ui.modal :as modal]
[uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.confirm :refer [confirm-dialog]] [uxbox.main.ui.confirm :refer [confirm-dialog]]
@ -66,10 +67,27 @@
;; --- Grid Item Thumbnail ;; --- 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 (mf/defc grid-item-thumbnail
[{:keys [project] :as props}] [{: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 [:div.grid-item-th
[:img.img-th {:src "/images/project-placeholder.svg"}]]) [:img.img-th {:src url}]]))
;; --- Grid Item ;; --- Grid Item

View file

@ -32,16 +32,3 @@
:image [:& image/image-wrapper {:shape shape}] :image [:& image/image-wrapper {:shape shape}]
:circle [:& circle/circle-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.color :as color]
[uxbox.util.data :refer [classnames normalize-props]] [uxbox.util.data :refer [classnames normalize-props]]
[uxbox.util.dom :as dom] [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 ;; TODO: this code need a good refactor
@ -150,7 +157,7 @@
(fn [own] (fn [own]
(let [shape (get-in own [::mf/props :shape]) (let [shape (get-in own [::mf/props :shape])
dom (mf/ref-node (::fobject 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)) (set! (.-innerHTML dom) html))
own) own)
@ -204,7 +211,7 @@
(fn [own] (fn [own]
(let [shape (::mf/props own) (let [shape (::mf/props own)
dom (mf/ref-node (::fobject 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)) (set! (.-innerHTML dom) html))
own) own)

View file

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

View file

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