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

Improved dashboard thumbnails

This commit is contained in:
alonso.torres 2023-12-12 10:05:53 +01:00
parent 5522430afe
commit 030ff398ed
9 changed files with 90 additions and 40 deletions

View file

@ -9,6 +9,7 @@
[app.common.spec :as us]
[app.db :as db]
[app.rpc :as-alias rpc]
[app.rpc.commands.files :refer [resolve-public-uri]]
[app.rpc.doc :as-alias doc]
[app.util.services :as sv]
[clojure.spec.alpha :as s]))
@ -37,12 +38,15 @@
)
select distinct
f.id,
f.revn,
f.project_id,
f.created_at,
f.modified_at,
f.name,
f.is_shared
f.is_shared,
ft.media_id
from file as f
left join file_thumbnail as ft on (ft.file_id = f.id and ft.revn = f.revn)
inner join projects as pr on (f.project_id = pr.id)
where f.name ilike ('%' || ? || '%')
and (f.deleted_at is null or f.deleted_at > now())
@ -50,10 +54,16 @@
(defn search-files
[conn profile-id team-id search-term]
(db/exec! conn [sql:search-files
profile-id team-id
profile-id team-id
search-term]))
(->> (db/exec! conn [sql:search-files
profile-id team-id
profile-id team-id
search-term])
(mapv (fn [row]
(if-let [media-id (:media-id row)]
(-> row
(dissoc :media-id)
(assoc :thumbnail-uri (resolve-public-uri media-id)))
(dissoc row :media-id))))))
(s/def ::team-id ::us/uuid)
(s/def ::search-files ::us/string)

View file

@ -353,3 +353,19 @@
(mth/max by1 y1)
(mth/min bx2 x2)
(mth/min by2 y2)))))
(defn fix-aspect-ratio
[bounds aspect-ratio]
(if aspect-ratio
(let [width (dm/get-prop bounds :width)
height (dm/get-prop bounds :height)
target-height (* width aspect-ratio)
target-width (* height (/ 1 aspect-ratio))]
(cond-> bounds
(> target-height height)
(-> (assoc :height target-height)
(update :y - (/ (- target-height height ) 2)))
(< target-height height)
(-> (assoc :width target-width)
(update :x - (/ (- target-width width ) 2)))))
bounds))

View file

@ -831,9 +831,15 @@
(ptk/reify ::set-file-thumbnail
ptk/UpdateEvent
(update [_ state]
(-> state
(d/update-in-when [:dashboard-files file-id] assoc :thumbnail-uri thumbnail-uri)
(d/update-in-when [:dashboard-recent-files file-id] assoc :thumbnail-uri thumbnail-uri)))))
(letfn [(update-search-files [files]
(->> files
(mapv #(cond-> %
(= file-id (:id %))
(assoc :thumbnail-uri thumbnail-uri)))))]
(-> state
(d/update-in-when [:dashboard-files file-id] assoc :thumbnail-uri thumbnail-uri)
(d/update-in-when [:dashboard-recent-files file-id] assoc :thumbnail-uri thumbnail-uri)
(d/update-when :dashboard-search-result update-search-files))))))
;; --- EVENT: create-file

View file

@ -66,16 +66,18 @@
:fill color}])
(defn- calculate-dimensions
[objects]
(let [bounds (->> (ctst/get-root-objects objects)
(map (partial gsb/get-object-bounds objects))
(grc/join-rects))]
[objects aspect-ratio]
(let [bounds
(->> (ctst/get-root-objects objects)
(map (partial gsb/get-object-bounds objects))
(grc/join-rects))]
(-> bounds
(update :x mth/finite 0)
(update :y mth/finite 0)
(update :width mth/finite 100000)
(update :height mth/finite 100000)
(grc/update-rect :position))))
(grc/update-rect :position)
(grc/fix-aspect-ratio aspect-ratio))))
(declare shape-wrapper-factory)
@ -194,11 +196,11 @@
(mf/defc page-svg
{::mf/wrap [mf/memo]}
[{:keys [data use-thumbnails embed include-metadata] :as props
[{:keys [data use-thumbnails embed include-metadata aspect-ratio] :as props
:or {embed false include-metadata false}}]
(let [objects (:objects data)
shapes (cfh/get-immediate-children objects)
dim (calculate-dimensions objects)
dim (calculate-dimensions objects aspect-ratio)
vbox (format-viewbox dim)
bgcolor (dm/get-in data [:options :background] default-color)
@ -253,11 +255,14 @@
;; the viewer and inspector
(mf/defc frame-svg
{::mf/wrap [mf/memo]}
[{:keys [objects frame zoom use-thumbnails] :or {zoom 1} :as props}]
[{:keys [objects frame zoom use-thumbnails aspect-ratio background-color] :or {zoom 1} :as props}]
(let [frame-id (:id frame)
bgcolor (d/nilv background-color default-color)
include-metadata (mf/use-ctx export/include-metadata-ctx)
bounds (gsb/get-object-bounds objects frame)
bounds (-> (gsb/get-object-bounds objects frame)
(grc/fix-aspect-ratio aspect-ratio))
;; Bounds without shadows/blur will be the bounds of the thumbnail
bounds2 (gsb/get-object-bounds objects (dissoc frame :shadow :blur))
@ -305,6 +310,7 @@
:xmlns "http://www.w3.org/2000/svg"
:xmlnsXlink "http://www.w3.org/1999/xlink"
:xmlns:penpot (when include-metadata "https://penpot.app/xmlns")
:style {:background bgcolor}
:fill "none"}
[:& shape-wrapper {:shape frame}]]]))

View file

@ -61,7 +61,7 @@
(rx/map (fn [styles]
(assoc result
:styles styles
:width 250))))))
:width 252))))))
(rx/mapcat thr/render)
(rx/mapcat (partial persist-thumbnail file-id revn))))

View file

@ -7,7 +7,7 @@
@import "refactor/common-refactor.scss";
$thumbnail-default-width: $s-252; // Default width
$thumbnail-aspect-ration: #{2 / 3}; // Ratio 2:3
$thumbnail-default-height: $s-168; // Default width
.dashboard-grid {
font-size: $fs-14;
@ -44,10 +44,12 @@ $thumbnail-aspect-ration: #{2 / 3}; // Ratio 2:3
}
.grid-item-th {
border-radius: $br-4;
border-radius: $br-8;
text-align: initial;
width: var(--th-width, #{$thumbnail-default-width});
height: calc(var(--th-width, #{$thumbnail-default-width}) * #{$thumbnail-aspect-ration});
height: var(--th-height, #{$thumbnail-default-height});
background-size: cover;
overflow: hidden;
img {
object-fit: contain;
@ -59,7 +61,7 @@ $thumbnail-aspect-ration: #{2 / 3}; // Ratio 2:3
outline: $br-4 solid $da-primary;
text-align: initial;
width: calc(var(--th-width) + $s-12);
height: calc(var(--th-width, #{$thumbnail-default-width}) * #{$thumbnail-aspect-ration});
height: var(--th-height, #{$thumbnail-default-height});
}
&.overlay {
@ -131,10 +133,10 @@ $thumbnail-aspect-ration: #{2 / 3}; // Ratio 2:3
.item-badge {
background-color: $da-primary;
border: none;
border-radius: $br-4;
border-radius: $br-6;
position: absolute;
top: $s-8;
right: $s-8;
top: $s-12;
right: $s-12;
height: $s-32;
width: $s-32;
display: flex;
@ -258,17 +260,10 @@ $thumbnail-aspect-ration: #{2 / 3}; // Ratio 2:3
.grid-item-th {
border-radius: $br-4;
cursor: pointer;
background-position: center;
background-size: auto 80%;
background-repeat: no-repeat;
height: 100%;
overflow: hidden;
position: relative;
width: 100%;
background-color: var(--canvas-color);
display: flex;
justify-content: center;
flex-direction: row;
@ -283,8 +278,9 @@ $thumbnail-aspect-ration: #{2 / 3}; // Ratio 2:3
width: 100%;
}
svg#loader-pencil {
fill: $db-cuaternary;
:global(svg#loader-pencil) {
stroke: $db-cuaternary;
width: calc(var(--th-width, #{$thumbnail-default-width}) * 0.25);
}
}

View file

@ -65,7 +65,7 @@
text-transform: uppercase;
border: $s-2 solid transparent;
width: var(--th-width, #{g.$thumbnail-default-width});
height: calc(var(--th-width, #{g.$thumbnail-default-width}) * #{g.$thumbnail-aspect-ration});
height: var(--th-height, #{g.$thumbnail-default-height});
svg {
width: $s-32;

View file

@ -367,13 +367,17 @@
limit (mth/max 1 limit)
th-size (when width
(- (/ (- width 32 (* (dec limit) 24)) limit) 12))]
(mth/floor (- (/ (- width 32 (* (dec limit) 24)) limit) 12)))
;; Need an even value
th-size (if (odd? (int th-size)) (- th-size 1) th-size)]
(mf/with-effect
[th-size]
(when th-size
(let [node (mf/ref-val rowref)]
(.setProperty (.-style node) "--th-width" (str th-size "px")))))
(.setProperty (.-style node) "--th-width" (str th-size "px"))
(.setProperty (.-style node) "--th-height" (str (mth/ceil (* th-size (/ 2 3))) "px")))))
(mf/with-effect []
(let [node (mf/ref-val rowref)

View file

@ -7,6 +7,7 @@
(ns app.worker.thumbnails
(:require
["react-dom/server" :as rds]
[app.common.data.macros :as dm]
[app.common.logging :as log]
[app.common.uri :as u]
[app.config :as cf]
@ -62,16 +63,27 @@
(binding [fonts/loaded-hints (l/atom #{})]
(let [objects (:objects page)
frame (some->> page :thumbnail-frame-id (get objects))
background-color (dm/get-in page [:options :background])
element (if frame
(mf/element render/frame-svg #js {:objects objects :frame frame :use-thumbnails true})
(mf/element render/page-svg #js {:data page :use-thumbnails true :embed true}))
(mf/element render/frame-svg #js
{:objects objects
:frame frame
:use-thumbnails true
:background-color background-color
:aspect-ratio (/ 2 3)})
(mf/element render/page-svg #js
{:data page
:use-thumbnails true
:embed true
:aspect-ratio (/ 2 3)}))
data (rds/renderToStaticMarkup element)]
{:data data
:fonts @fonts/loaded-hints
:file-id file-id
:revn revn}))
(catch :default cause
(js/console.error "unexpected erorr on rendering thumbnail" cause)
(js/console.error "unexpected error on rendering thumbnail" cause)
nil)))
(defmethod impl/handler :thumbnails/generate-for-file