Skip to content

Commit

Permalink
fix(gestures): gesture controller handled by components
Browse files Browse the repository at this point in the history
* fix(gestures): gesture controller is handled by components

fixes #9046

* fix(gestures): adds hybrid disable scroll assistance

fixes #9130
fixes #9052
fixes #7444
  • Loading branch information
manucorporat authored and adamdbradley committed Nov 16, 2016
1 parent 339857a commit 32ab817
Show file tree
Hide file tree
Showing 26 changed files with 525 additions and 263 deletions.
19 changes: 18 additions & 1 deletion src/components/action-sheet/action-sheet-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Form } from '../../util/form';
import { Key } from '../../util/key';
import { NavParams } from '../../navigation/nav-params';
import { ViewController } from '../../navigation/view-controller';

import { BlockerDelegate, GestureController, BLOCK_ALL } from '../../gestures/gesture-controller';
import { assert } from '../../util/util';

/**
* @private
Expand Down Expand Up @@ -53,15 +54,18 @@ export class ActionSheetCmp {
hdrId: string;
id: number;
mode: string;
gestureBlocker: BlockerDelegate;

constructor(
private _viewCtrl: ViewController,
private _config: Config,
private _elementRef: ElementRef,
private _form: Form,
gestureCtrl: GestureController,
params: NavParams,
renderer: Renderer
) {
this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
this.d = params.data;
this.mode = _config.get('mode');
renderer.setElementClass(_elementRef.nativeElement, `action-sheet-${this.mode}`, true);
Expand Down Expand Up @@ -110,6 +114,14 @@ export class ActionSheetCmp {
this.d.buttons = buttons;
}

ionViewWillEnter() {
this.gestureBlocker.block();
}

ionViewDidLeave() {
this.gestureBlocker.unblock();
}

ionViewDidEnter() {
this._form.focusOut();

Expand Down Expand Up @@ -166,6 +178,11 @@ export class ActionSheetCmp {
dismiss(role: any): Promise<any> {
return this._viewCtrl.dismiss(null, role);
}

ngOnDestroy() {
assert(this.gestureBlocker.blocked === false, 'gesture blocker must be already unblocked');
this.gestureBlocker.destroy();
}
}

let actionSheetIds = -1;
47 changes: 32 additions & 15 deletions src/components/alert/alert-component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Component, ElementRef, HostListener, Renderer, ViewEncapsulation } from '@angular/core';

import { Config } from '../../config/config';
import { isPresent } from '../../util/util';
import { isPresent, assert } from '../../util/util';
import { Key } from '../../util/key';
import { NavParams } from '../../navigation/nav-params';
import { ViewController } from '../../navigation/view-controller';

import { GestureController, BlockerDelegate, BLOCK_ALL } from '../../gestures/gesture-controller';

/**
* @private
Expand Down Expand Up @@ -86,14 +86,18 @@ export class AlertCmp {
msgId: string;
subHdrId: string;
mode: string;
gestureBlocker: BlockerDelegate;

constructor(
public _viewCtrl: ViewController,
public _elementRef: ElementRef,
public _config: Config,
gestureCtrl: GestureController,
params: NavParams,
renderer: Renderer
) {
// gesture blocker is used to disable gestures dynamically
this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
this.d = params.data;
this.mode = _config.get('mode');
renderer.setElementClass(_elementRef.nativeElement, `alert-${this.mode}`, true);
Expand Down Expand Up @@ -172,6 +176,27 @@ export class AlertCmp {
}
}

ionViewWillEnter() {
this.gestureBlocker.block();
}

ionViewDidLeave() {
this.gestureBlocker.unblock();
}

ionViewDidEnter() {
let activeElement: any = document.activeElement;
if (document.activeElement) {
activeElement.blur();
}

let focusableEle = this._elementRef.nativeElement.querySelector('input,button');
if (focusableEle) {
focusableEle.focus();
}
this.enabled = true;
}

@HostListener('body:keyup', ['$event'])
keyUp(ev: KeyboardEvent) {
if (this.enabled && this._viewCtrl.isLast()) {
Expand All @@ -193,19 +218,6 @@ export class AlertCmp {
}
}

ionViewDidEnter() {
let activeElement: any = document.activeElement;
if (document.activeElement) {
activeElement.blur();
}

let focusableEle = this._elementRef.nativeElement.querySelector('input,button');
if (focusableEle) {
focusableEle.focus();
}
this.enabled = true;
}

btnClick(button: any, dismissDelay?: number) {
if (!this.enabled) {
return;
Expand Down Expand Up @@ -293,6 +305,11 @@ export class AlertCmp {
});
return values;
}

ngOnDestroy() {
assert(this.gestureBlocker.blocked === false, 'gesture blocker must be already unblocked');
this.gestureBlocker.destroy();
}
}

let alertIds = -1;
25 changes: 24 additions & 1 deletion src/components/app/app-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Config } from '../../config/config';
import { Ion } from '../ion';
import { OverlayPortal } from '../nav/overlay-portal';
import { Platform } from '../../platform/platform';
import { nativeTimeout } from '../../util/dom';

export const AppRootToken = new OpaqueToken('USERROOT');

Expand All @@ -23,6 +24,8 @@ export const AppRootToken = new OpaqueToken('USERROOT');
})
export class IonicApp extends Ion implements OnInit {

private _stopScrollPlugin: any;
private _rafId: number;
@ViewChild('viewport', {read: ViewContainerRef}) _viewport: ViewContainerRef;

@ViewChild('modalPortal', { read: OverlayPortal }) _modalPortal: OverlayPortal;
Expand All @@ -45,6 +48,7 @@ export class IonicApp extends Ion implements OnInit {
super(config, elementRef, renderer);
// register with App that this is Ionic's appRoot component. tada!
app._appRoot = this;
this._stopScrollPlugin = window['IonicStopScroll'];
}

ngOnInit() {
Expand Down Expand Up @@ -109,7 +113,26 @@ export class IonicApp extends Ion implements OnInit {
* @private
*/
_disableScroll(shouldDisableScroll: boolean) {
this.setElementClass('disable-scroll', shouldDisableScroll);
console.log('App Root: Scroll Disable Assist', shouldDisableScroll);

if (shouldDisableScroll) {
this.stopScroll().then(() => {
this._rafId = nativeTimeout(() => this.setElementClass('disable-scroll', true), 16 * 2);
});
} else {
cancelAnimationFrame(this._rafId);
this.setElementClass('disable-scroll', false);
}
}

stopScroll(): Promise<boolean> {
if (this._stopScrollPlugin) {
return new Promise((resolve, reject) => {
this._stopScrollPlugin.stop(() => resolve(true));
});
} else {
return Promise.resolve(false);
}
}

}
Expand Down
6 changes: 3 additions & 3 deletions src/components/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class App {
private _title: string = '';
private _titleSrv: Title = new Title();
private _rootNav: NavController = null;
private _canDisableScroll: boolean;
private _disableScrollAssist: boolean;

/**
* @private
Expand Down Expand Up @@ -71,7 +71,7 @@ export class App {
// listen for hardware back button events
// register this back button action with a default priority
_platform.registerBackButtonAction(this.navPop.bind(this));
this._canDisableScroll = _config.get('canDisableScroll', false);
this._disableScrollAssist = _config.getBoolean('disableScrollAssist', false);
}

/**
Expand Down Expand Up @@ -124,7 +124,7 @@ export class App {
* scrolling is enabled. When set to `true`, scrolling is disabled.
*/
setScrollDisabled(disableScroll: boolean) {
if (this._canDisableScroll) {
if (this._disableScrollAssist) {
this._appRoot._disableScroll(disableScroll);
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/components/backdrop/backdrop.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,3 @@ ion-backdrop {
opacity: .01;
transform: translateZ(0);
}

ion-backdrop.hide-backdrop {
display: none;
}
25 changes: 3 additions & 22 deletions src/components/backdrop/backdrop.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { Directive, ElementRef, Input, Renderer } from '@angular/core';

import { GestureController } from '../../gestures/gesture-controller';
import { isTrueProperty } from '../../util/util';

import { Directive, ElementRef, Renderer } from '@angular/core';

/**
* @private
Expand All @@ -16,26 +12,11 @@ import { isTrueProperty } from '../../util/util';
},
})
export class Backdrop {
private _gestureID: number = null;
@Input() disableScroll = true;

constructor(
private _gestureCtrl: GestureController,
private _elementRef: ElementRef,
private _renderer: Renderer) { }

ngOnInit() {
if (isTrueProperty(this.disableScroll)) {
this._gestureID = this._gestureCtrl.newID();
this._gestureCtrl.disableScroll(this._gestureID);
}
}

ngOnDestroy() {
if (this._gestureID) {
this._gestureCtrl.enableScroll(this._gestureID);
}
}
private _renderer: Renderer
) { }

getNativeElement(): HTMLElement {
return this._elementRef.nativeElement;
Expand Down
2 changes: 1 addition & 1 deletion src/components/content/content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ion-content.js-scroll > .scroll-content {
will-change: initial;
}

.disable-scroll .ion-page .scroll-content {
.disable-scroll .ion-page {
pointer-events: none;
}

Expand Down
18 changes: 10 additions & 8 deletions src/components/item/item-sliding-gesture.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ItemSliding } from './item-sliding';
import { List } from '../list/list';

import { GesturePriority } from '../../gestures/gesture-controller';
import { GestureController, GesturePriority, GESTURE_ITEM_SWIPE } from '../../gestures/gesture-controller';
import { PanGesture } from '../../gestures/drag-gesture';
import { pointerCoord } from '../../util/dom';
import { NativeRafDebouncer } from '../../util/debouncer';

const DRAG_THRESHOLD = 10;
const MAX_ATTACK_ANGLE = 20;

/**
* @private
*/
export class ItemSlidingGesture extends PanGesture {

private preSelectedContainer: ItemSliding = null;
Expand All @@ -17,14 +17,16 @@ export class ItemSlidingGesture extends PanGesture {
private firstCoordX: number;
private firstTimestamp: number;

constructor(public list: List) {
constructor(public list: List, gestureCtrl: GestureController) {
super(list.getNativeElement(), {
maxAngle: MAX_ATTACK_ANGLE,
threshold: DRAG_THRESHOLD,
maxAngle: 20,
threshold: 10,
zone: false,
debouncer: new NativeRafDebouncer(),
gesture: list._gestureCtrl.create('item-sliding', {
gesture: gestureCtrl.createGesture({
name: GESTURE_ITEM_SWIPE,
priority: GesturePriority.SlidingItem,
disableScroll: false // TODO: set true
})
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class List extends Ion {

} else if (!this._slidingGesture) {
console.debug('enableSlidingItems');
this._slidingGesture = new ItemSlidingGesture(this);
this._slidingGesture = new ItemSlidingGesture(this, this._gestureCtrl);
this._slidingGesture.listen();
}
}
Expand Down
Loading

0 comments on commit 32ab817

Please sign in to comment.