Skip to content

Commit 86b2ac7

Browse files
committed
MOBILE-4842 menu: Use signals on main menu
1 parent f8a06a6 commit 86b2ac7

File tree

3 files changed

+44
-42
lines changed

3 files changed

+44
-42
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@if ((alwaysShow || (isMainScreen && menuPage?.tabsPlacement === 'bottom')) && siteInfo) {
1+
@if ((alwaysShow || (isMainScreen && menuPage?.tabsPlacement() === 'bottom')) && siteInfo) {
22
<core-user-avatar [site]="siteInfo" class="core-bar-button-image clickable" [linkProfile]="false"
33
(ariaButtonClick)="openUserMenu($event)" [attr.aria-label]="'core.user.useraccount' | translate" />
44
}

src/core/features/mainmenu/pages/menu/menu.html

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
<ion-tabs #mainTabs [hidden]="!showTabs" [class]="'placement-' + tabsPlacement"
2-
[class.tabshidden]="!isMainScreen && tabsPlacement === 'bottom' && hiddenAnimationFinished()" (ionTabsDidChange)="tabChanged($event)">
3-
<ion-tab-bar [slot]="tabsPlacement === 'side' ? 'top' : 'bottom'" class="mainmenu-tabs"
1+
<ion-tabs #mainTabs [hidden]="!showTabs" [class]="'placement-' + tabsPlacement()" (ionTabsDidChange)="tabChanged($event)"
2+
[class.tabshidden]="hiddenAnimationFinished()">
3+
<ion-tab-bar [slot]="tabsPlacement() === 'side' ? 'top' : 'bottom'" class="mainmenu-tabs"
44
[class.slide-in-bottom-animation]="visibility() === 'visible'" [class.slide-out-bottom-animation]="visibility() === 'hidden'">
5-
<core-loading [hideUntil]="loaded" [placeholderType]="tabsPlacement === 'bottom' ? 'rowwrap' : 'column'"
5+
<core-loading [hideUntil]="loaded()" [placeholderType]="tabsPlacement() === 'bottom' ? 'rowwrap' : 'column'"
66
[placeholderLimit]="loadingTabsLength" />
7-
@if (loaded && tabsPlacement === 'side') {
7+
8+
@if (loaded() && tabsPlacement() === 'side') {
89
<core-user-menu-button [alwaysShow]="true" />
910
}
1011

1112
<ion-tab-button *ngFor="let tab of tabs" (keydown)="tabAction.keyDown(tab.page, $event)" (keyup)="tabAction.keyUp(tab.page, $event)"
12-
[hidden]="!loaded && tab.hide" [tab]="tab.page" [disabled]="tab.hide" layout="label-hide" class="{{tab.class}}"
13+
[hidden]="!loaded() && tab.hide" [tab]="tab.page" [disabled]="tab.hide" layout="label-hide" class="{{tab.class}}"
1314
[selected]="tab.page === selectedTab" [tabindex]="selectedTab === tab.page ? 0 : -1" [attr.aria-controls]="tab.id">
1415
<ion-icon class="core-tab-icon" [name]="tab.icon" aria-hidden="true" />
1516
<ion-label aria-hidden="true">{{ tab.title | translate }}</ion-label>
@@ -25,7 +26,7 @@
2526
</ion-tab-button>
2627

2728
<ion-tab-button (keydown)="tabAction.keyDown(morePageName, $event)" (keyup)="tabAction.keyUp(morePageName, $event)"
28-
[hidden]="!loaded" [tab]="morePageName" layout="label-hide" [tabindex]="selectedTab === morePageName ? 0 : -1"
29+
[hidden]="!loaded()" [tab]="morePageName" layout="label-hide" [tabindex]="selectedTab === morePageName ? 0 : -1"
2930
[attr.aria-controls]="morePageName">
3031
<ion-icon class="core-tab-icon" name="ellipsis-horizontal" aria-hidden="true" />
3132
<ion-label aria-hidden="true">{{ 'core.more' | translate }}</ion-label>

src/core/features/mainmenu/pages/menu/menu.ts

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import { Component, OnInit, OnDestroy, effect, viewChild, signal, ElementRef, inject } from '@angular/core';
15+
import { Component, OnInit, OnDestroy, effect, viewChild, signal, ElementRef, inject, computed } from '@angular/core';
1616
import { IonTabs } from '@ionic/angular';
1717
import { BackButtonEvent } from '@ionic/core';
1818
import { Subscription } from 'rxjs';
@@ -59,17 +59,28 @@ import { CoreKeyboard } from '@singletons/keyboard';
5959
})
6060
export default class CoreMainMenuPage implements OnInit, OnDestroy {
6161

62+
readonly tabsPlacement = signal<CoreMainMenuPlacement>(CoreMainMenuPlacement.BOTTOM);
63+
readonly isMainScreen = signal(false);
64+
readonly visibility = computed(() => {
65+
const tabsPlacement = this.tabsPlacement();
66+
const isMainScreen = this.isMainScreen();
67+
68+
const visibility = tabsPlacement === CoreMainMenuPlacement.SIDE
69+
? ''
70+
: (isMainScreen ? 'visible' : 'hidden');
71+
72+
return visibility;
73+
});
74+
75+
readonly hiddenAnimationFinished = signal(false);
76+
6277
tabs: CoreMainMenuHandlerToDisplay[] = [];
6378
allHandlers?: CoreMainMenuHandlerToDisplay[];
64-
loaded = false;
79+
readonly loaded = signal(false);
6580
showTabs = false;
66-
tabsPlacement: CoreMainMenuPlacement = CoreMainMenuPlacement.BOTTOM;
6781
morePageName = MAIN_MENU_MORE_PAGE_NAME;
6882
selectedTab?: string;
69-
isMainScreen = false;
7083
moreBadge = false;
71-
readonly visibility = signal('hidden');
72-
readonly hiddenAnimationFinished = signal(true);
7384
loadingTabsLength = this.getLoadingTabsLength();
7485

7586
protected subscription?: Subscription;
@@ -96,8 +107,7 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
96107
this.navSubscription = Router.events
97108
.pipe(filter(event => event instanceof NavigationEnd))
98109
.subscribe(() => {
99-
this.isMainScreen = !this.mainTabs().outlet?.canGoBack();
100-
this.updateVisibility();
110+
this.isMainScreen.set(!this.mainTabs().outlet?.canGoBack());
101111
});
102112

103113
if (CorePlatform.isIOS()) {
@@ -115,6 +125,12 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
115125
}
116126
});
117127
}
128+
129+
effect(() => {
130+
this.visibility();
131+
// Tabs changed visibility, reset hidden animation.
132+
this.hiddenAnimationFinished.set(false);
133+
});
118134
}
119135

120136
/**
@@ -125,8 +141,7 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
125141

126142
this.initAfterLoginNavigations();
127143

128-
this.isMainScreen = !this.mainTabs().outlet?.canGoBack();
129-
this.updateVisibility();
144+
this.isMainScreen.set(!this.mainTabs().outlet?.canGoBack());
130145

131146
this.subscription = CoreMainMenuDelegate.getHandlersObservable().subscribe((handlers) => {
132147
const previousHandlers = this.allHandlers;
@@ -150,7 +165,8 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
150165

151166
const tabBar = this.hostElement.querySelector('ion-tab-bar');
152167
tabBar?.addEventListener('animationend', (ev) => {
153-
if (ev.animationName == 'slideOutBottom') {
168+
if (ev.animationName === 'slideOutBottom' &&
169+
!this.isMainScreen() && this.tabsPlacement() === CoreMainMenuPlacement.BOTTOM) {
154170
this.hiddenAnimationFinished.set(true);
155171
}
156172

@@ -167,8 +183,8 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
167183
if (!this.allHandlers) {
168184
return;
169185
}
170-
this.tabsPlacement = CoreMainMenu.getTabPlacement();
171-
this.updateVisibility();
186+
187+
this.tabsPlacement.set(CoreMainMenu.getTabPlacement());
172188

173189
this.loadingTabsLength = this.getLoadingTabsLength();
174190

@@ -207,9 +223,9 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
207223
}
208224

209225
const mainMenuTab = CoreNavigator.getCurrentMainMenuTab();
210-
this.loaded = CoreMainMenuDelegate.areHandlersLoaded();
226+
this.loaded.set(CoreMainMenuDelegate.areHandlersLoaded());
211227

212-
if (this.loaded && (!mainMenuTab || removedHandlersPages.includes(mainMenuTab))) {
228+
if (this.loaded() && (!mainMenuTab || removedHandlersPages.includes(mainMenuTab))) {
213229
// No tab selected or handler no longer available, select the first one.
214230
await CoreWait.nextTick();
215231

@@ -231,8 +247,9 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
231247
* @returns The total number of loading tabs to display.
232248
*/
233249
protected getLoadingTabsLength(): number {
234-
return CoreMainMenu.getNumItems() +
235-
(this.tabsPlacement === CoreMainMenuPlacement.BOTTOM ? 1 : 2); // +1 for the "More" tab and user button.
250+
const isBottomPlacement = this.tabsPlacement() === CoreMainMenuPlacement.BOTTOM;
251+
252+
return CoreMainMenu.getNumItems() + (isBottomPlacement ? 1 : 2); // +1 for the "More" tab and user button.
236253
}
237254

238255
/**
@@ -307,22 +324,6 @@ export default class CoreMainMenuPage implements OnInit, OnDestroy {
307324
this.selectHistory.push(event.tab);
308325
}
309326

310-
/**
311-
* Update menu visibility.
312-
*/
313-
protected updateVisibility(): void {
314-
const visibility = this.tabsPlacement === CoreMainMenuPlacement.SIDE
315-
? ''
316-
: (this.isMainScreen ? 'visible' : 'hidden');
317-
318-
if (visibility === this.visibility()) {
319-
return;
320-
}
321-
322-
this.hiddenAnimationFinished.set(false);
323-
this.visibility.set(visibility);
324-
}
325-
326327
/**
327328
* Back button clicked.
328329
*
@@ -401,7 +402,7 @@ class CoreMainMenuRoleTab extends CoreAriaRoleTab<CoreMainMenuPage> {
401402
* @inheritdoc
402403
*/
403404
isHorizontal(): boolean {
404-
return this.componentInstance.tabsPlacement === CoreMainMenuPlacement.BOTTOM;
405+
return this.componentInstance.tabsPlacement() === CoreMainMenuPlacement.BOTTOM;
405406
}
406407

407408
/**

0 commit comments

Comments
 (0)