mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 10:38:13 -05:00
✨ Include advanced interactions and flows in import/export
This commit is contained in:
parent
a6dfa6bbbd
commit
09d1c958ce
5 changed files with 146 additions and 50 deletions
|
@ -374,21 +374,76 @@
|
|||
(-> file
|
||||
(update :parent-stack pop)))
|
||||
|
||||
(defn- read-classifier
|
||||
[interaction-src]
|
||||
(select-keys interaction-src [:event-type :action-type]))
|
||||
|
||||
(defmulti read-event-opts :event-type)
|
||||
|
||||
(defmethod read-event-opts :after-delay
|
||||
[interaction-src]
|
||||
(select-keys interaction-src [:delay]))
|
||||
|
||||
(defmethod read-event-opts :default
|
||||
[_]
|
||||
{})
|
||||
|
||||
(defmulti read-action-opts :action-type)
|
||||
|
||||
(defmethod read-action-opts :navigate
|
||||
[interaction-src]
|
||||
(select-keys interaction-src [:destination]))
|
||||
|
||||
(defmethod read-action-opts :open-overlay
|
||||
[interaction-src]
|
||||
(select-keys interaction-src [:destination
|
||||
:overlay-position
|
||||
:overlay-pos-type
|
||||
:close-click-outside
|
||||
:background-overlay]))
|
||||
|
||||
(defmethod read-action-opts :toggle-overlay
|
||||
[interaction-src]
|
||||
(select-keys interaction-src [:destination
|
||||
:overlay-position
|
||||
:overlay-pos-type
|
||||
:close-click-outside
|
||||
:background-overlay]))
|
||||
|
||||
(defmethod read-action-opts :close-overlay
|
||||
[interaction-src]
|
||||
(select-keys interaction-src [:destination]))
|
||||
|
||||
(defmethod read-action-opts :prev-screen
|
||||
[_]
|
||||
{})
|
||||
|
||||
(defmethod read-action-opts :open-url
|
||||
[interaction-src]
|
||||
(select-keys interaction-src [:url]))
|
||||
|
||||
(defn add-interaction
|
||||
[file from-id {:keys [action-type event-type destination]}]
|
||||
[file from-id interaction-src]
|
||||
|
||||
(assert (some? (lookup-shape file from-id)) (str "Cannot locate shape with id " from-id))
|
||||
(assert (some? (lookup-shape file destination)) (str "Cannot locate shape with id " destination))
|
||||
|
||||
(let [interactions (->> (lookup-shape file from-id)
|
||||
:interactions
|
||||
(filterv #(or (not= (:action-type %) action-type)
|
||||
(not= (:event-type %) event-type))))
|
||||
interactions (-> interactions
|
||||
(let [{:keys [event-type action-type]} (read-classifier interaction-src)
|
||||
{:keys [delay]} (read-event-opts interaction-src)
|
||||
{:keys [destination overlay-pos-type overlay-position url
|
||||
close-click-outside background-overlay]} (read-action-opts interaction-src)
|
||||
|
||||
interactions (-> (lookup-shape file from-id)
|
||||
:interactions
|
||||
(conjv
|
||||
{:action-type action-type
|
||||
:event-type event-type
|
||||
:destination destination}))]
|
||||
(d/without-nils {:event-type event-type
|
||||
:action-type action-type
|
||||
:delay delay
|
||||
:destination destination
|
||||
:overlay-pos-type overlay-pos-type
|
||||
:overlay-position overlay-position
|
||||
:url url
|
||||
:close-click-outside close-click-outside
|
||||
:background-overlay background-overlay})))]
|
||||
(commit-change
|
||||
file
|
||||
{:type :mod-obj
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
|
||||
;; --- Grid options
|
||||
|
||||
(s/def :artboard-grid.color/value ::us/string)
|
||||
(s/def :artboard-grid.color/color ::us/string)
|
||||
(s/def :artboard-grid.color/opacity ::us/safe-number)
|
||||
|
||||
(s/def :artboard-grid/size ::us/safe-integer)
|
||||
(s/def :artboard-grid/color (s/keys :req-un [:artboard-grid.color/value
|
||||
(s/def :artboard-grid/color (s/keys :req-un [:artboard-grid.color/color
|
||||
:artboard-grid.color/opacity]))
|
||||
(s/def :artboard-grid/type #{:stretch :left :center :right})
|
||||
(s/def :artboard-grid/item-length (s/nilable ::us/safe-integer))
|
||||
|
@ -38,7 +38,7 @@
|
|||
(s/def :artboard-grid/row :artboard-grid/column)
|
||||
|
||||
(s/def ::saved-grids
|
||||
(s/keys :req-un [:artboard-grid/square
|
||||
(s/keys :opt-un [:artboard-grid/square
|
||||
:artboard-grid/row
|
||||
:artboard-grid/column]))
|
||||
|
||||
|
|
|
@ -131,30 +131,41 @@
|
|||
|
||||
(mf/defc export-grid-data
|
||||
[{:keys [grids]}]
|
||||
(when-not (empty? grids)
|
||||
[:> "penpot:grids" #js {}
|
||||
(for [{:keys [type display params]} grids]
|
||||
(let [props (->> (d/without-keys params [:color])
|
||||
(prefix-keys)
|
||||
(clj->js))]
|
||||
[:> "penpot:grid"
|
||||
(-> props
|
||||
(obj/set! "penpot:color" (get-in params [:color :color]))
|
||||
(obj/set! "penpot:opacity" (get-in params [:color :opacity]))
|
||||
(obj/set! "penpot:type" (d/name type))
|
||||
(cond-> (some? display)
|
||||
(obj/set! "penpot:display" (str display))))]))]))
|
||||
[:> "penpot:grids" #js {}
|
||||
(for [{:keys [type display params]} grids]
|
||||
(let [props (->> (d/without-keys params [:color])
|
||||
(prefix-keys)
|
||||
(clj->js))]
|
||||
[:> "penpot:grid"
|
||||
(-> props
|
||||
(obj/set! "penpot:color" (get-in params [:color :color]))
|
||||
(obj/set! "penpot:opacity" (get-in params [:color :opacity]))
|
||||
(obj/set! "penpot:type" (d/name type))
|
||||
(cond-> (some? display)
|
||||
(obj/set! "penpot:display" (str display))))]))])
|
||||
|
||||
(mf/defc export-flows
|
||||
[{:keys [flows]}]
|
||||
[:> "penpot:flows" #js {}
|
||||
(for [{:keys [id name starting-frame]} flows]
|
||||
[:> "penpot:flow" #js {:id id
|
||||
:name name
|
||||
:starting-frame starting-frame}])])
|
||||
|
||||
(mf/defc export-page
|
||||
[{:keys [options]}]
|
||||
(let [saved-grids (get options :saved-grids)]
|
||||
(when-not (empty? saved-grids)
|
||||
(let [parse-grid
|
||||
(fn [[type params]]
|
||||
{:type type :params params})
|
||||
grids (->> saved-grids (mapv parse-grid))]
|
||||
[:> "penpot:page" #js {}
|
||||
[:& export-grid-data {:grids grids}]]))))
|
||||
(let [saved-grids (get options :saved-grids)
|
||||
flows (get options :flows)]
|
||||
(when (or (seq saved-grids) (seq flows))
|
||||
(let [parse-grid
|
||||
(fn [[type params]]
|
||||
{:type type :params params})
|
||||
grids (->> saved-grids (mapv parse-grid))]
|
||||
[:> "penpot:page" #js {}
|
||||
(when (seq saved-grids)
|
||||
[:& export-grid-data {:grids grids}])
|
||||
(when (seq flows)
|
||||
[:& export-flows {:flows flows}])]))))
|
||||
|
||||
(mf/defc export-shadow-data
|
||||
[{:keys [shadow]}]
|
||||
|
@ -220,11 +231,18 @@
|
|||
[{:keys [interactions]}]
|
||||
(when-not (empty? interactions)
|
||||
[:> "penpot:interactions" #js {}
|
||||
(for [{:keys [action-type destination event-type]} interactions]
|
||||
(for [interaction interactions]
|
||||
[:> "penpot:interaction"
|
||||
#js {:penpot:action-type (d/name action-type)
|
||||
:penpot:destination (str destination)
|
||||
:penpot:event-type (d/name event-type)}])]))
|
||||
#js {:penpot:event-type (d/name (:event-type interaction))
|
||||
:penpot:action-type (d/name (:action-type interaction))
|
||||
:penpot:delay ((d/nilf str) (:delay interaction))
|
||||
:penpot:destination ((d/nilf str) (:destination interaction))
|
||||
:penpot:overlay-pos-type ((d/nilf d/name) (:overlay-pos-type interaction))
|
||||
:penpot:overlay-position-x ((d/nilf get-in) interaction [:overlay-position :x])
|
||||
:penpot:overlay-position-y ((d/nilf get-in) interaction [:overlay-position :y])
|
||||
:penpot:url (:url interaction)
|
||||
:penpot:close-click-outside ((d/nilf str) (:close-click-outside interaction))
|
||||
:penpot:background-overlay ((d/nilf str) (:background-overlay interaction))}])]))
|
||||
|
||||
(mf/defc export-data
|
||||
[{:keys [shape]}]
|
||||
|
|
|
@ -477,7 +477,6 @@
|
|||
:suffix (get-meta node :suffix)
|
||||
:scale (get-meta node :scale d/parse-double)})
|
||||
|
||||
|
||||
(defn parse-grid-node [node]
|
||||
(let [attrs (-> node :attrs remove-penpot-prefix)
|
||||
color {:color (:color attrs)
|
||||
|
@ -494,8 +493,18 @@
|
|||
:params params}))
|
||||
|
||||
(defn parse-grids [node]
|
||||
(let [grid-node (get-data node :penpot:grids)]
|
||||
(->> grid-node :content (mapv parse-grid-node))))
|
||||
(let [grids-node (get-data node :penpot:grids)]
|
||||
(->> grids-node :content (mapv parse-grid-node))))
|
||||
|
||||
(defn parse-flow-node [node]
|
||||
(let [attrs (-> node :attrs remove-penpot-prefix)]
|
||||
{:id (uuid/next)
|
||||
:name (-> attrs :name)
|
||||
:starting-frame (-> attrs :starting-frame uuid)}))
|
||||
|
||||
(defn parse-flows [node]
|
||||
(let [flows-node (get-data node :penpot:flows)]
|
||||
(->> flows-node :content (mapv parse-flow-node))))
|
||||
|
||||
(defn extract-from-data
|
||||
([node tag]
|
||||
|
@ -725,24 +734,35 @@
|
|||
|
||||
(defn parse-page-data
|
||||
[node]
|
||||
(let [style (parse-style (get-in node [:attrs :style]))
|
||||
(let [style (parse-style (get-in node [:attrs :style]))
|
||||
background (:background style)
|
||||
grids (->> (parse-grids node)
|
||||
(group-by :type)
|
||||
(d/mapm (fn [_ v] (-> v first :params))))]
|
||||
grids (->> (parse-grids node)
|
||||
(group-by :type)
|
||||
(d/mapm (fn [_ v] (-> v first :params))))
|
||||
flows (parse-flows node)]
|
||||
(cond-> {}
|
||||
(some? background)
|
||||
(assoc-in [:options :background] background)
|
||||
|
||||
(d/not-empty? grids)
|
||||
(assoc-in [:options :saved-grids] grids))))
|
||||
(assoc-in [:options :saved-grids] grids)
|
||||
|
||||
(d/not-empty? flows)
|
||||
(assoc-in [:options :flows] flows))))
|
||||
|
||||
(defn parse-interactions
|
||||
[node]
|
||||
(let [interactions-node (get-data node :penpot:interactions)]
|
||||
(->> (find-all-nodes interactions-node :penpot:interaction)
|
||||
(mapv (fn [node]
|
||||
{:destination (get-meta node :destination uuid/uuid)
|
||||
:action-type (get-meta node :action-type keyword)
|
||||
:event-type (get-meta node :event-type keyword)})))))
|
||||
{:event-type (get-meta node :event-type keyword)
|
||||
:action-type (get-meta node :action-type keyword)
|
||||
:delay (get-meta node :delay d/parse-double)
|
||||
:destination (get-meta node :destination uuid/uuid)
|
||||
:overlay-pos-type (get-meta node :overlay-pos-type keyword)
|
||||
:overlay-position-x (get-meta node :overlay-position-x d/parse-double)
|
||||
:overlay-position-y (get-meta node :overlay-position-x d/parse-double)
|
||||
:url (get-meta node :url str)
|
||||
:close-click-outside (get-meta node :close-click-outside str->bool)
|
||||
:background-overlay (get-meta node :background-overlay str->bool)})))))
|
||||
|
||||
|
|
|
@ -315,7 +315,10 @@
|
|||
page-data (-> (cip/parse-page-data content)
|
||||
(assoc :name page-name)
|
||||
(assoc :id (resolve page-id)))
|
||||
file (-> file (fb/add-page page-data))]
|
||||
flows (->> (get-in page-data [:options :flows])
|
||||
(mapv #(update % :starting-frame resolve)))
|
||||
page-data (d/assoc-in-when page-data [:options :flows] flows)
|
||||
file (-> file (fb/add-page page-data))]
|
||||
(->> (rx/from nodes)
|
||||
(rx/filter cip/shape?)
|
||||
(rx/mapcat (partial resolve-media context file-id))
|
||||
|
|
Loading…
Add table
Reference in a new issue