feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,94 @@
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint-disable */
import GestureHandler from './GestureHandler';
import { TEST_MAX_IF_NOT_NAN } from './utils';
class DiscreteGestureHandler extends GestureHandler {
get isDiscrete() {
return true;
}
get shouldEnableGestureOnSetup() {
return true;
}
shouldFailUnderCustomCriteria({
x,
y,
deltaX,
deltaY
}, {
maxDeltaX,
maxDeltaY,
maxDistSq,
shouldCancelWhenOutside
}) {
if (shouldCancelWhenOutside) {
if (!this.isPointInView({
x,
y
})) {
return true;
}
}
return TEST_MAX_IF_NOT_NAN(Math.abs(deltaX), maxDeltaX) || TEST_MAX_IF_NOT_NAN(Math.abs(deltaY), maxDeltaY) || TEST_MAX_IF_NOT_NAN(Math.abs(deltaY * deltaY + deltaX * deltaX), maxDistSq);
}
transformNativeEvent({
center: {
x,
y
}
}) {
// @ts-ignore FIXME(TS)
const rect = this.view.getBoundingClientRect();
return {
absoluteX: x,
absoluteY: y,
x: x - rect.left,
y: y - rect.top
};
}
isGestureEnabledForEvent({
minPointers,
maxPointers,
maxDeltaX,
maxDeltaY,
maxDistSq,
shouldCancelWhenOutside
}, _recognizer, {
maxPointers: pointerLength,
center,
deltaX,
deltaY
}) {
const validPointerCount = pointerLength >= minPointers && pointerLength <= maxPointers;
if (this.shouldFailUnderCustomCriteria({ ...center,
deltaX,
deltaY
}, {
maxDeltaX,
maxDeltaY,
maxDistSq,
shouldCancelWhenOutside
}) || // A user probably won't land a multi-pointer tap on the first tick (so we cannot just cancel each time)
// but if the gesture is running and the user adds or subtracts another pointer then it should fail.
!validPointerCount && this.isGestureRunning) {
return {
failed: true
};
}
return {
success: validPointerCount
};
}
}
export default DiscreteGestureHandler;
//# sourceMappingURL=DiscreteGestureHandler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["DiscreteGestureHandler.ts"],"names":["GestureHandler","TEST_MAX_IF_NOT_NAN","DiscreteGestureHandler","isDiscrete","shouldEnableGestureOnSetup","shouldFailUnderCustomCriteria","x","y","deltaX","deltaY","maxDeltaX","maxDeltaY","maxDistSq","shouldCancelWhenOutside","isPointInView","Math","abs","transformNativeEvent","center","rect","view","getBoundingClientRect","absoluteX","absoluteY","left","top","isGestureEnabledForEvent","minPointers","maxPointers","_recognizer","pointerLength","validPointerCount","isGestureRunning","failed","success"],"mappings":"AAAA;;AACA;AACA,OAAOA,cAAP,MAA2B,kBAA3B;AACA,SAASC,mBAAT,QAAoC,SAApC;;AAEA,MAAeC,sBAAf,SAA8CF,cAA9C,CAA6D;AAC7C,MAAVG,UAAU,GAAG;AACf,WAAO,IAAP;AACD;;AAE6B,MAA1BC,0BAA0B,GAAG;AAC/B,WAAO,IAAP;AACD;;AAEDC,EAAAA,6BAA6B,CAC3B;AAAEC,IAAAA,CAAF;AAAKC,IAAAA,CAAL;AAAQC,IAAAA,MAAR;AAAgBC,IAAAA;AAAhB,GAD2B,EAE3B;AAAEC,IAAAA,SAAF;AAAaC,IAAAA,SAAb;AAAwBC,IAAAA,SAAxB;AAAmCC,IAAAA;AAAnC,GAF2B,EAG3B;AACA,QAAIA,uBAAJ,EAA6B;AAC3B,UAAI,CAAC,KAAKC,aAAL,CAAmB;AAAER,QAAAA,CAAF;AAAKC,QAAAA;AAAL,OAAnB,CAAL,EAAmC;AACjC,eAAO,IAAP;AACD;AACF;;AACD,WACEN,mBAAmB,CAACc,IAAI,CAACC,GAAL,CAASR,MAAT,CAAD,EAAmBE,SAAnB,CAAnB,IACAT,mBAAmB,CAACc,IAAI,CAACC,GAAL,CAASP,MAAT,CAAD,EAAmBE,SAAnB,CADnB,IAEAV,mBAAmB,CACjBc,IAAI,CAACC,GAAL,CAASP,MAAM,GAAGA,MAAT,GAAkBD,MAAM,GAAGA,MAApC,CADiB,EAEjBI,SAFiB,CAHrB;AAQD;;AAEDK,EAAAA,oBAAoB,CAAC;AAAEC,IAAAA,MAAM,EAAE;AAAEZ,MAAAA,CAAF;AAAKC,MAAAA;AAAL;AAAV,GAAD,EAA4B;AAC9C;AACA,UAAMY,IAAI,GAAG,KAAKC,IAAL,CAAWC,qBAAX,EAAb;AAEA,WAAO;AACLC,MAAAA,SAAS,EAAEhB,CADN;AAELiB,MAAAA,SAAS,EAAEhB,CAFN;AAGLD,MAAAA,CAAC,EAAEA,CAAC,GAAGa,IAAI,CAACK,IAHP;AAILjB,MAAAA,CAAC,EAAEA,CAAC,GAAGY,IAAI,CAACM;AAJP,KAAP;AAMD;;AAEDC,EAAAA,wBAAwB,CACtB;AACEC,IAAAA,WADF;AAEEC,IAAAA,WAFF;AAGElB,IAAAA,SAHF;AAIEC,IAAAA,SAJF;AAKEC,IAAAA,SALF;AAMEC,IAAAA;AANF,GADsB,EAStBgB,WATsB,EAUtB;AAAED,IAAAA,WAAW,EAAEE,aAAf;AAA8BZ,IAAAA,MAA9B;AAAsCV,IAAAA,MAAtC;AAA8CC,IAAAA;AAA9C,GAVsB,EAWtB;AACA,UAAMsB,iBAAiB,GACrBD,aAAa,IAAIH,WAAjB,IAAgCG,aAAa,IAAIF,WADnD;;AAGA,QACE,KAAKvB,6BAAL,CACE,EAAE,GAAGa,MAAL;AAAaV,MAAAA,MAAb;AAAqBC,MAAAA;AAArB,KADF,EAEE;AACEC,MAAAA,SADF;AAEEC,MAAAA,SAFF;AAGEC,MAAAA,SAHF;AAIEC,MAAAA;AAJF,KAFF,KASA;AACA;AACC,KAACkB,iBAAD,IAAsB,KAAKC,gBAZ9B,EAaE;AACA,aAAO;AAAEC,QAAAA,MAAM,EAAE;AAAV,OAAP;AACD;;AAED,WAAO;AAAEC,MAAAA,OAAO,EAAEH;AAAX,KAAP;AACD;;AAzE0D;;AA4E7D,eAAe7B,sBAAf","sourcesContent":["/* eslint-disable eslint-comments/no-unlimited-disable */\n/* eslint-disable */\nimport GestureHandler from './GestureHandler';\nimport { TEST_MAX_IF_NOT_NAN } from './utils';\n\nabstract class DiscreteGestureHandler extends GestureHandler {\n get isDiscrete() {\n return true;\n }\n\n get shouldEnableGestureOnSetup() {\n return true;\n }\n\n shouldFailUnderCustomCriteria(\n { x, y, deltaX, deltaY }: any,\n { maxDeltaX, maxDeltaY, maxDistSq, shouldCancelWhenOutside }: any\n ) {\n if (shouldCancelWhenOutside) {\n if (!this.isPointInView({ x, y })) {\n return true;\n }\n }\n return (\n TEST_MAX_IF_NOT_NAN(Math.abs(deltaX), maxDeltaX) ||\n TEST_MAX_IF_NOT_NAN(Math.abs(deltaY), maxDeltaY) ||\n TEST_MAX_IF_NOT_NAN(\n Math.abs(deltaY * deltaY + deltaX * deltaX),\n maxDistSq\n )\n );\n }\n\n transformNativeEvent({ center: { x, y } }: any) {\n // @ts-ignore FIXME(TS)\n const rect = this.view!.getBoundingClientRect();\n\n return {\n absoluteX: x,\n absoluteY: y,\n x: x - rect.left,\n y: y - rect.top,\n };\n }\n\n isGestureEnabledForEvent(\n {\n minPointers,\n maxPointers,\n maxDeltaX,\n maxDeltaY,\n maxDistSq,\n shouldCancelWhenOutside,\n }: any,\n _recognizer: any,\n { maxPointers: pointerLength, center, deltaX, deltaY }: any\n ) {\n const validPointerCount =\n pointerLength >= minPointers && pointerLength <= maxPointers;\n\n if (\n this.shouldFailUnderCustomCriteria(\n { ...center, deltaX, deltaY },\n {\n maxDeltaX,\n maxDeltaY,\n maxDistSq,\n shouldCancelWhenOutside,\n }\n ) ||\n // A user probably won't land a multi-pointer tap on the first tick (so we cannot just cancel each time)\n // but if the gesture is running and the user adds or subtracts another pointer then it should fail.\n (!validPointerCount && this.isGestureRunning)\n ) {\n return { failed: true };\n }\n\n return { success: validPointerCount };\n }\n}\n\nexport default DiscreteGestureHandler;\n"]}

View File

@@ -0,0 +1,40 @@
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint-disable */
import GestureHandler from './GestureHandler';
import { PixelRatio } from 'react-native';
class DraggingGestureHandler extends GestureHandler {
get shouldEnableGestureOnSetup() {
return true;
}
transformNativeEvent({
deltaX,
deltaY,
velocityX,
velocityY,
center: {
x,
y
}
}) {
// @ts-ignore FIXME(TS)
const rect = this.view.getBoundingClientRect();
const ratio = PixelRatio.get();
return {
translationX: deltaX - (this.__initialX || 0),
translationY: deltaY - (this.__initialY || 0),
absoluteX: x,
absoluteY: y,
velocityX: velocityX * ratio,
velocityY: velocityY * ratio,
x: x - rect.left,
y: y - rect.top
};
}
}
export default DraggingGestureHandler;
//# sourceMappingURL=DraggingGestureHandler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["DraggingGestureHandler.ts"],"names":["GestureHandler","PixelRatio","DraggingGestureHandler","shouldEnableGestureOnSetup","transformNativeEvent","deltaX","deltaY","velocityX","velocityY","center","x","y","rect","view","getBoundingClientRect","ratio","get","translationX","__initialX","translationY","__initialY","absoluteX","absoluteY","left","top"],"mappings":"AAAA;;AACA;AACA,OAAOA,cAAP,MAA+C,kBAA/C;AACA,SAASC,UAAT,QAA2B,cAA3B;;AAEA,MAAeC,sBAAf,SAA8CF,cAA9C,CAA6D;AAC7B,MAA1BG,0BAA0B,GAAG;AAC/B,WAAO,IAAP;AACD;;AAEDC,EAAAA,oBAAoB,CAAC;AACnBC,IAAAA,MADmB;AAEnBC,IAAAA,MAFmB;AAGnBC,IAAAA,SAHmB;AAInBC,IAAAA,SAJmB;AAKnBC,IAAAA,MAAM,EAAE;AAAEC,MAAAA,CAAF;AAAKC,MAAAA;AAAL;AALW,GAAD,EAMD;AACjB;AACA,UAAMC,IAAI,GAAG,KAAKC,IAAL,CAAWC,qBAAX,EAAb;AACA,UAAMC,KAAK,GAAGd,UAAU,CAACe,GAAX,EAAd;AACA,WAAO;AACLC,MAAAA,YAAY,EAAEZ,MAAM,IAAI,KAAKa,UAAL,IAAmB,CAAvB,CADf;AAELC,MAAAA,YAAY,EAAEb,MAAM,IAAI,KAAKc,UAAL,IAAmB,CAAvB,CAFf;AAGLC,MAAAA,SAAS,EAAEX,CAHN;AAILY,MAAAA,SAAS,EAAEX,CAJN;AAKLJ,MAAAA,SAAS,EAAEA,SAAS,GAAGQ,KALlB;AAMLP,MAAAA,SAAS,EAAEA,SAAS,GAAGO,KANlB;AAOLL,MAAAA,CAAC,EAAEA,CAAC,GAAGE,IAAI,CAACW,IAPP;AAQLZ,MAAAA,CAAC,EAAEA,CAAC,GAAGC,IAAI,CAACY;AARP,KAAP;AAUD;;AAzB0D;;AA4B7D,eAAetB,sBAAf","sourcesContent":["/* eslint-disable eslint-comments/no-unlimited-disable */\n/* eslint-disable */\nimport GestureHandler, { HammerInputExt } from './GestureHandler';\nimport { PixelRatio } from 'react-native';\n\nabstract class DraggingGestureHandler extends GestureHandler {\n get shouldEnableGestureOnSetup() {\n return true;\n }\n\n transformNativeEvent({\n deltaX,\n deltaY,\n velocityX,\n velocityY,\n center: { x, y },\n }: HammerInputExt) {\n // @ts-ignore FIXME(TS)\n const rect = this.view!.getBoundingClientRect();\n const ratio = PixelRatio.get();\n return {\n translationX: deltaX - (this.__initialX || 0),\n translationY: deltaY - (this.__initialY || 0),\n absoluteX: x,\n absoluteY: y,\n velocityX: velocityX * ratio,\n velocityY: velocityY * ratio,\n x: x - rect.left,\n y: y - rect.top,\n };\n }\n}\n\nexport default DraggingGestureHandler;\n"]}

View File

@@ -0,0 +1,7 @@
export class GesturePropError extends Error {
constructor(name, value, expectedType) {
super(`Invalid property \`${name}: ${value}\` expected \`${expectedType}\``);
}
}
//# sourceMappingURL=Errors.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["Errors.ts"],"names":["GesturePropError","Error","constructor","name","value","expectedType"],"mappings":"AAAA,OAAO,MAAMA,gBAAN,SAA+BC,KAA/B,CAAqC;AAC1CC,EAAAA,WAAW,CAACC,IAAD,EAAeC,KAAf,EAA+BC,YAA/B,EAAqD;AAC9D,UACG,sBAAqBF,IAAK,KAAIC,KAAM,iBAAgBC,YAAa,IADpE;AAGD;;AALyC","sourcesContent":["export class GesturePropError extends Error {\n constructor(name: string, value: unknown, expectedType: string) {\n super(\n `Invalid property \\`${name}: ${value}\\` expected \\`${expectedType}\\``\n );\n }\n}\n"]}

View File

@@ -0,0 +1,156 @@
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint-disable */
import Hammer from '@egjs/hammerjs';
import { Direction } from './constants';
import { GesturePropError } from './Errors';
import DraggingGestureHandler from './DraggingGestureHandler';
import { isnan } from './utils';
class FlingGestureHandler extends DraggingGestureHandler {
get name() {
return 'swipe';
}
get NativeGestureClass() {
return Hammer.Swipe;
}
onGestureActivated(event) {
this.sendEvent({ ...event,
eventType: Hammer.INPUT_MOVE,
isFinal: false,
isFirst: true
});
this.isGestureRunning = false;
this.hasGestureFailed = false;
this.sendEvent({ ...event,
eventType: Hammer.INPUT_END,
isFinal: true
});
}
onRawEvent(ev) {
super.onRawEvent(ev);
if (this.hasGestureFailed) {
return;
} // Hammer doesn't send a `cancel` event for taps.
// Manually fail the event.
if (ev.isFinal) {
setTimeout(() => {
if (this.isGestureRunning) {
this.cancelEvent(ev);
}
});
} else if (!this.hasGestureFailed && !this.isGestureRunning) {
// Tap Gesture start event
const gesture = this.hammer.get(this.name); // @ts-ignore FIXME(TS)
if (gesture.options.enable(gesture, ev)) {
this.onStart(ev);
this.sendEvent(ev);
}
}
}
getHammerConfig() {
return {
// @ts-ignore FIXME(TS)
pointers: this.config.numberOfPointers,
direction: this.getDirection()
};
}
getTargetDirections(direction) {
const directions = [];
if (direction & Direction.RIGHT) {
directions.push(Hammer.DIRECTION_RIGHT);
}
if (direction & Direction.LEFT) {
directions.push(Hammer.DIRECTION_LEFT);
}
if (direction & Direction.UP) {
directions.push(Hammer.DIRECTION_UP);
}
if (direction & Direction.DOWN) {
directions.push(Hammer.DIRECTION_DOWN);
} // const hammerDirection = directions.reduce((a, b) => a | b, 0);
return directions;
}
getDirection() {
// @ts-ignore FIXME(TS)
const {
direction
} = this.getConfig();
let directions = [];
if (direction & Direction.RIGHT) {
directions.push(Hammer.DIRECTION_HORIZONTAL);
}
if (direction & Direction.LEFT) {
directions.push(Hammer.DIRECTION_HORIZONTAL);
}
if (direction & Direction.UP) {
directions.push(Hammer.DIRECTION_VERTICAL);
}
if (direction & Direction.DOWN) {
directions.push(Hammer.DIRECTION_VERTICAL);
}
directions = [...new Set(directions)];
if (directions.length === 0) return Hammer.DIRECTION_NONE;
if (directions.length === 1) return directions[0];
return Hammer.DIRECTION_ALL;
}
isGestureEnabledForEvent({
numberOfPointers
}, _recognizer, {
maxPointers: pointerLength
}) {
const validPointerCount = pointerLength === numberOfPointers;
if (!validPointerCount && this.isGestureRunning) {
return {
failed: true
};
}
return {
success: validPointerCount
};
}
updateGestureConfig({
numberOfPointers = 1,
direction,
...props
}) {
if (isnan(direction) || typeof direction !== 'number') {
throw new GesturePropError('direction', direction, 'number');
}
return super.updateGestureConfig({
numberOfPointers,
direction,
...props
});
}
}
export default FlingGestureHandler;
//# sourceMappingURL=FlingGestureHandler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,563 @@
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint-disable */
import Hammer from '@egjs/hammerjs';
import { findNodeHandle } from 'react-native';
import { State } from '../State';
import { EventMap } from './constants';
import * as NodeManager from './NodeManager';
import { ghQueueMicrotask } from '../ghQueueMicrotask'; // TODO(TS) Replace with HammerInput if https://github.com/DefinitelyTyped/DefinitelyTyped/pull/50438/files is merged
let gestureInstances = 0;
class GestureHandler {
get id() {
return `${this.name}${this.gestureInstance}`;
} // a simple way to check if GestureHandler is NativeViewGestureHandler, since importing it
// here to use instanceof would cause import cycle
get isNative() {
return false;
}
get isDiscrete() {
return false;
}
get shouldEnableGestureOnSetup() {
throw new Error('Must override GestureHandler.shouldEnableGestureOnSetup');
}
constructor() {
_defineProperty(this, "handlerTag", void 0);
_defineProperty(this, "isGestureRunning", false);
_defineProperty(this, "view", null);
_defineProperty(this, "hasCustomActivationCriteria", void 0);
_defineProperty(this, "hasGestureFailed", false);
_defineProperty(this, "hammer", null);
_defineProperty(this, "initialRotation", null);
_defineProperty(this, "__initialX", void 0);
_defineProperty(this, "__initialY", void 0);
_defineProperty(this, "config", {});
_defineProperty(this, "previousState", State.UNDETERMINED);
_defineProperty(this, "pendingGestures", {});
_defineProperty(this, "oldState", State.UNDETERMINED);
_defineProperty(this, "lastSentState", null);
_defineProperty(this, "gestureInstance", void 0);
_defineProperty(this, "_stillWaiting", void 0);
_defineProperty(this, "propsRef", void 0);
_defineProperty(this, "ref", void 0);
_defineProperty(this, "clearSelfAsPending", () => {
if (Array.isArray(this.config.waitFor)) {
for (const gesture of this.config.waitFor) {
gesture.removePendingGesture(this.id);
}
}
});
_defineProperty(this, "destroy", () => {
this.clearSelfAsPending();
if (this.hammer) {
this.hammer.stop(false);
this.hammer.destroy();
}
this.hammer = null;
});
_defineProperty(this, "isPointInView", ({
x,
y
}) => {
// @ts-ignore FIXME(TS)
const rect = this.view.getBoundingClientRect();
const pointerInside = x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
return pointerInside;
});
_defineProperty(this, "sendEvent", nativeEvent => {
const {
onGestureHandlerEvent,
onGestureHandlerStateChange
} = this.propsRef.current;
const event = this.transformEventData(nativeEvent);
invokeNullableMethod(onGestureHandlerEvent, event);
if (this.lastSentState !== event.nativeEvent.state) {
this.lastSentState = event.nativeEvent.state;
invokeNullableMethod(onGestureHandlerStateChange, event);
}
});
_defineProperty(this, "sync", () => {
const gesture = this.hammer.get(this.name);
if (!gesture) return;
const enable = (recognizer, inputData) => {
if (!this.config.enabled) {
this.isGestureRunning = false;
this.hasGestureFailed = false;
return false;
} // Prevent events before the system is ready.
if (!inputData || !recognizer.options || typeof inputData.maxPointers === 'undefined') {
return this.shouldEnableGestureOnSetup;
}
if (this.hasGestureFailed) {
return false;
}
if (!this.isDiscrete) {
if (this.isGestureRunning) {
return true;
} // The built-in hammer.js "waitFor" doesn't work across multiple views.
// Only process if there are views to wait for.
this._stillWaiting = this._getPendingGestures(); // This gesture should continue waiting.
if (this._stillWaiting.length) {
// Check to see if one of the gestures you're waiting for has started.
// If it has then the gesture should fail.
for (const gesture of this._stillWaiting) {
// When the target gesture has started, this gesture must force fail.
if (!gesture.isDiscrete && gesture.isGestureRunning) {
this.hasGestureFailed = true;
this.isGestureRunning = false;
return false;
}
} // This gesture shouldn't start until the others have finished.
return false;
}
} // Use default behaviour
if (!this.hasCustomActivationCriteria) {
return true;
}
const deltaRotation = this.initialRotation == null ? 0 : inputData.rotation - this.initialRotation; // @ts-ignore FIXME(TS)
const {
success,
failed
} = this.isGestureEnabledForEvent(this.getConfig(), recognizer, { ...inputData,
deltaRotation
});
if (failed) {
this.simulateCancelEvent(inputData);
this.hasGestureFailed = true;
}
return success;
};
const params = this.getHammerConfig(); // @ts-ignore FIXME(TS)
gesture.set({ ...params,
enable
});
});
this.gestureInstance = gestureInstances++;
this.hasCustomActivationCriteria = false;
}
getConfig() {
return this.config;
}
onWaitingEnded(_gesture) {}
removePendingGesture(id) {
delete this.pendingGestures[id];
}
addPendingGesture(gesture) {
this.pendingGestures[gesture.id] = gesture;
}
isGestureEnabledForEvent(_config, _recognizer, _event) {
return {
success: true
};
}
get NativeGestureClass() {
throw new Error('Must override GestureHandler.NativeGestureClass');
}
updateHasCustomActivationCriteria(_config) {
return true;
}
updateGestureConfig({
enabled = true,
...props
}) {
this.clearSelfAsPending();
this.config = this.ensureConfig({
enabled,
...props
});
this.hasCustomActivationCriteria = this.updateHasCustomActivationCriteria(this.config);
if (Array.isArray(this.config.waitFor)) {
for (const gesture of this.config.waitFor) {
gesture.addPendingGesture(this);
}
}
if (this.hammer) {
this.sync();
}
return this.config;
}
getState(type) {
// @ts-ignore TODO(TS) check if this is needed
if (type == 0) {
return 0;
}
return EventMap[type];
}
transformEventData(event) {
const {
eventType,
maxPointers: numberOfPointers
} = event; // const direction = DirectionMap[ev.direction];
const changedTouch = event.changedPointers[0];
const pointerInside = this.isPointInView({
x: changedTouch.clientX,
y: changedTouch.clientY
}); // TODO(TS) Remove cast after https://github.com/DefinitelyTyped/DefinitelyTyped/pull/50966 is merged.
const state = this.getState(eventType);
if (state !== this.previousState) {
this.oldState = this.previousState;
this.previousState = state;
}
return {
nativeEvent: {
numberOfPointers,
state,
pointerInside,
...this.transformNativeEvent(event),
// onHandlerStateChange only
handlerTag: this.handlerTag,
target: this.ref,
// send oldState only when the state was changed, or is different than ACTIVE
// GestureDetector relies on the presence of `oldState` to differentiate between
// update events and state change events
oldState: state !== this.previousState || state != 4 ? this.oldState : undefined
},
timeStamp: Date.now()
};
}
transformNativeEvent(_event) {
return {};
}
cancelPendingGestures(event) {
for (const gesture of Object.values(this.pendingGestures)) {
if (gesture && gesture.isGestureRunning) {
gesture.hasGestureFailed = true;
gesture.cancelEvent(event);
}
}
}
notifyPendingGestures() {
for (const gesture of Object.values(this.pendingGestures)) {
if (gesture) {
gesture.onWaitingEnded(this);
}
}
} // FIXME event is undefined in runtime when firstly invoked (see Draggable example), check other functions taking event as input
onGestureEnded(event) {
this.isGestureRunning = false;
this.cancelPendingGestures(event);
}
forceInvalidate(event) {
if (this.isGestureRunning) {
this.hasGestureFailed = true;
this.cancelEvent(event);
}
}
cancelEvent(event) {
this.notifyPendingGestures();
this.sendEvent({ ...event,
eventType: Hammer.INPUT_CANCEL,
isFinal: true
});
this.onGestureEnded(event);
}
onRawEvent({
isFirst
}) {
if (isFirst) {
this.hasGestureFailed = false;
}
}
shouldUseTouchEvents(config) {
var _config$simultaneousH, _config$simultaneousH2;
return (_config$simultaneousH = (_config$simultaneousH2 = config.simultaneousHandlers) === null || _config$simultaneousH2 === void 0 ? void 0 : _config$simultaneousH2.some(handler => handler.isNative)) !== null && _config$simultaneousH !== void 0 ? _config$simultaneousH : false;
}
setView(ref, propsRef) {
if (ref == null) {
this.destroy();
this.view = null;
return;
} // @ts-ignore window doesn't exist on global type as we don't want to use Node types
const SUPPORTS_TOUCH = ('ontouchstart' in window);
this.propsRef = propsRef;
this.ref = ref;
this.view = findNodeHandle(ref); // When the browser starts handling the gesture (e.g. scrolling), it sends a pointercancel event and stops
// sending additional pointer events. This is not the case with touch events, so if the gesture is simultaneous
// with a NativeGestureHandler, we need to check if touch events are supported and use them if possible.
this.hammer = SUPPORTS_TOUCH && this.shouldUseTouchEvents(this.config) ? new Hammer.Manager(this.view, {
inputClass: Hammer.TouchInput
}) : new Hammer.Manager(this.view);
this.oldState = State.UNDETERMINED;
this.previousState = State.UNDETERMINED;
this.lastSentState = null;
const {
NativeGestureClass
} = this; // @ts-ignore TODO(TS)
const gesture = new NativeGestureClass(this.getHammerConfig());
this.hammer.add(gesture);
this.hammer.on('hammer.input', ev => {
if (!this.config.enabled) {
this.hasGestureFailed = false;
this.isGestureRunning = false;
return;
}
this.onRawEvent(ev); // TODO: Bacon: Check against something other than null
// The isFirst value is not called when the first rotation is calculated.
if (this.initialRotation === null && ev.rotation !== 0) {
this.initialRotation = ev.rotation;
}
if (ev.isFinal) {
// in favor of a willFail otherwise the last frame of the gesture will be captured.
setTimeout(() => {
this.initialRotation = null;
this.hasGestureFailed = false;
});
}
});
this.setupEvents();
this.sync();
}
setupEvents() {
// TODO(TS) Hammer types aren't exactly that what we get in runtime
if (!this.isDiscrete) {
this.hammer.on(`${this.name}start`, event => this.onStart(event));
this.hammer.on(`${this.name}end ${this.name}cancel`, event => {
this.onGestureEnded(event);
});
}
this.hammer.on(this.name, ev => this.onGestureActivated(ev)); // TODO(TS) remove cast after https://github.com/DefinitelyTyped/DefinitelyTyped/pull/50438 is merged
}
onStart({
deltaX,
deltaY,
rotation
}) {
// Reset the state for the next gesture
this.oldState = State.UNDETERMINED;
this.previousState = State.UNDETERMINED;
this.lastSentState = null;
this.isGestureRunning = true;
this.__initialX = deltaX;
this.__initialY = deltaY;
this.initialRotation = rotation;
}
onGestureActivated(ev) {
this.sendEvent(ev);
}
onSuccess() {}
_getPendingGestures() {
if (Array.isArray(this.config.waitFor) && this.config.waitFor.length) {
// Get the list of gestures that this gesture is still waiting for.
// Use `=== false` in case a ref that isn't a gesture handler is used.
const stillWaiting = this.config.waitFor.filter(({
hasGestureFailed
}) => hasGestureFailed === false);
return stillWaiting;
}
return [];
}
getHammerConfig() {
const pointers = this.config.minPointers === this.config.maxPointers ? this.config.minPointers : 0;
return {
pointers
};
}
simulateCancelEvent(_inputData) {} // Validate the props
ensureConfig(config) {
const props = { ...config
}; // TODO(TS) We use ! to assert that if property is present then value is not empty (null, undefined)
if ('minDist' in config) {
props.minDist = config.minDist;
props.minDistSq = props.minDist * props.minDist;
}
if ('minVelocity' in config) {
props.minVelocity = config.minVelocity;
props.minVelocitySq = props.minVelocity * props.minVelocity;
}
if ('maxDist' in config) {
props.maxDist = config.maxDist;
props.maxDistSq = config.maxDist * config.maxDist;
}
if ('waitFor' in config) {
props.waitFor = asArray(config.waitFor).map(({
handlerTag
}) => NodeManager.getHandler(handlerTag)).filter(v => v);
} else {
props.waitFor = null;
}
if ('simultaneousHandlers' in config) {
const shouldUseTouchEvents = this.shouldUseTouchEvents(this.config);
props.simultaneousHandlers = asArray(config.simultaneousHandlers).map(handler => {
if (typeof handler === 'number') {
return NodeManager.getHandler(handler);
} else {
return NodeManager.getHandler(handler.handlerTag);
}
}).filter(v => v);
if (shouldUseTouchEvents !== this.shouldUseTouchEvents(props)) {
ghQueueMicrotask(() => {
// if the undelying event API needs to be changed, we need to unmount and mount
// the hammer instance again.
this.destroy();
this.setView(this.ref, this.propsRef);
});
}
} else {
props.simultaneousHandlers = null;
}
const configProps = ['minPointers', 'maxPointers', 'minDist', 'maxDist', 'maxDistSq', 'minVelocitySq', 'minDistSq', 'minVelocity', 'failOffsetXStart', 'failOffsetYStart', 'failOffsetXEnd', 'failOffsetYEnd', 'activeOffsetXStart', 'activeOffsetXEnd', 'activeOffsetYStart', 'activeOffsetYEnd'];
configProps.forEach(prop => {
if (typeof props[prop] === 'undefined') {
props[prop] = Number.NaN;
}
});
return props; // TODO(TS) how to convince TS that props are filled?
}
} // TODO(TS) investigate this method
// Used for sending data to a callback or AnimatedEvent
function invokeNullableMethod(method, event) {
if (method) {
if (typeof method === 'function') {
method(event);
} else {
// For use with reanimated's AnimatedEvent
if ('__getHandler' in method && typeof method.__getHandler === 'function') {
const handler = method.__getHandler();
invokeNullableMethod(handler, event);
} else {
if ('__nodeConfig' in method) {
const {
argMapping
} = method.__nodeConfig;
if (Array.isArray(argMapping)) {
for (const [index, [key, value]] of argMapping.entries()) {
if (key in event.nativeEvent) {
// @ts-ignore fix method type
const nativeValue = event.nativeEvent[key];
if (value && value.setValue) {
// Reanimated API
value.setValue(nativeValue);
} else {
// RN Animated API
method.__nodeConfig.argMapping[index] = [key, nativeValue];
}
}
}
}
}
}
}
}
}
function asArray(value) {
// TODO(TS) use config.waitFor type
return value == null ? [] : Array.isArray(value) ? value : [value];
}
export default GestureHandler;
//# sourceMappingURL=GestureHandler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,44 @@
import GestureHandler from './GestureHandler';
/**
* The base class for **Rotation** and **Pinch** gesture handlers.
*/
class IndiscreteGestureHandler extends GestureHandler {
get shouldEnableGestureOnSetup() {
return false;
}
updateGestureConfig({
minPointers = 2,
maxPointers = 2,
...props
}) {
return super.updateGestureConfig({
minPointers,
maxPointers,
...props
});
}
isGestureEnabledForEvent({
minPointers,
maxPointers
}, _recognizer, {
maxPointers: pointerLength
}) {
if (pointerLength > maxPointers) {
return {
failed: true
};
}
const validPointerCount = pointerLength >= minPointers;
return {
success: validPointerCount
};
}
}
export default IndiscreteGestureHandler;
//# sourceMappingURL=IndiscreteGestureHandler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["IndiscreteGestureHandler.ts"],"names":["GestureHandler","IndiscreteGestureHandler","shouldEnableGestureOnSetup","updateGestureConfig","minPointers","maxPointers","props","isGestureEnabledForEvent","_recognizer","pointerLength","failed","validPointerCount","success"],"mappings":"AAAA,OAAOA,cAAP,MAA2B,kBAA3B;AAEA;AACA;AACA;;AACA,MAAeC,wBAAf,SAAgDD,cAAhD,CAA+D;AAC/B,MAA1BE,0BAA0B,GAAG;AAC/B,WAAO,KAAP;AACD;;AAEDC,EAAAA,mBAAmB,CAAC;AAAEC,IAAAA,WAAW,GAAG,CAAhB;AAAmBC,IAAAA,WAAW,GAAG,CAAjC;AAAoC,OAAGC;AAAvC,GAAD,EAAiD;AAClE,WAAO,MAAMH,mBAAN,CAA0B;AAC/BC,MAAAA,WAD+B;AAE/BC,MAAAA,WAF+B;AAG/B,SAAGC;AAH4B,KAA1B,CAAP;AAKD;;AAEDC,EAAAA,wBAAwB,CACtB;AAAEH,IAAAA,WAAF;AAAeC,IAAAA;AAAf,GADsB,EAEtBG,WAFsB,EAGtB;AAAEH,IAAAA,WAAW,EAAEI;AAAf,GAHsB,EAItB;AACA,QAAIA,aAAa,GAAGJ,WAApB,EAAiC;AAC/B,aAAO;AAAEK,QAAAA,MAAM,EAAE;AAAV,OAAP;AACD;;AACD,UAAMC,iBAAiB,GAAGF,aAAa,IAAIL,WAA3C;AACA,WAAO;AACLQ,MAAAA,OAAO,EAAED;AADJ,KAAP;AAGD;;AAzB4D;;AA2B/D,eAAeV,wBAAf","sourcesContent":["import GestureHandler from './GestureHandler';\n\n/**\n * The base class for **Rotation** and **Pinch** gesture handlers.\n */\nabstract class IndiscreteGestureHandler extends GestureHandler {\n get shouldEnableGestureOnSetup() {\n return false;\n }\n\n updateGestureConfig({ minPointers = 2, maxPointers = 2, ...props }) {\n return super.updateGestureConfig({\n minPointers,\n maxPointers,\n ...props,\n });\n }\n\n isGestureEnabledForEvent(\n { minPointers, maxPointers }: any,\n _recognizer: any,\n { maxPointers: pointerLength }: any\n ) {\n if (pointerLength > maxPointers) {\n return { failed: true };\n }\n const validPointerCount = pointerLength >= minPointers;\n return {\n success: validPointerCount,\n };\n }\n}\nexport default IndiscreteGestureHandler;\n"]}

View File

@@ -0,0 +1,58 @@
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint-disable */
import Hammer from '@egjs/hammerjs';
import { State } from '../State';
import PressGestureHandler from './PressGestureHandler';
import { isnan, isValidNumber } from './utils';
class LongPressGestureHandler extends PressGestureHandler {
get minDurationMs() {
// @ts-ignore FIXNE(TS)
return isnan(this.config.minDurationMs) ? 251 : this.config.minDurationMs;
}
get maxDist() {
// @ts-ignore FIXNE(TS)
return isnan(this.config.maxDist) ? 9 : this.config.maxDist;
}
updateHasCustomActivationCriteria({
maxDistSq
}) {
return !isValidNumber(maxDistSq);
}
getConfig() {
if (!this.hasCustomActivationCriteria) {
// Default config
// If no params have been defined then this config should emulate the native gesture as closely as possible.
return {
shouldCancelWhenOutside: true,
maxDistSq: 10
};
}
return this.config;
}
getHammerConfig() {
return { ...super.getHammerConfig(),
// threshold: this.maxDist,
time: this.minDurationMs
};
}
getState(type) {
return {
[Hammer.INPUT_START]: State.ACTIVE,
[Hammer.INPUT_MOVE]: State.ACTIVE,
[Hammer.INPUT_END]: State.END,
[Hammer.INPUT_CANCEL]: State.FAILED
}[type];
}
}
export default LongPressGestureHandler;
//# sourceMappingURL=LongPressGestureHandler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["LongPressGestureHandler.ts"],"names":["Hammer","State","PressGestureHandler","isnan","isValidNumber","LongPressGestureHandler","minDurationMs","config","maxDist","updateHasCustomActivationCriteria","maxDistSq","getConfig","hasCustomActivationCriteria","shouldCancelWhenOutside","getHammerConfig","time","getState","type","INPUT_START","ACTIVE","INPUT_MOVE","INPUT_END","END","INPUT_CANCEL","FAILED"],"mappings":"AAAA;;AACA;AACA,OAAOA,MAAP,MAAmB,gBAAnB;AAEA,SAASC,KAAT,QAAsB,UAAtB;AACA,OAAOC,mBAAP,MAAgC,uBAAhC;AACA,SAASC,KAAT,EAAgBC,aAAhB,QAAqC,SAArC;;AAIA,MAAMC,uBAAN,SAAsCH,mBAAtC,CAA0D;AACvC,MAAbI,aAAa,GAAW;AAC1B;AACA,WAAOH,KAAK,CAAC,KAAKI,MAAL,CAAYD,aAAb,CAAL,GAAmC,GAAnC,GAAyC,KAAKC,MAAL,CAAYD,aAA5D;AACD;;AAEU,MAAPE,OAAO,GAAG;AACZ;AACA,WAAOL,KAAK,CAAC,KAAKI,MAAL,CAAYC,OAAb,CAAL,GAA6B,CAA7B,GAAiC,KAAKD,MAAL,CAAYC,OAApD;AACD;;AAEDC,EAAAA,iCAAiC,CAAC;AAAEC,IAAAA;AAAF,GAAD,EAAwB;AACvD,WAAO,CAACN,aAAa,CAACM,SAAD,CAArB;AACD;;AAEDC,EAAAA,SAAS,GAAG;AACV,QAAI,CAAC,KAAKC,2BAAV,EAAuC;AACrC;AACA;AACA,aAAO;AACLC,QAAAA,uBAAuB,EAAE,IADpB;AAELH,QAAAA,SAAS,EAAE;AAFN,OAAP;AAID;;AACD,WAAO,KAAKH,MAAZ;AACD;;AAEDO,EAAAA,eAAe,GAAG;AAChB,WAAO,EACL,GAAG,MAAMA,eAAN,EADE;AAEL;AACAC,MAAAA,IAAI,EAAE,KAAKT;AAHN,KAAP;AAKD;;AAEDU,EAAAA,QAAQ,CAACC,IAAD,EAAsC;AAC5C,WAAO;AACL,OAACjB,MAAM,CAACkB,WAAR,GAAsBjB,KAAK,CAACkB,MADvB;AAEL,OAACnB,MAAM,CAACoB,UAAR,GAAqBnB,KAAK,CAACkB,MAFtB;AAGL,OAACnB,MAAM,CAACqB,SAAR,GAAoBpB,KAAK,CAACqB,GAHrB;AAIL,OAACtB,MAAM,CAACuB,YAAR,GAAuBtB,KAAK,CAACuB;AAJxB,MAKLP,IALK,CAAP;AAMD;;AA1CuD;;AA6C1D,eAAeZ,uBAAf","sourcesContent":["/* eslint-disable eslint-comments/no-unlimited-disable */\n/* eslint-disable */\nimport Hammer from '@egjs/hammerjs';\n\nimport { State } from '../State';\nimport PressGestureHandler from './PressGestureHandler';\nimport { isnan, isValidNumber } from './utils';\nimport { Config } from './GestureHandler';\nimport { HammerInputNames } from './constants';\n\nclass LongPressGestureHandler extends PressGestureHandler {\n get minDurationMs(): number {\n // @ts-ignore FIXNE(TS)\n return isnan(this.config.minDurationMs) ? 251 : this.config.minDurationMs;\n }\n\n get maxDist() {\n // @ts-ignore FIXNE(TS)\n return isnan(this.config.maxDist) ? 9 : this.config.maxDist;\n }\n\n updateHasCustomActivationCriteria({ maxDistSq }: Config) {\n return !isValidNumber(maxDistSq);\n }\n\n getConfig() {\n if (!this.hasCustomActivationCriteria) {\n // Default config\n // If no params have been defined then this config should emulate the native gesture as closely as possible.\n return {\n shouldCancelWhenOutside: true,\n maxDistSq: 10,\n };\n }\n return this.config;\n }\n\n getHammerConfig() {\n return {\n ...super.getHammerConfig(),\n // threshold: this.maxDist,\n time: this.minDurationMs,\n };\n }\n\n getState(type: keyof typeof HammerInputNames) {\n return {\n [Hammer.INPUT_START]: State.ACTIVE,\n [Hammer.INPUT_MOVE]: State.ACTIVE,\n [Hammer.INPUT_END]: State.END,\n [Hammer.INPUT_CANCEL]: State.FAILED,\n }[type];\n }\n}\n\nexport default LongPressGestureHandler;\n"]}

View File

@@ -0,0 +1,49 @@
import DiscreteGestureHandler from './DiscreteGestureHandler';
import * as NodeManager from './NodeManager';
import PressGestureHandler from './PressGestureHandler';
import { TEST_MIN_IF_NOT_NAN, VEC_LEN_SQ } from './utils';
class NativeViewGestureHandler extends PressGestureHandler {
get isNative() {
return true;
}
onRawEvent(ev) {
super.onRawEvent(ev);
if (!ev.isFinal) {
// if (this.ref instanceof ScrollView) {
if (TEST_MIN_IF_NOT_NAN(VEC_LEN_SQ({
x: ev.deltaX,
y: ev.deltaY
}), 10)) {
// @ts-ignore FIXME(TS) config type
if (this.config.disallowInterruption) {
const gestures = Object.values(NodeManager.getNodes()).filter(gesture => {
const {
handlerTag,
view,
isGestureRunning
} = gesture;
return (// Check if this gesture isn't self
handlerTag !== this.handlerTag && // Ensure the gesture needs to be cancelled
isGestureRunning && // ScrollView can cancel discrete gestures like taps and presses
gesture instanceof DiscreteGestureHandler && // Ensure a view exists and is a child of the current view
view && // @ts-ignore FIXME(TS) view type
this.view.contains(view)
);
}); // Cancel all of the gestures that passed the filter
for (const gesture of gestures) {
// TODO: Bacon: Send some cached event.
gesture.forceInvalidate(ev);
}
}
}
}
}
}
export default NativeViewGestureHandler;
//# sourceMappingURL=NativeViewGestureHandler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["NativeViewGestureHandler.ts"],"names":["DiscreteGestureHandler","NodeManager","PressGestureHandler","TEST_MIN_IF_NOT_NAN","VEC_LEN_SQ","NativeViewGestureHandler","isNative","onRawEvent","ev","isFinal","x","deltaX","y","deltaY","config","disallowInterruption","gestures","Object","values","getNodes","filter","gesture","handlerTag","view","isGestureRunning","contains","forceInvalidate"],"mappings":"AAAA,OAAOA,sBAAP,MAAmC,0BAAnC;AAEA,OAAO,KAAKC,WAAZ,MAA6B,eAA7B;AACA,OAAOC,mBAAP,MAAgC,uBAAhC;AACA,SAASC,mBAAT,EAA8BC,UAA9B,QAAgD,SAAhD;;AAEA,MAAMC,wBAAN,SAAuCH,mBAAvC,CAA2D;AAC7C,MAARI,QAAQ,GAAG;AACb,WAAO,IAAP;AACD;;AAEDC,EAAAA,UAAU,CAACC,EAAD,EAAqB;AAC7B,UAAMD,UAAN,CAAiBC,EAAjB;;AACA,QAAI,CAACA,EAAE,CAACC,OAAR,EAAiB;AACf;AACA,UAAIN,mBAAmB,CAACC,UAAU,CAAC;AAAEM,QAAAA,CAAC,EAAEF,EAAE,CAACG,MAAR;AAAgBC,QAAAA,CAAC,EAAEJ,EAAE,CAACK;AAAtB,OAAD,CAAX,EAA6C,EAA7C,CAAvB,EAAyE;AACvE;AACA,YAAI,KAAKC,MAAL,CAAYC,oBAAhB,EAAsC;AACpC,gBAAMC,QAAQ,GAAGC,MAAM,CAACC,MAAP,CAAcjB,WAAW,CAACkB,QAAZ,EAAd,EAAsCC,MAAtC,CACdC,OAAD,IAAa;AACX,kBAAM;AAAEC,cAAAA,UAAF;AAAcC,cAAAA,IAAd;AAAoBC,cAAAA;AAApB,gBAAyCH,OAA/C;AACA,mBACE;AACAC,cAAAA,UAAU,KAAK,KAAKA,UAApB,IACA;AACAE,cAAAA,gBAFA,IAGA;AACAH,cAAAA,OAAO,YAAYrB,sBAJnB,IAKA;AACAuB,cAAAA,IANA,IAOA;AACA,mBAAKA,IAAL,CAAUE,QAAV,CAAmBF,IAAnB;AAVF;AAYD,WAfc,CAAjB,CADoC,CAkBpC;;AACA,eAAK,MAAMF,OAAX,IAAsBL,QAAtB,EAAgC;AAC9B;AACAK,YAAAA,OAAO,CAACK,eAAR,CAAwBlB,EAAxB;AACD;AACF;AACF;AACF;AACF;;AArCwD;;AAwC3D,eAAeH,wBAAf","sourcesContent":["import DiscreteGestureHandler from './DiscreteGestureHandler';\nimport { HammerInputExt } from './GestureHandler';\nimport * as NodeManager from './NodeManager';\nimport PressGestureHandler from './PressGestureHandler';\nimport { TEST_MIN_IF_NOT_NAN, VEC_LEN_SQ } from './utils';\n\nclass NativeViewGestureHandler extends PressGestureHandler {\n get isNative() {\n return true;\n }\n\n onRawEvent(ev: HammerInputExt) {\n super.onRawEvent(ev);\n if (!ev.isFinal) {\n // if (this.ref instanceof ScrollView) {\n if (TEST_MIN_IF_NOT_NAN(VEC_LEN_SQ({ x: ev.deltaX, y: ev.deltaY }), 10)) {\n // @ts-ignore FIXME(TS) config type\n if (this.config.disallowInterruption) {\n const gestures = Object.values(NodeManager.getNodes()).filter(\n (gesture) => {\n const { handlerTag, view, isGestureRunning } = gesture;\n return (\n // Check if this gesture isn't self\n handlerTag !== this.handlerTag &&\n // Ensure the gesture needs to be cancelled\n isGestureRunning &&\n // ScrollView can cancel discrete gestures like taps and presses\n gesture instanceof DiscreteGestureHandler &&\n // Ensure a view exists and is a child of the current view\n view &&\n // @ts-ignore FIXME(TS) view type\n this.view.contains(view)\n );\n }\n );\n // Cancel all of the gestures that passed the filter\n for (const gesture of gestures) {\n // TODO: Bacon: Send some cached event.\n gesture.forceInvalidate(ev);\n }\n }\n }\n }\n }\n}\n\nexport default NativeViewGestureHandler;\n"]}

View File

@@ -0,0 +1,33 @@
const gestures = {};
export function getHandler(tag) {
if (tag in gestures) {
return gestures[tag];
}
throw new Error(`No handler for tag ${tag}`);
}
export function createGestureHandler(handlerTag, handler) {
if (handlerTag in gestures) {
throw new Error(`Handler with tag ${handlerTag} already exists`);
}
gestures[handlerTag] = handler; // @ts-ignore no types for web handlers yet
gestures[handlerTag].handlerTag = handlerTag;
}
export function dropGestureHandler(handlerTag) {
// Since React 18, there are cases where componentWillUnmount gets called twice in a row
// so skip this if the tag was already removed.
if (!(handlerTag in gestures)) {
return;
}
getHandler(handlerTag).destroy(); // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete gestures[handlerTag];
}
export function getNodes() {
return { ...gestures
};
}
//# sourceMappingURL=NodeManager.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["NodeManager.ts"],"names":["gestures","getHandler","tag","Error","createGestureHandler","handlerTag","handler","dropGestureHandler","destroy","getNodes"],"mappings":"AAGA,MAAMA,QAGL,GAAG,EAHJ;AAKA,OAAO,SAASC,UAAT,CAAoBC,GAApB,EAAiC;AACtC,MAAIA,GAAG,IAAIF,QAAX,EAAqB;AACnB,WAAOA,QAAQ,CAACE,GAAD,CAAf;AACD;;AAED,QAAM,IAAIC,KAAJ,CAAW,sBAAqBD,GAAI,EAApC,CAAN;AACD;AAED,OAAO,SAASE,oBAAT,CACLC,UADK,EAELC,OAFK,EAGL;AACA,MAAID,UAAU,IAAIL,QAAlB,EAA4B;AAC1B,UAAM,IAAIG,KAAJ,CAAW,oBAAmBE,UAAW,iBAAzC,CAAN;AACD;;AACDL,EAAAA,QAAQ,CAACK,UAAD,CAAR,GAAuBC,OAAvB,CAJA,CAKA;;AACAN,EAAAA,QAAQ,CAACK,UAAD,CAAR,CAAqBA,UAArB,GAAkCA,UAAlC;AACD;AAED,OAAO,SAASE,kBAAT,CAA4BF,UAA5B,EAAgD;AACrD;AACA;AACA,MAAI,EAAEA,UAAU,IAAIL,QAAhB,CAAJ,EAA+B;AAC7B;AACD;;AACDC,EAAAA,UAAU,CAACI,UAAD,CAAV,CAAuBG,OAAvB,GANqD,CAOrD;;AACA,SAAOR,QAAQ,CAACK,UAAD,CAAf;AACD;AAED,OAAO,SAASI,QAAT,GAAoB;AACzB,SAAO,EAAE,GAAGT;AAAL,GAAP;AACD","sourcesContent":["import { ValueOf } from '../typeUtils';\nimport { HammerGestures } from '../web/Gestures';\n\nconst gestures: Record<\n number,\n InstanceType<ValueOf<typeof HammerGestures>>\n> = {};\n\nexport function getHandler(tag: number) {\n if (tag in gestures) {\n return gestures[tag];\n }\n\n throw new Error(`No handler for tag ${tag}`);\n}\n\nexport function createGestureHandler(\n handlerTag: number,\n handler: InstanceType<ValueOf<typeof HammerGestures>>\n) {\n if (handlerTag in gestures) {\n throw new Error(`Handler with tag ${handlerTag} already exists`);\n }\n gestures[handlerTag] = handler;\n // @ts-ignore no types for web handlers yet\n gestures[handlerTag].handlerTag = handlerTag;\n}\n\nexport function dropGestureHandler(handlerTag: number) {\n // Since React 18, there are cases where componentWillUnmount gets called twice in a row\n // so skip this if the tag was already removed.\n if (!(handlerTag in gestures)) {\n return;\n }\n getHandler(handlerTag).destroy();\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete gestures[handlerTag];\n}\n\nexport function getNodes() {\n return { ...gestures };\n}\n"]}

View File

@@ -0,0 +1,194 @@
import Hammer from '@egjs/hammerjs';
import { MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD, MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD } from './constants';
import DraggingGestureHandler from './DraggingGestureHandler';
import { isValidNumber, isnan, TEST_MIN_IF_NOT_NAN, VEC_LEN_SQ } from './utils';
import { State } from '../State';
class PanGestureHandler extends DraggingGestureHandler {
get name() {
return 'pan';
}
get NativeGestureClass() {
return Hammer.Pan;
}
getHammerConfig() {
return { ...super.getHammerConfig(),
direction: this.getDirection()
};
}
getState(type) {
const nextState = super.getState(type); // Ensure that the first state sent is `BEGAN` and not `ACTIVE`
if (this.previousState === State.UNDETERMINED && nextState === State.ACTIVE) {
return State.BEGAN;
}
return nextState;
}
getDirection() {
const config = this.getConfig();
const {
activeOffsetXStart,
activeOffsetXEnd,
activeOffsetYStart,
activeOffsetYEnd,
minDist
} = config;
let directions = [];
let horizontalDirections = [];
if (!isnan(minDist)) {
return Hammer.DIRECTION_ALL;
}
if (!isnan(activeOffsetXStart)) {
horizontalDirections.push(Hammer.DIRECTION_LEFT);
}
if (!isnan(activeOffsetXEnd)) {
horizontalDirections.push(Hammer.DIRECTION_RIGHT);
}
if (horizontalDirections.length === 2) {
horizontalDirections = [Hammer.DIRECTION_HORIZONTAL];
}
directions = directions.concat(horizontalDirections);
let verticalDirections = [];
if (!isnan(activeOffsetYStart)) {
verticalDirections.push(Hammer.DIRECTION_UP);
}
if (!isnan(activeOffsetYEnd)) {
verticalDirections.push(Hammer.DIRECTION_DOWN);
}
if (verticalDirections.length === 2) {
verticalDirections = [Hammer.DIRECTION_VERTICAL];
}
directions = directions.concat(verticalDirections);
if (!directions.length) {
return Hammer.DIRECTION_NONE;
}
if (directions[0] === Hammer.DIRECTION_HORIZONTAL && directions[1] === Hammer.DIRECTION_VERTICAL) {
return Hammer.DIRECTION_ALL;
}
if (horizontalDirections.length && verticalDirections.length) {
return Hammer.DIRECTION_ALL;
}
return directions[0];
}
getConfig() {
if (!this.hasCustomActivationCriteria) {
// Default config
// If no params have been defined then this config should emulate the native gesture as closely as possible.
return {
minDistSq: 10
};
}
return this.config;
}
shouldFailUnderCustomCriteria({
deltaX,
deltaY
}, criteria) {
return !isnan(criteria.failOffsetXStart) && deltaX < criteria.failOffsetXStart || !isnan(criteria.failOffsetXEnd) && deltaX > criteria.failOffsetXEnd || !isnan(criteria.failOffsetYStart) && deltaY < criteria.failOffsetYStart || !isnan(criteria.failOffsetYEnd) && deltaY > criteria.failOffsetYEnd;
}
shouldActivateUnderCustomCriteria({
deltaX,
deltaY,
velocity
}, criteria) {
return !isnan(criteria.activeOffsetXStart) && deltaX < criteria.activeOffsetXStart || !isnan(criteria.activeOffsetXEnd) && deltaX > criteria.activeOffsetXEnd || !isnan(criteria.activeOffsetYStart) && deltaY < criteria.activeOffsetYStart || !isnan(criteria.activeOffsetYEnd) && deltaY > criteria.activeOffsetYEnd || TEST_MIN_IF_NOT_NAN(VEC_LEN_SQ({
x: deltaX,
y: deltaY
}), criteria.minDistSq) || TEST_MIN_IF_NOT_NAN(velocity.x, criteria.minVelocityX) || TEST_MIN_IF_NOT_NAN(velocity.y, criteria.minVelocityY) || TEST_MIN_IF_NOT_NAN(VEC_LEN_SQ(velocity), criteria.minVelocitySq);
}
shouldMultiFingerPanFail({
pointerLength,
scale,
deltaRotation
}) {
if (pointerLength <= 1) {
return false;
} // Test if the pan had too much pinching or rotating.
const deltaScale = Math.abs(scale - 1);
const absDeltaRotation = Math.abs(deltaRotation);
if (deltaScale > MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD) {
// > If the threshold doesn't seem right.
// You can log the value which it failed at here:
return true;
}
if (absDeltaRotation > MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD) {
// > If the threshold doesn't seem right.
// You can log the value which it failed at here:
return true;
}
return false;
}
updateHasCustomActivationCriteria(criteria) {
return isValidNumber(criteria.minDistSq) || isValidNumber(criteria.minVelocityX) || isValidNumber(criteria.minVelocityY) || isValidNumber(criteria.minVelocitySq) || isValidNumber(criteria.activeOffsetXStart) || isValidNumber(criteria.activeOffsetXEnd) || isValidNumber(criteria.activeOffsetYStart) || isValidNumber(criteria.activeOffsetYEnd);
}
isGestureEnabledForEvent(props, _recognizer, inputData) {
if (this.shouldFailUnderCustomCriteria(inputData, props)) {
return {
failed: true
};
}
const velocity = {
x: inputData.velocityX,
y: inputData.velocityY
};
if (this.hasCustomActivationCriteria && this.shouldActivateUnderCustomCriteria({
deltaX: inputData.deltaX,
deltaY: inputData.deltaY,
velocity
}, props)) {
if (this.shouldMultiFingerPanFail({
pointerLength: inputData.maxPointers,
scale: inputData.scale,
deltaRotation: inputData.deltaRotation
})) {
return {
failed: true
};
}
return {
success: true
};
}
return {
success: false
};
}
}
export default PanGestureHandler;
//# sourceMappingURL=PanGestureHandler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
import Hammer from '@egjs/hammerjs';
import IndiscreteGestureHandler from './IndiscreteGestureHandler';
class PinchGestureHandler extends IndiscreteGestureHandler {
get name() {
return 'pinch';
}
get NativeGestureClass() {
return Hammer.Pinch;
}
transformNativeEvent({
scale,
velocity,
center
}) {
return {
focalX: center.x,
focalY: center.y,
velocity,
scale
};
}
}
export default PinchGestureHandler;
//# sourceMappingURL=PinchGestureHandler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["PinchGestureHandler.ts"],"names":["Hammer","IndiscreteGestureHandler","PinchGestureHandler","name","NativeGestureClass","Pinch","transformNativeEvent","scale","velocity","center","focalX","x","focalY","y"],"mappings":"AAAA,OAAOA,MAAP,MAAmB,gBAAnB;AAGA,OAAOC,wBAAP,MAAqC,4BAArC;;AAEA,MAAMC,mBAAN,SAAkCD,wBAAlC,CAA2D;AACjD,MAAJE,IAAI,GAAG;AACT,WAAO,OAAP;AACD;;AAEqB,MAAlBC,kBAAkB,GAAG;AACvB,WAAOJ,MAAM,CAACK,KAAd;AACD;;AAEDC,EAAAA,oBAAoB,CAAC;AAAEC,IAAAA,KAAF;AAASC,IAAAA,QAAT;AAAmBC,IAAAA;AAAnB,GAAD,EAA8C;AAChE,WAAO;AACLC,MAAAA,MAAM,EAAED,MAAM,CAACE,CADV;AAELC,MAAAA,MAAM,EAAEH,MAAM,CAACI,CAFV;AAGLL,MAAAA,QAHK;AAILD,MAAAA;AAJK,KAAP;AAMD;;AAhBwD;;AAmB3D,eAAeL,mBAAf","sourcesContent":["import Hammer from '@egjs/hammerjs';\nimport { HammerInputExt } from './GestureHandler';\n\nimport IndiscreteGestureHandler from './IndiscreteGestureHandler';\n\nclass PinchGestureHandler extends IndiscreteGestureHandler {\n get name() {\n return 'pinch';\n }\n\n get NativeGestureClass() {\n return Hammer.Pinch;\n }\n\n transformNativeEvent({ scale, velocity, center }: HammerInputExt) {\n return {\n focalX: center.x,\n focalY: center.y,\n velocity,\n scale,\n };\n }\n}\n\nexport default PinchGestureHandler;\n"]}

View File

@@ -0,0 +1,174 @@
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import Hammer from '@egjs/hammerjs';
import { State } from '../State';
import { CONTENT_TOUCHES_DELAY, CONTENT_TOUCHES_QUICK_TAP_END_DELAY } from './constants';
import DiscreteGestureHandler from './DiscreteGestureHandler';
import { fireAfterInterval, isValidNumber, isnan } from './utils';
class PressGestureHandler extends DiscreteGestureHandler {
constructor(...args) {
super(...args);
_defineProperty(this, "visualFeedbackTimer", void 0);
_defineProperty(this, "initialEvent", null);
_defineProperty(this, "shouldDelayTouches", true);
}
get name() {
return 'press';
}
get minDurationMs() {
// @ts-ignore FIXME(TS)
return isnan(this.config.minDurationMs) ? 5 : this.config.minDurationMs;
}
get maxDist() {
return isnan(this.config.maxDist) ? 9 : this.config.maxDist;
}
get NativeGestureClass() {
return Hammer.Press;
}
simulateCancelEvent(inputData) {
// Long press never starts so we can't rely on the running event boolean.
this.hasGestureFailed = true;
this.cancelEvent(inputData);
}
updateHasCustomActivationCriteria({
shouldCancelWhenOutside,
maxDistSq
}) {
return shouldCancelWhenOutside || !isValidNumber(maxDistSq);
}
getState(type) {
return {
[Hammer.INPUT_START]: State.BEGAN,
[Hammer.INPUT_MOVE]: State.ACTIVE,
[Hammer.INPUT_END]: State.END,
[Hammer.INPUT_CANCEL]: State.CANCELLED
}[type];
}
getConfig() {
if (!this.hasCustomActivationCriteria) {
// Default config
// If no params have been defined then this config should emulate the native gesture as closely as possible.
return {
shouldCancelWhenOutside: true,
maxDistSq: 10
};
}
return this.config;
}
getHammerConfig() {
return { ...super.getHammerConfig(),
// threshold: this.maxDist,
time: this.minDurationMs
};
}
onGestureActivated(ev) {
this.onGestureStart(ev);
}
shouldDelayTouchForEvent({
pointerType
}) {
// Don't disable event for mouse input
return this.shouldDelayTouches && pointerType === 'touch';
}
onGestureStart(ev) {
this.isGestureRunning = true;
clearTimeout(this.visualFeedbackTimer);
this.initialEvent = ev;
this.visualFeedbackTimer = fireAfterInterval(() => {
this.sendGestureStartedEvent(this.initialEvent);
this.initialEvent = null;
}, this.shouldDelayTouchForEvent(ev) && CONTENT_TOUCHES_DELAY);
}
sendGestureStartedEvent(ev) {
clearTimeout(this.visualFeedbackTimer);
this.visualFeedbackTimer = null;
this.sendEvent({ ...ev,
eventType: Hammer.INPUT_MOVE,
isFirst: true
});
}
forceInvalidate(event) {
super.forceInvalidate(event);
clearTimeout(this.visualFeedbackTimer);
this.visualFeedbackTimer = null;
this.initialEvent = null;
}
onRawEvent(ev) {
super.onRawEvent(ev);
if (this.isGestureRunning) {
if (ev.isFinal) {
let timeout;
if (this.visualFeedbackTimer) {
// Aesthetic timing for a quick tap.
// We haven't activated the tap right away to emulate iOS `delaysContentTouches`
// Now we must send the initial activation event and wait a set amount of time before firing the end event.
timeout = CONTENT_TOUCHES_QUICK_TAP_END_DELAY;
this.sendGestureStartedEvent(this.initialEvent);
this.initialEvent = null;
}
fireAfterInterval(() => {
this.sendEvent({ ...ev,
eventType: Hammer.INPUT_END,
isFinal: true
}); // @ts-ignore -- this should explicitly support undefined
this.onGestureEnded();
}, timeout);
} else {
this.sendEvent({ ...ev,
eventType: Hammer.INPUT_MOVE,
isFinal: false
});
}
}
}
updateGestureConfig({
shouldActivateOnStart = false,
disallowInterruption = false,
shouldCancelWhenOutside = true,
minDurationMs = Number.NaN,
maxDist = Number.NaN,
minPointers = 1,
maxPointers = 1,
...props
}) {
return super.updateGestureConfig({
shouldActivateOnStart,
disallowInterruption,
shouldCancelWhenOutside,
minDurationMs,
maxDist,
minPointers,
maxPointers,
...props
});
}
}
export default PressGestureHandler;
//# sourceMappingURL=PressGestureHandler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,32 @@
import Hammer from '@egjs/hammerjs';
import { DEG_RAD } from './constants';
import IndiscreteGestureHandler from './IndiscreteGestureHandler';
class RotationGestureHandler extends IndiscreteGestureHandler {
get name() {
return 'rotate';
}
get NativeGestureClass() {
return Hammer.Rotate;
}
transformNativeEvent({
rotation,
velocity,
center
}) {
var _this$initialRotation;
return {
rotation: (rotation - ((_this$initialRotation = this.initialRotation) !== null && _this$initialRotation !== void 0 ? _this$initialRotation : 0)) * DEG_RAD,
anchorX: center.x,
anchorY: center.y,
velocity
};
}
}
export default RotationGestureHandler;
//# sourceMappingURL=RotationGestureHandler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["RotationGestureHandler.ts"],"names":["Hammer","DEG_RAD","IndiscreteGestureHandler","RotationGestureHandler","name","NativeGestureClass","Rotate","transformNativeEvent","rotation","velocity","center","initialRotation","anchorX","x","anchorY","y"],"mappings":"AAAA,OAAOA,MAAP,MAAmB,gBAAnB;AAEA,SAASC,OAAT,QAAwB,aAAxB;AAEA,OAAOC,wBAAP,MAAqC,4BAArC;;AAEA,MAAMC,sBAAN,SAAqCD,wBAArC,CAA8D;AACpD,MAAJE,IAAI,GAAG;AACT,WAAO,QAAP;AACD;;AAEqB,MAAlBC,kBAAkB,GAAG;AACvB,WAAOL,MAAM,CAACM,MAAd;AACD;;AAEDC,EAAAA,oBAAoB,CAAC;AAAEC,IAAAA,QAAF;AAAYC,IAAAA,QAAZ;AAAsBC,IAAAA;AAAtB,GAAD,EAAiD;AAAA;;AACnE,WAAO;AACLF,MAAAA,QAAQ,EAAE,CAACA,QAAQ,6BAAI,KAAKG,eAAT,yEAA4B,CAA5B,CAAT,IAA2CV,OADhD;AAELW,MAAAA,OAAO,EAAEF,MAAM,CAACG,CAFX;AAGLC,MAAAA,OAAO,EAAEJ,MAAM,CAACK,CAHX;AAILN,MAAAA;AAJK,KAAP;AAMD;;AAhB2D;;AAkB9D,eAAeN,sBAAf","sourcesContent":["import Hammer from '@egjs/hammerjs';\n\nimport { DEG_RAD } from './constants';\nimport { HammerInputExt } from './GestureHandler';\nimport IndiscreteGestureHandler from './IndiscreteGestureHandler';\n\nclass RotationGestureHandler extends IndiscreteGestureHandler {\n get name() {\n return 'rotate';\n }\n\n get NativeGestureClass() {\n return Hammer.Rotate;\n }\n\n transformNativeEvent({ rotation, velocity, center }: HammerInputExt) {\n return {\n rotation: (rotation - (this.initialRotation ?? 0)) * DEG_RAD,\n anchorX: center.x,\n anchorY: center.y,\n velocity,\n };\n }\n}\nexport default RotationGestureHandler;\n"]}

View File

@@ -0,0 +1,180 @@
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import Hammer from '@egjs/hammerjs';
import DiscreteGestureHandler from './DiscreteGestureHandler';
import { isnan } from './utils';
class TapGestureHandler extends DiscreteGestureHandler {
constructor(...args) {
super(...args);
_defineProperty(this, "_shouldFireEndEvent", null);
_defineProperty(this, "_timer", void 0);
_defineProperty(this, "_multiTapTimer", void 0);
_defineProperty(this, "onSuccessfulTap", ev => {
if (this._getPendingGestures().length) {
this._shouldFireEndEvent = ev;
return;
}
if (ev.eventType === Hammer.INPUT_END) {
this.sendEvent({ ...ev,
eventType: Hammer.INPUT_MOVE
});
} // When handler gets activated it will turn into State.END immediately.
this.sendEvent({ ...ev,
isFinal: true
});
this.onGestureEnded(ev);
});
}
// TODO unused?
get name() {
return 'tap';
}
get NativeGestureClass() {
return Hammer.Tap;
}
get maxDelayMs() {
// @ts-ignore TODO(TS) trace down config
return isnan(this.config.maxDelayMs) ? 300 : this.config.maxDelayMs;
}
simulateCancelEvent(inputData) {
if (this.isGestureRunning) {
this.cancelEvent(inputData);
}
}
onGestureActivated(ev) {
if (this.isGestureRunning) {
this.onSuccessfulTap(ev);
}
}
onRawEvent(ev) {
super.onRawEvent(ev); // Attempt to create a touch-down event by checking if a valid tap hasn't started yet, then validating the input.
if (!this.hasGestureFailed && !this.isGestureRunning && // Prevent multi-pointer events from misfiring.
!ev.isFinal) {
// Tap Gesture start event
const gesture = this.hammer.get(this.name); // @ts-ignore TODO(TS) trace down config
if (gesture.options.enable(gesture, ev)) {
clearTimeout(this._multiTapTimer);
this.onStart(ev);
this.sendEvent(ev);
}
}
if (ev.isFinal && ev.maxPointers > 1) {
setTimeout(() => {
// Handle case where one finger presses slightly
// after the first finger on a multi-tap event
if (this.isGestureRunning) {
this.cancelEvent(ev);
}
});
}
if (this.hasGestureFailed) {
return;
} // Hammer doesn't send a `cancel` event for taps.
// Manually fail the event.
if (ev.isFinal) {
// Handle case where one finger presses slightly
// after the first finger on a multi-tap event
if (ev.maxPointers > 1) {
setTimeout(() => {
if (this.isGestureRunning) {
this.cancelEvent(ev);
}
});
} // Clear last timer
clearTimeout(this._timer); // Create time out for multi-taps.
this._timer = setTimeout(() => {
this.hasGestureFailed = true;
this.cancelEvent(ev);
}, this.maxDelayMs);
} else if (!this.hasGestureFailed && !this.isGestureRunning) {
// Tap Gesture start event
const gesture = this.hammer.get(this.name); // @ts-ignore TODO(TS) trace down config
if (gesture.options.enable(gesture, ev)) {
clearTimeout(this._multiTapTimer);
this.onStart(ev);
this.sendEvent(ev);
}
}
}
getHammerConfig() {
return { ...super.getHammerConfig(),
event: this.name,
// @ts-ignore TODO(TS) trace down config
taps: isnan(this.config.numberOfTaps) ? 1 : this.config.numberOfTaps,
interval: this.maxDelayMs,
time: // @ts-ignore TODO(TS) trace down config
isnan(this.config.maxDurationMs) || this.config.maxDurationMs == null ? 250 : // @ts-ignore TODO(TS) trace down config
this.config.maxDurationMs
};
}
updateGestureConfig({
shouldCancelWhenOutside = true,
maxDeltaX = Number.NaN,
maxDeltaY = Number.NaN,
numberOfTaps = 1,
minDurationMs = 525,
maxDelayMs = Number.NaN,
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- TODO possibly forgotten to use in updateGestureConfig?
maxDurationMs = Number.NaN,
maxDist = 2,
minPointers = 1,
maxPointers = 1,
...props
}) {
return super.updateGestureConfig({
shouldCancelWhenOutside,
numberOfTaps,
maxDeltaX,
maxDeltaY,
minDurationMs,
maxDelayMs,
maxDist,
minPointers,
maxPointers,
...props
});
}
onGestureEnded(...props) {
clearTimeout(this._timer); // @ts-ignore TODO(TS) check how onGestureEnded works
super.onGestureEnded(...props);
}
onWaitingEnded(_gesture) {
if (this._shouldFireEndEvent) {
this.onSuccessfulTap(this._shouldFireEndEvent);
this._shouldFireEndEvent = null;
}
}
}
export default TapGestureHandler;
//# sourceMappingURL=TapGestureHandler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,43 @@
import Hammer from '@egjs/hammerjs';
import { State } from '../State';
export const CONTENT_TOUCHES_DELAY = 240;
export const CONTENT_TOUCHES_QUICK_TAP_END_DELAY = 50;
export const MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD = 0.1;
export const MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD = 7;
export const DEG_RAD = Math.PI / 180; // Map Hammer values to RNGH
export const EventMap = {
[Hammer.INPUT_START]: State.BEGAN,
[Hammer.INPUT_MOVE]: State.ACTIVE,
[Hammer.INPUT_END]: State.END,
[Hammer.INPUT_CANCEL]: State.FAILED
};
export const Direction = {
RIGHT: 1,
LEFT: 2,
UP: 4,
DOWN: 8
};
export const DirectionMap = {
[Hammer.DIRECTION_RIGHT]: Direction.RIGHT,
[Hammer.DIRECTION_LEFT]: Direction.LEFT,
[Hammer.DIRECTION_UP]: Direction.UP,
[Hammer.DIRECTION_DOWN]: Direction.DOWN
};
export const HammerInputNames = {
[Hammer.INPUT_START]: 'START',
[Hammer.INPUT_MOVE]: 'MOVE',
[Hammer.INPUT_END]: 'END',
[Hammer.INPUT_CANCEL]: 'CANCEL'
};
export const HammerDirectionNames = {
[Hammer.DIRECTION_HORIZONTAL]: 'HORIZONTAL',
[Hammer.DIRECTION_UP]: 'UP',
[Hammer.DIRECTION_DOWN]: 'DOWN',
[Hammer.DIRECTION_VERTICAL]: 'VERTICAL',
[Hammer.DIRECTION_NONE]: 'NONE',
[Hammer.DIRECTION_ALL]: 'ALL',
[Hammer.DIRECTION_RIGHT]: 'RIGHT',
[Hammer.DIRECTION_LEFT]: 'LEFT'
};
//# sourceMappingURL=constants.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["constants.ts"],"names":["Hammer","State","CONTENT_TOUCHES_DELAY","CONTENT_TOUCHES_QUICK_TAP_END_DELAY","MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD","MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD","DEG_RAD","Math","PI","EventMap","INPUT_START","BEGAN","INPUT_MOVE","ACTIVE","INPUT_END","END","INPUT_CANCEL","FAILED","Direction","RIGHT","LEFT","UP","DOWN","DirectionMap","DIRECTION_RIGHT","DIRECTION_LEFT","DIRECTION_UP","DIRECTION_DOWN","HammerInputNames","HammerDirectionNames","DIRECTION_HORIZONTAL","DIRECTION_VERTICAL","DIRECTION_NONE","DIRECTION_ALL"],"mappings":"AAAA,OAAOA,MAAP,MAAmB,gBAAnB;AAEA,SAASC,KAAT,QAAsB,UAAtB;AAEA,OAAO,MAAMC,qBAAqB,GAAG,GAA9B;AACP,OAAO,MAAMC,mCAAmC,GAAG,EAA5C;AACP,OAAO,MAAMC,oCAAoC,GAAG,GAA7C;AACP,OAAO,MAAMC,uCAAuC,GAAG,CAAhD;AACP,OAAO,MAAMC,OAAO,GAAGC,IAAI,CAACC,EAAL,GAAU,GAA1B,C,CAEP;;AACA,OAAO,MAAMC,QAAQ,GAAG;AACtB,GAACT,MAAM,CAACU,WAAR,GAAsBT,KAAK,CAACU,KADN;AAEtB,GAACX,MAAM,CAACY,UAAR,GAAqBX,KAAK,CAACY,MAFL;AAGtB,GAACb,MAAM,CAACc,SAAR,GAAoBb,KAAK,CAACc,GAHJ;AAItB,GAACf,MAAM,CAACgB,YAAR,GAAuBf,KAAK,CAACgB;AAJP,CAAjB;AAOP,OAAO,MAAMC,SAAS,GAAG;AACvBC,EAAAA,KAAK,EAAE,CADgB;AAEvBC,EAAAA,IAAI,EAAE,CAFiB;AAGvBC,EAAAA,EAAE,EAAE,CAHmB;AAIvBC,EAAAA,IAAI,EAAE;AAJiB,CAAlB;AAOP,OAAO,MAAMC,YAAY,GAAG;AAC1B,GAACvB,MAAM,CAACwB,eAAR,GAA0BN,SAAS,CAACC,KADV;AAE1B,GAACnB,MAAM,CAACyB,cAAR,GAAyBP,SAAS,CAACE,IAFT;AAG1B,GAACpB,MAAM,CAAC0B,YAAR,GAAuBR,SAAS,CAACG,EAHP;AAI1B,GAACrB,MAAM,CAAC2B,cAAR,GAAyBT,SAAS,CAACI;AAJT,CAArB;AAOP,OAAO,MAAMM,gBAAgB,GAAG;AAC9B,GAAC5B,MAAM,CAACU,WAAR,GAAsB,OADQ;AAE9B,GAACV,MAAM,CAACY,UAAR,GAAqB,MAFS;AAG9B,GAACZ,MAAM,CAACc,SAAR,GAAoB,KAHU;AAI9B,GAACd,MAAM,CAACgB,YAAR,GAAuB;AAJO,CAAzB;AAMP,OAAO,MAAMa,oBAAoB,GAAG;AAClC,GAAC7B,MAAM,CAAC8B,oBAAR,GAA+B,YADG;AAElC,GAAC9B,MAAM,CAAC0B,YAAR,GAAuB,IAFW;AAGlC,GAAC1B,MAAM,CAAC2B,cAAR,GAAyB,MAHS;AAIlC,GAAC3B,MAAM,CAAC+B,kBAAR,GAA6B,UAJK;AAKlC,GAAC/B,MAAM,CAACgC,cAAR,GAAyB,MALS;AAMlC,GAAChC,MAAM,CAACiC,aAAR,GAAwB,KANU;AAOlC,GAACjC,MAAM,CAACwB,eAAR,GAA0B,OAPQ;AAQlC,GAACxB,MAAM,CAACyB,cAAR,GAAyB;AARS,CAA7B","sourcesContent":["import Hammer from '@egjs/hammerjs';\n\nimport { State } from '../State';\n\nexport const CONTENT_TOUCHES_DELAY = 240;\nexport const CONTENT_TOUCHES_QUICK_TAP_END_DELAY = 50;\nexport const MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD = 0.1;\nexport const MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD = 7;\nexport const DEG_RAD = Math.PI / 180;\n\n// Map Hammer values to RNGH\nexport const EventMap = {\n [Hammer.INPUT_START]: State.BEGAN,\n [Hammer.INPUT_MOVE]: State.ACTIVE,\n [Hammer.INPUT_END]: State.END,\n [Hammer.INPUT_CANCEL]: State.FAILED,\n} as const;\n\nexport const Direction = {\n RIGHT: 1,\n LEFT: 2,\n UP: 4,\n DOWN: 8,\n};\n\nexport const DirectionMap = {\n [Hammer.DIRECTION_RIGHT]: Direction.RIGHT,\n [Hammer.DIRECTION_LEFT]: Direction.LEFT,\n [Hammer.DIRECTION_UP]: Direction.UP,\n [Hammer.DIRECTION_DOWN]: Direction.DOWN,\n};\n\nexport const HammerInputNames = {\n [Hammer.INPUT_START]: 'START',\n [Hammer.INPUT_MOVE]: 'MOVE',\n [Hammer.INPUT_END]: 'END',\n [Hammer.INPUT_CANCEL]: 'CANCEL',\n};\nexport const HammerDirectionNames = {\n [Hammer.DIRECTION_HORIZONTAL]: 'HORIZONTAL',\n [Hammer.DIRECTION_UP]: 'UP',\n [Hammer.DIRECTION_DOWN]: 'DOWN',\n [Hammer.DIRECTION_VERTICAL]: 'VERTICAL',\n [Hammer.DIRECTION_NONE]: 'NONE',\n [Hammer.DIRECTION_ALL]: 'ALL',\n [Hammer.DIRECTION_RIGHT]: 'RIGHT',\n [Hammer.DIRECTION_LEFT]: 'LEFT',\n};\n"]}

View File

@@ -0,0 +1,19 @@
// TODO(TS) remove if not necessary after rewrite
export const isnan = v => Number.isNaN(v); // TODO(TS) remove if not necessary after rewrite
export const isValidNumber = v => typeof v === 'number' && !Number.isNaN(v);
export const TEST_MIN_IF_NOT_NAN = (value, limit) => !isnan(limit) && (limit < 0 && value <= limit || limit >= 0 && value >= limit);
export const VEC_LEN_SQ = ({
x = 0,
y = 0
} = {}) => x * x + y * y;
export const TEST_MAX_IF_NOT_NAN = (value, max) => !isnan(max) && (max < 0 && value < max || max >= 0 && value > max);
export function fireAfterInterval(method, interval) {
if (!interval) {
method();
return null;
}
return setTimeout(() => method(), interval);
}
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["utils.ts"],"names":["isnan","v","Number","isNaN","isValidNumber","TEST_MIN_IF_NOT_NAN","value","limit","VEC_LEN_SQ","x","y","TEST_MAX_IF_NOT_NAN","max","fireAfterInterval","method","interval","setTimeout"],"mappings":"AAAA;AACA,OAAO,MAAMA,KAAK,GAAIC,CAAD,IAAgBC,MAAM,CAACC,KAAP,CAAaF,CAAb,CAA9B,C,CAEP;;AACA,OAAO,MAAMG,aAAa,GAAIH,CAAD,IAC3B,OAAOA,CAAP,KAAa,QAAb,IAAyB,CAACC,MAAM,CAACC,KAAP,CAAaF,CAAb,CADrB;AAGP,OAAO,MAAMI,mBAAmB,GAAG,CAACC,KAAD,EAAgBC,KAAhB,KACjC,CAACP,KAAK,CAACO,KAAD,CAAN,KACEA,KAAK,GAAG,CAAR,IAAaD,KAAK,IAAIC,KAAvB,IAAkCA,KAAK,IAAI,CAAT,IAAcD,KAAK,IAAIC,KAD1D,CADK;AAGP,OAAO,MAAMC,UAAU,GAAG,CAAC;AAAEC,EAAAA,CAAC,GAAG,CAAN;AAASC,EAAAA,CAAC,GAAG;AAAb,IAAmB,EAApB,KAA2BD,CAAC,GAAGA,CAAJ,GAAQC,CAAC,GAAGA,CAA1D;AACP,OAAO,MAAMC,mBAAmB,GAAG,CAACL,KAAD,EAAgBM,GAAhB,KACjC,CAACZ,KAAK,CAACY,GAAD,CAAN,KAAiBA,GAAG,GAAG,CAAN,IAAWN,KAAK,GAAGM,GAApB,IAA6BA,GAAG,IAAI,CAAP,IAAYN,KAAK,GAAGM,GAAjE,CADK;AAGP,OAAO,SAASC,iBAAT,CACLC,MADK,EAELC,QAFK,EAGL;AACA,MAAI,CAACA,QAAL,EAAe;AACbD,IAAAA,MAAM;AACN,WAAO,IAAP;AACD;;AACD,SAAOE,UAAU,CAAC,MAAMF,MAAM,EAAb,EAAiBC,QAAjB,CAAjB;AACD","sourcesContent":["// TODO(TS) remove if not necessary after rewrite\nexport const isnan = (v: unknown) => Number.isNaN(v);\n\n// TODO(TS) remove if not necessary after rewrite\nexport const isValidNumber = (v: unknown) =>\n typeof v === 'number' && !Number.isNaN(v);\n\nexport const TEST_MIN_IF_NOT_NAN = (value: number, limit: number): boolean =>\n !isnan(limit) &&\n ((limit < 0 && value <= limit) || (limit >= 0 && value >= limit));\nexport const VEC_LEN_SQ = ({ x = 0, y = 0 } = {}) => x * x + y * y;\nexport const TEST_MAX_IF_NOT_NAN = (value: number, max: number) =>\n !isnan(max) && ((max < 0 && value < max) || (max >= 0 && value > max));\n\nexport function fireAfterInterval(\n method: () => void,\n interval?: number | boolean\n) {\n if (!interval) {\n method();\n return null;\n }\n return setTimeout(() => method(), interval as number);\n}\n"]}