From 796f2b214cb28ea818bfb07cb3929cd0b954de55 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Thu, 19 Oct 2023 19:37:13 +0100 Subject: [PATCH 1/6] prevent swap for asset with zero wallet and minor refactor Signed-off-by: Philemon Ukane --- ui/page/components/asset_selector.go | 18 +++--- ui/page/components/wallet_account_selector.go | 35 ++++++----- ui/page/exchange/create_order_page.go | 62 +++++++++++++------ 3 files changed, 72 insertions(+), 43 deletions(-) diff --git a/ui/page/components/asset_selector.go b/ui/page/components/asset_selector.go index 4fb4bc02c..df0035f0f 100644 --- a/ui/page/components/asset_selector.go +++ b/ui/page/components/asset_selector.go @@ -21,7 +21,6 @@ const AssetTypeSelectorID = "AssetTypeSelectorID" type AssetTypeSelector struct { openSelectorDialog *cryptomaterial.Clickable *assetTypeModal - changed bool hint string isDisableBorder bool @@ -40,7 +39,7 @@ type assetTypeModal struct { *cryptomaterial.Modal selectedAssetType *AssetTypeItem - assetTypeCallback func(*AssetTypeItem) + assetTypeCallback func(*AssetTypeItem) bool dialogTitle string onAssetTypeClicked func(*AssetTypeItem) assetTypeList layout.List @@ -58,14 +57,13 @@ func NewAssetTypeSelector(l *load.Load) *AssetTypeSelector { ats.assetTypeModal = newAssetTypeModal(l). assetTypeClicked(func(assetType *AssetTypeItem) { - if ats.selectedAssetType != nil { - if ats.selectedAssetType.Type.String() != assetType.Type.String() { - ats.changed = true - } - } - ats.selectedAssetType = assetType + ok := true if ats.assetTypeCallback != nil { - ats.assetTypeCallback(assetType) + ok = ats.assetTypeCallback(assetType) + } + + if ok && (ats.selectedAssetType == nil || ats.selectedAssetType.Type.String() != assetType.Type.String()) { + ats.selectedAssetType = assetType } }) ats.assetTypeItems = ats.buildExchangeItems() @@ -142,7 +140,7 @@ func (ats *AssetTypeSelector) Title(title string) *AssetTypeSelector { } // AssetTypeSelected sets the callback executed when an asset type is selected. -func (ats *AssetTypeSelector) AssetTypeSelected(callback func(*AssetTypeItem)) *AssetTypeSelector { +func (ats *AssetTypeSelector) AssetTypeSelected(callback func(*AssetTypeItem) bool) *AssetTypeSelector { ats.assetTypeCallback = callback return ats } diff --git a/ui/page/components/wallet_account_selector.go b/ui/page/components/wallet_account_selector.go index c23961957..79cdca0c7 100644 --- a/ui/page/components/wallet_account_selector.go +++ b/ui/page/components/wallet_account_selector.go @@ -142,11 +142,18 @@ func (ws *WalletAndAccountSelector) SelectFirstValidAccount(wallet *load.WalletM return errors.New(values.String(values.StrNoValidAccountFound)) } -func (ws *WalletAndAccountSelector) SetSelectedAsset(assetType ...utils.AssetType) { - ws.assetType = assetType +// SetSelectedAsset sets the specified assetType and returns true if the asset +// has at least one wallet. +func (ws *WalletAndAccountSelector) SetSelectedAsset(assetType ...utils.AssetType) bool { + ws.accountSelector = false ws.selectorModal.setupWallet(assetType[0]) + if len(ws.selectorItems) == 0 { + return false + } + + ws.assetType = assetType ws.selectedWallet = ws.selectorItems[0].item.(*load.WalletMapping) - ws.accountSelector = false + return true } func (ws *WalletAndAccountSelector) SelectedAsset() utils.AssetType { @@ -154,9 +161,7 @@ func (ws *WalletAndAccountSelector) SelectedAsset() utils.AssetType { } func (ws *WalletAndAccountSelector) SelectAccount(wallet *load.WalletMapping, accountNumber int32) error { - if !ws.accountSelector { - ws.accountSelector = true - } + ws.accountSelector = true ws.SetSelectedWallet(wallet) account, err := wallet.GetAccount(accountNumber) @@ -164,16 +169,17 @@ func (ws *WalletAndAccountSelector) SelectAccount(wallet *load.WalletMapping, ac return err } - if ws.accountIsValid(account) { - ws.SetSelectedAccount(account) - if ws.accountCallback != nil { - ws.accountCallback(account) - } - return nil + if !ws.accountIsValid(account) { + ws.ResetAccount() + return errors.New(values.String(values.StrNoValidAccountFound)) } - ws.ResetAccount() - return errors.New(values.String(values.StrNoValidAccountFound)) + ws.SetSelectedAccount(account) + if ws.accountCallback != nil { + ws.accountCallback(account) + } + + return nil } func (ws *WalletAndAccountSelector) ResetAccount() { @@ -463,6 +469,7 @@ func (sm *selectorModal) setupWallet(assetType ...utils.AssetType) { clickable: sm.Theme.NewClickable(true), }) } + sm.selectorItems = selectorItems } diff --git a/ui/page/exchange/create_order_page.go b/ui/page/exchange/create_order_page.go index 864881624..09bf7be77 100644 --- a/ui/page/exchange/create_order_page.go +++ b/ui/page/exchange/create_order_page.go @@ -165,20 +165,20 @@ func NewCreateOrderPage(l *load.Load) *CreateOrderPage { pg.toAmountEditor = *components.NewSelectAssetEditor(l) pg.fromAmountEditor = *components.NewSelectAssetEditor(l) - pg.fromAmountEditor.AssetTypeSelector.AssetTypeSelected(func(ati *components.AssetTypeItem) { + pg.fromAmountEditor.AssetTypeSelector.AssetTypeSelected(func(ati *components.AssetTypeItem) bool { isMatching := pg.fromCurrency == pg.toCurrency && pg.fromCurrency != libutils.NilAsset if pg.fromCurrency == ati.Type || isMatching { - return + return false } - pg.updateWalletAndAccountSelector([]libutils.AssetType{ati.Type}, nil) + return pg.updateWalletAndAccountSelector([]libutils.AssetType{ati.Type}, nil) }) - pg.toAmountEditor.AssetTypeSelector.AssetTypeSelected(func(ati *components.AssetTypeItem) { + pg.toAmountEditor.AssetTypeSelector.AssetTypeSelected(func(ati *components.AssetTypeItem) bool { isMatching := pg.fromCurrency == pg.toCurrency && pg.toCurrency != libutils.NilAsset if pg.toCurrency == ati.Type || isMatching { - return + return false } - pg.updateWalletAndAccountSelector(nil, []libutils.AssetType{ati.Type}) + return pg.updateWalletAndAccountSelector(nil, []libutils.AssetType{ati.Type}) }) pg.createOrderBtn = pg.Theme.Button(values.String(values.StrCreateOrder)) @@ -208,9 +208,14 @@ func NewCreateOrderPage(l *load.Load) *CreateOrderPage { return pg } -func (pg *CreateOrderPage) updateWalletAndAccountSelector(selectedFromAsset []utils.AssetType, selectedToAsset []utils.AssetType) { - pg.updateAssetSelection(selectedFromAsset, selectedToAsset) +func (pg *CreateOrderPage) updateWalletAndAccountSelector(selectedFromAsset []utils.AssetType, selectedToAsset []utils.AssetType) bool { + ok := pg.updateAssetSelection(selectedFromAsset, selectedToAsset) + if !ok { + return false + } + pg.updateExchangeRate() + return true } func (pg *CreateOrderPage) ID() string { @@ -466,23 +471,31 @@ func (pg *CreateOrderPage) inputsNotEmpty(editors ...*widget.Editor) bool { return true } -func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetType, selectedToAsset []utils.AssetType) { +func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetType, selectedToAsset []utils.AssetType) bool { if len(selectedFromAsset) > 0 { - pg.fromCurrency = selectedFromAsset[0] - pg.sourceWalletSelector.SetSelectedAsset(pg.fromCurrency) + selectedAsset := selectedFromAsset[0] + ok := pg.sourceWalletSelector.SetSelectedAsset(selectedAsset) + if !ok { + return false + } + pg.fromCurrency = selectedAsset pg.fromAmountEditor.AssetTypeSelector.SetSelectedAssetType(pg.fromCurrency) // If the to and from asset are the same, select a new to asset. - if selectedFromAsset[0] == pg.toCurrency { + if selectedAsset == pg.toCurrency { // Get all available assets. allAssets := pg.WL.AssetsManager.AllAssetTypes() for _, asset := range allAssets { - if asset != selectedFromAsset[0] { + if asset != selectedAsset { // Select the first available asset as the new to asset. + ok := pg.destinationWalletSelector.SetSelectedAsset(asset) + if !ok { + continue + } + pg.toCurrency = asset - pg.destinationWalletSelector.SetSelectedAsset(pg.toCurrency) pg.toAmountEditor.AssetTypeSelector.SetSelectedAssetType(pg.toCurrency) break @@ -492,23 +505,33 @@ func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetT } if len(selectedToAsset) > 0 { - pg.toCurrency = selectedToAsset[0] - pg.destinationWalletSelector.SetSelectedAsset(pg.toCurrency) + selectedAsset := selectedToAsset[0] + ok := pg.destinationWalletSelector.SetSelectedAsset(selectedAsset) + if !ok { + return false + } + pg.toCurrency = selectedAsset pg.toAmountEditor.AssetTypeSelector.SetSelectedAssetType(pg.toCurrency) // If the to and from asset are the same, select a new from asset. - if selectedToAsset[0] == pg.fromCurrency { + if selectedAsset == pg.fromCurrency { // Get all available assets. allAssets := pg.WL.AssetsManager.AllAssetTypes() for _, asset := range allAssets { - if asset != selectedToAsset[0] { + if asset != selectedAsset { // Select the first available asset as the new from asset. + ok := pg.sourceWalletSelector.SetSelectedAsset(asset) + if !ok { + continue + } + pg.fromCurrency = asset - pg.sourceWalletSelector.SetSelectedAsset(pg.fromCurrency) pg.fromAmountEditor.AssetTypeSelector.SetSelectedAssetType(pg.fromCurrency) + + break } } } @@ -525,6 +548,7 @@ func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetT // Save the exchange configuration changes. pg.updateExchangeConfig() + return true } // swapCurrency swaps the values of the from and to currency fields. From 04672844591e6de20b257e74e92b30ab9fb46650 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Thu, 26 Oct 2023 16:24:14 +0100 Subject: [PATCH 2/6] fix bug wherea posible nill wallet might panic Signed-off-by: Philemon Ukane --- ui/page/components/components.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/page/components/components.go b/ui/page/components/components.go index 3a77b3957..141acbe9a 100644 --- a/ui/page/components/components.go +++ b/ui/page/components/components.go @@ -235,6 +235,10 @@ func TransactionTitleIcon(l *load.Load, wal sharedW.Asset, tx *sharedW.Transacti func LayoutTransactionRow(gtx layout.Context, l *load.Load, row TransactionRow, isTxPage bool) layout.Dimensions { gtx.Constraints.Min.X = gtx.Constraints.Max.X wal := l.WL.AssetsManager.WalletWithID(row.Transaction.WalletID) + if wal == nil { + return D{} + } + txStatus := TransactionTitleIcon(l, wal, &row.Transaction) amount := wal.ToAmount(row.Transaction.Amount).String() assetIcon := CoinImageBySymbol(l, wal.GetAssetType(), wal.IsWatchingOnlyWallet()) From 3175b3f4856e04578eef20bf468b336ebcfde31a Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Thu, 26 Oct 2023 16:27:54 +0100 Subject: [PATCH 3/6] create-order-page: fix a bug that caused panic if previous source/dest wallet was deleted Signed-off-by: Philemon Ukane --- ui/page/exchange/create_order_page.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ui/page/exchange/create_order_page.go b/ui/page/exchange/create_order_page.go index 09bf7be77..41e886190 100644 --- a/ui/page/exchange/create_order_page.go +++ b/ui/page/exchange/create_order_page.go @@ -1161,17 +1161,25 @@ func (pg *CreateOrderPage) loadOrderConfig() { sourceAccount = exchangeConfig.SourceAccountNumber destinationAccount = exchangeConfig.DestinationAccountNumber - } else { + } + + noSourceWallet := sourceWallet == nil || sourceWallet.Asset == nil + noDestinationWallet := destinationWallet == nil || destinationWallet.Asset == nil + if noSourceWallet || noDestinationWallet { // New exchange configuration will be generated using the set asset // types since none existed before. It two distinct asset type wallet // don't exist execution does get here. wallets := pg.WL.AssetsManager.AllWallets() - pg.fromCurrency = wallets[0].GetAssetType() + if noSourceWallet { + pg.fromCurrency = wallets[0].GetAssetType() + } - for _, w := range wallets { - if w.GetAssetType() != pg.fromCurrency { - pg.toCurrency = w.GetAssetType() - break + if noDestinationWallet { + for _, w := range wallets { + if w.GetAssetType() != pg.fromCurrency { + pg.toCurrency = w.GetAssetType() + break + } } } } @@ -1180,7 +1188,7 @@ func (pg *CreateOrderPage) loadOrderConfig() { pg.sourceWalletSelector = components.NewWalletAndAccountSelector(pg.Load, pg.fromCurrency). Title(values.String(values.StrSource)) - if sourceWallet == nil { + if noSourceWallet { isConfigUpdateRequired = true pg.sourceWalletSelector.SetSelectedAsset(pg.fromCurrency) sourceWallet = pg.sourceWalletSelector.SelectedWallet() @@ -1216,7 +1224,7 @@ func (pg *CreateOrderPage) loadOrderConfig() { pg.destinationWalletSelector = components.NewWalletAndAccountSelector(pg.Load, pg.toCurrency). Title(values.String(values.StrDestination)) - if destinationWallet == nil { + if noDestinationWallet { isConfigUpdateRequired = true pg.destinationWalletSelector.SetSelectedAsset(pg.toCurrency) destinationWallet = pg.destinationWalletSelector.SelectedWallet() From eb5e1ea777fd7e4f362658403ef7c8a1b3f308d2 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Thu, 26 Oct 2023 16:28:57 +0100 Subject: [PATCH 4/6] create-order-page: Enable wallet creation for missing wallet Signed-off-by: Philemon Ukane --- libwallet/assets_manager.go | 21 ++++++++ ui/page/{info => components}/restore_page.go | 17 ++++--- .../{info => components}/seed_restore_page.go | 2 +- ui/page/components/wallet_account_selector.go | 17 +------ .../{root => components}/wallet_setup_page.go | 43 ++++++++++------- ui/page/exchange/create_order_page.go | 48 ++++++++++++++++--- ui/page/root/wallet_selector_page.go | 4 +- ui/page/start_page.go | 6 ++- ui/values/localizable/en.go | 1 + ui/values/strings.go | 1 + 10 files changed, 107 insertions(+), 53 deletions(-) rename ui/page/{info => components}/restore_page.go (97%) rename ui/page/{info => components}/seed_restore_page.go (99%) rename ui/page/{root => components}/wallet_setup_page.go (95%) diff --git a/libwallet/assets_manager.go b/libwallet/assets_manager.go index d63a706d1..66873a585 100644 --- a/libwallet/assets_manager.go +++ b/libwallet/assets_manager.go @@ -535,6 +535,27 @@ func (mgr *AssetsManager) WalletWithID(walletID int) sharedW.Asset { return nil } +// AssetWallets returns the wallets for the specified asset type(s). +func (mgr *AssetsManager) AssetWallets(assetTypes ...utils.AssetType) []sharedW.Asset { + var wallets []sharedW.Asset + for _, asset := range assetTypes { + switch asset { + case utils.BTCWalletAsset: + wallets = append(wallets, mgr.AllBTCWallets()...) + case utils.DCRWalletAsset: + wallets = append(wallets, mgr.AllDCRWallets()...) + case utils.LTCWalletAsset: + wallets = append(wallets, mgr.AllLTCWallets()...) + } + } + + if len(wallets) == 0 && len(assetTypes) == 0 { + wallets = mgr.AllWallets() + } + + return wallets +} + func (mgr *AssetsManager) getbadWallet(walletID int) *sharedW.Wallet { if badWallet, ok := mgr.Assets.BTC.BadWallets[walletID]; ok { return badWallet diff --git a/ui/page/info/restore_page.go b/ui/page/components/restore_page.go similarity index 97% rename from ui/page/info/restore_page.go rename to ui/page/components/restore_page.go index 378c81ec9..bfa92ac9b 100644 --- a/ui/page/info/restore_page.go +++ b/ui/page/components/restore_page.go @@ -1,4 +1,4 @@ -package info +package components import ( "image" @@ -17,7 +17,6 @@ import ( "github.com/crypto-power/cryptopower/ui/cryptomaterial" "github.com/crypto-power/cryptopower/ui/load" "github.com/crypto-power/cryptopower/ui/modal" - "github.com/crypto-power/cryptopower/ui/page/components" "github.com/crypto-power/cryptopower/ui/values" ) @@ -60,7 +59,7 @@ func NewRestorePage(l *load.Load, walletName string, walletType libutils.AssetTy toggleSeedInput: l.Theme.Switch(), } - pg.backButton, _ = components.SubpageHeaderButtons(l) + pg.backButton, _ = SubpageHeaderButtons(l) pg.backButton.Icon = pg.Theme.Icons.ContentClear pg.seedInputEditor = l.Theme.Editor(new(widget.Editor), values.String(values.StrEnterWalletSeed)) @@ -96,7 +95,7 @@ func (pg *Restore) Layout(gtx C) D { func (pg *Restore) layoutDesktop(gtx C) D { body := func(gtx C) D { - sp := components.SubPage{ + sp := SubPage{ Load: pg.Load, Title: values.String(values.StrRestoreWallet), BackButton: pg.backButton, @@ -109,12 +108,12 @@ func (pg *Restore) layoutDesktop(gtx C) D { } return sp.Layout(pg.ParentWindow(), gtx) } - return components.UniformPadding(gtx, body) + return UniformPadding(gtx, body) } func (pg *Restore) layoutMobile(gtx C) D { body := func(gtx C) D { - sp := components.SubPage{ + sp := SubPage{ Load: pg.Load, Title: values.String(values.StrRestoreWallet), BackButton: pg.backButton, @@ -127,11 +126,11 @@ func (pg *Restore) layoutMobile(gtx C) D { } return sp.Layout(pg.ParentWindow(), gtx) } - return components.UniformMobile(gtx, false, false, body) + return UniformMobile(gtx, false, false, body) } func (pg *Restore) restoreLayout(gtx layout.Context) layout.Dimensions { - return components.UniformPadding(gtx, func(gtx C) D { + return UniformPadding(gtx, func(gtx C) D { return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(pg.tabLayout), layout.Rigid(pg.Theme.Separator().Layout), @@ -353,7 +352,7 @@ func (pg *Restore) restoreFromSeedEditor() { seedOrHex := strings.TrimSpace(pg.seedInputEditor.Editor.Text()) // Check if the user did input a hex or seed. If its a hex set the correct tabindex. - if len(seedOrHex) > components.MaxSeedBytes { + if len(seedOrHex) > MaxSeedBytes { pg.tabIndex = 0 } else { pg.tabIndex = 1 diff --git a/ui/page/info/seed_restore_page.go b/ui/page/components/seed_restore_page.go similarity index 99% rename from ui/page/info/seed_restore_page.go rename to ui/page/components/seed_restore_page.go index 07c94c9c9..a350531c0 100644 --- a/ui/page/info/seed_restore_page.go +++ b/ui/page/components/seed_restore_page.go @@ -1,4 +1,4 @@ -package info +package components import ( "fmt" diff --git a/ui/page/components/wallet_account_selector.go b/ui/page/components/wallet_account_selector.go index 79cdca0c7..c8c3ba4ef 100644 --- a/ui/page/components/wallet_account_selector.go +++ b/ui/page/components/wallet_account_selector.go @@ -444,22 +444,7 @@ func (sm *selectorModal) OnResume() { func (sm *selectorModal) setupWallet(assetType ...utils.AssetType) { selectorItems := make([]*SelectorItem, 0) - var wallets []sharedW.Asset - for _, asset := range assetType { - switch asset { - case utils.BTCWalletAsset: - wallets = append(wallets, sm.WL.AssetsManager.AllBTCWallets()...) - case utils.DCRWalletAsset: - wallets = append(wallets, sm.WL.AssetsManager.AllDCRWallets()...) - case utils.LTCWalletAsset: - wallets = append(wallets, sm.WL.AssetsManager.AllLTCWallets()...) - } - } - - if len(wallets) == 0 { - wallets = sm.WL.AssetsManager.AllWallets() - } - + wallets := sm.WL.AssetsManager.AssetWallets(assetType...) for _, wal := range wallets { if wal.IsWatchingOnlyWallet() && !sm.isWatchOnlyEnabled { continue diff --git a/ui/page/root/wallet_setup_page.go b/ui/page/components/wallet_setup_page.go similarity index 95% rename from ui/page/root/wallet_setup_page.go rename to ui/page/components/wallet_setup_page.go index 1e41039b5..9dc7860ae 100644 --- a/ui/page/root/wallet_setup_page.go +++ b/ui/page/components/wallet_setup_page.go @@ -1,4 +1,4 @@ -package root +package components import ( "errors" @@ -15,8 +15,6 @@ import ( "github.com/crypto-power/cryptopower/ui/cryptomaterial" "github.com/crypto-power/cryptopower/ui/load" "github.com/crypto-power/cryptopower/ui/modal" - "github.com/crypto-power/cryptopower/ui/page/components" - "github.com/crypto-power/cryptopower/ui/page/info" "github.com/crypto-power/cryptopower/ui/utils" "github.com/crypto-power/cryptopower/ui/values" ) @@ -46,7 +44,7 @@ type CreateWallet struct { walletActions []*walletAction - assetTypeSelector *components.AssetTypeSelector + assetTypeSelector *AssetTypeSelector assetTypeError cryptomaterial.Label walletName cryptomaterial.Editor watchOnlyWalletHex cryptomaterial.Editor @@ -62,11 +60,13 @@ type CreateWallet struct { selectedWalletAction int + walletCreationSuccessCallback func() + showLoader bool isLoading bool } -func NewCreateWallet(l *load.Load, assetType ...libutils.AssetType) *CreateWallet { +func NewCreateWallet(l *load.Load, walletCreationSuccessCallback func(), assetType ...libutils.AssetType) *CreateWallet { pg := &CreateWallet{ GenericPageModal: app.NewGenericPageModal(CreateWalletID), scrollContainer: &widget.List{ @@ -75,7 +75,7 @@ func NewCreateWallet(l *load.Load, assetType ...libutils.AssetType) *CreateWalle Alignment: layout.Middle, }, }, - assetTypeSelector: components.NewAssetTypeSelector(l), + assetTypeSelector: NewAssetTypeSelector(l), list: layout.List{Axis: layout.Vertical}, continueBtn: l.Theme.Button(values.String(values.StrContinue)), @@ -85,7 +85,14 @@ func NewCreateWallet(l *load.Load, assetType ...libutils.AssetType) *CreateWalle selectedWalletAction: -1, assetTypeError: l.Theme.Body1(""), - Load: l, + Load: l, + walletCreationSuccessCallback: walletCreationSuccessCallback, + } + + if walletCreationSuccessCallback == nil { + pg.walletCreationSuccessCallback = func() { + pg.ParentNavigator().CloseCurrentPage() + } } bg := l.Theme.Color.White @@ -114,7 +121,7 @@ func NewCreateWallet(l *load.Load, assetType ...libutils.AssetType) *CreateWalle pg.materialLoader = material.Loader(l.Theme.Base) - pg.backButton, _ = components.SubpageHeaderButtons(l) + pg.backButton, _ = SubpageHeaderButtons(l) return pg } @@ -507,7 +514,7 @@ func (pg *CreateWallet) HandleUserInteractions() { pg.walletCreationSuccessCallback() } ast := pg.assetTypeSelector.SelectedAssetType() - pg.ParentNavigator().Display(info.NewRestorePage(pg.Load, pg.walletName.Editor.Text(), *ast, afterRestore)) + pg.ParentNavigator().Display(NewRestorePage(pg.Load, pg.walletName.Editor.Text(), *ast, afterRestore)) } // imported wallet click action control @@ -629,12 +636,12 @@ func (pg *CreateWallet) validRestoreWalletInputs() bool { return true } -func (pg *CreateWallet) walletCreationSuccessCallback() { - // display the overview page if the user is creating a wallet - // for the first time (i.e coming from the onboarding page) - if len(pg.WL.AssetsManager.AllWallets()) == 1 { - pg.ParentNavigator().Display(NewHomePage(pg.Load)) - return - } - pg.ParentNavigator().Display(NewWalletSelectorPage(pg.Load)) -} +// func (pg *CreateWallet) walletCreationSuccessCallback() { +// // display the overview page if the user is creating a wallet +// // for the first time (i.e coming from the onboarding page) +// if len(pg.WL.AssetsManager.AllWallets()) == 1 { +// pg.ParentNavigator().Display(NewHomePage(pg.Load)) +// return +// } +// pg.ParentNavigator().Display(NewWalletSelectorPage(pg.Load)) +// } diff --git a/ui/page/exchange/create_order_page.go b/ui/page/exchange/create_order_page.go index 41e886190..1978655a6 100644 --- a/ui/page/exchange/create_order_page.go +++ b/ui/page/exchange/create_order_page.go @@ -209,8 +209,10 @@ func NewCreateOrderPage(l *load.Load) *CreateOrderPage { } func (pg *CreateOrderPage) updateWalletAndAccountSelector(selectedFromAsset []utils.AssetType, selectedToAsset []utils.AssetType) bool { - ok := pg.updateAssetSelection(selectedFromAsset, selectedToAsset) + asset, ok := pg.updateAssetSelection(selectedFromAsset, selectedToAsset) if !ok { + isSourceWallet := len(selectedFromAsset) != 0 + pg.displayCreateWalletModal(isSourceWallet, asset) return false } @@ -218,6 +220,38 @@ func (pg *CreateOrderPage) updateWalletAndAccountSelector(selectedFromAsset []ut return true } +func (pg *CreateOrderPage) displayCreateWalletModal(isSourceWallet bool, asset libutils.AssetType) { + createWalletModal := modal.NewCustomModal(pg.Load). + Title(values.String(values.StrCreateWallet)). + UseCustomWidget(func(gtx C) D { + return layout.Inset{Top: values.MarginPadding10, Bottom: values.MarginPadding10}.Layout(gtx, func(gtx C) D { + return layout.Center.Layout(gtx, pg.Theme.Body2(values.StringF(values.StrCreateAssetWalletToSwapMsg, asset.ToFull())).Layout) + }) + }). + SetCancelable(true). + SetContentAlignment(layout.Center, layout.W, layout.Center). + SetPositiveButtonCallback(func(_ bool, _ *modal.InfoModal) bool { + pg.ParentNavigator().Display(components.NewCreateWallet(pg.Load, func() { + pg.walletCreationSuccessFunc(isSourceWallet, asset) + }, asset)) + return true + }). + SetNegativeButtonText(values.String(values.StrCancel)). + SetPositiveButtonText(values.String(values.StrContinue)) + pg.ParentWindow().ShowModal(createWalletModal) +} + +func (pg *CreateOrderPage) walletCreationSuccessFunc(isSourceWallet bool, asset libutils.AssetType) { + if isSourceWallet { + pg.updateWalletAndAccountSelector([]libutils.AssetType{asset}, nil) + } else { + pg.updateWalletAndAccountSelector(nil, []libutils.AssetType{asset}) + } + pg.ParentNavigator().ClosePagesAfter(CreateOrderPageID) + pg.ParentNavigator().ClosePagesAfter(CreateOrderPageID) + pg.ParentWindow().Reload() +} + func (pg *CreateOrderPage) ID() string { return CreateOrderPageID } @@ -471,12 +505,12 @@ func (pg *CreateOrderPage) inputsNotEmpty(editors ...*widget.Editor) bool { return true } -func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetType, selectedToAsset []utils.AssetType) bool { +func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetType, selectedToAsset []utils.AssetType) (libutils.AssetType, bool) { if len(selectedFromAsset) > 0 { selectedAsset := selectedFromAsset[0] ok := pg.sourceWalletSelector.SetSelectedAsset(selectedAsset) if !ok { - return false + return selectedAsset, false } pg.fromCurrency = selectedAsset @@ -508,7 +542,7 @@ func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetT selectedAsset := selectedToAsset[0] ok := pg.destinationWalletSelector.SetSelectedAsset(selectedAsset) if !ok { - return false + return selectedAsset, false } pg.toCurrency = selectedAsset @@ -548,7 +582,7 @@ func (pg *CreateOrderPage) updateAssetSelection(selectedFromAsset []utils.AssetT // Save the exchange configuration changes. pg.updateExchangeConfig() - return true + return "", true } // swapCurrency swaps the values of the from and to currency fields. @@ -984,7 +1018,7 @@ func (pg *CreateOrderPage) layout(gtx C) D { gtx.Constraints.Min.X = gtx.Constraints.Max.X return layout.Inset{Bottom: values.MarginPadding1}.Layout(gtx, pg.materialLoader.Layout) } - return layout.Inset{Right: values.MarginPadding16}.Layout(gtx, func(gtx layout.Context) layout.Dimensions { + return layout.Inset{Right: values.MarginPadding16}.Layout(gtx, func(gtx C) D { return pg.refreshIcon.LayoutSize(gtx, values.MarginPadding18) }) }), @@ -993,7 +1027,7 @@ func (pg *CreateOrderPage) layout(gtx C) D { ) }), layout.Rigid(func(gtx C) D { - return layout.Inset{Right: values.MarginPadding16}.Layout(gtx, func(gtx layout.Context) layout.Dimensions { + return layout.Inset{Right: values.MarginPadding16}.Layout(gtx, func(gtx C) D { return layout.E.Layout(gtx, pg.viewAllButton.Layout) }) }), diff --git a/ui/page/root/wallet_selector_page.go b/ui/page/root/wallet_selector_page.go index ed87d582a..9ae80e625 100644 --- a/ui/page/root/wallet_selector_page.go +++ b/ui/page/root/wallet_selector_page.go @@ -187,7 +187,9 @@ func (pg *WalletSelectorPage) HandleUserInteractions() { for asset, clickable := range pg.addWalClickable { if clickable.Clicked() { - pg.ParentNavigator().Display(NewCreateWallet(pg.Load, asset)) + pg.ParentNavigator().Display(components.NewCreateWallet(pg.Load, func() { + pg.ParentNavigator().ClosePagesAfter(WalletSelectorPageID) + }, asset)) } } } diff --git a/ui/page/start_page.go b/ui/page/start_page.go index f4cfac0b2..13950f94c 100644 --- a/ui/page/start_page.go +++ b/ui/page/start_page.go @@ -13,6 +13,7 @@ import ( "github.com/crypto-power/cryptopower/ui/cryptomaterial" "github.com/crypto-power/cryptopower/ui/load" "github.com/crypto-power/cryptopower/ui/modal" + "github.com/crypto-power/cryptopower/ui/page/components" "github.com/crypto-power/cryptopower/ui/page/root" "github.com/crypto-power/cryptopower/ui/values" ) @@ -171,7 +172,10 @@ func (sp *startPage) openWallets(password string) error { // Part of the load.Page interface. func (sp *startPage) HandleUserInteractions() { if sp.addWalletButton.Clicked() { - sp.ParentNavigator().Display(root.NewCreateWallet(sp.Load)) + sp.ParentNavigator().Display(components.NewCreateWallet(sp.Load, func() { + sp.ParentNavigator().Display(root.NewHomePage(sp.Load)) + return + })) } if sp.skipButton.Clicked() { diff --git a/ui/values/localizable/en.go b/ui/values/localizable/en.go index 3be8bbcdf..07cd7b08b 100644 --- a/ui/values/localizable/en.go +++ b/ui/values/localizable/en.go @@ -788,4 +788,5 @@ const EN = ` "minimumBondStrength" = "Minimum Bond Strength is %d" "assets" = "Assets" "noWalletsAvailable" = "You cannot spend from a watch only wallet, try creating another wallet." +"createAssetWalletToSwapMsg" = "You need to create a %s wallet to swap." ` diff --git a/ui/values/strings.go b/ui/values/strings.go index 9f4d65bab..978933387 100644 --- a/ui/values/strings.go +++ b/ui/values/strings.go @@ -898,4 +898,5 @@ const ( StrMinimumBondStrength = "minimumBondStrength" StrAssets = "assets" StrNoWalletsAvailable = "noWalletsAvailable" + StrCreateAssetWalletToSwapMsg = "createAssetWalletToSwapMsg" ) From acf5071a562b2a989072ea8ae61644ceceecf981 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Thu, 26 Oct 2023 16:37:52 +0100 Subject: [PATCH 5/6] go fmt and fix linter error Signed-off-by: Philemon Ukane --- ui/page/start_page.go | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/page/start_page.go b/ui/page/start_page.go index 13950f94c..5fb3220c4 100644 --- a/ui/page/start_page.go +++ b/ui/page/start_page.go @@ -174,7 +174,6 @@ func (sp *startPage) HandleUserInteractions() { if sp.addWalletButton.Clicked() { sp.ParentNavigator().Display(components.NewCreateWallet(sp.Load, func() { sp.ParentNavigator().Display(root.NewHomePage(sp.Load)) - return })) } From 50e40bd46e9940cd1e18459eb3705e0aac65a0aa Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Mon, 30 Oct 2023 18:40:20 +0100 Subject: [PATCH 6/6] remove commented code Signed-off-by: Philemon Ukane --- ui/page/components/wallet_setup_page.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ui/page/components/wallet_setup_page.go b/ui/page/components/wallet_setup_page.go index 9dc7860ae..e8090baac 100644 --- a/ui/page/components/wallet_setup_page.go +++ b/ui/page/components/wallet_setup_page.go @@ -635,13 +635,3 @@ func (pg *CreateWallet) validRestoreWalletInputs() bool { return true } - -// func (pg *CreateWallet) walletCreationSuccessCallback() { -// // display the overview page if the user is creating a wallet -// // for the first time (i.e coming from the onboarding page) -// if len(pg.WL.AssetsManager.AllWallets()) == 1 { -// pg.ParentNavigator().Display(NewHomePage(pg.Load)) -// return -// } -// pg.ParentNavigator().Display(NewWalletSelectorPage(pg.Load)) -// }