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 [_] (fn [_]
(anim/start (anim/spring val {:toValue @offset})))) (anim/start (anim/spring val {:toValue @offset}))))
(defn messages-container [messages] (defview messages-container [messages]
(let [offset (subscribe [:messages-offset]) [offset [:messages-offset]
staged-scroll-height [:get-chat-staged-commands-scroll-height]
messages-offset (anim/create-value 0) messages-offset (anim/create-value 0)
context {:offset offset context {:offset offset
:val messages-offset} :val messages-offset}
on-update (messages-container-animation-logic context)] on-update (messages-container-animation-logic context)]
(r/create-class {:component-did-mount on-update
{:component-did-mount :component-did-update on-update}
on-update [animated-view
:component-did-update {:style (st/messages-container staged-scroll-height messages-offset)}
on-update messages])
: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]))})))
(defn chat [] (defview chat []
(let [group-chat (subscribe [:chat :group-chat]) [group-chat [:chat :group-chat]
show-actions? (subscribe [:chat-ui-props :show-actions?]) show-actions? [:chat-ui-props :show-actions?]
show-bottom-info? (subscribe [:chat-ui-props :show-bottom-info?]) show-bottom-info? [:chat-ui-props :show-bottom-info?]
command? (subscribe [:command?]) command? [:command?]
staged-commands (subscribe [:get-chat-staged-commands]) staged-commands [:get-chat-staged-commands]
layout-height (subscribe [:get :layout-height])] layout-height [:get :layout-height]]
(r/create-class {:component-did-mount #(dispatch [:check-autorun])}
{:component-did-mount #(dispatch [:check-autorun])
:reagent-render
(fn []
[view {:style st/chat-view [view {:style st/chat-view
:onLayout (fn [event] :onLayout (fn [event]
(let [height (.. event -nativeEvent -layout -height)] (let [height (.. event -nativeEvent -layout -height)]
(when (not= height @layout-height) (when (not= height layout-height)
(dispatch [:set-layout-height height]))))} (dispatch [:set-layout-height height]))))}
[chat-toolbar] [chat-toolbar]
[messages-container [messages-container
[messages-view @group-chat]] [messages-view group-chat]]
;; todo uncomment this ;; todo uncomment this
#_(when @group-chat [typing-all]) #_(when @group-chat [typing-all])
(when (seq @staged-commands) (when (seq staged-commands)
[staged-commands-view @staged-commands]) [staged-commands-view staged-commands])
(when-not @command? (when-not command?
[suggestion-container]) [suggestion-container])
[response-view] [response-view]
[chat-message-input-view] [chat-message-input-view]
(when @show-actions? (when show-actions?
[actions-view]) [actions-view])
(when @show-bottom-info? (when show-bottom-info?
[bottom-info-view]) [bottom-info-view])
[offline-view {:top (get-in platform-specific [:component-styles :status-bar :default :height])}]])}))) [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] (defn prepare-subs [subs]
(let [pairs (map (fn [[form sub]] (let [pairs (map (fn [[form sub]]
{:form form {:form form
:sub sub :sub sub
:sym (gensym)}) :sym (if (atom? sub)
(partition 2 subs))] (gensym (str (if (map? form) "keys" form)))
[(mapcat (fn [{:keys [sym sub]}] form)})
[sym `(re-frame.core/subscribe ~sub)]) (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) pairs)
(mapcat (fn [{:keys [sym form]}] (apply concat (keep (fn [{:keys [sym form sub]}]
[form `(deref ~sym)]) (when (atom? sub)
pairs)])) [form `(deref ~sym)]))
pairs))]))
(defmacro defview (defmacro defview
[n params & rest] [n params & rest]
(let [[subs body] (if (= 1 (count rest)) (let [[subs component-map body] (case (count rest)
[nil (first rest)] 1 [nil {} (first rest)]
rest) 2 [(first rest) {} (second rest)]
3 rest)
[subs-bindings vars-bindings] (prepare-subs subs)] [subs-bindings vars-bindings] (prepare-subs subs)]
`(defn ~n ~params `(defn ~n ~params
(let [~@subs-bindings] (let [~@subs-bindings]
(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 (fn ~params
(let [~@vars-bindings] (let [~@vars-bindings]
~body)))))) ~body))}))))))