From 0342764051dd1222a225f3be9f09e94dff036fb9 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Mon, 13 Nov 2023 14:30:52 +0100 Subject: [PATCH] refactor master page and page stack -- Refactor app.NewMasterPage to accept and handle a start page. -- Refactor *app.MasterPage.Display() -- Refactor app.PageStack.Push to only prepare the next page. -- Refactor pages that embed app.Masterpage. -- Fix some TODOs. Signed-off-by: Philemon Ukane --- app/masterpage.go | 20 ++++++++++++++--- app/pagestack.go | 10 --------- app/window.go | 5 +++++ ui/page/dcrdex/dcrdex_page.go | 10 ++++----- ui/page/governance/governance_page.go | 29 ++++++++---------------- ui/page/root/home_page.go | 32 +++++++++++++-------------- ui/page/root/main_page.go | 10 ++++----- ui/page/root/overview_page.go | 1 - ui/page/root/trade_page.go | 27 +++++++++------------- 9 files changed, 65 insertions(+), 79 deletions(-) diff --git a/app/masterpage.go b/app/masterpage.go index a83d494f0..823d02179 100644 --- a/app/masterpage.go +++ b/app/masterpage.go @@ -13,12 +13,21 @@ type MasterPage struct { subPages *PageStack } -// NewMasterPage returns an instance of MasterPage. -func NewMasterPage(id string) *MasterPage { - return &MasterPage{ +// NewMasterPage returns an instance of MasterPage. startPage is optional. +func NewMasterPage(id string, startPage Page) *MasterPage { + mp := &MasterPage{ GenericPageModal: NewGenericPageModal(id), subPages: NewPageStack(id), } + + if startPage == nil { + return mp + } + + // Bind the navigator to the page. + startPage.OnAttachedToNavigator(mp) + mp.subPages.pages = append(mp.subPages.pages, startPage) + return mp } // CurrentPage returns the page that is at the top of the stack. Returns nil if @@ -47,6 +56,11 @@ func (masterPage *MasterPage) Display(newPage Page) { if pushed { masterPage.ParentWindow().Reload() } + + // Page is ready to be displayed. + newPage.OnAttachedToNavigator(masterPage) + newPage.OnNavigatedTo() + masterPage.ParentWindow().Reload() } // CloseCurrentPage dismisses the page at the top of the stack and gets the next diff --git a/app/pagestack.go b/app/pagestack.go index 16494f776..998648699 100644 --- a/app/pagestack.go +++ b/app/pagestack.go @@ -41,14 +41,6 @@ func (pageStack *PageStack) PushAndNavigate(newPage Page, navigator PageNavigato pageStack.mtx.Lock() defer pageStack.mtx.Unlock() - if l := len(pageStack.pages); l > 0 { - currentPage := pageStack.pages[l-1] - if currentPage.ID() == newPage.ID() { - return false - } - currentPage.OnNavigatedFrom() - } - // Close any previous instance of this type. Use the Closed() method if // implemented, to signal that the instance will never be re-displayed. for i, existingPage := range pageStack.pages { @@ -63,8 +55,6 @@ func (pageStack *PageStack) PushAndNavigate(newPage Page, navigator PageNavigato } pageStack.pages = append(pageStack.pages, newPage) - newPage.OnAttachedToNavigator(navigator) - newPage.OnNavigatedTo() return true } diff --git a/app/window.go b/app/window.go index 5113b23ea..fcca68341 100644 --- a/app/window.go +++ b/app/window.go @@ -50,6 +50,11 @@ func (window *SimpleWindowNavigator) Display(newPage Page) { if pushed { window.Reload() } + + // Page is ready to be displayed. + newPage.OnAttachedToNavigator(window) + newPage.OnNavigatedTo() + window.Reload() } // CloseCurrentPage dismisses the page at the top of the stack and gets the next diff --git a/ui/page/dcrdex/dcrdex_page.go b/ui/page/dcrdex/dcrdex_page.go index 013bd7174..acfa30a40 100644 --- a/ui/page/dcrdex/dcrdex_page.go +++ b/ui/page/dcrdex/dcrdex_page.go @@ -9,7 +9,7 @@ import ( "github.com/crypto-power/cryptopower/ui/load" ) -const DCRDEXID = "DCRDEXID" +const DCRDEXPageID = "DCRDEXID" type ( C = layout.Context @@ -31,7 +31,7 @@ type DEXPage struct { func NewDEXPage(l *load.Load) *DEXPage { dp := &DEXPage{ Load: l, - MasterPage: app.NewMasterPage(DCRDEXID), + MasterPage: app.NewMasterPage(DCRDEXPageID, nil), openTradeMainPage: l.Theme.NewClickable(false), } return dp @@ -41,7 +41,7 @@ func NewDEXPage(l *load.Load) *DEXPage { // differentiate this page from other pages. // Part of the load.Page interface. func (pg *DEXPage) ID() string { - return DCRDEXID + return DCRDEXPageID } // OnNavigatedTo is called when the page is about to be displayed and may be @@ -54,9 +54,9 @@ func (pg *DEXPage) OnNavigatedTo() { if pg.CurrentPage() == nil { // TODO: Handle pg.inited pg.Display(NewDEXOnboarding(pg.Load)) + } else { + pg.CurrentPage().OnNavigatedTo() } - - pg.CurrentPage().OnNavigatedTo() } // Layout draws the page UI components into the provided layout context to be diff --git a/ui/page/governance/governance_page.go b/ui/page/governance/governance_page.go index 40a396e96..45adab87e 100644 --- a/ui/page/governance/governance_page.go +++ b/ui/page/governance/governance_page.go @@ -40,7 +40,7 @@ var governanceTabTitles = []string{ func NewGovernancePage(l *load.Load) *Page { pg := &Page{ Load: l, - MasterPage: app.NewMasterPage(GovernancePageID), + MasterPage: app.NewMasterPage(GovernancePageID, NewProposalsPage(l)), modal: l.Theme.ModalFloatTitle(values.String(values.StrSettings)), tabCategoryList: l.Theme.NewClickableList(layout.Horizontal), } @@ -58,11 +58,7 @@ func NewGovernancePage(l *load.Load) *Page { // the page is displayed. // Part of the load.Page interface. func (pg *Page) OnNavigatedTo() { - if activeTab := pg.CurrentPage(); activeTab != nil { - activeTab.OnNavigatedTo() - } else { - pg.Display(NewProposalsPage(pg.Load)) - } + pg.CurrentPage().OnNavigatedTo() } func (pg *Page) isGovernanceAPIAllowed() bool { @@ -77,16 +73,10 @@ func (pg *Page) isGovernanceAPIAllowed() bool { // components unless they'll be recreated in the OnNavigatedTo() method. // Part of the load.Page interface. func (pg *Page) OnNavigatedFrom() { - if activeTab := pg.CurrentPage(); activeTab != nil { - activeTab.OnNavigatedFrom() - } + pg.CurrentPage().OnNavigatedFrom() } func (pg *Page) HandleUserInteractions() { - if activeTab := pg.CurrentPage(); activeTab != nil { - activeTab.HandleUserInteractions() - } - if pg.navigateToSettingsBtn.Button.Clicked() { pg.ParentWindow().Display(settings.NewSettingsPage(pg.Load)) } @@ -96,19 +86,18 @@ func (pg *Page) HandleUserInteractions() { } if tabItemClicked, clickedTabIndex := pg.tabCategoryList.ItemClicked(); tabItemClicked { - if clickedTabIndex == 0 { - pg.Display(NewProposalsPage(pg.Load)) // Display should do nothing if the page is already displayed. - } else if clickedTabIndex == 1 { + currentPageID := pg.CurrentPageID() + if clickedTabIndex == 0 && currentPageID != ProposalsPageID { + pg.Display(NewProposalsPage(pg.Load)) + } else if clickedTabIndex == 1 && currentPageID != ConsensusPageID { pg.Display(NewConsensusPage(pg.Load)) - } else { + } else if currentPageID != TreasuryPageID { pg.Display(NewTreasuryPage(pg.Load)) } } // Handle individual page user interactions. - if activeTab := pg.CurrentPage(); activeTab != nil { - activeTab.HandleUserInteractions() - } + pg.CurrentPage().HandleUserInteractions() } func (pg *Page) Layout(gtx C) D { diff --git a/ui/page/root/home_page.go b/ui/page/root/home_page.go index bf3ca7e38..7384dfa9e 100644 --- a/ui/page/root/home_page.go +++ b/ui/page/root/home_page.go @@ -70,10 +70,19 @@ var navigationTabTitles = []string{ func NewHomePage(l *load.Load) *HomePage { hp := &HomePage{ Load: l, - MasterPage: app.NewMasterPage(HomePageID), isConnected: new(atomic.Bool), } + // Initialize wallet page + hp.walletSelectorPage = NewWalletSelectorPage(l) + hp.showNavigationFunc = func(isHiddenNavigation bool) { + hp.isHiddenNavigation = isHiddenNavigation + } + hp.walletSelectorPage.showNavigationFunc = hp.showNavigationFunc + + // Initialize master page. + hp.MasterPage = app.NewMasterPage(HomePageID, NewOverviewPage(l, hp.showNavigationFunc)) + hp.hideBalanceButton = hp.Theme.NewClickable(false) hp.appLevelSettingsButton = hp.Theme.NewClickable(false) hp.appNotificationButton = hp.Theme.NewClickable(false) @@ -113,13 +122,6 @@ func NewHomePage(l *load.Load) *HomePage { } l.ToggleSync = toggleSync - // initialize wallet page - hp.walletSelectorPage = NewWalletSelectorPage(l) - hp.showNavigationFunc = func(isHiddenNavigation bool) { - hp.isHiddenNavigation = isHiddenNavigation - } - hp.walletSelectorPage.showNavigationFunc = hp.showNavigationFunc - hp.initBottomNavItems() hp.bottomNavigationBar.OnViewCreated() @@ -138,6 +140,8 @@ func (hp *HomePage) ID() string { // the page is displayed. // Part of the load.Page interface. func (hp *HomePage) OnNavigatedTo() { + hp.CurrentPage().OnNavigatedTo() + hp.ctx, hp.ctxCancel = context.WithCancel(context.TODO()) go hp.CalculateAssetsUSDBalance() @@ -176,10 +180,6 @@ func (hp *HomePage) OnDarkModeChanged(isDarkModeOn bool) { // displayed. // Part of the load.Page interface. func (hp *HomePage) HandleUserInteractions() { - if hp.CurrentPage() != nil { - hp.CurrentPage().HandleUserInteractions() - } - if hp.navigationTab.Changed() { var pg app.Page switch hp.navigationTab.SelectedTab() { @@ -286,6 +286,8 @@ func (hp *HomePage) HandleUserInteractions() { } } } + + hp.CurrentPage().HandleUserInteractions() } func (hp *HomePage) showWarningNoWallet() { @@ -334,11 +336,7 @@ func (hp *HomePage) OnCurrencyChanged() { // components unless they'll be recreated in the OnNavigatedTo() method. // Part of the load.Page interface. func (hp *HomePage) OnNavigatedFrom() { - // Also remove all child pages. - if activeTab := hp.CurrentPage(); activeTab != nil { - activeTab.OnNavigatedFrom() - } - + hp.CurrentPage().OnNavigatedFrom() hp.ctxCancel() } diff --git a/ui/page/root/main_page.go b/ui/page/root/main_page.go index 4ae6557a7..db9910e74 100644 --- a/ui/page/root/main_page.go +++ b/ui/page/root/main_page.go @@ -82,10 +82,10 @@ type SingleWalletMasterPage struct { func NewSingleWalletMasterPage(l *load.Load, wallet sharedW.Asset, showNavigationFunc func()) *SingleWalletMasterPage { swmp := &SingleWalletMasterPage{ Load: l, - MasterPage: app.NewMasterPage(MainPageID), - selectedWallet: wallet, + MasterPage: app.NewMasterPage(MainPageID, info.NewInfoPage(l, wallet)), checkBox: l.Theme.CheckBox(new(widget.Bool), values.String(values.StrAwareOfRisk)), showNavigationFunc: showNavigationFunc, + selectedWallet: wallet, } swmp.activeTab = make(map[string]string) @@ -262,10 +262,6 @@ func (swmp *SingleWalletMasterPage) OnCurrencyChanged() { // displayed. // Part of the load.Page interface. func (swmp *SingleWalletMasterPage) HandleUserInteractions() { - if swmp.CurrentPage() != nil { - swmp.CurrentPage().HandleUserInteractions() - } - if swmp.refreshExchangeRateBtn.Clicked() { go swmp.fetchExchangeRate() } @@ -332,6 +328,8 @@ func (swmp *SingleWalletMasterPage) HandleUserInteractions() { swmp.isBalanceHidden = !swmp.isBalanceHidden swmp.selectedWallet.SetBoolConfigValueForKey(sharedW.HideBalanceConfigKey, swmp.isBalanceHidden) } + + swmp.CurrentPage().HandleUserInteractions() } // KeysToHandle returns an expression that describes a set of key combinations diff --git a/ui/page/root/overview_page.go b/ui/page/root/overview_page.go index 9d895640a..c3164cafd 100644 --- a/ui/page/root/overview_page.go +++ b/ui/page/root/overview_page.go @@ -203,7 +203,6 @@ func (pg *OverviewPage) OnNavigatedTo() { } pg.listenForMixerNotifications() // listeners are stopped in OnNavigatedFrom(). - } // HandleUserInteractions is called just before Layout() to determine diff --git a/ui/page/root/trade_page.go b/ui/page/root/trade_page.go index e2af2cd7a..0cc0aa764 100644 --- a/ui/page/root/trade_page.go +++ b/ui/page/root/trade_page.go @@ -38,7 +38,7 @@ type TradePage struct { func NewTradePage(l *load.Load) *TradePage { pg := &TradePage{ Load: l, - MasterPage: app.NewMasterPage(TradePageID), + MasterPage: app.NewMasterPage(TradePageID, dcrdex.NewDEXPage(l)), shadowBox: l.Theme.Shadow(), scrollContainer: &widget.List{ @@ -73,11 +73,7 @@ func (pg *TradePage) ID() string { // the page is displayed. // Part of the load.Page interface. func (pg *TradePage) OnNavigatedTo() { - if activeTab := pg.CurrentPage(); activeTab != nil { - activeTab.OnNavigatedTo() - } else { - pg.Display(dcrdex.NewDEXPage(pg.Load)) - } + pg.CurrentPage().OnNavigatedTo() } // HandleUserInteractions is called just before Layout() to determine @@ -86,16 +82,15 @@ func (pg *TradePage) OnNavigatedTo() { // displayed. // Part of the load.Page interface. func (pg *TradePage) HandleUserInteractions() { - if activeTab := pg.CurrentPage(); activeTab != nil { - activeTab.HandleUserInteractions() + if pg.tab.Changed() { + if pg.tab.SelectedIndex() == 1 { + pg.Display(exchange.NewCreateOrderPage(pg.Load)) + } else if pg.CurrentPageID() != dcrdex.DCRDEXPageID { + pg.Display(dcrdex.NewDEXPage(pg.Load)) + } } - if pg.tab.SelectedIndex() == 0 { - pg.Display(dcrdex.NewDEXPage(pg.Load)) - } - if pg.tab.SelectedIndex() == 1 { - pg.Display(exchange.NewCreateOrderPage(pg.Load)) - } + pg.CurrentPage().HandleUserInteractions() } // OnNavigatedFrom is called when the page is about to be removed from @@ -106,9 +101,7 @@ func (pg *TradePage) HandleUserInteractions() { // components unless they'll be recreated in the OnNavigatedTo() method. // Part of the load.Page interface. func (pg *TradePage) OnNavigatedFrom() { - if activeTab := pg.CurrentPage(); activeTab != nil { - activeTab.OnNavigatedFrom() - } + pg.CurrentPage().OnNavigatedFrom() } // Layout draws the page UI components into the provided layout context