mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +08:00
fix(clickblock): add NavOptions.minClickBlockDuration
* feat(clickblock): ability to set a minimum duration for click block * fix(clickblock): add NavOptions.minClickBlockDuration
This commit is contained in:

committed by
Justin Willis

parent
3f164237ae
commit
8ca9797c0f
@ -6,6 +6,7 @@ import { Config } from '../../config/config';
|
|||||||
import { Key } from '../../platform/key';
|
import { Key } from '../../platform/key';
|
||||||
import { Platform } from '../../platform/platform';
|
import { Platform } from '../../platform/platform';
|
||||||
import { NavParams } from '../../navigation/nav-params';
|
import { NavParams } from '../../navigation/nav-params';
|
||||||
|
import { NavOptions } from '../../navigation/nav-util';
|
||||||
import { ViewController } from '../../navigation/view-controller';
|
import { ViewController } from '../../navigation/view-controller';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +175,10 @@ export class ActionSheetCmp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dismiss(role: any): Promise<any> {
|
dismiss(role: any): Promise<any> {
|
||||||
return this._viewCtrl.dismiss(null, role);
|
const opts: NavOptions = {
|
||||||
|
minClickBlockDuration: 400
|
||||||
|
};
|
||||||
|
return this._viewCtrl.dismiss(null, role, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
@ -58,6 +58,7 @@ export class ActionSheet extends ViewController {
|
|||||||
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
|
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
|
||||||
*/
|
*/
|
||||||
present(navOptions: NavOptions = {}) {
|
present(navOptions: NavOptions = {}) {
|
||||||
|
navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
|
||||||
return this._app.present(this, navOptions);
|
return this._app.present(this, navOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import { GestureController, BlockerDelegate, BLOCK_ALL } from '../../gestures/ge
|
|||||||
import { isPresent, assert } from '../../util/util';
|
import { isPresent, assert } from '../../util/util';
|
||||||
import { Key } from '../../platform/key';
|
import { Key } from '../../platform/key';
|
||||||
import { NavParams } from '../../navigation/nav-params';
|
import { NavParams } from '../../navigation/nav-params';
|
||||||
|
import { NavOptions } from '../../navigation/nav-util';
|
||||||
import { Platform } from '../../platform/platform';
|
import { Platform } from '../../platform/platform';
|
||||||
import { ViewController } from '../../navigation/view-controller';
|
import { ViewController } from '../../navigation/view-controller';
|
||||||
|
|
||||||
@ -298,7 +299,10 @@ export class AlertCmp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dismiss(role: any): Promise<any> {
|
dismiss(role: any): Promise<any> {
|
||||||
return this._viewCtrl.dismiss(this.getValues(), role);
|
const opts: NavOptions = {
|
||||||
|
minClickBlockDuration: 400
|
||||||
|
};
|
||||||
|
return this._viewCtrl.dismiss(this.getValues(), role, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
getValues(): any {
|
getValues(): any {
|
||||||
|
@ -81,6 +81,7 @@ export class Alert extends ViewController {
|
|||||||
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
|
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
|
||||||
*/
|
*/
|
||||||
present(navOptions: NavOptions = {}) {
|
present(navOptions: NavOptions = {}) {
|
||||||
|
navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
|
||||||
return this._app.present(this, navOptions);
|
return this._app.present(this, navOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,17 +119,17 @@ export class App {
|
|||||||
* it will automatically enable the app again. It's basically a fallback incase
|
* it will automatically enable the app again. It's basically a fallback incase
|
||||||
* something goes wrong during a transition and the app wasn't re-enabled correctly.
|
* something goes wrong during a transition and the app wasn't re-enabled correctly.
|
||||||
*/
|
*/
|
||||||
setEnabled(isEnabled: boolean, duration: number = 700) {
|
setEnabled(isEnabled: boolean, duration: number = 700, minDuration: number = 0) {
|
||||||
this._disTime = (isEnabled ? 0 : Date.now() + duration);
|
this._disTime = (isEnabled ? 0 : Date.now() + duration);
|
||||||
|
|
||||||
if (this._clickBlock) {
|
if (this._clickBlock) {
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
// disable the click block if it's enabled, or the duration is tiny
|
// disable the click block if it's enabled, or the duration is tiny
|
||||||
this._clickBlock.activate(false, CLICK_BLOCK_BUFFER_IN_MILLIS);
|
this._clickBlock.activate(false, CLICK_BLOCK_BUFFER_IN_MILLIS, minDuration);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// show the click block for duration + some number
|
// show the click block for duration + some number
|
||||||
this._clickBlock.activate(true, duration + CLICK_BLOCK_BUFFER_IN_MILLIS);
|
this._clickBlock.activate(true, duration + CLICK_BLOCK_BUFFER_IN_MILLIS, minDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { Component, ComponentFactoryResolver, HostListener, Renderer, ViewChild,
|
|||||||
|
|
||||||
import { Key } from '../../platform/key';
|
import { Key } from '../../platform/key';
|
||||||
import { NavParams } from '../../navigation/nav-params';
|
import { NavParams } from '../../navigation/nav-params';
|
||||||
|
import { NavOptions } from '../../navigation/nav-util';
|
||||||
import { ViewController } from '../../navigation/view-controller';
|
import { ViewController } from '../../navigation/view-controller';
|
||||||
import { GestureController, BlockerDelegate, GESTURE_MENU_SWIPE, GESTURE_GO_BACK_SWIPE } from '../../gestures/gesture-controller';
|
import { GestureController, BlockerDelegate, GESTURE_MENU_SWIPE, GESTURE_GO_BACK_SWIPE } from '../../gestures/gesture-controller';
|
||||||
import { assert } from '../../util/util';
|
import { assert } from '../../util/util';
|
||||||
@ -78,7 +79,10 @@ export class ModalCmp {
|
|||||||
|
|
||||||
_bdClick() {
|
_bdClick() {
|
||||||
if (this._enabled && this._bdDismiss) {
|
if (this._enabled && this._bdDismiss) {
|
||||||
return this._viewCtrl.dismiss(null, 'backdrop').catch(() => {
|
const opts: NavOptions = {
|
||||||
|
minClickBlockDuration: 400
|
||||||
|
};
|
||||||
|
return this._viewCtrl.dismiss(null, 'backdrop', opts).catch(() => {
|
||||||
console.debug('Dismiss modal by clicking backdrop was cancelled');
|
console.debug('Dismiss modal by clicking backdrop was cancelled');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ export class Modal extends ViewController {
|
|||||||
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
|
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
|
||||||
*/
|
*/
|
||||||
present(navOptions: NavOptions = {}) {
|
present(navOptions: NavOptions = {}) {
|
||||||
|
navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
|
||||||
return this._app.present(this, navOptions, AppPortal.MODAL);
|
return this._app.present(this, navOptions, AppPortal.MODAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,7 +663,7 @@ export class NavControllerBase extends Ion implements NavController {
|
|||||||
if (duration > DISABLE_APP_MINIMUM_DURATION && opts.disableApp !== false) {
|
if (duration > DISABLE_APP_MINIMUM_DURATION && opts.disableApp !== false) {
|
||||||
// if this transition has a duration and this is the root transition
|
// if this transition has a duration and this is the root transition
|
||||||
// then set that the app is actively disabled
|
// then set that the app is actively disabled
|
||||||
this._app.setEnabled(false, duration + ACTIVE_TRANSITION_OFFSET);
|
this._app.setEnabled(false, duration + ACTIVE_TRANSITION_OFFSET, opts.minClickBlockDuration);
|
||||||
} else {
|
} else {
|
||||||
console.debug('transition is running but app has not been disabled');
|
console.debug('transition is running but app has not been disabled');
|
||||||
}
|
}
|
||||||
|
@ -162,6 +162,7 @@ export interface NavOptions {
|
|||||||
keyboardClose?: boolean;
|
keyboardClose?: boolean;
|
||||||
progressAnimation?: boolean;
|
progressAnimation?: boolean;
|
||||||
disableApp?: boolean;
|
disableApp?: boolean;
|
||||||
|
minClickBlockDuration?: number;
|
||||||
ev?: any;
|
ev?: any;
|
||||||
updateUrl?: boolean;
|
updateUrl?: boolean;
|
||||||
isNavRoot?: boolean;
|
isNavRoot?: boolean;
|
||||||
|
@ -167,6 +167,12 @@ export class ViewController {
|
|||||||
if (!this._nav) {
|
if (!this._nav) {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
if (this.isOverlay && !navOptions.minClickBlockDuration) {
|
||||||
|
// This is a Modal being dismissed so we need
|
||||||
|
// to add the minClickBlockDuration option
|
||||||
|
// for UIWebView
|
||||||
|
navOptions.minClickBlockDuration = 400;
|
||||||
|
}
|
||||||
this._dismissData = data;
|
this._dismissData = data;
|
||||||
this._dismissRole = role;
|
this._dismissRole = role;
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ ion-input :focus {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translate3d(0, -100%, 0) translateY(1px);
|
transform: translate3d(0, -100%, 0) translateY(1px);
|
||||||
|
|
||||||
// background: red;
|
background: red;
|
||||||
// opacity: .3;
|
opacity: .3;
|
||||||
contain: strict;
|
contain: strict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ import { Platform } from '../platform/platform';
|
|||||||
export class ClickBlock {
|
export class ClickBlock {
|
||||||
private _tmr: number;
|
private _tmr: number;
|
||||||
private _showing: boolean = false;
|
private _showing: boolean = false;
|
||||||
|
private _start: number;
|
||||||
|
private _minEnd: number;
|
||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -31,10 +33,15 @@ export class ClickBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
activate(shouldShow: boolean, expire: number = 100) {
|
activate(shouldShow: boolean, expire: number = 100, minDuration: number = 0) {
|
||||||
if (this.isEnabled) {
|
if (this.isEnabled) {
|
||||||
this.plt.cancelTimeout(this._tmr);
|
this.plt.cancelTimeout(this._tmr);
|
||||||
if (shouldShow) {
|
if (shouldShow) {
|
||||||
|
// remember when we started the click block
|
||||||
|
this._start = Date.now();
|
||||||
|
// figure out the minimum time it should be showing until
|
||||||
|
// this is useful for transitions that are less than 300ms
|
||||||
|
this._minEnd = this._start + (minDuration || 0);
|
||||||
this._activate(true);
|
this._activate(true);
|
||||||
}
|
}
|
||||||
this._tmr = this.plt.timeout(this._activate.bind(this, false), expire);
|
this._tmr = this.plt.timeout(this._activate.bind(this, false), expire);
|
||||||
@ -44,6 +51,17 @@ export class ClickBlock {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_activate(shouldShow: boolean) {
|
_activate(shouldShow: boolean) {
|
||||||
if (this._showing !== shouldShow) {
|
if (this._showing !== shouldShow) {
|
||||||
|
|
||||||
|
if (!shouldShow) {
|
||||||
|
// check if it was enabled before the minimum duration
|
||||||
|
// this is useful for transitions that are less than 300ms
|
||||||
|
var now = Date.now();
|
||||||
|
if (now < this._minEnd) {
|
||||||
|
this._tmr = this.plt.timeout(this._activate.bind(this, false), this._minEnd - now);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this._setElementClass('click-block-active', shouldShow);
|
this._setElementClass('click-block-active', shouldShow);
|
||||||
this._showing = shouldShow;
|
this._showing = shouldShow;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user