diff --git a/src/quo/components/list_items/dapp/style.cljs b/src/quo/components/list_items/dapp/style.cljs index d9f67b62b4..d0592bf14b 100644 --- a/src/quo/components/list_items/dapp/style.cljs +++ b/src/quo/components/list_items/dapp/style.cljs @@ -47,3 +47,12 @@ (defn style-text-value [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}) diff --git a/src/quo/components/list_items/dapp/view.cljs b/src/quo/components/list_items/dapp/view.cljs index 0626158480..5a5fbdd7a6 100644 --- a/src/quo/components/list_items/dapp/view.cljs +++ b/src/quo/components/list_items/dapp/view.cljs @@ -1,5 +1,6 @@ (ns quo.components.list-items.dapp.view (:require + [quo.components.avatars.user-avatar.view :as user-avatar] [quo.components.list-items.dapp.style :as style] [quo.components.markdown.text :as text] [quo.theme :as quo.theme] @@ -20,9 +21,15 @@ :on-press-in on-press-in :on-press-out on-press-out} [rn/view {:style style/container-info} - [fast-image/fast-image - {:source (:avatar dapp) - :style {:width 32 :height 32}}] + (if (:avatar dapp) + [fast-image/fast-image + {: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} [text/text {:weight :semi-bold diff --git a/src/status_im/contexts/preview/quo/list_items/dapp.cljs b/src/status_im/contexts/preview/quo/list_items/dapp.cljs index f14e18f7fe..6530797f96 100644 --- a/src/status_im/contexts/preview/quo/list_items/dapp.cljs +++ b/src/status_im/contexts/preview/quo/list_items/dapp.cljs @@ -13,14 +13,17 @@ :value "Default"} {:key :active :value "Active"}]} - {:key :action + {:key :dapp :type :select - :options [{:key :none - :value "None"} - {:key :icon - :value "Icon"}]} - {:key :blur? - :type :boolean}]) + :options [{:value "With icon" + :key {:avatar (resources/get-dapp :coingecko) + :name "Coingecko" + :value "coingecko.com"}} + {:value "Without icon" + :key {:avatar nil + :name "Coingecko" + :value "coingecko.com" + :customization-color :blue}}]}]) (defn preview [] diff --git a/src/status_im/contexts/wallet/connected_dapps/view.cljs b/src/status_im/contexts/wallet/connected_dapps/view.cljs index ca72c9cccf..69d24e44bb 100644 --- a/src/status_im/contexts/wallet/connected_dapps/view.cljs +++ b/src/status_im/contexts/wallet/connected_dapps/view.cljs @@ -9,8 +9,10 @@ [status-im.common.resources :as resources] [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.wallet-connect.core :as core] [utils.i18n :as i18n] - [utils.re-frame :as rf])) + [utils.re-frame :as rf] + [utils.string])) (defn- on-disconnect [wallet-account {:keys [name topic]}] @@ -84,7 +86,8 @@ {:keys [color] :as wallet-account} (rf/sub [:wallet/current-viewing-account]) sessions (rf/sub [: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} [header {:title (i18n/label :t/connected-dapps) @@ -104,11 +107,13 @@ :content-container-style (style/dapps-list theme) :render-fn (fn [{:keys [topic pairingTopic name url iconUrl]}] [quo/dapp - {:dapp {:avatar iconUrl - :name name - :value url - :topic topic - :pairing-topic pairingTopic} + {:dapp {:avatar (core/compute-dapp-icon-path iconUrl + url) + :name (core/compute-dapp-name name url) + :value url + :topic topic + :pairing-topic pairingTopic + :customization-color customization-color} :accessibility-label (str "dapp-" topic) :state :default :action :icon diff --git a/src/status_im/contexts/wallet/wallet_connect/core.cljs b/src/status_im/contexts/wallet/wallet_connect/core.cljs index e8a0196dfc..1a2f994461 100644 --- a/src/status_im/contexts/wallet/wallet_connect/core.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/core.cljs @@ -4,6 +4,7 @@ [native-module.core :as native-module] [status-im.constants :as constants] [utils.security.core :as security] + [utils.string] [utils.transforms :as transforms])) (def method-to-screen @@ -143,3 +144,23 @@ account-addresses)) accounts)) 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)))) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs index 14e853eae1..ddfc222b1a 100644 --- a/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs @@ -1,6 +1,7 @@ (ns status-im.contexts.wallet.wallet-connect.modals.common.footer.view (:require [quo.core :as quo] [quo.foundations.colors :as colors] + [quo.theme] [react-native.core :as rn] [status-im.common.standard-authentication.core :as standard-authentication] [status-im.contexts.wallet.wallet-connect.modals.common.footer.style :as style] @@ -14,7 +15,8 @@ (defn view [{: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} (into [rn/view {:style style/data-items-container}] @@ -30,6 +32,8 @@ [rn/view {:style style/warning-container} [quo/text {: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} warning-label]]])) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs index 5a13a0401e..ab76aee8d5 100644 --- a/src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs @@ -1,7 +1,10 @@ (ns status-im.contexts.wallet.wallet-connect.modals.common.header.view - (:require [quo.core :as quo] - [react-native.core :as rn] - [status-im.contexts.wallet.wallet-connect.modals.common.header.style :as style])) + (:require + [quo.core :as quo] + [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 [{:keys [label dapp account]}] @@ -10,12 +13,13 @@ [quo/text {:size :heading-1 :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} [quo/summary-tag {:type :dapp :label name - :image-source iconUrl}]]) + :image-source image-source}]]) (str " " label " ") (let [{:keys [emoji customization-color name]} account] [rn/view {:style style/header-account-name} diff --git a/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs b/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs index a828d46a23..af73ef6c62 100644 --- a/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs @@ -5,14 +5,15 @@ {:padding-horizontal 20 :padding-top 12}) -(def approval-note-container +(defn approval-note-container + [theme] {:margin-horizontal 20 :padding-horizontal 16 :padding-vertical 12 :border-radius 16 :border-width 1 - :border-color colors/neutral-10 - :background-color colors/neutral-2_5}) + :border-color (colors/theme-colors colors/neutral-10 colors/black-opa-30 theme) + :background-color (colors/theme-colors colors/neutral-2_5 colors/black-opa-30 theme)}) (def approval-note-title {:color colors/neutral-50 diff --git a/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs b/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs index fab5752cf6..42231f81d1 100644 --- a/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs @@ -6,21 +6,27 @@ [quo.theme] [react-native.core :as rn] [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] [utils.i18n :as i18n] - [utils.re-frame :as rf])) + [utils.re-frame :as rf] + [utils.string])) (defn- dapp-metadata [] (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} [quo/user-avatar - {:profile-picture (first icons) - :size :big}]] + {:profile-picture profile-picture + :size :big + :full-name dapp-name}]] [quo/page-top - {:title name + {:title dapp-name :description :context-tag :context-tag {:type :icon :size 32 @@ -31,8 +37,9 @@ [] (let [dapp-name (rf/sub [:wallet-connect/session-proposer-name]) labels [(i18n/label :t/check-your-account-balance-and-activity) - (i18n/label :t/request-txns-and-message-signing)]] - [rn/view {:style style/approval-note-container} + (i18n/label :t/request-txns-and-message-signing)] + theme (quo.theme/use-theme)] + [rn/view {:style (style/approval-note-container theme)} [quo/text {:style style/approval-note-title :weight :regular @@ -46,7 +53,8 @@ {:color colors/neutral-40}] [quo/text {:weight :regular - :size :paragraph-2} + :size :paragraph-2 + :color colors/neutral-40} label]]) labels)])) diff --git a/src/status_im/subs/wallet/wallet_connect.cljs b/src/status_im/subs/wallet/wallet_connect.cljs index 6b4fe542a6..eae794c7c7 100644 --- a/src/status_im/subs/wallet/wallet_connect.cljs +++ b/src/status_im/subs/wallet/wallet_connect.cljs @@ -5,7 +5,8 @@ [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.transactions :as transactions] - [utils.money :as money])) + [utils.money :as money] + [utils.string])) (rf/reg-sub :wallet-connect/current-request-address @@ -44,7 +45,8 @@ (let [dapp-url (get-in request [:event :verifyContext :verified :origin])] (->> sessions (filter (fn [session] - (= dapp-url (get session :url)))) + (= (utils.string/remove-trailing-slash dapp-url) + (utils.string/remove-trailing-slash (get session :url))))) (first))))) (rf/reg-sub @@ -168,7 +170,8 @@ :wallet-connect/session-proposer-name :<- [:wallet-connect/session-proposer] (fn [proposer] - (-> proposer :metadata :name))) + (let [{:keys [name url]} (-> proposer :metadata)] + (wallet-connect-core/compute-dapp-name name url)))) (rf/reg-sub :wallet-connect/session-proposal-network-details diff --git a/src/status_im/subs/wallet/wallet_connect_test.cljs b/src/status_im/subs/wallet/wallet_connect_test.cljs index ac39debacb..936f48fc78 100644 --- a/src/status_im/subs/wallet/wallet_connect_test.cljs +++ b/src/status_im/subs/wallet/wallet_connect_test.cljs @@ -42,6 +42,41 @@ :origin "https://lab.web3modal.com" :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 [sub-name] (testing "Return the session proposer public key and metadata" diff --git a/src/utils/string.cljs b/src/utils/string.cljs index 9de548234a..b5ffe92562 100644 --- a/src/utils/string.cljs +++ b/src/utils/string.cljs @@ -73,3 +73,18 @@ (defn contains-special-character? [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?://" ""))) diff --git a/src/utils/string_test.cljs b/src/utils/string_test.cljs index 3f898b1361..cea239f22e 100644 --- a/src/utils/string_test.cljs +++ b/src/utils/string_test.cljs @@ -18,3 +18,25 @@ "AB" "a b" 2 "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))