mirror of
https://github.com/penpot/penpot.git
synced 2025-08-06 08:18:26 +02:00
♻️ Refactor file persistence layer.
This commit is contained in:
parent
182afedc54
commit
4e694ff194
86 changed files with 3205 additions and 3313 deletions
|
@ -1,22 +1,34 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.dashboard.grid
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[beicon.core :as rx]
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cfg]
|
||||
[app.main.data.dashboard :as dsh]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.modal :as modal]
|
||||
[app.main.ui.keyboard :as kbd]
|
||||
[app.main.ui.confirm :refer [confirm-dialog]]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
[app.main.worker :as wrk]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
[app.main.ui.confirm :refer [confirm-dialog]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.keyboard :as kbd]
|
||||
[app.main.ui.modal :as modal]
|
||||
[app.main.worker :as wrk]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [t tr]]
|
||||
[app.util.router :as rt]
|
||||
[app.util.time :as dt]
|
||||
[app.util.timers :as ts]
|
||||
[app.util.time :as dt]))
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[lambdaisland.uri :as uri]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
;; --- Grid Item Thumbnail
|
||||
|
||||
|
@ -25,15 +37,15 @@
|
|||
[{:keys [file] :as props}]
|
||||
(let [container (mf/use-ref)]
|
||||
(mf/use-effect
|
||||
(mf/deps file)
|
||||
(mf/deps (:id file))
|
||||
(fn []
|
||||
(-> (wrk/ask! {:cmd :thumbnails/generate
|
||||
:id (first (:pages file))
|
||||
})
|
||||
(rx/subscribe (fn [{:keys [svg fonts]}]
|
||||
(run! fonts/ensure-loaded! fonts)
|
||||
(when-let [node (mf/ref-val container)]
|
||||
(set! (.-innerHTML ^js node) svg)))))))
|
||||
(->> (wrk/ask! {:cmd :thumbnails/generate
|
||||
:file-id (:id file)
|
||||
:page-id (get-in file [:data :pages 0])})
|
||||
(rx/subs (fn [{:keys [svg fonts]}]
|
||||
(run! fonts/ensure-loaded! fonts)
|
||||
(when-let [node (mf/ref-val container)]
|
||||
(set! (.-innerHTML ^js node) svg)))))))
|
||||
[:div.grid-item-th {:style {:background-color (get-in file [:data :options :background])}
|
||||
:ref container}]))
|
||||
|
||||
|
@ -41,61 +53,90 @@
|
|||
|
||||
(mf/defc grid-item-metadata
|
||||
[{:keys [modified-at]}]
|
||||
(let [locale (i18n/use-locale)
|
||||
time (dt/timeago modified-at {:locale locale})]
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
time (dt/timeago modified-at {:locale locale})]
|
||||
(str (t locale "ds.updated-at" time))))
|
||||
|
||||
(mf/defc grid-item
|
||||
{:wrap [mf/memo]}
|
||||
[{:keys [file] :as props}]
|
||||
(let [local (mf/use-state {:menu-open false
|
||||
:edition false})
|
||||
locale (i18n/use-locale)
|
||||
on-navigate #(st/emit! (rt/nav :workspace
|
||||
{:project-id (:project-id file)
|
||||
:file-id (:id file)}
|
||||
{:page-id (first (:pages file))}))
|
||||
delete-fn #(st/emit! nil (dsh/delete-file (:id file)))
|
||||
on-delete #(do
|
||||
(dom/stop-propagation %)
|
||||
(modal/show! confirm-dialog {:on-accept delete-fn}))
|
||||
[{:keys [id file] :as props}]
|
||||
(let [local (mf/use-state {:menu-open false :edition false})
|
||||
locale (mf/deref i18n/locale)
|
||||
|
||||
delete (mf/use-callback (mf/deps id) #(st/emit! nil (dsh/delete-file id)))
|
||||
add-shared (mf/use-callback (mf/deps id) #(st/emit! (dsh/set-file-shared id true)))
|
||||
del-shared (mf/use-callback (mf/deps id) #(st/emit! (dsh/set-file-shared id false)))
|
||||
on-close (mf/use-callback #(swap! local assoc :menu-open false))
|
||||
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! confirm-dialog {:on-accept delete})))
|
||||
|
||||
on-navigate
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn []
|
||||
(let [pparams {:project-id (:project-id file)
|
||||
:file-id (:id file)}
|
||||
qparams {:page-id (first (get-in file [:data :pages]))}]
|
||||
(st/emit! (rt/nav :workspace pparams qparams)))))
|
||||
|
||||
add-shared-fn #(st/emit! nil (dsh/set-file-shared (:id file) true))
|
||||
on-add-shared
|
||||
#(do
|
||||
(dom/stop-propagation %)
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! confirm-dialog
|
||||
{:message (t locale "dashboard.grid.add-shared-message" (:name file))
|
||||
:hint (t locale "dashboard.grid.add-shared-hint")
|
||||
:accept-text (t locale "dashboard.grid.add-shared-accept")
|
||||
:not-danger? true
|
||||
:on-accept add-shared-fn}))
|
||||
:on-accept add-shared})))
|
||||
|
||||
remove-shared-fn #(st/emit! nil (dsh/set-file-shared (:id file) false))
|
||||
on-remove-shared
|
||||
#(do
|
||||
(dom/stop-propagation %)
|
||||
on-edit
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(swap! local assoc :edition true)))
|
||||
|
||||
on-del-shared
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! confirm-dialog
|
||||
{:message (t locale "dashboard.grid.remove-shared-message" (:name file))
|
||||
:hint (t locale "dashboard.grid.remove-shared-hint")
|
||||
:accept-text (t locale "dashboard.grid.remove-shared-accept")
|
||||
:not-danger? false
|
||||
:on-accept remove-shared-fn}))
|
||||
:on-accept del-shared})))
|
||||
|
||||
on-blur #(let [name (-> % dom/get-target dom/get-value)]
|
||||
(st/emit! (dsh/rename-file (:id file) name))
|
||||
(swap! local assoc :edition false))
|
||||
on-menu-click
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(swap! local assoc :menu-open true)))
|
||||
|
||||
on-key-down #(cond
|
||||
(kbd/enter? %) (on-blur %)
|
||||
(kbd/esc? %) (swap! local assoc :edition false))
|
||||
on-menu-click #(do
|
||||
(dom/stop-propagation %)
|
||||
(swap! local assoc :menu-open true))
|
||||
on-menu-close #(swap! local assoc :menu-open false)
|
||||
on-edit #(do
|
||||
(dom/stop-propagation %)
|
||||
(swap! local assoc :edition true))]
|
||||
on-blur
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn [event]
|
||||
(let [name (-> event dom/get-target dom/get-value)]
|
||||
(st/emit! (dsh/rename-file id name))
|
||||
(swap! local assoc :edition false))))
|
||||
|
||||
on-key-down
|
||||
(mf/use-callback
|
||||
#(cond
|
||||
(kbd/enter? %) (on-blur %)
|
||||
(kbd/esc? %) (swap! local assoc :edition false)))
|
||||
|
||||
]
|
||||
[:div.grid-item.project-th {:on-click on-navigate}
|
||||
[:div.overlay]
|
||||
[:& grid-item-thumbnail {:file file}]
|
||||
|
@ -113,42 +154,39 @@
|
|||
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
|
||||
[:div.project-th-actions {:class (dom/classnames
|
||||
:force-display (:menu-open @local))}
|
||||
;; [:div.project-th-icon.pages
|
||||
;; i/page
|
||||
;; #_[:span (:total-pages project)]]
|
||||
;; [:div.project-th-icon.comments
|
||||
;; i/chat
|
||||
;; [:span "0"]]
|
||||
[:div.project-th-icon.menu
|
||||
{:on-click on-menu-click}
|
||||
i/actions]
|
||||
[:& context-menu {:on-close on-menu-close
|
||||
[:& context-menu {:on-close on-close
|
||||
:show (:menu-open @local)
|
||||
:options [[(t locale "dashboard.grid.rename") on-edit]
|
||||
[(t locale "dashboard.grid.delete") on-delete]
|
||||
(if (:is-shared file)
|
||||
[(t locale "dashboard.grid.remove-shared") on-remove-shared]
|
||||
[(t locale "dashboard.grid.remove-shared") on-del-shared]
|
||||
[(t locale "dashboard.grid.add-shared") on-add-shared])]}]]]))
|
||||
|
||||
;; --- Grid
|
||||
|
||||
(mf/defc grid
|
||||
[{:keys [id opts files hide-new?] :as props}]
|
||||
(let [locale (i18n/use-locale)
|
||||
order (:order opts :modified)
|
||||
filter (:filter opts "")
|
||||
on-click #(do
|
||||
(dom/prevent-default %)
|
||||
(st/emit! (dsh/create-file id)))]
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
click #(st/emit! (dsh/create-file id))]
|
||||
[:section.dashboard-grid
|
||||
(if (> (count files) 0)
|
||||
[:div.dashboard-grid-row
|
||||
(when (not hide-new?)
|
||||
[:div.grid-item.add-file {:on-click on-click}
|
||||
[:span (tr "ds.new-file")]])
|
||||
(for [item files]
|
||||
[:& grid-item {:file item :key (:id item)}])]
|
||||
[:div.grid-files-empty
|
||||
[:div.grid-files-desc (t locale "dashboard.grid.empty-files")]
|
||||
[:div.grid-files-link
|
||||
[:a.btn-secondary.btn-small {:on-click on-click} (t locale "ds.new-file")]]])]))
|
||||
(cond
|
||||
(pos? (count files))
|
||||
[:div.dashboard-grid-row
|
||||
(when (not hide-new?)
|
||||
[:div.grid-item.add-file {:on-click click}
|
||||
[:span (t locale "ds.new-file")]])
|
||||
|
||||
(for [item files]
|
||||
[:& grid-item
|
||||
{:id (:id item)
|
||||
:file item
|
||||
:key (:id item)}])]
|
||||
|
||||
(zero? (count files))
|
||||
[:div.grid-files-empty
|
||||
[:div.grid-files-desc (t locale "dashboard.grid.empty-files")]
|
||||
[:div.grid-files-link
|
||||
[:a.btn-secondary.btn-small {:on-click click} (t locale "ds.new-file")]]])]))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue