mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 07:29:08 -05:00
Major images page refactor.
This commit is contained in:
parent
5b995f78aa
commit
2143bb6e04
6 changed files with 326 additions and 105 deletions
|
@ -2,8 +2,7 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.main.data.images
|
||||
(:require [cuerdas.core :as str]
|
||||
|
@ -26,10 +25,8 @@
|
|||
(defrecord Initialize [type id]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(let [type (or type :builtin)
|
||||
id (or id (if (= type :builtin) 1 nil))
|
||||
(let [type (or type :own)
|
||||
data {:type type :id id :selected #{}}]
|
||||
(println "initialize:" data)
|
||||
(-> state
|
||||
(assoc-in [:dashboard :images] data)
|
||||
(assoc-in [:dashboard :section] :dashboard/images))))
|
||||
|
@ -159,8 +156,8 @@
|
|||
(rx/of (update-collection id))))
|
||||
|
||||
(defn rename-collection
|
||||
[item name]
|
||||
(RenameCollection. item name))
|
||||
[id name]
|
||||
(RenameCollection. id name))
|
||||
|
||||
;; --- Delete Collection
|
||||
|
||||
|
@ -193,7 +190,7 @@
|
|||
|
||||
(def allowed-file-types #{"image/jpeg" "image/png"})
|
||||
|
||||
(defrecord CreateImages [coll-id files]
|
||||
(defrecord CreateImages [id files]
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(letfn [(image-size [file]
|
||||
|
@ -202,7 +199,7 @@
|
|||
(allowed-file? [file]
|
||||
(contains? allowed-file-types (.-type file)))
|
||||
(prepare [[file [width height]]]
|
||||
{:coll coll-id
|
||||
{:collection id
|
||||
:mimetype (.-type file)
|
||||
:id (uuid/random)
|
||||
:file file
|
||||
|
@ -217,12 +214,13 @@
|
|||
(rx/map image-created)))))
|
||||
|
||||
(defn create-images
|
||||
[coll-id files]
|
||||
(CreateImages. coll-id files))
|
||||
[id files]
|
||||
{:pre [(or (uuid? id) (nil? id))]}
|
||||
(CreateImages. id files))
|
||||
|
||||
;; --- Images Fetched
|
||||
|
||||
(defrecord ImagesFetched [coll-id items]
|
||||
(defrecord ImagesFetched [items]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(reduce (fn [state {:keys [id] :as image}]
|
||||
|
@ -231,58 +229,77 @@
|
|||
items)))
|
||||
|
||||
(defn images-fetched
|
||||
[coll-id items]
|
||||
(ImagesFetched. coll-id items))
|
||||
[items]
|
||||
(ImagesFetched. items))
|
||||
|
||||
;; --- Fetch Images
|
||||
|
||||
(defrecord FetchImages [coll-id]
|
||||
(defrecord FetchImages [id]
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(let [params {:coll coll-id}]
|
||||
(let [params {:coll id}]
|
||||
(->> (rp/req :fetch/images params)
|
||||
(rx/map :payload)
|
||||
(rx/map #(images-fetched coll-id %))))))
|
||||
(rx/map images-fetched)))))
|
||||
|
||||
(defn fetch-images
|
||||
[coll-id]
|
||||
(FetchImages. coll-id))
|
||||
"Fetch a list of images of the selected collection"
|
||||
[id]
|
||||
{:pre [(or (uuid? id) (nil? id))]}
|
||||
(FetchImages. id))
|
||||
|
||||
;; --- Fetch Image
|
||||
|
||||
(declare image-fetched)
|
||||
|
||||
(defrecord FetchImage [id]
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state stream]
|
||||
(let [existing (get-in state [:images-by-id id])]
|
||||
(if existing
|
||||
(rx/empty)
|
||||
(->> (rp/req :fetch/image {:id id})
|
||||
(rx/map :payload)
|
||||
(rx/map image-fetched))))))
|
||||
|
||||
(defn fetch-image
|
||||
"Conditionally fetch image by its id. If image
|
||||
is already loaded, this event is noop."
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(FetchImage. id))
|
||||
|
||||
;; --- Image Fetched
|
||||
|
||||
(defrecord ImageFetched [image]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(let [id (:id image)]
|
||||
(update state :images-by-id assoc id image))))
|
||||
|
||||
(defn image-fetched
|
||||
[image]
|
||||
{:pre [(map? image)]}
|
||||
(ImageFetched. image))
|
||||
|
||||
;; --- Delete Images
|
||||
|
||||
(defrecord DeleteImage [coll-id image-id]
|
||||
(defrecord DeleteImage [id]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(update state [:images-by-id] dissoc image-id))
|
||||
(-> state
|
||||
(update :images-by-id dissoc id)
|
||||
(update-in [:dashboard :images :selected] disj id)))
|
||||
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(->> (rp/req :delete/image image-id)
|
||||
(->> (rp/req :delete/image id)
|
||||
(rx/ignore))))
|
||||
|
||||
(defn delete-image
|
||||
[coll-id image-id]
|
||||
{:pre [(uuid? coll-id)
|
||||
(uuid? image-id)]}
|
||||
(DeleteImage. coll-id image-id))
|
||||
|
||||
;; --- Remove Image
|
||||
|
||||
(defrecord RemoveImages [id images]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
#_(update-in state [:image-colls-by-id id :data]
|
||||
#(set/difference % images)))
|
||||
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(rx/of (update-collection id))))
|
||||
|
||||
(defn remove-images
|
||||
"Remove image in a collection."
|
||||
[id images]
|
||||
(RemoveImages. id images))
|
||||
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(DeleteImage. id))
|
||||
|
||||
;; --- Select image
|
||||
|
||||
|
@ -314,9 +331,9 @@
|
|||
(defrecord DeleteSelected []
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state stream]
|
||||
(let [{:keys [id selected]} (get-in state [:dashboard :images])]
|
||||
(rx/of (remove-images id selected)
|
||||
#(assoc-in % [:dashboard :images :selected] #{})))))
|
||||
(let [selected (get-in state [:dashboard :images :selected])]
|
||||
(->> (rx/from-coll selected)
|
||||
(rx/map delete-image)))))
|
||||
|
||||
(defn delete-selected
|
||||
[]
|
||||
|
|
|
@ -40,20 +40,28 @@
|
|||
|
||||
(defmethod request :fetch/images
|
||||
[_ {:keys [coll]}]
|
||||
(let [params {:url (str url "/library/image-collections/" coll "/images")
|
||||
(let [url (if coll
|
||||
(str url "/library/image-collections/" coll "/images")
|
||||
(str url "/library/image-collections/images"))
|
||||
params {:url url :method :get}]
|
||||
(send! params)))
|
||||
|
||||
(defmethod request :fetch/image
|
||||
[_ {:keys [id]}]
|
||||
(let [params {:url (str url "/library/images/" id)
|
||||
:method :get}]
|
||||
(send! params)))
|
||||
|
||||
(defmethod request :create/image
|
||||
[_ {:keys [coll id file width height mimetype] :as body}]
|
||||
[_ {:keys [collection id file width height mimetype] :as body}]
|
||||
(let [body (doto (js/FormData.)
|
||||
(.append "mimetype" mimetype)
|
||||
;; (.append "collection" (str coll))
|
||||
(.append "collection" (str collection))
|
||||
(.append "file" file)
|
||||
(.append "width" width)
|
||||
(.append "height" height)
|
||||
(.append "id" id))
|
||||
params {:url (str url "/library/image-collections/" coll "/images")
|
||||
params {:url (str url "/library/images/")
|
||||
:method :post
|
||||
:body body}]
|
||||
(send! params)))
|
||||
|
|
|
@ -166,19 +166,148 @@
|
|||
(defn- new-element-lightbox-render
|
||||
[own]
|
||||
(html
|
||||
[:div.lightbox-body
|
||||
[:h3 "New element"]
|
||||
[:div.row-flex
|
||||
[:div.lightbox-big-btn
|
||||
[:span.big-svg i/shapes]
|
||||
[:span.text "Go to workspace"]]
|
||||
[:div.lightbox-big-btn
|
||||
[:span.big-svg.upload i/exit]
|
||||
[:span.text "Upload file"]]]
|
||||
;;------Element lightbox
|
||||
|
||||
;;[:div.lightbox-body
|
||||
;;[:h3 "New element"]
|
||||
;;[:div.row-flex
|
||||
;;[:div.lightbox-big-btn
|
||||
;;[:span.big-svg i/shapes]
|
||||
;;[:span.text "Go to workspace"]]
|
||||
;;[:div.lightbox-big-btn
|
||||
;;[:span.big-svg.upload i/exit]
|
||||
;;[:span.text "Upload file"]]]
|
||||
;;[:a.close {:href "#"
|
||||
;;:on-click #(do (dom/prevent-default %)
|
||||
;;(udl/close!))}
|
||||
;;i/close]]
|
||||
|
||||
;;------Upload image lightbox
|
||||
|
||||
;;[:div.lightbox-body
|
||||
;;[:h3 "Import image"]
|
||||
;;[:div.row-flex
|
||||
;;[:div.lightbox-big-btn
|
||||
;;[:span.big-svg i/image]
|
||||
;;[:span.text "Select from library"]]
|
||||
;;[:div.lightbox-big-btn
|
||||
;;[:span.big-svg.upload i/exit]
|
||||
;;[:span.text "Upload file"]]]
|
||||
;;[:a.close {:href "#"
|
||||
;;:on-click #(do (dom/prevent-default %)
|
||||
;;(udl/close!))}
|
||||
;;i/close]]
|
||||
|
||||
;;------Upload image library lightbox
|
||||
|
||||
[:div.lightbox-body.big-lightbox
|
||||
[:h3 "Import image from library"]
|
||||
[:div.import-img-library
|
||||
[:div.library-actions
|
||||
[:ul.toggle-library
|
||||
[:li.standard.current "STANDARD"]
|
||||
[:li.your-images "YOUR IMAGES"]]
|
||||
[:select.input-select
|
||||
[:option "Library 1"]
|
||||
[:option "Library 2"]
|
||||
[:option "Library 3"]
|
||||
[:option "Library 4"]
|
||||
[:option "Library 5"]
|
||||
[:option "Library 6"]]]
|
||||
|
||||
[:div.library-content
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
[:div.library-item
|
||||
[:div.library-item-th
|
||||
{:style
|
||||
{:background-image "url('https://images.unsplash.com/photo-1441986380878-c4248f5b8b5b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=1080&fit=max&s=486f09671860a11e70bdd0a45e7c5014')"}}]
|
||||
[:span "image_name.jpg"]]
|
||||
|
||||
]]
|
||||
[:a.close {:href "#"
|
||||
:on-click #(do (dom/prevent-default %)
|
||||
(udl/close!))}
|
||||
i/close]]))
|
||||
i/close]]
|
||||
|
||||
))
|
||||
|
||||
(def ^:private new-element-lightbox
|
||||
(mx/component
|
||||
|
|
|
@ -6,25 +6,19 @@
|
|||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
(ns uxbox.main.ui.dashboard.images
|
||||
(:require [sablono.core :as html :refer-macros [html]]
|
||||
[rum.core :as rum]
|
||||
[cuerdas.core :as str]
|
||||
(:require [cuerdas.core :as str]
|
||||
[lentes.core :as l]
|
||||
[uxbox.util.i18n :as t :refer (tr)]
|
||||
[uxbox.main.state :as st]
|
||||
[uxbox.util.rstore :as rs]
|
||||
[uxbox.main.library :as library]
|
||||
[uxbox.main.data.dashboard :as dd]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.data.images :as di]
|
||||
[uxbox.main.ui.icons :as i]
|
||||
[uxbox.util.mixins :as mx :include-macros true]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.main.ui.keyboard :as kbd]
|
||||
[uxbox.main.ui.library-bar :as ui.library-bar]
|
||||
[uxbox.main.ui.dashboard.header :refer (header)]
|
||||
[uxbox.util.data :as data :refer (read-string)]
|
||||
[uxbox.util.lens :as ul]
|
||||
[uxbox.util.dom :as dom]))
|
||||
|
||||
;; --- Helpers & Constants
|
||||
|
@ -65,15 +59,6 @@
|
|||
(-> (l/key :images-by-id)
|
||||
(l/derive st/state)))
|
||||
|
||||
;; (def ^:private collections-ref
|
||||
;; (-> (l/lens vals)
|
||||
;; (l/derive collections-map-ref)))
|
||||
|
||||
;; (defn- focus-collection
|
||||
;; [id]
|
||||
;; (-> (l/key id)
|
||||
;; (l/derive collections-map-ref)))
|
||||
|
||||
;; --- Page Title
|
||||
|
||||
(mx/defcs page-title
|
||||
|
@ -117,7 +102,7 @@
|
|||
[:span.close {:on-click on-cancel} i/close]]
|
||||
[:span.dashboard-title-field
|
||||
{:on-double-click on-edit}
|
||||
(:name coll)])]
|
||||
(:name coll "Storage")])]
|
||||
(if (and (not own?) coll)
|
||||
[:div.edition
|
||||
(if edit?
|
||||
|
@ -127,19 +112,26 @@
|
|||
|
||||
;; --- Nav
|
||||
|
||||
(defn react-count-images
|
||||
[id]
|
||||
(->> (mx/react images-ref)
|
||||
(vals)
|
||||
(filter #(= id (:collection %)))
|
||||
(count)))
|
||||
|
||||
(mx/defc nav-item
|
||||
{:mixins [mx/static]}
|
||||
[collection selected?]
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
[{:keys [id type name] :as coll} selected?]
|
||||
(letfn [(on-click [event]
|
||||
(let [type (:type collection)
|
||||
id (:id collection)]
|
||||
(let [type (or type :own)]
|
||||
(rs/emit! (di/select-collection type id))))]
|
||||
(let [images (count (:images collection []))]
|
||||
(let [num-images (react-count-images id)]
|
||||
[:li {:on-click on-click
|
||||
:class-name (when selected? "current")}
|
||||
[:span.element-title (:name collection)]
|
||||
[:span.element-title
|
||||
(if coll name "Storage")]
|
||||
[:span.element-subtitle
|
||||
(tr "ds.num-elements" (t/c images))]])))
|
||||
(tr "ds.num-elements" (t/c num-images))]])))
|
||||
|
||||
(mx/defc nav-section
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
|
@ -156,6 +148,8 @@
|
|||
[:a.btn-primary
|
||||
{:on-click #(rs/emit! (di/create-collection))}
|
||||
"+ New library"]])
|
||||
(when own?
|
||||
(nav-item nil (nil? selected)))
|
||||
(for [coll collections
|
||||
:let [selected? (= (:id coll) selected)
|
||||
key (str (:id coll))]]
|
||||
|
@ -179,12 +173,13 @@
|
|||
[:div.library-bar
|
||||
[:div.library-bar-inside
|
||||
[:ul.library-tabs
|
||||
[:li {:class-name (when builtin? "current")
|
||||
:on-click (partial select-tab :builtin)}
|
||||
"STANDARD"]
|
||||
[:li {:class-name (when own? "current")
|
||||
:on-click (partial select-tab :own)}
|
||||
"YOUR LIBRARIES"]]
|
||||
"YOUR IMAGES"]
|
||||
[:li {:class-name (when builtin? "current")
|
||||
:on-click (partial select-tab :builtin)}
|
||||
"IMAGES STORE"]]
|
||||
|
||||
(nav-section type id colls)]])))
|
||||
|
||||
;; --- Grid
|
||||
|
@ -208,15 +203,15 @@
|
|||
:on-change on-file-selected}]]))
|
||||
|
||||
(mx/defc grid-options
|
||||
[coll]
|
||||
(let [own? (= (:type coll) :own)]
|
||||
[{:keys [type] :as coll}]
|
||||
(let [editable? (or (= type :own) (nil? coll))]
|
||||
(letfn [(delete []
|
||||
(rs/emit! (di/delete-selected)))
|
||||
(on-delete [event]
|
||||
(udl/open! :confirm {:on-accept delete}))]
|
||||
;; MULTISELECT OPTIONS BAR
|
||||
[:div.multiselect-bar
|
||||
(if own?
|
||||
(if editable?
|
||||
[:div.multiselect-nav
|
||||
#_[:span.move-item.tooltip.tooltip-top
|
||||
{:alt "Move to"}
|
||||
|
@ -251,19 +246,18 @@
|
|||
|
||||
(mx/defc grid
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
[{:keys [id type selected] :as state}]
|
||||
(let [filtering (:filter state)
|
||||
[{:keys [id type selected] :as state}]
|
||||
(let [editable? (or (= type :own) (nil? id))
|
||||
filtering (:filter state)
|
||||
ordering (:order state)
|
||||
own? (= type :own)
|
||||
images (rum/react images-ref)
|
||||
images (mx/react images-ref)
|
||||
images (->> (vals images)
|
||||
(filter #(= id (:collection %)))
|
||||
(filter-images-by filtering)
|
||||
(sort-images-by ordering))]
|
||||
[:div.dashboard-grid-content
|
||||
[:div.dashboard-grid-row
|
||||
(when own?
|
||||
(grid-form id))
|
||||
(when editable? (grid-form id))
|
||||
(for [image images
|
||||
:let [id (:id image)
|
||||
selected? (contains? selected id)]]
|
||||
|
@ -273,13 +267,11 @@
|
|||
(mx/defc content
|
||||
{:mixins [mx/static]}
|
||||
[{:keys [type id selected] :as state} coll]
|
||||
(let [own? (= type :own)]
|
||||
(when coll
|
||||
[:section.dashboard-grid.library
|
||||
(page-title coll)
|
||||
(grid state)
|
||||
(when (seq selected)
|
||||
(grid-options coll))])))
|
||||
[:section.dashboard-grid.library
|
||||
(page-title coll)
|
||||
(grid state)
|
||||
(when (seq selected)
|
||||
(grid-options coll))])
|
||||
|
||||
;; --- Menu
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[uxbox.main.ui.shapes.circle :as circle]
|
||||
[uxbox.main.ui.shapes.text :as text]
|
||||
[uxbox.main.ui.shapes.path :as path]
|
||||
[uxbox.main.ui.shapes.image :as image]
|
||||
[uxbox.main.geom :as geom]))
|
||||
|
||||
;; --- Helpers
|
||||
|
@ -34,6 +35,7 @@
|
|||
:icon (icon/icon-component shape)
|
||||
:rect (rect/rect-component shape)
|
||||
:path (path/path-component shape)
|
||||
:image (image/image-component shape)
|
||||
:circle (circle/circle-component shape)))
|
||||
|
||||
(mx/defc component-container
|
||||
|
|
73
src/uxbox/main/ui/shapes/image.cljs
Normal file
73
src/uxbox/main/ui/shapes/image.cljs
Normal file
|
@ -0,0 +1,73 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.main.ui.shapes.image
|
||||
(:require [beicon.core :as rx]
|
||||
[lentes.core :as l]
|
||||
[uxbox.util.mixins :as mx :include-macros true]
|
||||
[uxbox.util.http :as http]
|
||||
[uxbox.util.rstore :as rs]
|
||||
[uxbox.main.state :as st]
|
||||
[uxbox.main.ui.shapes.common :as common]
|
||||
[uxbox.main.ui.shapes.attrs :as attrs]
|
||||
[uxbox.main.data.images :as udi]
|
||||
[uxbox.main.geom :as geom]))
|
||||
|
||||
;; --- Refs
|
||||
|
||||
(defn image-ref
|
||||
[id]
|
||||
(-> (l/in [:images-by-id id])
|
||||
(l/derive st/state)))
|
||||
|
||||
;; --- Image Component
|
||||
|
||||
(declare image-shape)
|
||||
|
||||
(defn- will-mount
|
||||
[own]
|
||||
(let [{:keys [image-id]} (first (:rum/args own))]
|
||||
(rs/emit! (udi/fetch-image image-id))
|
||||
own))
|
||||
|
||||
(mx/defcs image-component
|
||||
{:mixins [mx/static mx/reactive]
|
||||
:will-mount will-mount}
|
||||
[own {:keys [id image-id] :as shape}]
|
||||
(let [selected (mx/react common/selected-ref)
|
||||
image (mx/react (image-ref image-id))
|
||||
selected? (contains? selected id)
|
||||
local (:rum/local own)
|
||||
on-mouse-down #(common/on-mouse-down % shape selected)]
|
||||
(when image
|
||||
[:g.shape {:class (when selected? "selected")
|
||||
:on-mouse-down on-mouse-down}
|
||||
(image-shape (assoc shape :image image))])))
|
||||
|
||||
;; --- Image Shape
|
||||
|
||||
(mx/defc image-shape
|
||||
{:mixins [mx/static]}
|
||||
[{:keys [id x1 y1 image] :as shape}]
|
||||
(let [key (str "shape-" id)
|
||||
;; rfm (geom/transformation-matrix shape)
|
||||
size (geom/size shape)
|
||||
props {:x x1 :y y1 :id key :key key
|
||||
:preserve-aspect-ratio "none"
|
||||
:xlink-href (:url image)}
|
||||
attrs (-> (attrs/extract-style-attrs shape)
|
||||
(merge props size))]
|
||||
[:image attrs]))
|
||||
|
||||
;; --- Image SVG
|
||||
|
||||
(mx/defc image-svg
|
||||
{:mixins [mx/static]}
|
||||
[{:keys [data id view-box] :as shape}]
|
||||
(let [key (str "image-svg-" id)
|
||||
view-box (apply str (interpose " " view-box))
|
||||
props {:view-box view-box :id key :key key}]
|
||||
[:svg props data]))
|
Loading…
Add table
Reference in a new issue