diff --git a/ui/decredmaterial/icon_gallery.go b/ui/decredmaterial/icon_gallery.go index bd31538af..bcc9b8f84 100644 --- a/ui/decredmaterial/icon_gallery.go +++ b/ui/decredmaterial/icon_gallery.go @@ -11,7 +11,7 @@ import ( type Icons struct { ContentAdd, NavigationCheck, NavigationMore, ActionCheckCircle, ActionInfo, NavigationArrowBack, NavigationArrowForward, ActionCheck, ChevronRight, NavigationCancel, NavMoreIcon, - ImageBrightness1, ContentClear, DropDownIcon, Cached, ContentRemove, SearchIcon, PlayIcon *widget.Icon + ImageBrightness1, ContentClear, DropDownIcon, Cached, ContentRemove, SearchIcon, PlayIcon, ErrorIcon *widget.Icon OverviewIcon, OverviewIconInactive, WalletIcon, WalletIconInactive, MixerInactive, RedAlert, ReceiveIcon, Transferred, TransactionsIcon, TransactionsIconInactive, SendIcon, MoreIcon, MoreIconInactive, @@ -56,6 +56,7 @@ func (i *Icons) StandardMaterialIcons() *Icons { i.ContentRemove = MustIcon(widget.NewIcon(icons.ContentRemove)) i.SearchIcon = MustIcon(widget.NewIcon(icons.ActionSearch)) i.PlayIcon = MustIcon(widget.NewIcon(icons.AVPlayArrow)) + i.ErrorIcon = MustIcon(widget.NewIcon(icons.AlertError)) return i } diff --git a/ui/modal/create_watch_only_modal.go b/ui/modal/create_watch_only_modal.go index 6297d2487..492d11869 100644 --- a/ui/modal/create_watch_only_modal.go +++ b/ui/modal/create_watch_only_modal.go @@ -132,12 +132,19 @@ func (cm *CreateWatchOnlyModal) Handle() { matchedWalletID, err := cm.WL.MultiWallet.WalletWithXPub(cm.extendedPubKey.Editor.Text()) if err != nil { log.Errorf("Error checking xpub: %v", err) - cm.Toast.NotifyError(values.StringF(values.StrXpubKeyErr, err)) // Error maybe useful to user. + errorModal := NewErrorModal(cm.Load, values.StringF(values.StrXpubKeyErr, err), func(isChecked bool) bool { + return true + }) + cm.ParentWindow().ShowModal(errorModal) + return } if matchedWalletID != -1 { - cm.Toast.NotifyError(values.String(values.StrXpubWalletExist)) + errorModal := NewErrorModal(cm.Load, values.String(values.StrXpubWalletExist), func(isChecked bool) bool { + return true + }) + cm.ParentWindow().ShowModal(errorModal) return } diff --git a/ui/modal/info_modal.go b/ui/modal/info_modal.go index 4e3462031..7c8c29148 100644 --- a/ui/modal/info_modal.go +++ b/ui/modal/info_modal.go @@ -18,8 +18,6 @@ type InfoModal struct { *load.Load *decredmaterial.Modal - enterKeyPressed bool - dialogIcon *decredmaterial.Icon dialogTitle string @@ -46,17 +44,49 @@ type InfoModal struct { isLoading bool } +// ButtonType is the type of button in modal. +type ButtonType uint8 + +const ( + Normal ButtonType = iota + Outline + Danger +) + func NewInfoModal(l *load.Load) *InfoModal { - return NewInfoModalWithKey(l, "info_modal", false) + return NewInfoModalWithKey(l, "info_modal", Outline) +} + +func NewSuccessModal(l *load.Load, title string, clicked func(isChecked bool) bool) *InfoModal { + icon := decredmaterial.NewIcon(l.Theme.Icons.ActionCheckCircle) + icon.Color = l.Theme.Color.Green500 + return NewNotice(l, title, icon, clicked) +} + +func NewErrorModal(l *load.Load, title string, clicked func(isChecked bool) bool) *InfoModal { + icon := decredmaterial.NewIcon(l.Theme.Icons.ErrorIcon) + icon.Color = l.Theme.Color.Danger + return NewNotice(l, title, icon, clicked) +} + +func NewNotice(l *load.Load, title string, icon *decredmaterial.Icon, clicked func(isChecked bool) bool) *InfoModal { + info := NewInfoModalWithKey(l, "info_modal", Normal) + info.positiveButtonText = values.String(values.StrOk) + info.positiveButtonClicked = clicked + info.btnPositiveWidth = values.MarginPadding100 + info.dialogIcon = icon + info.dialogTitle = title + info.titleAlignment = layout.Center + info.btnAlignment = layout.Center + return info } // This function for normal positive button func NewInfoModal2(l *load.Load) *InfoModal { - return NewInfoModalWithKey(l, "info_modal", true) + return NewInfoModalWithKey(l, "info_modal", Outline) } -func NewInfoModalWithKey(l *load.Load, key string, isPositiveButtonNormal bool) *InfoModal { - +func NewInfoModalWithKey(l *load.Load, key string, btnPositiveType ButtonType) *InfoModal { in := &InfoModal{ Load: l, Modal: l.Theme.ModalFloatTitle(key), @@ -67,12 +97,7 @@ func NewInfoModalWithKey(l *load.Load, key string, isPositiveButtonNormal bool) btnPositiveWidth: 0, } - if isPositiveButtonNormal { - in.btnPositive = l.Theme.Button(values.String(values.StrYes)) - } else { - in.btnPositive = l.Theme.OutlineButton(values.String(values.StrYes)) - } - + in.btnPositive = getPositiveButtonType(l, btnPositiveType) in.btnPositive.Font.Weight = text.Medium in.btnNegative.Font.Weight = text.Medium @@ -81,6 +106,16 @@ func NewInfoModalWithKey(l *load.Load, key string, isPositiveButtonNormal bool) return in } +func getPositiveButtonType(l *load.Load, btnType ButtonType) decredmaterial.Button { + if btnType == Normal { + return l.Theme.Button(values.String(values.StrYes)) + } else if btnType == Outline { + return l.Theme.OutlineButton(values.String(values.StrYes)) + } else { + return l.Theme.DangerButton(values.String(values.StrYes)) + } +} + func (in *InfoModal) OnResume() {} func (in *InfoModal) OnDismiss() {} diff --git a/ui/modal/text_input_modal.go b/ui/modal/text_input_modal.go index 721dfa2db..32fe66c29 100644 --- a/ui/modal/text_input_modal.go +++ b/ui/modal/text_input_modal.go @@ -22,13 +22,12 @@ type TextInputModal struct { textInput decredmaterial.Editor callback func(string, *TextInputModal) bool - positiveButtonColor color.NRGBA - textCustomTemplate []layout.Widget + textCustomTemplate []layout.Widget } func NewTextInputModal(l *load.Load) *TextInputModal { tm := &TextInputModal{ - InfoModal: NewInfoModalWithKey(l, "text_input_modal", false), + InfoModal: NewInfoModalWithKey(l, "text_input_modal", Outline), isCancelable: true, } diff --git a/ui/page/account_details_page.go b/ui/page/account_details_page.go index 4b1f093bc..d0f27ff86 100644 --- a/ui/page/account_details_page.go +++ b/ui/page/account_details_page.go @@ -344,7 +344,10 @@ func (pg *AcctDetailsPage) HandleUserInteractions() { return false } pg.account.Name = newName - pg.Toast.Notify(values.String(values.StrAcctRenamed)) + successModal := modal.NewSuccessModal(pg.Load, values.String(values.StrAcctRenamed), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(successModal) return true }) diff --git a/ui/page/components/dexserver_selector.go b/ui/page/components/dexserver_selector.go index dc87f721d..855e51595 100644 --- a/ui/page/components/dexserver_selector.go +++ b/ui/page/components/dexserver_selector.go @@ -10,6 +10,7 @@ import ( "github.com/planetdecred/godcr/app" "github.com/planetdecred/godcr/ui/decredmaterial" "github.com/planetdecred/godcr/ui/load" + "github.com/planetdecred/godcr/ui/modal" "github.com/planetdecred/godcr/ui/values" ) @@ -60,7 +61,10 @@ func (ds *DexServerSelector) isLoadingDexClient() bool { func (ds *DexServerSelector) startDexClient() { _, err := ds.WL.MultiWallet.StartDexClient() if err != nil { - ds.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(ds.Load, err.Error(), func(isChecked bool) bool { + return true + }) + ds.ParentWindow().ShowModal(errModal) return } @@ -68,7 +72,10 @@ func (ds *DexServerSelector) startDexClient() { if !ds.Dexc().Initialized() { err = ds.Dexc().InitializeWithPassword([]byte(values.DEXClientPass)) if err != nil { - ds.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(ds.Load, err.Error(), func(isChecked bool) bool { + return true + }) + ds.ParentWindow().ShowModal(errModal) return } } @@ -76,8 +83,10 @@ func (ds *DexServerSelector) startDexClient() { if !ds.Dexc().IsLoggedIn() { err := ds.Dexc().Login([]byte(values.DEXClientPass)) if err != nil { - // todo fix dex password error - // ds.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(ds.Load, err.Error(), func(isChecked bool) bool { + return true + }) + ds.ParentWindow().ShowModal(errModal) return } } diff --git a/ui/page/components/vsp_selector.go b/ui/page/components/vsp_selector.go index 4bcb9c800..11b2f7c64 100644 --- a/ui/page/components/vsp_selector.go +++ b/ui/page/components/vsp_selector.go @@ -13,6 +13,7 @@ import ( "github.com/planetdecred/godcr/app" "github.com/planetdecred/godcr/ui/decredmaterial" "github.com/planetdecred/godcr/ui/load" + "github.com/planetdecred/godcr/ui/modal" "github.com/planetdecred/godcr/ui/values" ) @@ -166,7 +167,10 @@ func (v *vspSelectorModal) Handle() { go func() { err := v.WL.MultiWallet.SaveVSP(v.inputVSP.Editor.Text()) if err != nil { - v.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(v.Load, err.Error(), func(isChecked bool) bool { + return true + }) + v.ParentWindow().ShowModal(errModal) } else { v.inputVSP.Editor.SetText("") } diff --git a/ui/page/components/wallet_selector.go b/ui/page/components/wallet_selector.go index 634b07770..01402752f 100644 --- a/ui/page/components/wallet_selector.go +++ b/ui/page/components/wallet_selector.go @@ -133,10 +133,16 @@ func (ws *WalletSelector) deleteBadWallet(badWalletID int) { go func() { err := ws.WL.MultiWallet.DeleteBadWallet(badWalletID) if err != nil { - ws.Toast.NotifyError(err.Error()) + errorModal := modal.NewErrorModal(ws.Load, err.Error(), func(isChecked bool) bool { + return true + }) + ws.ParentWindow().ShowModal(errorModal) return } - ws.Toast.Notify(values.String(values.StrWalletRemoved)) + infoModal := modal.NewSuccessModal(ws.Load, values.String(values.StrWalletRemoved), func(isChecked bool) bool { + return true + }) + ws.ParentWindow().ShowModal(infoModal) ws.loadBadWallets() // refresh bad wallets list ws.ParentWindow().Reload() }() diff --git a/ui/page/dexclient/add_dex_modal.go b/ui/page/dexclient/add_dex_modal.go index c9d212985..622272c59 100644 --- a/ui/page/dexclient/add_dex_modal.go +++ b/ui/page/dexclient/add_dex_modal.go @@ -100,7 +100,10 @@ func (md *AddDexModal) doAddDexServer(serverAddr string) { dexServer, paid, err := md.Dexc().Core().DiscoverAccount(serverAddr, []byte(DEXClientPass), cert) if err != nil { - md.Toast.NotifyError(err.Error()) + errorModal := modal.NewErrorModal(md.Load, err.Error(), func(isChecked bool) bool { + return true + }) + md.ParentWindow().ShowModal(errorModal) return } diff --git a/ui/page/governance/agenda_vote_modal.go b/ui/page/governance/agenda_vote_modal.go index 0087dfdd2..82eacf170 100644 --- a/ui/page/governance/agenda_vote_modal.go +++ b/ui/page/governance/agenda_vote_modal.go @@ -12,6 +12,7 @@ import ( "github.com/planetdecred/dcrlibwallet" "github.com/planetdecred/godcr/ui/decredmaterial" "github.com/planetdecred/godcr/ui/load" + "github.com/planetdecred/godcr/ui/modal" "github.com/planetdecred/godcr/ui/page/components" "github.com/planetdecred/godcr/ui/values" ) @@ -92,7 +93,10 @@ func (avm *agendaVoteModal) FetchUnspentUnexpiredTickets(walletID int) { wallet := avm.WL.MultiWallet.WalletWithID(walletID) tickets, err := wallet.UnspentUnexpiredTickets() if err != nil { - avm.Toast.NotifyError(err.Error()) + errorModal := modal.NewErrorModal(avm.Load, err.Error(), func(isChecked bool) bool { + return true + }) + avm.ParentWindow().ShowModal(errorModal) return } @@ -234,12 +238,17 @@ func (avm *agendaVoteModal) sendVotes() { if err.Error() == dcrlibwallet.ErrInvalidPassphrase { avm.spendingPassword.SetError(values.String(values.StrInvalidPassphrase)) } else { - avm.Toast.NotifyError(err.Error()) + errorModal := modal.NewErrorModal(avm.Load, err.Error(), func(isChecked bool) bool { + return true + }) + avm.ParentWindow().ShowModal(errorModal) } return } - avm.Toast.Notify(values.String(values.StrVoteUpdated)) - + successModal := modal.NewSuccessModal(avm.Load, values.String(values.StrVoteUpdated), func(isChecked bool) bool { + return true + }) + avm.ParentWindow().ShowModal(successModal) avm.Dismiss() avm.onPreferenceUpdated() }() diff --git a/ui/page/governance/proposal_vote_modal.go b/ui/page/governance/proposal_vote_modal.go index 393eeeb26..9f19800c3 100644 --- a/ui/page/governance/proposal_vote_modal.go +++ b/ui/page/governance/proposal_vote_modal.go @@ -161,7 +161,10 @@ func (vm *voteModal) sendVotes() { return } pm.Dismiss() - vm.Toast.Notify(values.String(values.StrVoteSent)) + infoModal := modal.NewSuccessModal(vm.Load, values.String(values.StrVoteSent), func(isChecked bool) bool { + return true + }) + vm.ParentWindow().ShowModal(infoModal) go vm.WL.MultiWallet.Politeia.Sync() vm.Dismiss() }() diff --git a/ui/page/governance/treasury_page.go b/ui/page/governance/treasury_page.go index d0e508b75..d2e712fbb 100644 --- a/ui/page/governance/treasury_page.go +++ b/ui/page/governance/treasury_page.go @@ -276,13 +276,19 @@ func (pg *TreasuryPage) updatePolicyPreference(treasuryItem *components.Treasury if err.Error() == dcrlibwallet.ErrInvalidPassphrase { pm.SetError(values.String(values.StrInvalidPassphrase)) } else { - pm.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(pg.Load, err.Error(), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) } pm.SetLoading(false) return } go pg.FetchPolicies() // re-fetch policies when voting is done. - pm.Toast.Notify(values.String(values.StrPolicySetSuccessful)) + infoModal := modal.NewSuccessModal(pg.Load, values.String(values.StrPolicySetSuccessful), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(infoModal) pm.Dismiss() }() diff --git a/ui/page/info/restore_page.go b/ui/page/info/restore_page.go index 7de13c440..e7da14241 100644 --- a/ui/page/info/restore_page.go +++ b/ui/page/info/restore_page.go @@ -248,7 +248,10 @@ func (pg *Restore) showHexRestoreModal() { return } - pg.Toast.Notify(values.String(values.StrWalletRestored)) + successModal := modal.NewSuccessModal(pg.Load, values.String(values.StrWalletRestored), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(successModal) m.Dismiss() if pg.restoreComplete == nil { pg.ParentNavigator().CloseCurrentPage() @@ -286,7 +289,10 @@ func (pg *Restore) verifyHex(hex string) bool { } if walletWithSameSeed != -1 { - pg.Toast.NotifyError(values.String(values.StrSeedAlreadyExist)) + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrSeedAlreadyExist), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return false } diff --git a/ui/page/info/seed_restore_page.go b/ui/page/info/seed_restore_page.go index 57a7d6a6a..aa741c9fe 100644 --- a/ui/page/info/seed_restore_page.go +++ b/ui/page/info/seed_restore_page.go @@ -496,7 +496,10 @@ func (pg *SeedRestore) verifySeeds() bool { if isValid { pg.seedPhrase = seedphrase if !dcrlibwallet.VerifySeed(pg.seedPhrase) { - pg.Toast.NotifyError(values.String(values.StrInvalidSeedPhrase)) + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrInvalidSeedPhrase), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return false } } @@ -510,7 +513,10 @@ func (pg *SeedRestore) verifySeeds() bool { } if walletWithSameSeed != -1 { - pg.Toast.NotifyError(values.String(values.StrSeedAlreadyExist)) + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrSeedAlreadyExist), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return false } @@ -573,7 +579,10 @@ func (pg *SeedRestore) HandleUserInteractions() { return } - pg.Toast.Notify(values.String(values.StrWalletRestored)) + infoModal := modal.NewErrorModal(pg.Load, values.String(values.StrWalletRestored), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(infoModal) pg.resetSeeds() m.Dismiss() if pg.restoreComplete == nil { diff --git a/ui/page/main_page.go b/ui/page/main_page.go index 1c2050639..bafc6a396 100644 --- a/ui/page/main_page.go +++ b/ui/page/main_page.go @@ -512,9 +512,15 @@ func (mp *MainPage) HandleUserInteractions() { if mp.WL.MultiWallet.IsSynced() { mp.Display(pg) } else if mp.WL.MultiWallet.IsSyncing() { - mp.Toast.NotifyError(values.String(values.StrNotConnected)) + errModal := modal.NewErrorModal(mp.Load, values.String(values.StrNotConnected), func(isChecked bool) bool { + return true + }) + mp.ParentWindow().ShowModal(errModal) } else { - mp.Toast.NotifyError(values.String(values.StrWalletSyncing)) + errModal := modal.NewErrorModal(mp.Load, values.String(values.StrWalletSyncing), func(isChecked bool) bool { + return true + }) + mp.ParentWindow().ShowModal(errModal) } } else { mp.Display(pg) @@ -567,9 +573,15 @@ func (mp *MainPage) HandleUserInteractions() { if mp.WL.MultiWallet.IsSynced() { mp.Display(pg) } else if mp.WL.MultiWallet.IsSyncing() { - mp.Toast.NotifyError(values.String(values.StrWalletSyncing)) + errModal := modal.NewErrorModal(mp.Load, values.String(values.StrWalletSyncing), func(isChecked bool) bool { + return true + }) + mp.ParentWindow().ShowModal(errModal) } else { - mp.Toast.NotifyError(values.String(values.StrNotConnected)) + errModal := modal.NewErrorModal(mp.Load, values.String(values.StrNotConnected), func(isChecked bool) bool { + return true + }) + mp.ParentWindow().ShowModal(errModal) } } } diff --git a/ui/page/privacy/manual_mixer_setup_page.go b/ui/page/privacy/manual_mixer_setup_page.go index 82aab3779..070ab0da0 100644 --- a/ui/page/privacy/manual_mixer_setup_page.go +++ b/ui/page/privacy/manual_mixer_setup_page.go @@ -187,7 +187,10 @@ func (pg *ManualMixerSetupPage) mixerAccountSections(gtx layout.Context, title s func (pg *ManualMixerSetupPage) showModalSetupMixerAcct() { if pg.mixedAccountSelector.SelectedAccount().Number == pg.unmixedAccountSelector.SelectedAccount().Number { - pg.Toast.NotifyError("Cannot use same account for mixed & unmixed") + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrNotSameAccoutMixUnmix), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return } diff --git a/ui/page/receive_page.go b/ui/page/receive_page.go index 0be4846e8..15894103d 100644 --- a/ui/page/receive_page.go +++ b/ui/page/receive_page.go @@ -148,7 +148,10 @@ func (pg *ReceivePage) OnNavigatedTo() { currentAddress, err := selectedWallet.CurrentAddress(pg.selector.SelectedAccount().Number) if err != nil { log.Errorf("Error getting current address: %v", err) - pg.Toast.NotifyError(fmt.Sprintf("Error getting current address: %v", err)) + errModal := modal.NewErrorModal(pg.Load, fmt.Sprintf("Error getting current address: %v", err), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) } else { pg.currentAddress = currentAddress pg.generateQRForAddress() diff --git a/ui/page/security/validate_address.go b/ui/page/security/validate_address.go index 99452ba34..509e3c2bd 100644 --- a/ui/page/security/validate_address.go +++ b/ui/page/security/validate_address.go @@ -221,7 +221,7 @@ func (pg *ValidateAddressPage) validateAddress() { Title(verifyMessageText). SetContentAlignment(layout.Center, layout.Center). PositiveButtonStyle(pg.Theme.Color.Primary, pg.Theme.Color.Surface). - PositiveButton(values.String(values.StrOK), func(isChecked bool) bool { + PositiveButton(values.String(values.StrOk), func(isChecked bool) bool { return true }) pg.ParentWindow().ShowModal(info) diff --git a/ui/page/security/verify_message_page.go b/ui/page/security/verify_message_page.go index ef677ac35..44828b5b0 100644 --- a/ui/page/security/verify_message_page.go +++ b/ui/page/security/verify_message_page.go @@ -192,7 +192,7 @@ func (pg *VerifyMessagePage) HandleUserInteractions() { Title(verifyMessageText). SetContentAlignment(layout.Center, layout.Center). PositiveButtonStyle(pg.Theme.Color.Primary, pg.Theme.Color.Surface). - PositiveButton(values.String(values.StrOK), func(isChecked bool) bool { + PositiveButton(values.String(values.StrOk), func(isChecked bool) bool { return true }) pg.ParentWindow().ShowModal(info) diff --git a/ui/page/seedbackup/verify_seed.go b/ui/page/seedbackup/verify_seed.go index 9ad6370c9..74df3f17e 100644 --- a/ui/page/seedbackup/verify_seed.go +++ b/ui/page/seedbackup/verify_seed.go @@ -164,7 +164,10 @@ func (pg *VerifySeedPage) verifySeed() { _, err := pg.WL.MultiWallet.VerifySeedForWallet(pg.wallet.ID, seed, []byte(password)) if err != nil { if err.Error() == dcrlibwallet.ErrInvalid { - pg.Toast.NotifyError("Failed to verify. Please go through every word and try again.") + errModal := modal.NewErrorModal(pg.Load, "Failed to verify. Please go through every word and try again.", func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) m.Dismiss() return } diff --git a/ui/page/send/page.go b/ui/page/send/page.go index f1a515078..732b9c31d 100644 --- a/ui/page/send/page.go +++ b/ui/page/send/page.go @@ -320,7 +320,10 @@ func (pg *Page) feeEstimationError(err string) { pg.amount.setError(invalidAmountErr) } else { pg.amount.setError(err) - pg.Toast.NotifyError(values.StringF(values.StrTxEstimateErr, err)) + errModal := modal.NewErrorModal(pg.Load, values.StringF(values.StrTxEstimateErr, err), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) } pg.clearEstimates() diff --git a/ui/page/send/send_confirm_modal.go b/ui/page/send/send_confirm_modal.go index 210b7eb8f..534514d7d 100644 --- a/ui/page/send/send_confirm_modal.go +++ b/ui/page/send/send_confirm_modal.go @@ -11,6 +11,7 @@ import ( "github.com/planetdecred/godcr/ui/decredmaterial" "github.com/planetdecred/godcr/ui/load" + "github.com/planetdecred/godcr/ui/modal" "github.com/planetdecred/godcr/ui/page/components" "github.com/planetdecred/godcr/ui/values" ) @@ -72,10 +73,16 @@ func (scm *sendConfirmModal) broadcastTransaction() { scm.isSending = false scm.Modal.SetDisabled(false) if err != nil { - scm.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(scm.Load, err.Error(), func(isChecked bool) bool { + return true + }) + scm.ParentWindow().ShowModal(errModal) return } - scm.Toast.Notify(values.String(values.StrTxSent)) + successModal := modal.NewSuccessModal(scm.Load, values.String(values.StrTxSent), func(isChecked bool) bool { + return true + }) + scm.ParentWindow().ShowModal(successModal) scm.txSent() scm.Dismiss() diff --git a/ui/page/settings_page.go b/ui/page/settings_page.go index bfd0b81ee..f997eb710 100644 --- a/ui/page/settings_page.go +++ b/ui/page/settings_page.go @@ -384,16 +384,19 @@ func (pg *SettingsPage) HandleUserInteractions() { pg.WL.MultiWallet.SaveUserConfigValue(load.DarkModeConfigKey, pg.isDarkModeOn) pg.RefreshTheme(pg.ParentWindow()) } - if pg.transactionNotification.Changed() { go func() { pg.WL.MultiWallet.SaveUserConfigValue(load.TransactionNotificationConfigKey, pg.transactionNotification.IsChecked()) }() + infoModal := modal.NewSuccessModal(pg.Load, values.StringF(values.StrTxNotification, values.String(values.StrDisabled)), func(isChecked bool) bool { + return true + }) if pg.transactionNotification.IsChecked() { - pg.Toast.Notify(values.StringF(values.StrTxNotification, values.String(values.StrEnabled))) - } else { - pg.Toast.Notify(values.StringF(values.StrTxNotification, values.String(values.StrDisabled))) + infoModal = modal.NewSuccessModal(pg.Load, values.StringF(values.StrTxNotification, values.String(values.StrEnabled)), func(isChecked bool) bool { + return true + }) } + pg.ParentWindow().ShowModal(infoModal) } if pg.infoButton.Button.Clicked() { @@ -517,11 +520,14 @@ func (pg *SettingsPage) HandleUserInteractions() { select { case err := <-pg.errorReceiver: + erro := err.Error() if err.Error() == dcrlibwallet.ErrInvalidPassphrase { - pg.Toast.NotifyError(values.String(values.StrInvalidPassphrase)) - return + erro = values.String(values.StrInvalidPassphrase) } - pg.Toast.NotifyError(err.Error()) + infoModal := modal.NewErrorModal(pg.Load, erro, func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(infoModal) default: } } diff --git a/ui/page/staking/stake_list.go b/ui/page/staking/stake_list.go index 70823ad57..f811f2a82 100644 --- a/ui/page/staking/stake_list.go +++ b/ui/page/staking/stake_list.go @@ -6,6 +6,7 @@ import ( "github.com/planetdecred/dcrlibwallet" "github.com/planetdecred/godcr/listeners" + "github.com/planetdecred/godcr/ui/modal" "github.com/planetdecred/godcr/ui/values" ) @@ -46,7 +47,10 @@ func (pg *Page) listenForTxNotifications() { func (pg *Page) fetchTickets() { txs, err := pg.WL.SelectedWallet.Wallet.GetTransactionsRaw(0, 0, dcrlibwallet.TxFilterTickets, true) if err != nil { - pg.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(pg.Load, err.Error(), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return } @@ -54,7 +58,10 @@ func (pg *Page) fetchTickets() { return filter == dcrlibwallet.TxFilterTickets }) if err != nil { - pg.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(pg.Load, err.Error(), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return } diff --git a/ui/page/staking/stake_modal.go b/ui/page/staking/stake_modal.go index 93d686b98..48d8ef90e 100644 --- a/ui/page/staking/stake_modal.go +++ b/ui/page/staking/stake_modal.go @@ -11,6 +11,7 @@ import ( "github.com/planetdecred/dcrlibwallet" "github.com/planetdecred/godcr/ui/decredmaterial" "github.com/planetdecred/godcr/ui/load" + "github.com/planetdecred/godcr/ui/modal" "github.com/planetdecred/godcr/ui/page/components" "github.com/planetdecred/godcr/ui/values" ) @@ -79,7 +80,10 @@ func (tb *ticketBuyerModal) OnResume() { tbConfig := tb.WL.SelectedWallet.Wallet.AutoTicketsBuyerConfig() acct, err := tb.WL.SelectedWallet.Wallet.GetAccount(tbConfig.PurchaseAccount) if err != nil { - tb.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(tb.Load, err.Error(), func(isChecked bool) bool { + return true + }) + tb.ParentWindow().ShowModal(errModal) } if tb.WL.SelectedWallet.Wallet.ReadBoolConfigValueForKey(dcrlibwallet.AccountMixerConfigSet, false) && @@ -89,7 +93,10 @@ func (tb *ticketBuyerModal) OnResume() { } else { err := tb.accountSelector.SelectFirstWalletValidAccount() if err != nil { - tb.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(tb.Load, err.Error(), func(isChecked bool) bool { + return true + }) + tb.ParentWindow().ShowModal(errModal) } } @@ -100,7 +107,10 @@ func (tb *ticketBuyerModal) OnResume() { if tb.accountSelector.SelectedAccount() == nil { err := tb.accountSelector.SelectFirstWalletValidAccount() if err != nil { - tb.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(tb.Load, err.Error(), func(isChecked bool) bool { + return true + }) + tb.ParentWindow().ShowModal(errModal) } } } @@ -200,7 +210,10 @@ func (tb *ticketBuyerModal) Handle() { vspHost := tb.vspSelector.SelectedVSP().Host amount, err := strconv.ParseFloat(tb.balToMaintainEditor.Editor.Text(), 64) if err != nil { - tb.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(tb.Load, err.Error(), func(isChecked bool) bool { + return true + }) + tb.ParentWindow().ShowModal(errModal) return } diff --git a/ui/page/staking/stake_overview.go b/ui/page/staking/stake_overview.go index 2e829263f..336a017a6 100644 --- a/ui/page/staking/stake_overview.go +++ b/ui/page/staking/stake_overview.go @@ -101,7 +101,10 @@ func (pg *Page) fetchTicketPrice() { if err != nil && !pg.WL.MultiWallet.IsSynced() { log.Error(err) pg.ticketPrice = values.String(values.StrNotAvailable) - pg.Toast.NotifyError(values.String(values.StrWalletNotSynced)) + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrWalletNotSynced), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) } else { pg.ticketPrice = dcrutil.Amount(ticketPrice.TicketPrice).String() } @@ -123,14 +126,20 @@ func (pg *Page) loadPageData() { totalRewards, err := pg.WL.SelectedWallet.Wallet.TotalStakingRewards() if err != nil { - pg.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(pg.Load, err.Error(), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) } else { pg.totalRewards = dcrutil.Amount(totalRewards).String() } overview, err := pg.WL.SelectedWallet.Wallet.StakingOverview() if err != nil { - pg.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(pg.Load, err.Error(), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) } else { pg.ticketOverview = overview } @@ -223,13 +232,19 @@ func (pg *Page) HandleUserInteractions() { if pg.stakeSettings.Clicked() && !pg.WL.SelectedWallet.Wallet.IsWatchingOnlyWallet() { if pg.WL.SelectedWallet.Wallet.IsAutoTicketsPurchaseActive() { - pg.Toast.NotifyError(values.String(values.StrAutoTicketWarn)) + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrAutoTicketWarn), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return } ticketBuyerModal := newTicketBuyerModal(pg.Load). OnSettingsSaved(func() { - pg.Toast.Notify(values.String(values.StrTicketSettingSaved)) + infoModal := modal.NewSuccessModal(pg.Load, values.String(values.StrTicketSettingSaved), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(infoModal) }). OnCancel(func() { pg.stake.SetChecked(false) @@ -295,7 +310,10 @@ func (pg *Page) ticketBuyerSettingsModal() { }). OnSettingsSaved(func() { pg.startTicketBuyerPasswordModal() - pg.Toast.Notify(values.String(values.StrTicketSettingSaved)) + infoModal := modal.NewSuccessModal(pg.Load, values.String(values.StrTicketSettingSaved), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(infoModal) }) pg.ParentWindow().ShowModal(ticketBuyerModal) } @@ -305,7 +323,10 @@ func (pg *Page) startTicketBuyerPasswordModal() { balToMaintain := dcrlibwallet.AmountCoin(tbConfig.BalanceToMaintain) name, err := pg.WL.SelectedWallet.Wallet.AccountNameRaw(uint32(tbConfig.PurchaseAccount)) if err != nil { - pg.Toast.NotifyError(values.StringF(values.StrTicketError, err)) + errModal := modal.NewErrorModal(pg.Load, values.StringF(values.StrTicketError, err), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) return } @@ -352,7 +373,10 @@ func (pg *Page) startTicketBuyerPasswordModal() { }). PositiveButton(values.String(values.StrConfirm), func(password string, pm *modal.PasswordModal) bool { if !pg.WL.MultiWallet.IsConnectedToDecredNetwork() { - pg.Toast.NotifyError(values.String(values.StrNotConnected)) + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrNotConnected), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) pm.SetLoading(false) pg.stake.SetChecked(false) return false @@ -361,7 +385,10 @@ func (pg *Page) startTicketBuyerPasswordModal() { go func() { err := pg.WL.SelectedWallet.Wallet.StartTicketBuyer([]byte(password)) if err != nil { - pg.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(pg.Load, err.Error(), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) pm.SetLoading(false) return } diff --git a/ui/page/transaction/transaction_details_page.go b/ui/page/transaction/transaction_details_page.go index 6c8d380ab..8d0f66bbc 100644 --- a/ui/page/transaction/transaction_details_page.go +++ b/ui/page/transaction/transaction_details_page.go @@ -802,7 +802,10 @@ func (pg *TxDetailsPage) HandleUserInteractions() { pg.rebroadcastClickable.SetEnabled(false, nil) if !pg.Load.WL.MultiWallet.IsConnectedToDecredNetwork() { // if user is not conected to the network, notify the user - pg.Toast.NotifyError(values.String(values.StrNotConnected)) + errModal := modal.NewErrorModal(pg.Load, values.String(values.StrNotConnected), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) if !pg.rebroadcastClickable.Enabled() { pg.rebroadcastClickable.SetEnabled(true, nil) } @@ -812,9 +815,15 @@ func (pg *TxDetailsPage) HandleUserInteractions() { err := pg.wallet.PublishUnminedTransactions() if err != nil { // If transactions are not published, notify the user - pg.Toast.NotifyError(err.Error()) + errModal := modal.NewErrorModal(pg.Load, err.Error(), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errModal) } else { - pg.Toast.Notify(values.String(values.StrRepublished)) + infoModal := modal.NewSuccessModal(pg.Load, values.String(values.StrRepublished), func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(infoModal) } if !pg.rebroadcastClickable.Enabled() { pg.rebroadcastClickable.SetEnabled(true, nil) diff --git a/ui/page/wallet_settings_page.go b/ui/page/wallet_settings_page.go index 19418ae1d..49948af40 100644 --- a/ui/page/wallet_settings_page.go +++ b/ui/page/wallet_settings_page.go @@ -550,15 +550,21 @@ func (pg *WalletSettingsPage) HandleUserInteractions() { PositiveButton(values.String(values.StrRescan), func(isChecked bool) bool { err := pg.WL.MultiWallet.RescanBlocks(pg.wallet.ID) if err != nil { + errMsg := err.Error() if err.Error() == dcrlibwallet.ErrNotConnected { - pg.Toast.NotifyError(values.String(values.StrNotConnected)) - return true + errMsg = values.String(values.StrNotConnected) } - pg.Toast.NotifyError(err.Error()) + errorModal := modal.NewErrorModal(pg.Load, errMsg, func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(errorModal) return true } msg := values.String(values.StrRescanProgressNotification) - pg.Toast.Notify(msg) + infoModal := modal.NewSuccessModal(pg.Load, msg, func(isChecked bool) bool { + return true + }) + pg.ParentWindow().ShowModal(infoModal) return true }) @@ -583,7 +589,7 @@ func (pg *WalletSettingsPage) HandleUserInteractions() { SetContentAlignment(layout.W, layout.Center). SetupWithTemplate(modal.SecurityToolsInfoTemplate). Title(values.String(values.StrSecurityTools)). - PositiveButton(values.String(values.StrOK), func(isChecked bool) bool { + PositiveButton(values.String(values.StrOk), func(isChecked bool) bool { return true }) pg.ParentWindow().ShowModal(info) diff --git a/ui/values/localizable/en.go b/ui/values/localizable/en.go index a6b7aa8aa..c96785c15 100644 --- a/ui/values/localizable/en.go +++ b/ui/values/localizable/en.go @@ -503,7 +503,10 @@ unlockWithPassword = "Unlock with password" "confirmVote" = "Confirm your vote" "policySetSuccessfully" = "Your treasury policy has been successfully updated!" "colon" = ": " +"ok" = "OK" +"dexDataReset" = "DEX client data reset complete." +"dexDataResetFalse" = "DEX client data reset failed. Check the logs." +"notSameAccoutMixUnmix" = ""Cannot use same account for mixed & unmixed"" "removeWalletInfo" = "%v Are you sure you want to remove %v %s%v? Enter the name of the wallet below to verify. %v" "confirmUmixedSpending" = "Confirm to allow spending from unmixed accounts" -"ok" = "OK" ` diff --git a/ui/values/strings.go b/ui/values/strings.go index 0ca82fd22..4a17fa491 100644 --- a/ui/values/strings.go +++ b/ui/values/strings.go @@ -607,9 +607,11 @@ const ( StrConfirmVote = "confirmVote" StrPolicySetSuccessful = "policySetSuccessfully" StrColon = "colon" + StrDexDataReset = "dexDataReset" + StrDexDataResetFalse = "dexDataResetFalse" + StrNotSameAccoutMixUnmix = "notSameAccoutMixUnmix" StrRemoveWalletInfo = "removeWalletInfo" StrPropNotif = "propNotif" StrPeer = "peer" StrConfirmUmixedSpending = "confirmUmixedSpending" - StrOK = "ok" )