Skip to content

Commit 97d4edc

Browse files
fix(wallet): Collectibles not fetched for new and recovered accounts (#20961)
This commit fixes collectibles not fetched for new and recovered accounts until the user re-login. Signed-off-by: Mohamed Javid <[email protected]>
1 parent 1663848 commit 97d4edc

File tree

13 files changed

+267
-99
lines changed

13 files changed

+267
-99
lines changed

src/quo/components/profile/collectible_list_item/view.cljs

+5-3
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
:color-index gradient-color-index}]])
9292

9393
(defn- card-details
94-
[{:keys [community? avatar-image-src collectible-name theme state set-state]}]
94+
[{:keys [community? avatar-image-src collectible-name theme state set-state loading?]}]
9595
(let [loader-opacity (reanimated/use-shared-value 1)
9696
avatar-opacity (reanimated/use-shared-value 0)
9797
[load-time set-load-time] (rn/use-state (datetime/now))
@@ -102,7 +102,7 @@
102102
:avatar-opacity avatar-opacity}))
103103
empty-name? (string/blank? collectible-name)]
104104
(rn/use-mount (fn []
105-
(when (string/blank? avatar-image-src)
105+
(when (and (string/blank? avatar-image-src) (not loading?))
106106
(set-avatar-loaded))))
107107
[rn/view {:style style/card-details-container}
108108
[reanimated/view {:style (style/avatar-container avatar-opacity)}
@@ -137,7 +137,7 @@
137137

138138
(defn- card-view
139139
[{:keys [avatar-image-src collectible-name community? counter state set-state
140-
gradient-color-index image-src supported-file?]}]
140+
gradient-color-index image-src supported-file? loading?]}]
141141
(let [theme (quo.theme/use-theme)
142142
loader-opacity (reanimated/use-shared-value (if supported-file? 1 0))
143143
image-opacity (reanimated/use-shared-value (if supported-file? 0 1))
@@ -189,6 +189,7 @@
189189
:community? community?
190190
:avatar-image-src avatar-image-src
191191
:collectible-name collectible-name
192+
:loading? loading?
192193
:theme theme}]]))
193194

194195
(defn- image-view
@@ -276,6 +277,7 @@
276277
[:supported-file? {:optional true} [:maybe boolean?]]
277278
[:native-ID {:optional true} [:maybe [:or string? keyword?]]]
278279
[:community? {:optional true} [:maybe boolean?]]
280+
[:loading? {:optional true} [:maybe boolean?]]
279281
[:counter {:optional true} [:maybe [:or :string :int]]]
280282
[:gradient-color-index {:optional true}
281283
[:maybe [:enum :gradient-1 :gradient-2 :gradient-3 :gradient-4 :gradient-5]]]

src/status_im/contexts/wallet/account/tabs/view.cljs

+24-18
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,29 @@
2525
[]
2626
(rf/dispatch [:wallet/request-collectibles-for-current-viewing-account]))
2727

28-
(defn view
29-
[{:keys [selected-tab]}]
30-
(let [collectible-list (rf/sub
28+
(defn- collectibles-tab
29+
[]
30+
(let [updating? (rf/sub [:wallet/current-viewing-account-collectibles-updating?])
31+
collectible-list (rf/sub
3132
[:wallet/current-viewing-account-collectibles-in-selected-networks])
3233
current-account-address (rf/sub [:wallet/current-viewing-account-address])]
33-
[rn/view {:style {:flex 1}}
34-
(case selected-tab
35-
:assets [assets/view]
36-
:collectibles [collectibles/view
37-
{:collectibles collectible-list
38-
:current-account-address current-account-address
39-
:on-end-reached on-end-reached
40-
:on-collectible-press on-collectible-press
41-
:on-collectible-long-press on-collectible-long-press}]
42-
:activity [activity/view]
43-
:permissions [empty-tab/view
44-
{:title (i18n/label :t/no-permissions)
45-
:description (i18n/label :t/no-collectibles-description)
46-
:placeholder? true}]
47-
[about/view])]))
34+
[collectibles/view
35+
{:loading? updating?
36+
:collectibles collectible-list
37+
:current-account-address current-account-address
38+
:on-end-reached on-end-reached
39+
:on-collectible-press on-collectible-press
40+
:on-collectible-long-press on-collectible-long-press}]))
41+
42+
(defn view
43+
[{:keys [selected-tab]}]
44+
[rn/view {:style {:flex 1}}
45+
(case selected-tab
46+
:assets [assets/view]
47+
:collectibles [collectibles-tab]
48+
:activity [activity/view]
49+
:permissions [empty-tab/view
50+
{:title (i18n/label :t/no-permissions)
51+
:description (i18n/label :t/no-collectibles-description)
52+
:placeholder? true}]
53+
[about/view])])

src/status_im/contexts/wallet/collectible/events.cljs

+128-23
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
(ns status-im.contexts.wallet.collectible.events
22
(:require [camel-snake-kebab.extras :as cske]
3+
[clojure.set]
34
[clojure.string :as string]
45
[react-native.platform :as platform]
56
[status-im.contexts.network.data-store :as network.data-store]
67
[status-im.contexts.wallet.collectible.utils :as collectible-utils]
8+
[status-im.contexts.wallet.data-store :as data-store]
79
[taoensso.timbre :as log]
10+
[utils.collection]
811
[utils.ethereum.chain :as chain]
12+
[utils.number :as utils.number]
913
[utils.re-frame :as rf]
1014
[utils.transforms :as transforms]))
1115

@@ -24,6 +28,12 @@
2428
(def max-cache-age-seconds 3600)
2529
(def collectibles-request-batch-size 25)
2630

31+
(def ownership-state
32+
{:idle 1
33+
:delayed 2
34+
:updating 3
35+
:error 4})
36+
2737
(defn- move-collectibles-to-accounts
2838
[accounts new-collectibles-per-account]
2939
(reduce-kv (fn [acc account new-collectibles]
@@ -84,12 +94,18 @@
8494
(rf/reg-event-fx
8595
:wallet/request-collectibles-for-all-accounts
8696
(fn [{:keys [db]} [{:keys [new-request?]}]]
87-
(let [accounts (->> (get-in db [:wallet :accounts])
97+
(let [updating-addresses (-> (get-in db [:wallet :ui :collectibles :updating])
98+
keys
99+
set)
100+
accounts (->> (get-in db [:wallet :accounts])
88101
(filter (fn [[_ {:keys [has-more-collectibles?]}]]
89102
(or (nil? has-more-collectibles?)
90103
(true? has-more-collectibles?))))
91104
(keys))
92-
num-accounts (count accounts)
105+
;; filter the addresses which are requested before and the collectibles are updating
106+
requestable-addresses (clojure.set/difference (set accounts)
107+
updating-addresses)
108+
num-accounts (count requestable-addresses)
93109
collectibles-per-account (quot collectibles-request-batch-size num-accounts)
94110
;; We need to pass unique IDs for simultaneous requests, otherwise they'll fail
95111
request-ids (get-unique-collectible-request-id num-accounts)
@@ -100,13 +116,13 @@
100116
:account account
101117
:amount collectibles-per-account}]])
102118
request-ids
103-
accounts)]
119+
requestable-addresses)]
104120
{:db (cond-> db
105121
:always (assoc-in [:wallet :ui :collectibles :pending-requests] num-accounts)
106122
new-request? (update-in [:wallet :accounts] update-vals #(dissoc % :collectibles)))
107123
:fx collectible-requests})))
108124

109-
(defn request-new-collectibles-for-account-from-signal
125+
(defn request-collectibles-for-account
110126
[{:keys [db]} [address]]
111127
(let [pending-requests (get-in db [:wallet :ui :collectibles :pending-requests] 0)
112128
[request-id] (get-unique-collectible-request-id 1)]
@@ -117,49 +133,138 @@
117133
:account address
118134
:amount collectibles-request-batch-size}]]]}))
119135

120-
(rf/reg-event-fx :wallet/request-new-collectibles-for-account-from-signal
121-
request-new-collectibles-for-account-from-signal)
136+
(rf/reg-event-fx :wallet/request-collectibles-for-account request-collectibles-for-account)
122137

123138
(rf/reg-event-fx
124139
:wallet/request-collectibles-for-current-viewing-account
125140
(fn [{:keys [db]} _]
126141
(when (network.data-store/online? db)
127-
(let [current-viewing-account (-> db :wallet :current-viewing-account-address)
128-
[request-id] (get-unique-collectible-request-id 1)]
129-
{:db (assoc-in db [:wallet :ui :collectibles :pending-requests] 1)
130-
:fx [[:dispatch
131-
[:wallet/request-new-collectibles-for-account
132-
{:request-id request-id
133-
:account current-viewing-account
134-
:amount collectibles-request-batch-size}]]]}))))
142+
(let [current-viewing-account (-> db :wallet :current-viewing-account-address)]
143+
{:fx [[:dispatch [:wallet/request-collectibles-for-account current-viewing-account]]]}))))
144+
145+
(rf/reg-event-fx
146+
:wallet/collectible-ownership-update-finished-with-error
147+
(fn [{:keys [db]} [{:keys [accounts message chainId]}]]
148+
(let [address (first accounts)
149+
pending-chain-ids (get-in db [:wallet :ui :collectibles :updating address])
150+
updated-chain-ids (disj pending-chain-ids chainId)
151+
all-chain-updated? (and (some? pending-chain-ids) (empty? updated-chain-ids))]
152+
{:db (cond-> db
153+
(some? pending-chain-ids)
154+
(assoc-in [:wallet :ui :collectibles :updating address] updated-chain-ids))
155+
:fx [[:dispatch
156+
[:wallet/log-rpc-error
157+
{:event :wallet/collectible-ownership-update-finished-with-error
158+
:params {:address address
159+
:chain-id chainId}}
160+
message]]
161+
(when all-chain-updated?
162+
[:dispatch [:wallet/request-collectibles-for-account address]])]})))
163+
164+
(rf/reg-event-fx
165+
:wallet/collectible-ownership-update-finished
166+
(fn [{:keys [db]} [{:keys [accounts chainId]}]]
167+
(let [address (first accounts)
168+
pending-chain-ids (get-in db [:wallet :ui :collectibles :updating address])
169+
updated-chain-ids (disj pending-chain-ids chainId)
170+
all-chain-updated? (and (some? pending-chain-ids) (empty? updated-chain-ids))]
171+
{:db (cond-> db
172+
(some? pending-chain-ids)
173+
(assoc-in [:wallet :ui :collectibles :updating address] updated-chain-ids))
174+
:fx [(when all-chain-updated?
175+
[:dispatch [:wallet/request-collectibles-for-account address]])]})))
176+
177+
(defn- update-collectibles-in-account
178+
[existing-collectibles updated-collectibles]
179+
(let [indexed-existing (utils.collection/index-by
180+
:unique-id
181+
existing-collectibles)
182+
existing-ids (-> indexed-existing keys vec)
183+
;; pick collectibles only in the app-db
184+
indexed-updated (-> (utils.collection/index-by
185+
:unique-id
186+
updated-collectibles)
187+
(select-keys existing-ids))]
188+
(-> (merge-with
189+
merge
190+
indexed-existing
191+
indexed-updated)
192+
vals
193+
vec)))
194+
195+
(rf/reg-event-fx
196+
:wallet/collectibles-data-updated
197+
(fn [{:keys [db]} [{:keys [message]}]]
198+
(let [collectibles-by-address (->> message
199+
transforms/json->clj
200+
data-store/rpc->collectibles
201+
(group-by #(-> % :ownership first :address)))]
202+
{:db (update-in db
203+
[:wallet :accounts]
204+
#(reduce-kv
205+
(fn [accounts address updated-collectibles]
206+
(if (contains? accounts address)
207+
(update-in accounts
208+
[address :collectibles]
209+
update-collectibles-in-account
210+
updated-collectibles)
211+
accounts))
212+
%
213+
collectibles-by-address))})))
214+
215+
(rf/reg-event-fx
216+
:wallet/set-collectibles-updating-status
217+
(fn [{:keys [db]} [address chain-ids]]
218+
{:db (assoc-in db [:wallet :ui :collectibles :updating address] chain-ids)}))
135219

136220
(defn- update-fetched-collectibles-progress
137221
[db owner-address collectibles offset has-more?]
138222
(-> db
223+
(update-in [:wallet :ui :collectibles :updating] dissoc owner-address)
139224
(assoc-in [:wallet :ui :collectibles :fetched owner-address] collectibles)
140225
(assoc-in [:wallet :accounts owner-address :current-collectible-idx]
141226
(+ offset (count collectibles)))
142227
(assoc-in [:wallet :accounts owner-address :has-more-collectibles?] has-more?)))
143228

229+
(defn- updating-collectibles?
230+
[status]
231+
(and (= (:state status) (ownership-state :updating))
232+
(= (:timestamp status) -1)))
233+
144234
(rf/reg-event-fx
145235
:wallet/owned-collectibles-filtering-done
146236
(fn [{:keys [db]} [{:keys [message]}]]
147237
(let [{:keys [offset ownershipStatus collectibles
148-
hasMore]} (transforms/json->clj message)
149-
collectibles (cske/transform-keys transforms/->kebab-case-keyword collectibles)
150-
pending-requests (dec (get-in db [:wallet :ui :collectibles :pending-requests]))
151-
owner-address (some->> ownershipStatus
152-
first
153-
key
154-
name)]
238+
hasMore]} (transforms/json->clj message)
239+
ownership-status-by-address (-> ownershipStatus
240+
(update-keys name)
241+
(update-vals #(update-keys %
242+
(comp utils.number/parse-int name))))
243+
owner-address (some-> ownership-status-by-address
244+
first
245+
key)
246+
ownership-status (get ownership-status-by-address owner-address)
247+
collectibles (data-store/rpc->collectibles collectibles)
248+
pending-requests (dec (get-in db [:wallet :ui :collectibles :pending-requests]))
249+
;; check if collectibles are updating (never fetched and cached before) for this address
250+
updating-chains (-> (select-keys
251+
ownership-status
252+
(for [[k v] ownership-status
253+
:when (updating-collectibles? v)]
254+
k))
255+
keys
256+
set)
257+
updating? (-> updating-chains count pos?)]
155258
{:db (cond-> db
156259
:always (assoc-in [:wallet :ui :collectibles :pending-requests] pending-requests)
157260
owner-address (update-fetched-collectibles-progress owner-address
158261
collectibles
159262
offset
160-
hasMore))
263+
(when-not updating? hasMore)))
161264
:fx [(when (zero? pending-requests)
162-
[:dispatch [:wallet/flush-collectibles-fetched]])]})))
265+
[:dispatch [:wallet/flush-collectibles-fetched]])
266+
(when updating?
267+
[:dispatch [:wallet/set-collectibles-updating-status owner-address updating-chains]])]})))
163268

164269
(rf/reg-event-fx
165270
:wallet/navigate-to-collectible-details

src/status_im/contexts/wallet/collectible/events_test.cljs

+4-4
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343

4444
(is (match? result-db expected-db))))))
4545

46-
(deftest request-new-collectibles-for-account-from-signal-test
47-
(testing "request new collectibles for account from signal"
46+
(deftest request-collectibles-for-account-test
47+
(testing "request collectibles for account"
4848
(let [db {:wallet {}}
4949
address "0x1"
5050
expected {:db {:wallet {:ui {:collectibles {:pending-requests 1}}}}
@@ -53,6 +53,6 @@
5353
{:request-id 0
5454
:account address
5555
:amount events/collectibles-request-batch-size}]]]}
56-
effects (events/request-new-collectibles-for-account-from-signal {:db db}
57-
[address])]
56+
effects (events/request-collectibles-for-account {:db db}
57+
[address])]
5858
(is (match? expected effects)))))

src/status_im/contexts/wallet/collectible/utils.cljs

+7
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,10 @@
7070
test-networks-enabled?
7171
is-goerli-enabled?)]
7272
(str base-link "/assets/" opensea-network-name "/" contract-address "/" token-id)))
73+
74+
(defn get-collectible-unique-id
75+
[{:keys [id]}]
76+
(let [chain-id (-> id :contract-id :chain-id)
77+
contract-address (-> id :contract-id :address)
78+
token-id (-> id :token-id)]
79+
(str chain-id contract-address token-id)))

0 commit comments

Comments
 (0)