MOBILE-2903 menu: Move menu to side on tablet
This commit is contained in:
		
							parent
							
								
									19e0cf59e5
								
							
						
					
					
						commit
						809753aac1
					
				| @ -7,7 +7,7 @@ | |||||||
|         </span> |         </span> | ||||||
|     </div> |     </div> | ||||||
| </div> | </div> | ||||||
| <div #originalTabs> | <div #originalTabs class="tabcontent"> | ||||||
|     <ng-content></ng-content> |     <ng-content></ng-content> | ||||||
| </div> | </div> | ||||||
| <div #portal tab-portal></div> | <div #portal tab-portal></div> | ||||||
|  | |||||||
| @ -1,3 +1,5 @@ | |||||||
|  | $core-sidetab-size: 60px !default; | ||||||
|  | 
 | ||||||
| ion-app.app-root core-ion-tabs { | ion-app.app-root core-ion-tabs { | ||||||
|     .tabbar { |     .tabbar { | ||||||
|         z-index: 101; // For some reason, the regular z-index isn't enough with our tabs, use a higher one. |         z-index: 101; // For some reason, the regular z-index isn't enough with our tabs, use a higher one. | ||||||
| @ -21,6 +23,31 @@ ion-app.app-root core-ion-tabs { | |||||||
|     .tab-badge.badge { |     .tab-badge.badge { | ||||||
|         background-color: $ion-tabs-badge-color; |         background-color: $ion-tabs-badge-color; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     &[tabsplacement="side"] { | ||||||
|  |         .tabbar { | ||||||
|  |             @include float(start); | ||||||
|  |             width: $core-sidetab-size; | ||||||
|  |             height: 100%; | ||||||
|  |             flex-direction: column; | ||||||
|  |             .tab-button { | ||||||
|  |                 width: 100%; | ||||||
|  |                 .tab-badge.badge { | ||||||
|  |                     @include position(calc(50% - 30px), 2px, null, null); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .tabcontent { | ||||||
|  |             width: calc(100% - #{($core-sidetab-size)}); | ||||||
|  |             position: absolute; | ||||||
|  |             @include position(0, 0, 0, 0); | ||||||
|  |             core-ion-tab { | ||||||
|  |                 @include position(0, 0, 0, $core-sidetab-size); | ||||||
|  |                 position: relative; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ion-app.app-root.ios core-ion-tabs .core-ion-tabs-loading { | ion-app.app-root.ios core-ion-tabs .core-ion-tabs-loading { | ||||||
|  | |||||||
| @ -223,10 +223,6 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy { | |||||||
|      * @param {CoreIonTabComponent} tab The tab to remove. |      * @param {CoreIonTabComponent} tab The tab to remove. | ||||||
|      */ |      */ | ||||||
|     remove(tab: CoreIonTabComponent): void { |     remove(tab: CoreIonTabComponent): void { | ||||||
|         if (tab.isSelected) { |  | ||||||
|             // TODO: If selected we should move this navigation to the phantom tab.
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // First search in the list of initialized tabs.
 |         // First search in the list of initialized tabs.
 | ||||||
|         let index = this._tabs.indexOf(tab); |         let index = this._tabs.indexOf(tab); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| <core-ion-tabs #mainTabs [hidden]="!showTabs" [loaded]="loaded" tabsPlacement="bottom" tabsLayout="title-hide"> | <core-ion-tabs #mainTabs [hidden]="!showTabs" [loaded]="loaded" tabsLayout="title-hide" [attr.tabsPlacement]="tabsPlacement"> | ||||||
|     <core-ion-tab [enabled]="false" [show]="false" [root]="redirectPage" [rootParams]="redirectParams"></core-ion-tab> |     <core-ion-tab [enabled]="false" [show]="false" [root]="redirectPage" [rootParams]="redirectParams"></core-ion-tab> | ||||||
|     <core-ion-tab *ngFor="let tab of tabs" [root]="tab.page" [rootParams]="tab.pageParams" [tabTitle]="tab.title | translate" [tabIcon]="tab.icon" [tabBadge]="tab.badge" class="{{tab.class}}"></core-ion-tab> |     <core-ion-tab *ngFor="let tab of tabs" [root]="tab.page" [rootParams]="tab.pageParams" [tabTitle]="tab.title | translate" [tabIcon]="tab.icon" [tabBadge]="tab.badge" class="{{tab.class}}" [enabled]="!tab.hide" [show]="!tab.hide"></core-ion-tab> | ||||||
|     <core-ion-tab root="CoreMainMenuMorePage" [tabTitle]="'core.more' | translate" tabIcon="more"></core-ion-tab> |     <core-ion-tab root="CoreMainMenuMorePage" [tabTitle]="'core.more' | translate" tabIcon="more"></core-ion-tab> | ||||||
| </core-ion-tabs> | </core-ion-tabs> | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ export class CoreMainMenuPage implements OnDestroy { | |||||||
|     redirectPage: string; |     redirectPage: string; | ||||||
|     redirectParams: any; |     redirectParams: any; | ||||||
|     showTabs = false; |     showTabs = false; | ||||||
|  |     tabsPlacement = 'bottom'; | ||||||
| 
 | 
 | ||||||
|     protected subscription; |     protected subscription; | ||||||
|     protected redirectObs: any; |     protected redirectObs: any; | ||||||
| @ -105,6 +106,8 @@ export class CoreMainMenuPage implements OnDestroy { | |||||||
|      */ |      */ | ||||||
|     initHandlers(): void { |     initHandlers(): void { | ||||||
|         if (this.allHandlers) { |         if (this.allHandlers) { | ||||||
|  |             this.tabsPlacement = this.mainMenuProvider.getTabPlacement(this.navCtrl); | ||||||
|  | 
 | ||||||
|             const handlers = this.allHandlers.slice(0, this.mainMenuProvider.getNumItems()); // Get main handlers.
 |             const handlers = this.allHandlers.slice(0, this.mainMenuProvider.getNumItems()); // Get main handlers.
 | ||||||
| 
 | 
 | ||||||
|             // Re-build the list of tabs. If a handler is already in the list, use existing object to prevent re-creating the tab.
 |             // Re-build the list of tabs. If a handler is already in the list, use existing object to prevent re-creating the tab.
 | ||||||
| @ -118,9 +121,32 @@ export class CoreMainMenuPage implements OnDestroy { | |||||||
|                     return tab.title == handler.title && tab.icon == handler.icon; |                     return tab.title == handler.title && tab.icon == handler.icon; | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |                 tab ? tab.hide = false : null; | ||||||
|  |                 handler.hide = false; | ||||||
|  | 
 | ||||||
|                 newTabs.push(tab || handler); |                 newTabs.push(tab || handler); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             // Maintain tab in phantom mode in case is not visible.
 | ||||||
|  |             const selectedTab = this.mainTabs.getSelected(); | ||||||
|  |             if (selectedTab) { | ||||||
|  |                 const oldTab = this.tabs.find((tab) => { | ||||||
|  |                     return tab.page == selectedTab.root && tab.icon == selectedTab.tabIcon; | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 if (oldTab) { | ||||||
|  |                     // Check if the selected handler is visible.
 | ||||||
|  |                     const isVisible = newTabs.some((newTab) => { | ||||||
|  |                         return oldTab.title == newTab.title && oldTab.icon == newTab.icon; | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|  |                     if (!isVisible) { | ||||||
|  |                         oldTab.hide = true; | ||||||
|  |                         newTabs.push(oldTab); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             this.tabs = newTabs; |             this.tabs = newTabs; | ||||||
| 
 | 
 | ||||||
|             // Sort them by priority so new handlers are in the right position.
 |             // Sort them by priority so new handlers are in the right position.
 | ||||||
|  | |||||||
| @ -111,6 +111,12 @@ export interface CoreMainMenuHandlerToDisplay extends CoreMainMenuHandlerData { | |||||||
|      * @type {number} |      * @type {number} | ||||||
|      */ |      */ | ||||||
|     priority?: number; |     priority?: number; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hide tab. Used then resizing. | ||||||
|  |      * @type {[type]} | ||||||
|  |      */ | ||||||
|  |     hide?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ | |||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Injectable } from '@angular/core'; | import { Injectable } from '@angular/core'; | ||||||
|  | import { NavController } from 'ionic-angular'; | ||||||
| import { CoreLangProvider } from '@providers/lang'; | import { CoreLangProvider } from '@providers/lang'; | ||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreConfigConstants } from '../../../configconstants'; | import { CoreConfigConstants } from '../../../configconstants'; | ||||||
| @ -53,8 +54,11 @@ export interface CoreMainMenuCustomItem { | |||||||
| export class CoreMainMenuProvider { | export class CoreMainMenuProvider { | ||||||
|     static NUM_MAIN_HANDLERS = 4; |     static NUM_MAIN_HANDLERS = 4; | ||||||
|     static ITEM_MIN_WIDTH = 72; // Min with of every item, based on 5 items on a 360 pixel wide screen.
 |     static ITEM_MIN_WIDTH = 72; // Min with of every item, based on 5 items on a 360 pixel wide screen.
 | ||||||
|  |     protected tablet = false; | ||||||
| 
 | 
 | ||||||
|     constructor(private langProvider: CoreLangProvider, private sitesProvider: CoreSitesProvider) { } |     constructor(private langProvider: CoreLangProvider, private sitesProvider: CoreSitesProvider) { | ||||||
|  |         this.tablet = window && window.innerWidth && window.innerWidth >= 576 && window.innerHeight >= 576; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Get a list of custom menu items for a certain site. |      * Get a list of custom menu items for a certain site. | ||||||
| @ -169,7 +173,12 @@ export class CoreMainMenuProvider { | |||||||
|         if (window && window.innerWidth) { |         if (window && window.innerWidth) { | ||||||
|             let numElements; |             let numElements; | ||||||
| 
 | 
 | ||||||
|  |             if (this.tablet) { | ||||||
|  |                 // Tablet, menu will be displayed vertically.
 | ||||||
|  |                 numElements = Math.floor(window.innerHeight / CoreMainMenuProvider.ITEM_MIN_WIDTH); | ||||||
|  |             } else { | ||||||
|                 numElements = Math.floor(window.innerWidth / CoreMainMenuProvider.ITEM_MIN_WIDTH); |                 numElements = Math.floor(window.innerWidth / CoreMainMenuProvider.ITEM_MIN_WIDTH); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             // Set a mínimum elements to show and skip more button.
 |             // Set a mínimum elements to show and skip more button.
 | ||||||
|             return numElements > 1 ? numElements - 1 : 1; |             return numElements > 1 ? numElements - 1 : 1; | ||||||
| @ -177,4 +186,25 @@ export class CoreMainMenuProvider { | |||||||
| 
 | 
 | ||||||
|         return CoreMainMenuProvider.NUM_MAIN_HANDLERS; |         return CoreMainMenuProvider.NUM_MAIN_HANDLERS; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get tabs placement depending on the device size. | ||||||
|  |      * | ||||||
|  |      * @param  {NavController} navCtrl  NavController to resize the content. | ||||||
|  |      * @return {string}                Tabs placement including side value. | ||||||
|  |      */ | ||||||
|  |     getTabPlacement(navCtrl: NavController): string { | ||||||
|  |         const tablet = window && window.innerWidth && window.innerWidth >= 576 && window.innerHeight >= 576; | ||||||
|  | 
 | ||||||
|  |         if (tablet != this.tablet) { | ||||||
|  |             this.tablet = tablet; | ||||||
|  | 
 | ||||||
|  |             // Resize so content margins can be updated.
 | ||||||
|  |             setTimeout(() => { | ||||||
|  |                 navCtrl.resize(); | ||||||
|  |             }, 500); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return tablet ? 'side' : 'bottom'; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user