MOBILE-2735 tabs: Ask confirm when going to root of current tab
This commit is contained in:
		
							parent
							
								
									08322a299d
								
							
						
					
					
						commit
						dc5b9875b3
					
				@ -1260,6 +1260,8 @@
 | 
				
			|||||||
  "core.completion-alt-manual-y-override": "completion",
 | 
					  "core.completion-alt-manual-y-override": "completion",
 | 
				
			||||||
  "core.confirmcanceledit": "local_moodlemobileapp",
 | 
					  "core.confirmcanceledit": "local_moodlemobileapp",
 | 
				
			||||||
  "core.confirmdeletefile": "repository",
 | 
					  "core.confirmdeletefile": "repository",
 | 
				
			||||||
 | 
					  "core.confirmgotabroot": "local_moodlemobileapp",
 | 
				
			||||||
 | 
					  "core.confirmgotabrootdefault": "local_moodlemobileapp",
 | 
				
			||||||
  "core.confirmloss": "local_moodlemobileapp",
 | 
					  "core.confirmloss": "local_moodlemobileapp",
 | 
				
			||||||
  "core.confirmopeninbrowser": "local_moodlemobileapp",
 | 
					  "core.confirmopeninbrowser": "local_moodlemobileapp",
 | 
				
			||||||
  "core.considereddigitalminor": "moodle",
 | 
					  "core.considereddigitalminor": "moodle",
 | 
				
			||||||
 | 
				
			|||||||
@ -1260,6 +1260,8 @@
 | 
				
			|||||||
    "core.completion-alt-manual-y-override": "Completed: {{$a.modname}} (set by {{$a.overrideuser}}). Select to mark as not complete.",
 | 
					    "core.completion-alt-manual-y-override": "Completed: {{$a.modname}} (set by {{$a.overrideuser}}). Select to mark as not complete.",
 | 
				
			||||||
    "core.confirmcanceledit": "Are you sure you want to leave this page? All changes will be lost.",
 | 
					    "core.confirmcanceledit": "Are you sure you want to leave this page? All changes will be lost.",
 | 
				
			||||||
    "core.confirmdeletefile": "Are you sure you want to delete this file?",
 | 
					    "core.confirmdeletefile": "Are you sure you want to delete this file?",
 | 
				
			||||||
 | 
					    "core.confirmgotabroot": "Are you sure you want to go back to {{name}}?",
 | 
				
			||||||
 | 
					    "core.confirmgotabrootdefault": "Are you sure you want to go to the initial page of the current tab?",
 | 
				
			||||||
    "core.confirmloss": "Are you sure? All changes will be lost.",
 | 
					    "core.confirmloss": "Are you sure? All changes will be lost.",
 | 
				
			||||||
    "core.confirmopeninbrowser": "Do you want to open it in a web browser?",
 | 
					    "core.confirmopeninbrowser": "Do you want to open it in a web browser?",
 | 
				
			||||||
    "core.considereddigitalminor": "You are too young to create an account on this site.",
 | 
					    "core.considereddigitalminor": "You are too young to create an account on this site.",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<div class="tabbar" role="tablist" #tabbar [hidden]="hidden">
 | 
					<div class="tabbar" role="tablist" #tabbar [hidden]="hidden">
 | 
				
			||||||
    <a [hidden]="_loaded === false" *ngFor="let t of _tabs" [tab]="t" class="tab-button" role="tab" href="#" (ionSelect)="select(t)" [attr.aria-hidden]="!t.show" [attr.aria-label]="t.tabTitle || ''" [title]="t.tabTitle || ''"></a>
 | 
					    <a [hidden]="_loaded === false" *ngFor="let t of _tabs" [tab]="t" class="tab-button" role="tab" href="#" (ionSelect)="select(t, undefined, undefined, true)" [attr.aria-hidden]="!t.show" [attr.aria-label]="t.tabTitle || ''" [title]="t.tabTitle || ''"></a>
 | 
				
			||||||
    <div class="tab-highlight"></div>
 | 
					    <div class="tab-highlight"></div>
 | 
				
			||||||
    <div *ngIf="_loaded === false" class="core-ion-tabs-loading">
 | 
					    <div *ngIf="_loaded === false" class="core-ion-tabs-loading">
 | 
				
			||||||
        <span class="core-ion-tabs-loading-spinner">
 | 
					        <span class="core-ion-tabs-loading-spinner">
 | 
				
			||||||
 | 
				
			|||||||
@ -20,11 +20,14 @@ import {
 | 
				
			|||||||
import { CoreIonTabComponent } from './ion-tab';
 | 
					import { CoreIonTabComponent } from './ion-tab';
 | 
				
			||||||
import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils';
 | 
					import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils';
 | 
				
			||||||
import { CoreAppProvider } from '@providers/app';
 | 
					import { CoreAppProvider } from '@providers/app';
 | 
				
			||||||
 | 
					import { CoreDomUtilsProvider } from '@providers/utils/dom';
 | 
				
			||||||
 | 
					import { TranslateService } from '@ngx-translate/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Equivalent to ion-tabs. It has 2 improvements:
 | 
					 * Equivalent to ion-tabs. It has several improvements:
 | 
				
			||||||
 *     - If a core-ion-tab is added or removed, it will be reflected in the tab bar in the right position.
 | 
					 *     - If a core-ion-tab is added or removed, it will be reflected in the tab bar in the right position.
 | 
				
			||||||
 *     - It supports a loaded input to tell when are the tabs ready.
 | 
					 *     - It supports a loaded input to tell when are the tabs ready.
 | 
				
			||||||
 | 
					 *     - When the user clicks the tab again to go to root, a confirm modal is shown.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
    selector: 'core-ion-tabs',
 | 
					    selector: 'core-ion-tabs',
 | 
				
			||||||
@ -73,7 +76,8 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    constructor(protected utils: CoreUtilsProvider, protected appProvider: CoreAppProvider, @Optional() parent: NavController,
 | 
					    constructor(protected utils: CoreUtilsProvider, protected appProvider: CoreAppProvider, @Optional() parent: NavController,
 | 
				
			||||||
            @Optional() viewCtrl: ViewController, _app: App, config: Config, elementRef: ElementRef, _plt: Platform,
 | 
					            @Optional() viewCtrl: ViewController, _app: App, config: Config, elementRef: ElementRef, _plt: Platform,
 | 
				
			||||||
            renderer: Renderer, _linker: DeepLinker, keyboard?: Keyboard) {
 | 
					            renderer: Renderer, _linker: DeepLinker, protected domUtils: CoreDomUtilsProvider,
 | 
				
			||||||
 | 
					            protected translate: TranslateService, keyboard?: Keyboard) {
 | 
				
			||||||
        super(parent, viewCtrl, _app, config, elementRef, _plt, renderer, _linker, keyboard);
 | 
					        super(parent, viewCtrl, _app, config, elementRef, _plt, renderer, _linker, keyboard);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -272,13 +276,25 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
 | 
					     * @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
 | 
				
			||||||
     * @param {NavOptions} Nav options.
 | 
					     * @param {NavOptions} Nav options.
 | 
				
			||||||
     * @param {boolean} [fromUrl=true] Whether to load from a URL.
 | 
					     * @param {boolean} [fromUrl] Whether to load from a URL.
 | 
				
			||||||
 | 
					     * @param {boolean} [manualClick] Whether the user manually clicked the tab.
 | 
				
			||||||
     * @return {Promise<any>} Promise resolved when selected.
 | 
					     * @return {Promise<any>} Promise resolved when selected.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    select(tabOrIndex: number | Tab, opts: NavOptions = {}, fromUrl: boolean = false): Promise<any> {
 | 
					    select(tabOrIndex: number | Tab, opts: NavOptions = {}, fromUrl?: boolean, manualClick?: boolean): Promise<any> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this.initialized) {
 | 
					        if (this.initialized) {
 | 
				
			||||||
            // Tabs have been initialized, select the tab.
 | 
					            // Tabs have been initialized, select the tab.
 | 
				
			||||||
 | 
					            if (manualClick) {
 | 
				
			||||||
 | 
					                // If we'll go to the root of the current tab, ask the user to confirm first.
 | 
				
			||||||
 | 
					                const tab = typeof tabOrIndex == 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return this.confirmGoToRoot(tab).then(() => {
 | 
				
			||||||
 | 
					                    return super.select(tabOrIndex, opts, fromUrl);
 | 
				
			||||||
 | 
					                }, () => {
 | 
				
			||||||
 | 
					                    // User cancelled.
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return super.select(tabOrIndex, opts, fromUrl);
 | 
					            return super.select(tabOrIndex, opts, fromUrl);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // Tabs not initialized yet. Mark it as "selectedIndex" input so it's treated when the tabs are initialized.
 | 
					            // Tabs not initialized yet. Mark it as "selectedIndex" input so it's treated when the tabs are initialized.
 | 
				
			||||||
@ -305,12 +321,17 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy {
 | 
				
			|||||||
        if (this.initialized) {
 | 
					        if (this.initialized) {
 | 
				
			||||||
            const tab = this.getByIndex(index);
 | 
					            const tab = this.getByIndex(index);
 | 
				
			||||||
            if (tab) {
 | 
					            if (tab) {
 | 
				
			||||||
                return tab.goToRoot({animate: false, updateUrl: true, isNavRoot: true}).then(() => {
 | 
					                return this.confirmGoToRoot(tab).then(() => {
 | 
				
			||||||
 | 
					                    // User confirmed, go to root.
 | 
				
			||||||
 | 
					                    return tab.goToRoot({animate: tab.isSelected, updateUrl: true, isNavRoot: true}).then(() => {
 | 
				
			||||||
                        // Tab not previously selected. Select it after going to root.
 | 
					                        // Tab not previously selected. Select it after going to root.
 | 
				
			||||||
                        if (!tab.isSelected) {
 | 
					                        if (!tab.isSelected) {
 | 
				
			||||||
                            return this.select(tab, {animate: false, updateUrl: true, isNavRoot: true});
 | 
					                            return this.select(tab, {animate: false, updateUrl: true, isNavRoot: true});
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					                }, () => {
 | 
				
			||||||
 | 
					                    // User cancelled.
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Not found.
 | 
					            // Not found.
 | 
				
			||||||
@ -349,4 +370,23 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy {
 | 
				
			|||||||
        // Unregister the custom back button action for this page
 | 
					        // Unregister the custom back button action for this page
 | 
				
			||||||
        this.unregisterBackButtonAction && this.unregisterBackButtonAction();
 | 
					        this.unregisterBackButtonAction && this.unregisterBackButtonAction();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Confirm if the user wants to go to the root of the current tab.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {Tab} tab Tab to go to root.
 | 
				
			||||||
 | 
					     * @return {Promise<any>} Promise resolved when confirmed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    confirmGoToRoot(tab: Tab): Promise<any> {
 | 
				
			||||||
 | 
					        if (!tab || !tab.isSelected || (tab.getActive() && tab.getActive().isFirst())) {
 | 
				
			||||||
 | 
					            // Tab not selected or is already at root, no need to confirm.
 | 
				
			||||||
 | 
					            return Promise.resolve();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (tab.tabTitle) {
 | 
				
			||||||
 | 
					                return this.domUtils.showConfirm(this.translate.instant('core.confirmgotabroot', {name: tab.tabTitle}));
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                return this.domUtils.showConfirm(this.translate.instant('core.confirmgotabrootdefault'));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,8 @@
 | 
				
			|||||||
    "completion-alt-manual-y-override": "Completed: {{$a.modname}} (set by {{$a.overrideuser}}). Select to mark as not complete.",
 | 
					    "completion-alt-manual-y-override": "Completed: {{$a.modname}} (set by {{$a.overrideuser}}). Select to mark as not complete.",
 | 
				
			||||||
    "confirmcanceledit": "Are you sure you want to leave this page? All changes will be lost.",
 | 
					    "confirmcanceledit": "Are you sure you want to leave this page? All changes will be lost.",
 | 
				
			||||||
    "confirmdeletefile": "Are you sure you want to delete this file?",
 | 
					    "confirmdeletefile": "Are you sure you want to delete this file?",
 | 
				
			||||||
 | 
					    "confirmgotabroot": "Are you sure you want to go back to {{name}}?",
 | 
				
			||||||
 | 
					    "confirmgotabrootdefault": "Are you sure you want to go to the initial page of the current tab?",
 | 
				
			||||||
    "confirmloss": "Are you sure? All changes will be lost.",
 | 
					    "confirmloss": "Are you sure? All changes will be lost.",
 | 
				
			||||||
    "confirmopeninbrowser": "Do you want to open it in a web browser?",
 | 
					    "confirmopeninbrowser": "Do you want to open it in a web browser?",
 | 
				
			||||||
    "considereddigitalminor": "You are too young to create an account on this site.",
 | 
					    "considereddigitalminor": "You are too young to create an account on this site.",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user