diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index b36f52a48f..2523388f7f 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -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])}]]) diff --git a/src/status_im/utils/views.clj b/src/status_im/utils/views.clj index 7620143590..5894081f5c 100644 --- a/src/status_im/utils/views.clj +++ b/src/status_im/utils/views.clj @@ -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))}))))))