Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(core): stop accepting GestureTypes enum as an eventName #10537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 1 addition & 83 deletions apps/automated/src/ui/gestures/gestures-tests.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
/* tslint:disable:no-unused-variable */
import { GestureEventData, Label, GestureTypes, PanGestureEventData, PinchGestureEventData, SwipeGestureEventData, RotationGestureEventData } from '@nativescript/core';

export var test_DummyTestForSnippetOnly0 = function () {
// >> gestures-double-tap
var label = new Label();
var observer = label.on(GestureTypes.doubleTap, function (args: GestureEventData) {
console.log('Double Tap');
});
// << gestures-double-tap
};
import { GestureEventData, Label, PanGestureEventData, PinchGestureEventData, SwipeGestureEventData, RotationGestureEventData } from '@nativescript/core';

export var test_DummyTestForSnippetOnly01 = function () {
// >> gestures-double-tap-alt
Expand All @@ -19,15 +10,6 @@ export var test_DummyTestForSnippetOnly01 = function () {
// << gestures-double-tap-alt
};

export var test_DummyTestForSnippetOnly1 = function () {
// >> gestures-long-press
var label = new Label();
var observer = label.on(GestureTypes.longPress, function (args: GestureEventData) {
console.log('Long Press');
});
// << gestures-long-press
};

export var test_DummyTestForSnippetOnly11 = function () {
// >> gestures-long-press-alt
var label = new Label();
Expand All @@ -37,15 +19,6 @@ export var test_DummyTestForSnippetOnly11 = function () {
// << gestures-long-press-alt
};

export var test_DummyTestForSnippetOnly2 = function () {
// >> gestures-pan
var label = new Label();
var observer = label.on(GestureTypes.pan, function (args: PanGestureEventData) {
console.log('Pan deltaX:' + args.deltaX + '; deltaY:' + args.deltaY + ';');
});
// << gestures-pan
};

export var test_DummyTestForSnippetOnly22 = function () {
// >> gestures-pan-alt
var label = new Label();
Expand All @@ -55,15 +28,6 @@ export var test_DummyTestForSnippetOnly22 = function () {
// << gestures-pan-alt
};

export var test_DummyTestForSnippetOnly3 = function () {
// >> gestures-pan-pinch
var label = new Label();
var observer = label.on(GestureTypes.pinch, function (args: PinchGestureEventData) {
console.log('Pinch scale: ' + args.scale);
});
// << gestures-pan-pinch
};

export var test_DummyTestForSnippetOnly33 = function () {
// >> gestures-pan-pinch-alt
var label = new Label();
Expand All @@ -73,15 +37,6 @@ export var test_DummyTestForSnippetOnly33 = function () {
// << gestures-pan-pinch-alt
};

export var test_DummyTestForSnippetOnly4 = function () {
// >> gestures-rotation
var label = new Label();
var observer = label.on(GestureTypes.rotation, function (args: RotationGestureEventData) {
console.log('Rotation: ' + args.rotation);
});
// << gestures-rotation
};

export var test_DummyTestForSnippetOnly44 = function () {
// >> gestures-rotation-alt
var label = new Label();
Expand All @@ -91,15 +46,6 @@ export var test_DummyTestForSnippetOnly44 = function () {
// << gestures-rotation-alt
};

export var test_DummyTestForSnippetOnly5 = function () {
// >> gestures-swipe
var label = new Label();
var observer = label.on(GestureTypes.swipe, function (args: SwipeGestureEventData) {
console.log('Swipe direction: ' + args.direction);
});
// << gestures-swipe
};

export var test_DummyTestForSnippetOnly55 = function () {
// >> gestures-swipe-alt
var label = new Label();
Expand All @@ -109,15 +55,6 @@ export var test_DummyTestForSnippetOnly55 = function () {
// << gestures-swipe-alt
};

export var test_DummyTestForSnippetOnly6 = function () {
// >> gestures-tap
var label = new Label();
var observer = label.on(GestureTypes.tap, function (args: GestureEventData) {
console.log('Tap');
});
// << gestures-tap
};

export var test_DummyTestForSnippetOnly66 = function () {
// >> gestures-tap-alt
var label = new Label();
Expand All @@ -127,25 +64,6 @@ export var test_DummyTestForSnippetOnly66 = function () {
// << gestures-tap-alt
};

export var test_DummyTestForSnippetOnly7 = function () {
// >> gestures-stop-observe
var label = new Label();
var observer = label.on(GestureTypes.tap, function (args: GestureEventData) {
console.log('Tap');
});
observer.disconnect();
// << gestures-stop-observe
};

export var test_DummyTestForSnippetOnly8 = function () {
// >> gestures-multiple
var label = new Label();
var observer = label.on(GestureTypes.tap | GestureTypes.doubleTap | GestureTypes.longPress, function (args: GestureEventData) {
console.log('Event: ' + args.eventName);
});
// << gestures-multiple
};

export var test_DummyTestForSnippetOnly88 = function () {
// >> gestures-string
var label = new Label();
Expand Down
6 changes: 3 additions & 3 deletions packages/core/ui/button/index.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingB
import { textAlignmentProperty } from '../text-base';
import { CoreTypes } from '../../core-types';
import { profile } from '../../profiling';
import { TouchGestureEventData, GestureTypes, TouchAction } from '../gestures';
import { TouchGestureEventData, TouchAction, GestureTypes } from '../gestures';
import { Device } from '../../platform';
import { SDK_VERSION } from '../../utils/constants';
import lazy from '../../utils/lazy';
Expand Down Expand Up @@ -126,9 +126,9 @@ export class Button extends ButtonBase {
break;
}
});
this.on(GestureTypes.touch, this._highlightedHandler);
this.on(GestureTypes[GestureTypes.touch], this._highlightedHandler);
} else {
this.off(GestureTypes.touch, this._highlightedHandler);
this.off(GestureTypes[GestureTypes.touch], this._highlightedHandler);
Comment on lines -129 to +131
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@farfromrefug As requested, now using the string constants instead (forgot how enums worked).

Copy link
Contributor

@CatchABus CatchABus May 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is we have guided people to use the types as explained in old docs for years: https://old.docs.nativescript.org/ui/gestures

How are we going to make up for that?

Copy link
Contributor Author

@shirakaba shirakaba May 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch 🤔

Optimistically, I’d imagine they’d see a compiler error, see that it now accepts only a string, and be able to take a good guess at what the string is (as it comes from the same enum).

Arguably, it’s now left unmentioned in the new docs, so the typings serve as the up-to-date documentation.

I’d rather not handle it at runtime and just pull the plaster, if possible. It’s unlikely to be the only breaking change regarding event-handling that’s to come, so once the dust has settled, we could provide a migration guide based on what makes it into the release. Most likely in the blog post announcing the new release.

}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/ui/core/view/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -595,15 +595,15 @@ export abstract class View extends ViewCommon {
* @param callback An optional parameter pointing to a specific listener. If not defined, all listeners for the event names will be removed.
* @param thisArg An optional parameter which when set will be used to refine search of the correct callback which will be removed as event listener.
*/
off(eventNames: string | GestureTypes, callback?: (args: EventData) => void, thisArg?: any);
off(eventNames: string, callback?: (args: EventData) => void, thisArg?: any);

/**
* A basic method signature to hook an event listener (shortcut alias to the addEventListener method).
* @param eventNames - String corresponding to events (e.g. "propertyChange"). Optionally could be used more events separated by `,` (e.g. "propertyChange", "change") or you can use gesture types.
* @param callback - Callback function which will be executed when event is raised.
* @param thisArg - An optional parameter which will be used as `this` context for callback execution.
*/
on(eventNames: string | GestureTypes, callback: (args: EventData) => void, thisArg?: any);
on(eventNames: string, callback: (args: EventData) => void, thisArg?: any);

/**
* Raised when a loaded event occurs.
Expand Down
18 changes: 4 additions & 14 deletions packages/core/ui/core/view/view-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,14 +290,9 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
return this._gestureObservers[type];
}

public addEventListener(arg: string | GestureTypes, callback: (data: EventData) => void, thisArg?: any) {
if (typeof arg === 'number') {
this._observe(arg, callback as unknown as (data: GestureEventData) => void, thisArg);
return;
}

public addEventListener(eventNames: string, callback: (data: EventData) => void, thisArg?: any) {
// Normalize "ontap" -> "tap"
const normalizedName = getEventOrGestureName(arg);
const normalizedName = getEventOrGestureName(eventNames);

// Coerce "tap" -> GestureTypes.tap
// Coerce "loaded" -> undefined
Expand All @@ -312,14 +307,9 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
super.addEventListener(normalizedName, callback, thisArg);
}

public removeEventListener(arg: string | GestureTypes, callback?: (data: EventData) => void, thisArg?: any) {
if (typeof arg === 'number') {
this._disconnectGestureObservers(arg);
return;
}

public removeEventListener(eventNames: string, callback?: (data: EventData) => void, thisArg?: any) {
// Normalize "ontap" -> "tap"
const normalizedName = getEventOrGestureName(arg);
const normalizedName = getEventOrGestureName(eventNames);

// Coerce "tap" -> GestureTypes.tap
// Coerce "loaded" -> undefined
Expand Down
46 changes: 15 additions & 31 deletions packages/core/ui/gestures/gestures-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,38 +284,42 @@ export interface RotationGestureEventData extends GestureEventDataWithState {
* @param separator(optional) - Text separator between gesture type strings.
*/
export function toString(type: GestureTypes, separator?: string): string {
const types = new Array<string>();
// We can get stronger typings with `keyof typeof GestureTypes`, but sadly
// indexing into an enum simply returns `string`, so we'd have to type-assert
// all of the below anyway. Even this `(typeof GestureTypes)[GestureTypes]` is
// more for documentation than for type-safety (it resolves to `string`, too).
const types = new Array<(typeof GestureTypes)[GestureTypes]>();

if (type & GestureTypes.tap) {
types.push('tap');
types.push(GestureTypes[GestureTypes.tap]);
}

if (type & GestureTypes.doubleTap) {
types.push('doubleTap');
types.push(GestureTypes[GestureTypes.doubleTap]);
}

if (type & GestureTypes.pinch) {
types.push('pinch');
types.push(GestureTypes[GestureTypes.pinch]);
}

if (type & GestureTypes.pan) {
types.push('pan');
types.push(GestureTypes[GestureTypes.pan]);
}

if (type & GestureTypes.swipe) {
types.push('swipe');
types.push(GestureTypes[GestureTypes.swipe]);
}

if (type & GestureTypes.rotation) {
types.push('rotation');
types.push(GestureTypes[GestureTypes.rotation]);
}

if (type & GestureTypes.longPress) {
types.push('longPress');
types.push(GestureTypes[GestureTypes.longPress]);
}

if (type & GestureTypes.touch) {
types.push('touch');
types.push(GestureTypes[GestureTypes.touch]);
}

return types.join(separator);
Expand All @@ -327,28 +331,8 @@ export function toString(type: GestureTypes, separator?: string): string {
* Returns a gesture type enum value from a string (case insensitive).
* @param type - A string representation of a gesture type (e.g. Tap).
*/
export function fromString(type: string): GestureTypes {
const t = type.trim().toLowerCase();

if (t === 'tap') {
return GestureTypes.tap;
} else if (t === 'doubletap') {
return GestureTypes.doubleTap;
} else if (t === 'pinch') {
return GestureTypes.pinch;
} else if (t === 'pan') {
return GestureTypes.pan;
} else if (t === 'swipe') {
return GestureTypes.swipe;
} else if (t === 'rotation') {
return GestureTypes.rotation;
} else if (t === 'longpress') {
return GestureTypes.longPress;
} else if (t === 'touch') {
return GestureTypes.touch;
}

return undefined;
export function fromString(type: string): GestureTypes | undefined {
return GestureTypes[type.trim()];
}
Comment on lines +334 to 336
Copy link
Contributor Author

@shirakaba shirakaba May 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the .toLowerCase() as:

  1. Event names have mostly been input via the toString() convenience function up until now.
  2. Users should have been getting the string keys from the GestureTypes enum to begin with.

To be honest, we can likely remove the .trim() too, but I'd prefer to do that in the PR where we remove support for multiple event names.


export abstract class GesturesObserverBase implements GesturesObserverDefinition {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/ui/gestures/touch-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class TouchManager {
(<UILongPressGestureRecognizer>args.ios).minimumPressDuration = (<View>args.object)?.touchDelay || 0;
}
});
view.on(GestureTypes.longPress, (args: GestureEventDataWithState) => {
view.on(GestureTypes[GestureTypes.longPress], (args: GestureEventDataWithState) => {
switch (args.state) {
case GestureStateTypes.began:
if (handleDown) {
Expand All @@ -133,7 +133,7 @@ export class TouchManager {
}
} else {
if (handleDown || handleUp) {
view.on(GestureTypes.touch, (args: TouchGestureEventData) => {
view.on(GestureTypes[GestureTypes.touch], (args: TouchGestureEventData) => {
switch (args.action) {
case 'down':
if (handleDown) {
Expand Down Expand Up @@ -280,7 +280,7 @@ export class TouchManager {
TouchManager.visionHoverStyleCache['default'] = createHoverStyleFromOptions(
defaultOptions || {
effect: 'automatic',
}
},
);
}

Expand Down
4 changes: 2 additions & 2 deletions tools/scripts/api-reports/NativeScript.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2749,8 +2749,8 @@ export abstract class View extends ViewBase {
modal: View;
// (undocumented)
_modalParent?: View;
off(eventNames: string | GestureTypes, callback?: (args: EventData) => void, thisArg?: any);
on(eventNames: string | GestureTypes, callback: (args: EventData) => void, thisArg?: any);
off(eventNames: string, callback?: (args: EventData) => void, thisArg?: any);
on(eventNames: string, callback: (args: EventData) => void, thisArg?: any);
on(event: "loaded", callback: (args: EventData) => void, thisArg?: any);
on(event: "unloaded", callback: (args: EventData) => void, thisArg?: any);
on(event: "androidBackPressed", callback: (args: EventData) => void, thisArg?: any);
Expand Down
Loading