diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index 4fdab9cb4d..6081ffd86d 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -98,8 +98,8 @@ [react/text {:style style/empty-chat-text} (i18n/label :t/empty-chat-description)]] [list/flat-list {:data messages - :render-fn (fn [{:keys [message-id] :as message}] - ^{:key message-id} + :key-fn #(or (:message-id %) (:value %)) + :render-fn (fn [message] [message-row {:group-chat group-chat :current-public-key current-public-key :row message}]) diff --git a/src/status_im/chat/views/api/choose_contact.cljs b/src/status_im/chat/views/api/choose_contact.cljs index cc9abac56f..b17fbd62d6 100644 --- a/src/status_im/chat/views/api/choose_contact.cljs +++ b/src/status_im/chat/views/api/choose_contact.cljs @@ -27,6 +27,7 @@ :padding-bottom 12}} title] [list/flat-list {:data contacts + :key-fn :address :render-fn (render-contact arg-index bot-db-key) :enableEmptySections true :keyboardShouldPersistTaps :always diff --git a/src/status_im/chat/views/bottom_info.cljs b/src/status_im/chat/views/bottom_info.cljs index d8eca9784c..c26efb110e 100644 --- a/src/status_im/chat/views/bottom_info.cljs +++ b/src/status_im/chat/views/bottom_info.cljs @@ -76,5 +76,6 @@ [container (* styles/item-height (count statuses)) [list/flat-list {:contentContainerStyle styles/bottom-info-list-container :data statuses + :key-fn :address :render-fn (render-status @contacts) :enableEmptySections true}]]]))}))) diff --git a/src/status_im/ui/components/list/views.cljs b/src/status_im/ui/components/list/views.cljs index 950e765cc5..1f8e452a68 100644 --- a/src/status_im/ui/components/list/views.cljs +++ b/src/status_im/ui/components/list/views.cljs @@ -100,6 +100,11 @@ (fn [data] (reagent/as-element (f (.-item data) (.-index data) (.-separators data))))) +(defn- wrap-key-fn [f] + (fn [data index] + {:post [(string? %)]} + (f data index))) + (def default-separator [react/view styles/separator]) (def default-header [react/view styles/list-header-footer-spacing]) @@ -109,13 +114,13 @@ (def section-separator [react/view styles/section-separator]) (defn- base-list-props - [{:keys [render-fn empty-component header separator default-separator?]}] + [{:keys [key-fn render-fn empty-component header separator default-separator?]}] (let [separator (or separator (when (and platform/ios? default-separator?) default-separator))] - (merge {:keyExtractor (fn [_ i] (str i))} - (when render-fn {:renderItem (wrap-render-fn render-fn)}) - (when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))}) - (when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))}) - (when header {:ListHeaderComponent (fn [] (reagent/as-element header))})))) + (merge (when key-fn {:keyExtractor (wrap-key-fn key-fn)}) + (when render-fn {:renderItem (wrap-render-fn render-fn)}) + (when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))}) + (when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))}) + (when header {:ListHeaderComponent (fn [] (reagent/as-element header))})))) ;; Workaround an issue in reagent that does not consider JS array as JS value ;; This forces clj <-> js serialization and breaks clj semantic @@ -206,6 +211,7 @@ [react/view (merge styles/action-separator action-separator-style)]) :data actions + :key-fn (fn [_ i] (str i)) :render-fn #(render-action % styles)}]]) (defn list-with-label [{:keys [style]} label list] diff --git a/src/status_im/ui/screens/accounts/views.cljs b/src/status_im/ui/screens/accounts/views.cljs index b113159229..9e100421b0 100644 --- a/src/status_im/ui/screens/accounts/views.cljs +++ b/src/status_im/ui/screens/accounts/views.cljs @@ -37,6 +37,7 @@ [react/view styles/accounts-container [react/view styles/accounts-list-container [list/flat-list {:data (vals accounts) + :key-fn :address :render-fn (fn [account] [account-view account]) :separator [react/view {:height 12}]}]] [react/view diff --git a/src/status_im/ui/screens/add_new/new_chat/views.cljs b/src/status_im/ui/screens/add_new/new_chat/views.cljs index 5a439d2b33..6ca089474c 100644 --- a/src/status_im/ui/screens/add_new/new_chat/views.cljs +++ b/src/status_im/ui/screens/add_new/new_chat/views.cljs @@ -43,6 +43,7 @@ [react/text {:style open-dapp.styles/list-title} (i18n/label :t/contacts)] [list/flat-list {:data contacts + :key-fn :address :render-fn render-row :default-separator? true :enableEmptySections true diff --git a/src/status_im/ui/screens/add_new/new_public_chat/view.cljs b/src/status_im/ui/screens/add_new/new_public_chat/view.cljs index 99cc8c7e51..5bf891977c 100644 --- a/src/status_im/ui/screens/add_new/new_public_chat/view.cljs +++ b/src/status_im/ui/screens/add_new/new_public_chat/view.cljs @@ -73,5 +73,6 @@ :font :medium} (i18n/label :t/selected)]] [list/flat-list {:data default-public-chats + :key-fn identity :render-fn render-topic :default-separator? true}]])) diff --git a/src/status_im/ui/screens/add_new/open_dapp/views.cljs b/src/status_im/ui/screens/add_new/open_dapp/views.cljs index 349f4ae1ec..eae21808e2 100644 --- a/src/status_im/ui/screens/add_new/open_dapp/views.cljs +++ b/src/status_im/ui/screens/add_new/open_dapp/views.cljs @@ -39,6 +39,7 @@ [react/text {:style styles/list-title} (i18n/label :t/selected-dapps)] [list/flat-list {:data dapps + :key-fn :dapp-url :render-fn render-row :default-separator? true :enableEmptySections true diff --git a/src/status_im/ui/screens/contacts/contact_list/views.cljs b/src/status_im/ui/screens/contacts/contact_list/views.cljs index 15268d9b46..a0a55dd694 100644 --- a/src/status_im/ui/screens/contacts/contact_list/views.cljs +++ b/src/status_im/ui/screens/contacts/contact_list/views.cljs @@ -32,6 +32,7 @@ (letsubs [contacts [:all-added-group-contacts (:group-id group)]] [list/flat-list {:style styles/contacts-list :data contacts + :key-fn :address :render-fn (render-row group edit?) :enableEmptySections true :keyboardShouldPersistTaps :always diff --git a/src/status_im/ui/screens/contacts/contact_list_modal/views.cljs b/src/status_im/ui/screens/contacts/contact_list_modal/views.cljs index de84f617b3..8ad05e5762 100644 --- a/src/status_im/ui/screens/contacts/contact_list_modal/views.cljs +++ b/src/status_im/ui/screens/contacts/contact_list_modal/views.cljs @@ -51,6 +51,7 @@ [toolbar/simple-toolbar (i18n/label :t/contacts)] [list/flat-list {:style st/contacts-list-modal :data contacts + :key-fn :address :render-fn (render-row click-handler action params) :header (when-not (:hide-actions? params) [react/view diff --git a/src/status_im/ui/screens/discover/all_dapps/views.cljs b/src/status_im/ui/screens/discover/all_dapps/views.cljs index f7af631a23..a545d197bd 100644 --- a/src/status_im/ui/screens/discover/all_dapps/views.cljs +++ b/src/status_im/ui/screens/discover/all_dapps/views.cljs @@ -38,6 +38,7 @@ true] (if (seq dapps) [list/flat-list {:data (vals dapps) + :key-fn :dapp-url :render-fn render-dapp :horizontal true :default-separator? false @@ -54,7 +55,9 @@ (if (zero? extras) dapps (concat dapps - (repeat (- columns extras) {:name ""}))))) + (map (fn [i] {:name "" + :dapp-url (str "blank-" i)}) + (range (- columns extras))))))) (defview main [] (letsubs [all-dapps [:discover/all-dapps]] @@ -65,6 +68,7 @@ toolbar/default-nav-back [toolbar/content-title (i18n/label :t/dapps)]] [list/flat-list {:data (add-blank-dapps-for-padding columns (vals all-dapps)) + :key-fn :dapp-url :render-fn render-dapp :num-columns columns :content-container-style styles/all-dapps-flat-list}]])))) diff --git a/src/status_im/ui/screens/discover/popular_hashtags/views.cljs b/src/status_im/ui/screens/discover/popular_hashtags/views.cljs index f94c1ed31b..1d519a438f 100644 --- a/src/status_im/ui/screens/discover/popular_hashtags/views.cljs +++ b/src/status_im/ui/screens/discover/popular_hashtags/views.cljs @@ -19,6 +19,7 @@ (defn tags-menu [tags] [react/view styles/tag-title-container [list/flat-list {:data tags + :key-fn (fn [_ i] (str i)) :render-fn render-tag :horizontal true :shows-horizontal-scroll-indicator false diff --git a/src/status_im/ui/screens/discover/views.cljs b/src/status_im/ui/screens/discover/views.cljs index 7836ad07d9..ce39c928f7 100644 --- a/src/status_im/ui/screens/discover/views.cljs +++ b/src/status_im/ui/screens/discover/views.cljs @@ -126,6 +126,7 @@ [react/view styles/public-chats-container [components/title-no-action :t/public-chats] [list/flat-list {:data public-chats-mock-data + :key-fn :topic :render-fn render-public-chats-item}]]) (defview discover [current-view?] diff --git a/src/status_im/ui/screens/group/add_contacts/views.cljs b/src/status_im/ui/screens/group/add_contacts/views.cljs index 4923da7ab3..4593664485 100644 --- a/src/status_im/ui/screens/group/add_contacts/views.cljs +++ b/src/status_im/ui/screens/group/add_contacts/views.cljs @@ -37,6 +37,7 @@ [react/view {:flex 1} [list/flat-list {:style contacts.styles/contacts-list :data contacts + :key-fn :address :render-fn render-function :keyboardShouldPersistTaps :always}]]) diff --git a/src/status_im/ui/screens/group/edit_contacts/views.cljs b/src/status_im/ui/screens/group/edit_contacts/views.cljs index 522fee1912..697747184b 100644 --- a/src/status_im/ui/screens/group/edit_contacts/views.cljs +++ b/src/status_im/ui/screens/group/edit_contacts/views.cljs @@ -13,6 +13,7 @@ [react/view {:flex 1} [list/flat-list {:data contacts :enableEmptySections true + :key-fn :address :render-fn (fn [contact] [contact-view {:contact contact :extended? extended? diff --git a/src/status_im/ui/screens/group/views.cljs b/src/status_im/ui/screens/group/views.cljs index 55e1e750f8..8cb9772089 100644 --- a/src/status_im/ui/screens/group/views.cljs +++ b/src/status_im/ui/screens/group/views.cljs @@ -56,6 +56,7 @@ [list/list-with-label {:flex 1} (i18n/label :t/members-title) [list/flat-list {:data contacts + :key-fn :address :render-fn render-contact :bounces false :keyboardShouldPersistTaps :always diff --git a/src/status_im/ui/screens/home/views.cljs b/src/status_im/ui/screens/home/views.cljs index d2b3f8b3a7..752d18cf8d 100644 --- a/src/status_im/ui/screens/home/views.cljs +++ b/src/status_im/ui/screens/home/views.cljs @@ -82,8 +82,9 @@ (i18n/label :t/no-recent-chats)]] :else [list/flat-list {:data home-items - :render-fn (fn [[home-item-id :as home-item]] - ^{:key home-item-id} [home-list-deletable home-item])}]) + :key-fn first + :render-fn (fn [home-item] + [home-list-deletable home-item])}]) (when platform/android? [home-action-button]) [connectivity/error-view]])) diff --git a/src/status_im/ui/screens/network_settings/views.cljs b/src/status_im/ui/screens/network_settings/views.cljs index 8dbcd61513..4863610132 100644 --- a/src/status_im/ui/screens/network_settings/views.cljs +++ b/src/status_im/ui/screens/network_settings/views.cljs @@ -66,6 +66,7 @@ [react/view {:flex 1} [list/flat-list {:style styles/networks-list :data (vals networks) + :key-fn :id :render-fn (render-network network) :header [react/view [actions-view diff --git a/src/status_im/ui/screens/offline_messaging_settings/views.cljs b/src/status_im/ui/screens/offline_messaging_settings/views.cljs index 72ac4c1d60..096ddfb523 100644 --- a/src/status_im/ui/screens/offline_messaging_settings/views.cljs +++ b/src/status_im/ui/screens/offline_messaging_settings/views.cljs @@ -65,6 +65,7 @@ [render-header wnodes] [list/flat-list {:data (vals wnodes) :separator? false + :key-fn :id :render-fn (render-row current-wnode) :ListFooterComponent (reagent/as-element (render-footer)) :style styles/wnodes-list}]]])) diff --git a/src/status_im/ui/screens/profile/group_chat/views.cljs b/src/status_im/ui/screens/profile/group_chat/views.cljs index 2e8f98f598..9e8b0b4055 100644 --- a/src/status_im/ui/screens/profile/group_chat/views.cljs +++ b/src/status_im/ui/screens/profile/group_chat/views.cljs @@ -84,6 +84,7 @@ [react/view [list/flat-list {:data contacts :separator list/default-separator + :key-fn :address :render-fn #(render-contact % admin?)}]])) (defn members-list [admin?] diff --git a/src/status_im/ui/screens/wallet/components/views.cljs b/src/status_im/ui/screens/wallet/components/views.cljs index aee4bcdbe5..06a490db76 100644 --- a/src/status_im/ui/screens/wallet/components/views.cljs +++ b/src/status_im/ui/screens/wallet/components/views.cljs @@ -60,6 +60,7 @@ [react/view {:style (assoc components.styles/flex :background-color :white)} [list/flat-list {:default-separator? true :data (concat [tokens/ethereum] (wallet/current-tokens visible-tokens network)) + :key-fn (comp str :symbol) :render-fn #(render-token % balance type)}]]])) (defn send-assets [] @@ -129,6 +130,7 @@ [components/toolbar (i18n/label :t/recipient)] [react/view styles/recent-recipients [list/flat-list {:data contacts + :key-fn :address :render-fn render-contact}]]])) (defn contact-code [] diff --git a/src/status_im/ui/screens/wallet/settings/views.cljs b/src/status_im/ui/screens/wallet/settings/views.cljs index 8a23c15d33..ed5aa8259d 100644 --- a/src/status_im/ui/screens/wallet/settings/views.cljs +++ b/src/status_im/ui/screens/wallet/settings/views.cljs @@ -34,4 +34,5 @@ (i18n/label :t/wallet-assets)]] [react/view {:style components.styles/flex} [list/flat-list {:data (tokens/tokens-for (ethereum/network->chain-keyword network)) + :key-fn (comp str :symbol) :render-fn #(render-token % visible-tokens)}]]])) diff --git a/src/status_im/ui/screens/wallet/transactions/views.cljs b/src/status_im/ui/screens/wallet/transactions/views.cljs index 276522997d..da0e8d3c17 100644 --- a/src/status_im/ui/screens/wallet/transactions/views.cljs +++ b/src/status_im/ui/screens/wallet/transactions/views.cljs @@ -121,6 +121,7 @@ (when error-message? (re-frame/dispatch [:wallet/show-error])) [list/section-list {:sections (map #(update-transactions % filter-data) transactions-history-list) + :key-fn :hash :render-fn render-transaction :empty-component [react/text {:style styles/empty-text} (i18n/label :t/transactions-history-empty)] @@ -131,6 +132,7 @@ (letsubs [transactions [:wallet.transactions/unsigned-transactions-list]] [react/view {:style components.styles/flex} [list/flat-list {:data transactions + :key-fn (fn [_ i] (str i)) :render-fn render-transaction :empty-component [react/text {:style styles/empty-text :accessibility-label :no-unsigned-transactions-text} @@ -171,7 +173,8 @@ :accessibility-label :select-all-button} (i18n/label :t/transactions-filter-select-all)]] [react/view {:style (merge {:background-color :white} components.styles/flex)} - [list/section-list {:sections (wrap-filter-data filter-data)}]]])) + [list/section-list {:sections (wrap-filter-data filter-data) + :key-fn :id}]]])) (defn history-tab [active?] [react/text {:force-uppercase? true diff --git a/src/status_im/ui/screens/wallet/views.cljs b/src/status_im/ui/screens/wallet/views.cljs index a3bd39796a..9426d4dcd4 100644 --- a/src/status_im/ui/screens/wallet/views.cljs +++ b/src/status_im/ui/screens/wallet/views.cljs @@ -75,6 +75,7 @@ [list/flat-list {:default-separator? true :data assets + :key-fn (comp str :symbol) :render-fn render-asset :on-refresh #(re-frame/dispatch [:update-wallet (map :symbol tokens)]) :refreshing refreshing?}]]))