extended defview macro

This commit is contained in:
Roman Volosovskyi 2016-12-07 16:55:34 +02:00
parent fdecec9f28
commit cc687986cc
2 changed files with 88 additions and 65 deletions

View File

@ -167,53 +167,45 @@
(fn [_]
(anim/start (anim/spring val {:toValue @offset}))))
(defn messages-container [messages]
(let [offset (subscribe [:messages-offset])
messages-offset (anim/create-value 0)
context {:offset offset
(defview messages-container [messages]
[offset [:messages-offset]
staged-scroll-height [:get-chat-staged-commands-scroll-height]
messages-offset (anim/create-value 0)
context {:offset offset
:val messages-offset}
on-update (messages-container-animation-logic context)]
(r/create-class
{:component-did-mount
on-update
:component-did-update
on-update
:reagent-render
(fn [messages]
@offset
(let [staged-scroll-height (subscribe [:get-chat-staged-commands-scroll-height])]
[animated-view {:style (st/messages-container @staged-scroll-height messages-offset)}
messages]))})))
on-update (messages-container-animation-logic context)]
{:component-did-mount on-update
:component-did-update on-update}
[animated-view
{:style (st/messages-container staged-scroll-height messages-offset)}
messages])
(defn chat []
(let [group-chat (subscribe [:chat :group-chat])
show-actions? (subscribe [:chat-ui-props :show-actions?])
show-bottom-info? (subscribe [:chat-ui-props :show-bottom-info?])
command? (subscribe [:command?])
staged-commands (subscribe [:get-chat-staged-commands])
layout-height (subscribe [:get :layout-height])]
(r/create-class
{:component-did-mount #(dispatch [:check-autorun])
:reagent-render
(fn []
[view {:style st/chat-view
:onLayout (fn [event]
(let [height (.. event -nativeEvent -layout -height)]
(when (not= height @layout-height)
(dispatch [:set-layout-height height]))))}
[chat-toolbar]
[messages-container
[messages-view @group-chat]]
;; todo uncomment this
#_(when @group-chat [typing-all])
(when (seq @staged-commands)
[staged-commands-view @staged-commands])
(when-not @command?
[suggestion-container])
[response-view]
[chat-message-input-view]
(when @show-actions?
[actions-view])
(when @show-bottom-info?
[bottom-info-view])
[offline-view {:top (get-in platform-specific [:component-styles :status-bar :default :height])}]])})))
(defview chat []
[group-chat [:chat :group-chat]
show-actions? [:chat-ui-props :show-actions?]
show-bottom-info? [:chat-ui-props :show-bottom-info?]
command? [:command?]
staged-commands [:get-chat-staged-commands]
layout-height [:get :layout-height]]
{:component-did-mount #(dispatch [:check-autorun])}
[view {:style st/chat-view
:onLayout (fn [event]
(let [height (.. event -nativeEvent -layout -height)]
(when (not= height layout-height)
(dispatch [:set-layout-height height]))))}
[chat-toolbar]
[messages-container
[messages-view group-chat]]
;; todo uncomment this
#_(when @group-chat [typing-all])
(when (seq staged-commands)
[staged-commands-view staged-commands])
(when-not command?
[suggestion-container])
[response-view]
[chat-message-input-view]
(when show-actions?
[actions-view])
(when show-bottom-info?
[bottom-info-view])
[offline-view {:top (get-in platform-specific [:component-styles :status-bar :default :height])}]])

View File

@ -1,27 +1,58 @@
(ns status-im.utils.views)
(ns status-im.utils.views
(:require [clojure.walk :as w]))
(defn atom? [sub]
(or (vector? sub)
(and (seq sub)
(#{'atom `reagent.core/atom} (first sub)))))
(defn walk-sub [sub form->sym]
(if (coll? sub)
(w/postwalk (fn [f]
(or (form->sym f) f)) sub)
(or (form->sym sub) sub)))
(defn prepare-subs [subs]
(let [pairs (map (fn [[form sub]]
{:form form
:sub sub
:sym (gensym)})
(partition 2 subs))]
[(mapcat (fn [{:keys [sym sub]}]
[sym `(re-frame.core/subscribe ~sub)])
(let [pairs (map (fn [[form sub]]
{:form form
:sub sub
:sym (if (atom? sub)
(gensym (str (if (map? form) "keys" form)))
form)})
(partition 2 subs))
form->sym (->> pairs
(map (fn [{:keys [form sym]}]
[form sym]))
(into {}))]
[(mapcat (fn [{:keys [form sym sub]}]
(if (vector? sub)
[sym `(re-frame.core/subscribe ~(walk-sub sub form->sym))]
[form (walk-sub sub form->sym)]))
pairs)
(mapcat (fn [{:keys [sym form]}]
[form `(deref ~sym)])
pairs)]))
(apply concat (keep (fn [{:keys [sym form sub]}]
(when (atom? sub)
[form `(deref ~sym)]))
pairs))]))
(defmacro defview
[n params & rest]
(let [[subs body] (if (= 1 (count rest))
[nil (first rest)]
rest)
(let [[subs component-map body] (case (count rest)
1 [nil {} (first rest)]
2 [(first rest) {} (second rest)]
3 rest)
[subs-bindings vars-bindings] (prepare-subs subs)]
`(defn ~n ~params
(let [~@subs-bindings]
(fn ~params
(let [~@vars-bindings]
~body))))))
(reagent.core/create-class
(merge ~(->> component-map
(map (fn [[k f]]
(let [args (gensym "args")]
[k `(fn [& ~args]
(let [~@vars-bindings]
(apply ~f ~args)))])))
(into {}))
{:reagent-render
(fn ~params
(let [~@vars-bindings]
~body))}))))))