Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix key uniqueness in message history and chat list #4578

Merged
merged 9 commits into from
Jul 2, 2018
Merged
2 changes: 1 addition & 1 deletion env/dev/figwheel.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{:nrepl-port 7888
:builds [{:id :desktop
:source-paths ["react-native/src" "src" "env/dev"]
:compiler {:output-to "target/dektop/app.js"
:compiler {:output-to "target/desktop/app.js"
:main "env.desktop.main"
:output-dir "target/desktop"
:npm-deps false
Expand Down
2 changes: 1 addition & 1 deletion src/status_im/desktop/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

(defn app-root []
(reagent/create-class
{:reagent-render views/main}))
{:reagent-render views/main}))

(defn init []
(core/init app-root))
2 changes: 1 addition & 1 deletion src/status_im/transport/shh.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

(defn post-message
[{:keys [web3 whisper-message on-success on-error]}]
(.. web3
(.. web3
-shh
(extPost (clj->js whisper-message) (fn [err resp]
(if-not err
Expand Down
107 changes: 52 additions & 55 deletions src/status_im/ui/screens/desktop/main/chat/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[clojure.string :as string]
[status-im.chat.styles.message.message :as message.style]
[status-im.utils.gfycat.core :as gfycat.core]
[taoensso.timbre :as log]
[status-im.utils.gfycat.core :as gfycat]
[status-im.constants :as constants]
[status-im.utils.identicon :as identicon]
Expand All @@ -19,11 +20,11 @@
(views/letsubs [{:keys [chat-id name public-key public? group-chat]} [:get-current-chat]
{:keys [pending?]} [:get-current-chat-contact]]
(let [chat-name (str
(if public? "#" "")
(if (string/blank? name)
(gfycat.core/generate-gfy public-key)
(or name
(i18n/label :t/chat-name))))]
(if public? "#" "")
(if (string/blank? name)
(gfycat.core/generate-gfy public-key)
(or name
(i18n/label :t/chat-name))))]
[react/view {:style styles/toolbar-chat-view}
[react/view {:style {:flex-direction :row}}
(when public?
Expand All @@ -42,9 +43,9 @@
(views/defview message-author-name [{:keys [outgoing from] :as message}]
(views/letsubs [current-account [:get-current-account]
incoming-name [:get-contact-name-by-identity from]]
(let [name (or incoming-name (gfycat/generate-gfy from))]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-contact-dialog from name (boolean incoming-name)])}
[react/text {:style styles/author} name]])))
(let [name (or incoming-name (gfycat/generate-gfy from))]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-contact-dialog from name (boolean incoming-name)])}
[react/text {:style styles/author} name]])))

(views/defview member-photo [from]
[react/view
Expand All @@ -61,57 +62,55 @@
:style styles/photo-style}]])))

(views/defview message-with-timestamp [text {:keys [timestamp] :as message} style]
[react/view {:style style}
[react/view {:style {:flex-direction :row :flex-wrap :wrap}}
[react/text {:style styles/message-text}
text]
[react/text {:style (styles/message-timestamp-placeholder)}
(time/timestamp->time timestamp)]
[react/text {:style (styles/message-timestamp)}
(time/timestamp->time timestamp)]]])

[react/view {:style style}
[react/view {:style {:flex-direction :row :flex-wrap :wrap}}
[react/text {:style styles/message-text}
text]
[react/text {:style (styles/message-timestamp-placeholder)}
(time/timestamp->time timestamp)]
[react/text {:style (styles/message-timestamp)}
(time/timestamp->time timestamp)]]])

(views/defview text-only-message [text message]
[react/view {:style (styles/message-row message) }
[message-with-timestamp text message (styles/message-box message)]])
[react/view {:style (styles/message-row message)}
[message-with-timestamp text message (styles/message-box message)]])

(views/defview photo-placeholder []
[react/view {:style styles/photo-style}])

(views/defview message-with-name-and-avatar [text {:keys [from first-in-group? last-in-group?] :as message}]
[react/view {:style (styles/message-row message)}
[react/view {:style {:flex-direction :column}}
(when first-in-group?
[message-author-name message])
[react/view {:style {:flex-direction :row}}
(if last-in-group?
[member-photo from]
[photo-placeholder])
[message-with-timestamp text message (styles/message-box message)]]]])
[react/view {:style (styles/message-row message)}
[react/view {:style {:flex-direction :column}}
(when first-in-group?
[message-author-name message])
[react/view {:style {:flex-direction :row}}
(if last-in-group?
[member-photo from]
[photo-placeholder])
[message-with-timestamp text message (styles/message-box message)]]]])

(defn message [text me? {:keys [ message-id chat-id message-status user-statuses from
(defn message [text me? {:keys [message-id chat-id message-status user-statuses from
current-public-key content-type group-chat outgoing type value] :as message}]
(if (= type :datemark)
^{:key (str "datemark" message-id)}
[message.datemark/chat-datemark value]
(when (= content-type constants/text-content-type)
(reagent.core/create-class
(reagent.core/create-class
{:component-did-mount
#(when (and message-id
chat-id
(not outgoing)
(not= :seen message-status)
(not= :seen (keyword (get-in user-statuses [current-public-key :status]))))
(re-frame/dispatch [:send-seen! {:chat-id chat-id
:from from
:message-id message-id}]))
:reagent-render
(fn []
#(when (and message-id
chat-id
(not outgoing)
(not= :seen message-status)
(not= :seen (keyword (get-in user-statuses [current-public-key :status]))))
(re-frame/dispatch [:send-seen! {:chat-id chat-id
:from from
:message-id message-id}]))
:reagent-render
(fn []
^{:key (str "message" message-id)}
(if (and group-chat (not outgoing))
[message-with-name-and-avatar text message]
[text-only-message text message]))})
)))
[text-only-message text message]))}))))

(views/defview messages-view [{:keys [chat-id group-chat]}]
(views/letsubs [chat-id* (atom nil)
Expand All @@ -126,21 +125,19 @@
[react/view {:style styles/messages-view}
[react/scroll-view {:scrollEventThrottle 16
:on-scroll (fn [e]
(let [ne (.-nativeEvent e)
y (.-y (.-contentOffset ne))]
(when (zero? y)
(when @scroll-timer (js/clearTimeout @scroll-timer))
(reset! scroll-timer (js/setTimeout #(re-frame/dispatch [:load-more-messages]) 300)))
(reset! scroll-height (+ y (.-height (.-layoutMeasurement ne))))))
:on-content-size-change #(when (or (not @scroll-height) (< (- %2 @scroll-height) 500))
(.scrollToEnd @scroll-ref))
(let [ne (.-nativeEvent e)
y (.-y (.-contentOffset ne))]
(when (zero? y)
(when @scroll-timer (js/clearTimeout @scroll-timer))
(reset! scroll-timer (js/setTimeout #(re-frame/dispatch [:load-more-messages]) 300)))
(reset! scroll-height (+ y (.-height (.-layoutMeasurement ne))))))
:on-content-size-change #(.scrollToEnd @scroll-ref)
:ref #(reset! scroll-ref %)}
[react/view {:style {:padding-vertical 60}}
[react/view {:style {:padding-vertical 46}}
(doall
(for [[index {:keys [from content message-id] :as message-obj}] (map-indexed vector (reverse @messages))]
^{:key (str message index)}
[message content (= from @current-public-key) (assoc message-obj :group-chat group-chat)]))]]])))

(for [[index {:keys [from content message-id] :as message-obj}] (map-indexed vector (reverse @messages))]
^{:key (or message-id "0")}
[message content (= from @current-public-key) (assoc message-obj :group-chat group-chat)]))]]])))

(views/defview chat-text-input []
(views/letsubs [inp-ref (atom nil)]
Expand Down
5 changes: 3 additions & 2 deletions src/status_im/ui/screens/desktop/main/tabs/home/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
(:require-macros [status-im.utils.views :as views])
(:require [re-frame.core :as re-frame]
[status-im.utils.gfycat.core :as gfycat]
[taoensso.timbre :as log]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.react :as react]))

Expand Down Expand Up @@ -43,5 +44,5 @@
[react/scroll-view
[react/view
(for [[index chat] (map-indexed vector home-items)]
^{:key (str chat index)}
[chat-list-item chat])]]]))
^{:key (first chat)}
[chat-list-item chat])]]]))
6 changes: 3 additions & 3 deletions src/status_im/ui/screens/desktop/main/tabs/profile/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
label]
[react/view {:height 10}]
[react/touchable-opacity {:on-press #(react/copy-to-clipboard value)}
[react/text {:number-of-lines 1
:ellipsizeMode :middle}
value]]]])
[react/text {:number-of-lines 1
:ellipsizeMode :middle}
value]]]])

(defn my-profile-info [{:keys [public-key]}]
[react/view
Expand Down
1 change: 0 additions & 1 deletion src/status_im/ui/screens/desktop/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
[status-im.ui.screens.accounts.recover.views :as recover.views]
[status-im.ui.screens.accounts.views :as accounts.views]))


(enable-console-print!)

(views/defview main []
Expand Down