diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index 1ddb552cc0..9711892283 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -22,8 +22,6 @@ [status-im.chat.handlers.animation :refer [update-response-height get-response-height]])) -(def delta 1) - (register-handler :set-show-actions (fn [db [_ show-actions]] (assoc db :show-actions show-actions))) diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index a2fc957b1e..daeba29ebc 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -13,7 +13,7 @@ [status-im.components.chat-icon.screen :refer [chat-icon-view-action chat-icon-view-menu-item]] [status-im.chat.styles.screen :as st] - [status-im.utils.listview :refer [to-datasource]] + [status-im.utils.listview :refer [to-datasource-inverted]] [status-im.utils.utils :refer [truncate-str]] [status-im.components.invertible-scroll-view :refer [invertible-scroll-view]] [status-im.components.toolbar :refer [toolbar]] @@ -61,12 +61,12 @@ (for [member ["Geoff" "Justas"]] ^{:key member} [typing member])]) -(defn message-row [contact-by-identity group-chat] +(defn message-row [contact-by-identity group-chat messages-count] (fn [row _ idx] (let [msg (-> row (add-msg-color contact-by-identity) (assoc :group-chat group-chat) - (assoc :last-msg (zero? (js/parseInt idx))))] + (assoc :last-msg (= (js/parseInt idx) (dec messages-count))))] (list-item [chat-message msg])))) (defn on-action-selected [position] @@ -222,12 +222,12 @@ [messages [:chat :messages] contacts [:chat :contacts]] (let [contacts' (contacts-by-identity contacts)] - [list-view {:renderRow (message-row contacts' group-chat) + [list-view {:renderRow (message-row contacts' group-chat (count messages)) :renderScrollComponent #(invertible-scroll-view (js->clj %)) :onEndReached #(dispatch [:load-more-messages]) :enableEmptySections true :keyboardShouldPersistTaps true - :dataSource (to-datasource messages)}])) + :dataSource (to-datasource-inverted messages)}])) (defn messages-container-animation-logic [{:keys [to-value val]}] (fn [_] diff --git a/src/status_im/chat/styles/message.cljs b/src/status_im/chat/styles/message.cljs index 937d85b994..464c90ddd5 100644 --- a/src/status_im/chat/styles/message.cljs +++ b/src/status_im/chat/styles/message.cljs @@ -316,6 +316,9 @@ (def message-date-text (assoc style-sub-text :textAlign :center)) +(defn message-container [height] + {:height height}) + (def new-message-container {:backgroundColor color-white :elevation 4}) diff --git a/src/status_im/chat/views/message.cljs b/src/status_im/chat/views/message.cljs index 6cd5f02917..746fdd8d65 100644 --- a/src/status_im/chat/views/message.cljs +++ b/src/status_im/chat/views/message.cljs @@ -1,24 +1,28 @@ (ns status-im.chat.views.message (:require [clojure.string :as s] [re-frame.core :refer [subscribe dispatch]] + [reagent.core :as r] [status-im.components.react :refer [view + animated-view text image touchable-highlight]] + [status-im.components.animation :as anim] [status-im.chat.views.request-message :refer [message-content-command-request]] [status-im.chat.styles.message :as st] [status-im.models.commands :refer [parse-command-msg-content parse-command-request]] [status-im.resources :as res] + [status-im.utils.datetime :as time] [status-im.constants :refer [text-content-type content-type-status content-type-command content-type-command-request]])) -(defn message-date [{:keys [date]}] +(defn message-date [timestamp] [view {} [view st/message-date-container - [text {:style st/message-date-text} date]]]) + [text {:style st/message-date-text} (time/to-short-str timestamp)]]]) (defn contact-photo [{:keys [photo-path]}] [view st/contact-photo-container @@ -156,12 +160,47 @@ (when (and outgoing delivery-status) [message-delivery-status {:delivery-status delivery-status}])])) +(defn message-container-animation-logic [{:keys [to-value val]}] + (fn [_] + (let [to-value @to-value] + (when (< 0 to-value) + (anim/start + (anim/spring val {:toValue to-value + :friction 4 + :tension 10}) + (fn [arg] + (when (.-finished arg) + ;; todo ??? + nil))))))) + +(defn message-container [& children] + (let [layout-height (r/atom 0) + anim-value (anim/create-value 1) + context {:to-value layout-height + :val anim-value} + on-update (message-container-animation-logic context)] + (r/create-class + {:component-did-mount + on-update + :component-did-update + on-update + :reagent-render + (fn [& children] + @layout-height + [animated-view {:style (st/message-container anim-value)} + (into [view {:onLayout (fn [event] + (let [height (.. event -nativeEvent -layout -height)] + (reset! layout-height height)))}] + children)])}))) + (defn chat-message - [{:keys [outgoing delivery-status date new-day group-chat] + [{:keys [outgoing delivery-status timestamp new-day group-chat] :as message}] - [view {} - (when new-day [message-date {:date date}]) - [view {} + [message-container + ;; TODO there is no new-day info in message + (when new-day + [message-date timestamp]) + [view (let [incoming-group (and group-chat (not outgoing))] [message-content (if incoming-group diff --git a/src/status_im/models/messages.cljs b/src/status_im/models/messages.cljs index 5c8c17fa5f..65de1d2476 100644 --- a/src/status_im/models/messages.cljs +++ b/src/status_im/models/messages.cljs @@ -48,9 +48,10 @@ (defn get-messages [chat-id] (->> (-> (r/get-by-field :msgs :chat-id chat-id) - (r/sorted :timestamp :asc) + (r/sorted :timestamp :desc) (r/collection->map)) (into '()) + reverse (map (fn [{:keys [content-type] :as message}] (if (command-type? content-type) (update message :content str-to-map) diff --git a/src/status_im/utils/listview.cljs b/src/status_im/utils/listview.cljs index dcd63da8bd..d9ab791710 100644 --- a/src/status_im/utils/listview.cljs +++ b/src/status_im/utils/listview.cljs @@ -7,3 +7,12 @@ (defn to-datasource [items] (clone-with-rows (data-source {:rowHasChanged not=}) items)) + +(defn clone-with-rows-inverted [ds rows] + (let [rows (reduce (fn [ac el] (.push ac el) ac) + (clj->js []) (reverse rows)) + row-ids (.reverse (.map rows (fn [_ index] index)))] + (.cloneWithRows ds rows row-ids))) + +(defn to-datasource-inverted [items] + (clone-with-rows-inverted (data-source {:rowHasChanged not=}) items))