chore(wallet): add options menu for collectibles

This commit is contained in:
Jamie Caprani 2024-04-10 17:50:07 +01:00 committed by GitHub
parent 7987e537c8
commit ec53f17897
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 160 additions and 79 deletions

View File

@ -124,9 +124,10 @@
[remaining-tiles (- (count remaining-images) 3)]])]]))))
(defn collectible
[{:keys [images on-press]}]
[{:keys [images on-press on-long-press]}]
[rn/view {:style style/tile-outer-container}
[rn/pressable
{:on-press on-press
:style style/tile-inner-container}
{:on-press on-press
:on-long-press on-long-press
:style style/tile-inner-container}
[tile-container {:images images}]]])

View File

@ -29,6 +29,11 @@
(def mainnet-chain-explorer-link "https://etherscan.io/address/")
(def optimism-mainnet-chain-explorer-link "https://optimistic.etherscan.io/address/")
(def arbitrum-mainnet-chain-explorer-link "https://arbiscan.io/address/")
(def sepolia-chain-explorer-link "https://sepolia.etherscan.io/address/")
(def optimism-sepolia-chain-explorer-link "https://sepolia-optimistic.etherscan.io/address/")
(def arbitrum-sepolia-chain-explorer-link "https://sepolia.arbiscan.io/address/")
(def goerli-chain-explorer-link "https://goerli.etherscan.io/address/")
(def optimism-goerli-chain-explorer-link "https://goerli-optimistic.etherscan.io/address/")
(def opensea-api-key OPENSEA_API_KEY)
(def bootnodes-settings-enabled? (enabled? (get-config :BOOTNODES_SETTINGS_ENABLED "1")))
(def mailserver-confirmations-enabled? (enabled? (get-config :MAILSERVER_CONFIRMATIONS_ENABLED)))

View File

@ -4,6 +4,7 @@
[status-im.contexts.wallet.account.tabs.about.view :as about]
[status-im.contexts.wallet.account.tabs.assets.view :as assets]
[status-im.contexts.wallet.account.tabs.dapps.view :as dapps]
[status-im.contexts.wallet.collectible.options.view :as options-drawer]
[status-im.contexts.wallet.common.activity-tab.view :as activity]
[status-im.contexts.wallet.common.collectibles-tab.view :as collectibles]
[status-im.contexts.wallet.common.empty-tab.view :as empty-tab]
@ -21,7 +22,14 @@
:on-end-reached #(rf/dispatch
[:wallet/request-collectibles-for-current-viewing-account])
:on-collectible-press (fn [{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))}]
(rf/dispatch [:wallet/get-collectible-details id]))
:on-collectible-long-press (fn [{:keys [preview-url collectible-details]}]
(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[options-drawer/view
{:name (:name collectible-details)
:image (:uri preview-url)}])}]))}]
:activity [activity/view]
:permissions [empty-tab/view
{:title (i18n/label :t/no-permissions)

View File

@ -0,0 +1,41 @@
(ns status-im.contexts.wallet.collectible.options.view
(:require
[quo.core :as quo]
[react-native.platform :as platform]
[status-im.contexts.wallet.common.utils.external-links :as external-links]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.url :as url]))
(defn view
[{:keys [image name chain-id address]}]
(let [uri (url/replace-port image (rf/sub [:mediaserver/port]))]
[quo/action-drawer
[[{:icon :i/link
:accessibility-label :view-on-etherscan
:on-press (fn []
(rf/dispatch [:wallet/navigate-to-chain-explorer-from-bottom-sheet
(external-links/get-explorer-url-by-chain-id chain-id)
address]))
:label (i18n/label :t/view-on-eth)
:right-icon :i/external}]
[{:icon :i/save
:accessibility-label :save-image
:label (i18n/label :t/save-image-to-photos)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch
[:lightbox/save-image-to-gallery
uri
#(rf/dispatch [:toasts/upsert
{:id :random-id
:type :positive
:container-style {:bottom (when platform/android? 20)}
:text (i18n/label :t/photo-saved)}])]))}]
[{:icon :i/share
:accessibility-label :share-collectible
:label (i18n/label :t/share-collectible)
:on-press #(rf/dispatch [:wallet/share-collectible
{:in-sheet? true
:title name
:uri uri}])}]]]))

View File

@ -3,15 +3,14 @@
[quo.core :as quo]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.svg :as svg]
[reagent.core :as reagent]
[status-im.common.scroll-page.view :as scroll-page]
[status-im.contexts.wallet.collectible.options.view :as options-drawer]
[status-im.contexts.wallet.collectible.style :as style]
[status-im.contexts.wallet.collectible.tabs.view :as tabs]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.url :as url]))
[utils.re-frame :as rf]))
(defn header
[collectible-name collection-name collection-image-url]
@ -51,51 +50,6 @@
:label (i18n/label :t/about)
:accessibility-label :about-tab}])
(defn collectible-actions-sheet
[]
[quo/action-drawer
[[{:icon :i/messages
:accessibility-label :share-opensea-link
:label (i18n/label :t/share-opensea-link)}
{:icon :i/link
:accessibility-label :view-on-eth
:label (i18n/label :t/view-on-eth)}
{:icon :i/download
:accessibility-label :save-image-to-photos
:label (i18n/label :t/save-image-to-photos)}
{:icon :i/copy
:accessibility-label :copy-all-details
:label (i18n/label :t/copy-all-details)}
{:icon :i/share
:accessibility-label :share-details
:label (i18n/label :t/share-details)}]]])
(defn options-drawer
[images index]
(let [{:keys [image]} (nth images index)
uri (url/replace-port image (rf/sub [:mediaserver/port]))]
[quo/action-drawer
[[{:icon :i/link
:accessibility-label :view-on-etherscan
:label (i18n/label :t/view-on-eth)}]
[{:icon :i/save
:accessibility-label :save-image
:label (i18n/label :t/save-image-to-photos)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch
[:lightbox/save-image-to-gallery
uri
#(rf/dispatch [:toasts/upsert
{:id :random-id
:type :positive
:container-style {:bottom (when platform/android? 20)}
:text (i18n/label :t/photo-saved)}])]))}]
[{:icon :i/share
:accessibility-label :share-collectible
:label (i18n/label :t/share-collectible)
:right-icon :i/external}]]]))
(defn f-view-internal
[{:keys [theme] :as _props}]
(let [selected-tab (reagent/atom :overview)
@ -112,7 +66,17 @@
token-id (:token-id id)
{collection-image :image-url
collection-name :name} collection-data
{collectible-name :name} collectible-data]
{collectible-name :name} collectible-data
collectible-image {:image preview-uri
:image-width 300
; collectibles don't have width/height
; but we need to pass something
; without it animation doesn't work smoothly
; and :border-radius not applied
:image-height 300
:id token-id
:header collectible-name
:description collection-name}]
(rn/use-unmount #(rf/dispatch [:wallet/clear-last-collectible-details]))
[scroll-page/scroll-page
{:navigate-back? true
@ -123,7 +87,9 @@
:right-side [{:icon-name :i/options
:on-press #(rf/dispatch
[:show-bottom-sheet
{:content collectible-actions-sheet
{:content (fn [] [options-drawer/view
{:name collectible-name
:image preview-uri}])
:theme theme}])}]
:picture preview-uri}}
[rn/view {:style style/container}
@ -136,24 +102,14 @@
(rf/dispatch
[:lightbox/navigate-to-lightbox
token-id
{:images [{:image preview-uri
:image-width 300 ; collectibles don't have
; width/height but we need
; to pass something
:image-height 300 ; without it animation
; doesn't work smoothly
; and :border-radius not
; applied
:id token-id
:header collectible-name
:description collection-name}]
{:images [collectible-image]
:index 0
:on-options-press (fn [images index]
(rf/dispatch [:show-bottom-sheet
{:content (fn []
[options-drawer
images
index])}]))}])))}
:on-options-press #(rf/dispatch [:show-bottom-sheet
{:content
(fn []
[options-drawer/view
{:name collectible-name
:image preview-uri}])}])}])))}
(if svg?
[rn/view
{:style (assoc style/preview :overflow :hidden)

View File

@ -8,7 +8,7 @@
[utils.i18n :as i18n]))
(defn- view-internal
[{:keys [theme collectibles filtered? on-collectible-press on-end-reached]}]
[{:keys [theme collectibles filtered? on-collectible-press on-collectible-long-press on-end-reached]}]
(let [no-results-match-query? (and filtered? (empty? collectibles))]
(cond
no-results-match-query?
@ -33,9 +33,11 @@
:num-columns 2
:render-fn (fn [{:keys [preview-url] :as collectible}]
[quo/collectible
{:images [preview-url]
:on-press #(when on-collectible-press
(on-collectible-press collectible))}])
{:images [preview-url]
:on-press #(when on-collectible-press
(on-collectible-press collectible))
:on-long-press #(when on-collectible-long-press
(on-collectible-long-press collectible))}])
:on-end-reached on-end-reached
:on-end-reached-threshold 4}])))

View File

@ -0,0 +1,32 @@
(ns status-im.contexts.wallet.common.utils.external-links
(:require [status-im.config :as config]
[status-im.constants :as constants]))
(defn get-explorer-url-by-chain-id
[chain-id]
(cond
(= chain-id constants/ethereum-mainnet-chain-id)
config/mainnet-chain-explorer-link
(= chain-id constants/arbitrum-mainnet-chain-id)
config/arbitrum-mainnet-chain-explorer-link
(= chain-id constants/optimism-mainnet-chain-id)
config/optimism-mainnet-chain-explorer-link
(= chain-id constants/ethereum-goerli-chain-id)
config/goerli-chain-explorer-link
(= chain-id constants/optimism-goerli-chain-id)
config/optimism-goerli-chain-explorer-link
(= chain-id constants/ethereum-sepolia-chain-id)
config/sepolia-chain-explorer-link
(= chain-id constants/arbitrum-sepolia-chain-id)
config/arbitrum-sepolia-chain-explorer-link
(= chain-id constants/optimism-sepolia-chain-id)
config/optimism-sepolia-chain-explorer-link
:else config/mainnet-chain-explorer-link))

View File

@ -182,3 +182,25 @@
:wallet/clear-last-collectible-details
(fn [{:keys [db]}]
{:db (update-in db [:wallet] dissoc :last-collectible-details)}))
(rf/reg-event-fx :wallet/trigger-share-collectible
(fn [_ [{:keys [title uri]}]]
{:fx [[:effects.share/open
{:title title
:message title
:url uri}]]}))
(rf/reg-event-fx :wallet/share-collectible
(fn [_ [{:keys [title uri in-sheet?]}]]
(if in-sheet?
{:fx [[:dispatch
[:hide-bottom-sheet]]
[:dispatch-later
{:ms 600
:dispatch [:wallet/trigger-share-collectible
{:title title
:uri uri}]}]]}
{:fx [[:dispatch
[:wallet/trigger-share-collectible
{:title title
:uri uri}]]]})))

View File

@ -1,6 +1,7 @@
(ns status-im.contexts.wallet.home.tabs.view
(:require
[react-native.core :as rn]
[status-im.contexts.wallet.collectible.options.view :as options-drawer]
[status-im.contexts.wallet.common.activity-tab.view :as activity]
[status-im.contexts.wallet.common.collectibles-tab.view :as collectibles]
[status-im.contexts.wallet.home.tabs.assets.view :as assets]
@ -16,8 +17,21 @@
(case selected-tab
:assets [assets/view]
:collectibles [collectibles/view
{:collectibles collectible-list
:on-end-reached request-collectibles
:on-collectible-press (fn [{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))}]
{:collectibles collectible-list
:on-collectible-long-press (fn [{:keys [preview-url collectible-details id]}]
(let [chain-id (get-in id [:contract-id :chain-id])
address (get-in id [:contract-id :address])]
(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[options-drawer/view
{:chain-id chain-id
:address address
:name (:name
collectible-details)
:image (:uri
preview-url)}])}])))
:on-end-reached request-collectibles
:on-collectible-press (fn [{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))}]
[activity/view])]))