🦁 Fix issues with missing dapp images and dapp names (#20811)

* 🦁 Beast mode

* 🗑️ Remove `prn` calls

* 🌎 Add utils to remove http:// prefix

* ⏭️ Extracted name and avatar computation

* 🧹 Cleanup

* ✏️ Fix lint and remove REPL flow

*  Remove broken test

* 🖊️ Fix lint
This commit is contained in:
Shivek Khurana 2024-07-23 13:34:03 +02:00 committed by GitHub
parent 1a4987478c
commit 3bb7c308e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 175 additions and 38 deletions

View File

@ -47,3 +47,12 @@
(defn style-text-value (defn style-text-value
[theme] [theme]
{:color (colors/theme-colors colors/neutral-50 colors/white theme)}) {:color (colors/theme-colors colors/neutral-50 colors/white theme)})
(def initials-avatar-container
{:width 32
:height 32})
(def image-avatar
{:width 32
:height 32
:border-radius 32})

View File

@ -1,5 +1,6 @@
(ns quo.components.list-items.dapp.view (ns quo.components.list-items.dapp.view
(:require (:require
[quo.components.avatars.user-avatar.view :as user-avatar]
[quo.components.list-items.dapp.style :as style] [quo.components.list-items.dapp.style :as style]
[quo.components.markdown.text :as text] [quo.components.markdown.text :as text]
[quo.theme :as quo.theme] [quo.theme :as quo.theme]
@ -20,9 +21,15 @@
:on-press-in on-press-in :on-press-in on-press-in
:on-press-out on-press-out} :on-press-out on-press-out}
[rn/view {:style style/container-info} [rn/view {:style style/container-info}
[fast-image/fast-image (if (:avatar dapp)
{:source (:avatar dapp) [fast-image/fast-image
:style {:width 32 :height 32}}] {:source (:avatar dapp)
:style style/image-avatar}]
[rn/view {:style style/initials-avatar-container}
[user-avatar/initials-avatar
{:full-name (:name dapp)
:size :small
:customization-color (:customization-color dapp)}]])
[rn/view {:style style/user-info} [rn/view {:style style/user-info}
[text/text [text/text
{:weight :semi-bold {:weight :semi-bold

View File

@ -13,14 +13,17 @@
:value "Default"} :value "Default"}
{:key :active {:key :active
:value "Active"}]} :value "Active"}]}
{:key :action {:key :dapp
:type :select :type :select
:options [{:key :none :options [{:value "With icon"
:value "None"} :key {:avatar (resources/get-dapp :coingecko)
{:key :icon :name "Coingecko"
:value "Icon"}]} :value "coingecko.com"}}
{:key :blur? {:value "Without icon"
:type :boolean}]) :key {:avatar nil
:name "Coingecko"
:value "coingecko.com"
:customization-color :blue}}]}])
(defn preview (defn preview
[] []

View File

@ -9,8 +9,10 @@
[status-im.common.resources :as resources] [status-im.common.resources :as resources]
[status-im.contexts.wallet.connected-dapps.disconnect-dapp.view :as disconnect-dapp] [status-im.contexts.wallet.connected-dapps.disconnect-dapp.view :as disconnect-dapp]
[status-im.contexts.wallet.connected-dapps.style :as style] [status-im.contexts.wallet.connected-dapps.style :as style]
[status-im.contexts.wallet.wallet-connect.core :as core]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]
[utils.string]))
(defn- on-disconnect (defn- on-disconnect
[wallet-account {:keys [name topic]}] [wallet-account {:keys [name topic]}]
@ -84,7 +86,8 @@
{:keys [color] :as wallet-account} (rf/sub [:wallet/current-viewing-account]) {:keys [color] :as wallet-account} (rf/sub [:wallet/current-viewing-account])
sessions (rf/sub sessions (rf/sub
[:wallet-connect/sessions-for-current-account]) [:wallet-connect/sessions-for-current-account])
theme (quo.theme/use-theme)] theme (quo.theme/use-theme)
customization-color (rf/sub [:profile/customization-color])]
[rn/view {:flex 1} [rn/view {:flex 1}
[header [header
{:title (i18n/label :t/connected-dapps) {:title (i18n/label :t/connected-dapps)
@ -104,11 +107,13 @@
:content-container-style (style/dapps-list theme) :content-container-style (style/dapps-list theme)
:render-fn (fn [{:keys [topic pairingTopic name url iconUrl]}] :render-fn (fn [{:keys [topic pairingTopic name url iconUrl]}]
[quo/dapp [quo/dapp
{:dapp {:avatar iconUrl {:dapp {:avatar (core/compute-dapp-icon-path iconUrl
:name name url)
:value url :name (core/compute-dapp-name name url)
:topic topic :value url
:pairing-topic pairingTopic} :topic topic
:pairing-topic pairingTopic
:customization-color customization-color}
:accessibility-label (str "dapp-" topic) :accessibility-label (str "dapp-" topic)
:state :default :state :default
:action :icon :action :icon

View File

@ -4,6 +4,7 @@
[native-module.core :as native-module] [native-module.core :as native-module]
[status-im.constants :as constants] [status-im.constants :as constants]
[utils.security.core :as security] [utils.security.core :as security]
[utils.string]
[utils.transforms :as transforms])) [utils.transforms :as transforms]))
(def method-to-screen (def method-to-screen
@ -143,3 +144,23 @@
account-addresses)) account-addresses))
accounts)) accounts))
sessions)) sessions))
(defn compute-dapp-name
"Sometimes dapps have no name or an empty name. Return url as name in that case"
[name url]
(if (seq name)
name
(when (seq url)
(-> url
utils.string/remove-trailing-slash
utils.string/remove-http-prefix
string/capitalize))))
(defn compute-dapp-icon-path
"Some dapps have icons with relative paths, make paths absolute in those cases, send nil if icon is missing"
[icon-path url]
(when (and (seq icon-path)
(seq url))
(if (string/starts-with? icon-path "http")
icon-path
(str (utils.string/remove-trailing-slash url) icon-path))))

View File

@ -1,6 +1,7 @@
(ns status-im.contexts.wallet.wallet-connect.modals.common.footer.view (ns status-im.contexts.wallet.wallet-connect.modals.common.footer.view
(:require [quo.core :as quo] (:require [quo.core :as quo]
[quo.foundations.colors :as colors] [quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn] [react-native.core :as rn]
[status-im.common.standard-authentication.core :as standard-authentication] [status-im.common.standard-authentication.core :as standard-authentication]
[status-im.contexts.wallet.wallet-connect.modals.common.footer.style :as style] [status-im.contexts.wallet.wallet-connect.modals.common.footer.style :as style]
@ -14,7 +15,8 @@
(defn view (defn view
[{:keys [warning-label slide-button-text disabled?]} & children] [{:keys [warning-label slide-button-text disabled?]} & children]
(let [{:keys [customization-color]} (rf/sub [:wallet-connect/current-request-account-details])] (let [{:keys [customization-color]} (rf/sub [:wallet-connect/current-request-account-details])
theme (quo.theme/use-theme)]
[rn/view {:style style/content-container} [rn/view {:style style/content-container}
(into [rn/view (into [rn/view
{:style style/data-items-container}] {:style style/data-items-container}]
@ -30,6 +32,8 @@
[rn/view {:style style/warning-container} [rn/view {:style style/warning-container}
[quo/text [quo/text
{:size :paragraph-2 {:size :paragraph-2
:style {:color colors/neutral-80-opa-70} :style {:color (if (= theme :dark)
colors/white-opa-70
colors/neutral-80-opa-70)}
:weight :medium} :weight :medium}
warning-label]]])) warning-label]]]))

View File

@ -1,7 +1,10 @@
(ns status-im.contexts.wallet.wallet-connect.modals.common.header.view (ns status-im.contexts.wallet.wallet-connect.modals.common.header.view
(:require [quo.core :as quo] (:require
[react-native.core :as rn] [quo.core :as quo]
[status-im.contexts.wallet.wallet-connect.modals.common.header.style :as style])) [react-native.core :as rn]
[status-im.contexts.wallet.wallet-connect.core :as core]
[status-im.contexts.wallet.wallet-connect.modals.common.header.style :as style]
[utils.string]))
(defn view (defn view
[{:keys [label dapp account]}] [{:keys [label dapp account]}]
@ -10,12 +13,13 @@
[quo/text [quo/text
{:size :heading-1 {:size :heading-1
:weight :semi-bold} :weight :semi-bold}
(let [{:keys [name iconUrl]} dapp] (let [{:keys [name iconUrl url]} dapp
image-source (core/compute-dapp-icon-path iconUrl url)]
[rn/view {:style style/header-dapp-name} [rn/view {:style style/header-dapp-name}
[quo/summary-tag [quo/summary-tag
{:type :dapp {:type :dapp
:label name :label name
:image-source iconUrl}]]) :image-source image-source}]])
(str " " label " ") (str " " label " ")
(let [{:keys [emoji customization-color name]} account] (let [{:keys [emoji customization-color name]} account]
[rn/view {:style style/header-account-name} [rn/view {:style style/header-account-name}

View File

@ -5,14 +5,15 @@
{:padding-horizontal 20 {:padding-horizontal 20
:padding-top 12}) :padding-top 12})
(def approval-note-container (defn approval-note-container
[theme]
{:margin-horizontal 20 {:margin-horizontal 20
:padding-horizontal 16 :padding-horizontal 16
:padding-vertical 12 :padding-vertical 12
:border-radius 16 :border-radius 16
:border-width 1 :border-width 1
:border-color colors/neutral-10 :border-color (colors/theme-colors colors/neutral-10 colors/black-opa-30 theme)
:background-color colors/neutral-2_5}) :background-color (colors/theme-colors colors/neutral-2_5 colors/black-opa-30 theme)})
(def approval-note-title (def approval-note-title
{:color colors/neutral-50 {:color colors/neutral-50

View File

@ -6,21 +6,27 @@
[quo.theme] [quo.theme]
[react-native.core :as rn] [react-native.core :as rn]
[status-im.common.floating-button-page.view :as floating-button-page] [status-im.common.floating-button-page.view :as floating-button-page]
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
[status-im.contexts.wallet.wallet-connect.session-proposal.style :as style] [status-im.contexts.wallet.wallet-connect.session-proposal.style :as style]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]
[utils.string]))
(defn- dapp-metadata (defn- dapp-metadata
[] []
(let [proposer (rf/sub [:wallet-connect/session-proposer]) (let [proposer (rf/sub [:wallet-connect/session-proposer])
{:keys [icons name url]} (:metadata proposer)] {:keys [icons name url]} (:metadata proposer)
first-icon (first icons)
dapp-name (wallet-connect-core/compute-dapp-name name url)
profile-picture (wallet-connect-core/compute-dapp-icon-path first-icon url)]
[:<> [:<>
[rn/view {:style style/dapp-avatar} [rn/view {:style style/dapp-avatar}
[quo/user-avatar [quo/user-avatar
{:profile-picture (first icons) {:profile-picture profile-picture
:size :big}]] :size :big
:full-name dapp-name}]]
[quo/page-top [quo/page-top
{:title name {:title dapp-name
:description :context-tag :description :context-tag
:context-tag {:type :icon :context-tag {:type :icon
:size 32 :size 32
@ -31,8 +37,9 @@
[] []
(let [dapp-name (rf/sub [:wallet-connect/session-proposer-name]) (let [dapp-name (rf/sub [:wallet-connect/session-proposer-name])
labels [(i18n/label :t/check-your-account-balance-and-activity) labels [(i18n/label :t/check-your-account-balance-and-activity)
(i18n/label :t/request-txns-and-message-signing)]] (i18n/label :t/request-txns-and-message-signing)]
[rn/view {:style style/approval-note-container} theme (quo.theme/use-theme)]
[rn/view {:style (style/approval-note-container theme)}
[quo/text [quo/text
{:style style/approval-note-title {:style style/approval-note-title
:weight :regular :weight :regular
@ -46,7 +53,8 @@
{:color colors/neutral-40}] {:color colors/neutral-40}]
[quo/text [quo/text
{:weight :regular {:weight :regular
:size :paragraph-2} :size :paragraph-2
:color colors/neutral-40}
label]]) label]])
labels)])) labels)]))

View File

@ -5,7 +5,8 @@
[status-im.contexts.wallet.common.utils.networks :as networks] [status-im.contexts.wallet.common.utils.networks :as networks]
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core] [status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
[status-im.contexts.wallet.wallet-connect.transactions :as transactions] [status-im.contexts.wallet.wallet-connect.transactions :as transactions]
[utils.money :as money])) [utils.money :as money]
[utils.string]))
(rf/reg-sub (rf/reg-sub
:wallet-connect/current-request-address :wallet-connect/current-request-address
@ -44,7 +45,8 @@
(let [dapp-url (get-in request [:event :verifyContext :verified :origin])] (let [dapp-url (get-in request [:event :verifyContext :verified :origin])]
(->> sessions (->> sessions
(filter (fn [session] (filter (fn [session]
(= dapp-url (get session :url)))) (= (utils.string/remove-trailing-slash dapp-url)
(utils.string/remove-trailing-slash (get session :url)))))
(first))))) (first)))))
(rf/reg-sub (rf/reg-sub
@ -168,7 +170,8 @@
:wallet-connect/session-proposer-name :wallet-connect/session-proposer-name
:<- [:wallet-connect/session-proposer] :<- [:wallet-connect/session-proposer]
(fn [proposer] (fn [proposer]
(-> proposer :metadata :name))) (let [{:keys [name url]} (-> proposer :metadata)]
(wallet-connect-core/compute-dapp-name name url))))
(rf/reg-sub (rf/reg-sub
:wallet-connect/session-proposal-network-details :wallet-connect/session-proposal-network-details

View File

@ -42,6 +42,41 @@
:origin "https://lab.web3modal.com" :origin "https://lab.web3modal.com"
:isScam false}}}}) :isScam false}}}})
(def sample-session-empty-name
{:session-proposal
{:id 1716798889093634
:params
{:id 1716798889093634
:pairingTopic "9b18e1348817a548bbc97f9b4a09278f4fdf7c984e4a61ddf461bd1f57710d33"
:expiryTimestamp 1716799189
:requiredNamespaces {}
:optionalNamespaces {:eip155
{:chains ["eip155:1" "eip155:42161" "eip155:137" "eip155:43114" "eip155:56"
"eip155:10" "eip155:100"
"eip155:324" "eip155:7777777" "eip155:8453" "eip155:42220"
"eip155:1313161554" "eip155:11155111" "eip155:11155420"]
:methods ["personal_sign" "eth_accounts" "eth_requestAccounts"
"eth_sendRawTransaction" "eth_sendTransaction"
"eth_sign" "eth_signTransaction" "eth_signTypedData"
"eth_signTypedData_v3" "eth_signTypedData_v4"
"wallet_addEthereumChain" "wallet_getCallsStatus"
"wallet_getCapabilities" "wallet_getPermissions"
"wallet_registerOnboarding" "wallet_requestPermissions"
"wallet_scanQRCode" "wallet_sendCalls"
"wallet_showCallsStatus" "wallet_switchEthereumChain"
"wallet_watchAsset"]
:events ["chainChanged" "accountsChanged"]}}
:relays [{:protocol "irn"}]
:proposer {:publicKey "cddea055b8974d93380e6c7e72110145506c06524047866f8034f3db0990137a"
:metadata {:name ""
:description "Web3Modal Laboratory"
:url "https://lab.web3modal.com"
:icons ["https://avatars.githubusercontent.com/u/37784886"]}}}
:verifyContext {:verified {:verifyUrl "https://verify.walletconnect.com"
:validation "VALID"
:origin "https://lab.web3modal.com"
:isScam false}}}})
(h/deftest-sub :wallet-connect/session-proposer (h/deftest-sub :wallet-connect/session-proposer
[sub-name] [sub-name]
(testing "Return the session proposer public key and metadata" (testing "Return the session proposer public key and metadata"

View File

@ -73,3 +73,18 @@
(defn contains-special-character? (defn contains-special-character?
[s] [s]
(re-find #"[^a-zA-Z0-9\s]" s)) (re-find #"[^a-zA-Z0-9\s]" s))
(defn remove-trailing-slash
"Given a URL, checks if it has a trailing slash and removes it.
Returns the URL as-is if there is no trailing slash."
[url]
(if (and (string? url) (string/ends-with? url "/"))
(subs url 0 (dec (count url)))
url))
(defn remove-http-prefix
"Given a URL, removes the 'http://' or 'https://' prefix if present.
Returns the URL without the prefix."
[url]
(when (string? url)
(string/replace url #"^https?://" "")))

View File

@ -18,3 +18,25 @@
"AB" "a b" 2 "AB" "a b" 2
"ABC" "a b c d" 3 "ABC" "a b c d" 3
"ABC" " a b c d" 3)) "ABC" " a b c d" 3))
(deftest remove-trailing-slash-test
(are [expected input]
(= expected (utils.string/remove-trailing-slash input))
"http://example.com" "http://example.com/"
"http://example.com" "http://example.com"
"http://example.com/path" "http://example.com/path/"
"http://example.com/path" "http://example.com/path"
"" ""
nil nil))
(deftest remove-http-prefix-test
(are [expected input]
(= expected (utils.string/remove-http-prefix input))
"example.com" "http://example.com"
"example.com" "https://example.com"
"example.com" "example.com"
"example.com/path" "http://example.com/path"
"example.com/path" "https://example.com/path"
"example.com/path" "example.com/path"
"" ""
nil nil))