- 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
156 lines
4.9 KiB
TypeScript
156 lines
4.9 KiB
TypeScript
import { DeviceEventEmitter, EmitterSubscription } from 'react-native';
|
|
import { State } from '../../State';
|
|
import { TouchEventType } from '../../TouchEventType';
|
|
import {
|
|
GestureTouchEvent,
|
|
GestureUpdateEvent,
|
|
GestureStateChangeEvent,
|
|
} from '../gestureHandlerCommon';
|
|
import { findHandler, findOldGestureHandler } from '../handlersRegistry';
|
|
import { BaseGesture } from './gesture';
|
|
import {
|
|
GestureStateManager,
|
|
GestureStateManagerType,
|
|
} from './gestureStateManager';
|
|
|
|
let gestureHandlerEventSubscription: EmitterSubscription | null = null;
|
|
let gestureHandlerStateChangeEventSubscription: EmitterSubscription | null =
|
|
null;
|
|
|
|
const gestureStateManagers: Map<number, GestureStateManagerType> = new Map<
|
|
number,
|
|
GestureStateManagerType
|
|
>();
|
|
|
|
const lastUpdateEvent: (GestureUpdateEvent | undefined)[] = [];
|
|
|
|
function isStateChangeEvent(
|
|
event: GestureUpdateEvent | GestureStateChangeEvent | GestureTouchEvent
|
|
): event is GestureStateChangeEvent {
|
|
// @ts-ignore oldState doesn't exist on GestureTouchEvent and that's the point
|
|
return event.oldState != null;
|
|
}
|
|
|
|
function isTouchEvent(
|
|
event: GestureUpdateEvent | GestureStateChangeEvent | GestureTouchEvent
|
|
): event is GestureTouchEvent {
|
|
return event.eventType != null;
|
|
}
|
|
|
|
export function onGestureHandlerEvent(
|
|
event: GestureUpdateEvent | GestureStateChangeEvent | GestureTouchEvent
|
|
) {
|
|
const handler = findHandler(event.handlerTag) as BaseGesture<
|
|
Record<string, unknown>
|
|
>;
|
|
|
|
if (handler) {
|
|
if (isStateChangeEvent(event)) {
|
|
if (
|
|
event.oldState === State.UNDETERMINED &&
|
|
event.state === State.BEGAN
|
|
) {
|
|
handler.handlers.onBegin?.(event);
|
|
} else if (
|
|
(event.oldState === State.BEGAN ||
|
|
event.oldState === State.UNDETERMINED) &&
|
|
event.state === State.ACTIVE
|
|
) {
|
|
handler.handlers.onStart?.(event);
|
|
lastUpdateEvent[handler.handlers.handlerTag] = event;
|
|
} else if (event.oldState !== event.state && event.state === State.END) {
|
|
if (event.oldState === State.ACTIVE) {
|
|
handler.handlers.onEnd?.(event, true);
|
|
}
|
|
handler.handlers.onFinalize?.(event, true);
|
|
lastUpdateEvent[handler.handlers.handlerTag] = undefined;
|
|
} else if (
|
|
(event.state === State.FAILED || event.state === State.CANCELLED) &&
|
|
event.oldState !== event.state
|
|
) {
|
|
if (event.oldState === State.ACTIVE) {
|
|
handler.handlers.onEnd?.(event, false);
|
|
}
|
|
handler.handlers.onFinalize?.(event, false);
|
|
gestureStateManagers.delete(event.handlerTag);
|
|
lastUpdateEvent[handler.handlers.handlerTag] = undefined;
|
|
}
|
|
} else if (isTouchEvent(event)) {
|
|
if (!gestureStateManagers.has(event.handlerTag)) {
|
|
gestureStateManagers.set(
|
|
event.handlerTag,
|
|
GestureStateManager.create(event.handlerTag)
|
|
);
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
const manager = gestureStateManagers.get(event.handlerTag)!;
|
|
|
|
switch (event.eventType) {
|
|
case TouchEventType.TOUCHES_DOWN:
|
|
handler.handlers?.onTouchesDown?.(event, manager);
|
|
break;
|
|
case TouchEventType.TOUCHES_MOVE:
|
|
handler.handlers?.onTouchesMove?.(event, manager);
|
|
break;
|
|
case TouchEventType.TOUCHES_UP:
|
|
handler.handlers?.onTouchesUp?.(event, manager);
|
|
break;
|
|
case TouchEventType.TOUCHES_CANCELLED:
|
|
handler.handlers?.onTouchesCancelled?.(event, manager);
|
|
break;
|
|
}
|
|
} else {
|
|
handler.handlers.onUpdate?.(event);
|
|
|
|
if (handler.handlers.onChange && handler.handlers.changeEventCalculator) {
|
|
handler.handlers.onChange?.(
|
|
handler.handlers.changeEventCalculator?.(
|
|
event,
|
|
lastUpdateEvent[handler.handlers.handlerTag]
|
|
)
|
|
);
|
|
|
|
lastUpdateEvent[handler.handlers.handlerTag] = event;
|
|
}
|
|
}
|
|
} else {
|
|
const oldHandler = findOldGestureHandler(event.handlerTag);
|
|
if (oldHandler) {
|
|
const nativeEvent = { nativeEvent: event };
|
|
if (isStateChangeEvent(event)) {
|
|
oldHandler.onGestureStateChange(nativeEvent);
|
|
} else {
|
|
oldHandler.onGestureEvent(nativeEvent);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
export function startListening() {
|
|
stopListening();
|
|
|
|
gestureHandlerEventSubscription = DeviceEventEmitter.addListener(
|
|
'onGestureHandlerEvent',
|
|
onGestureHandlerEvent
|
|
);
|
|
|
|
gestureHandlerStateChangeEventSubscription = DeviceEventEmitter.addListener(
|
|
'onGestureHandlerStateChange',
|
|
onGestureHandlerEvent
|
|
);
|
|
}
|
|
|
|
export function stopListening() {
|
|
if (gestureHandlerEventSubscription) {
|
|
gestureHandlerEventSubscription.remove();
|
|
gestureHandlerEventSubscription = null;
|
|
}
|
|
|
|
if (gestureHandlerStateChangeEventSubscription) {
|
|
gestureHandlerStateChangeEventSubscription.remove();
|
|
gestureHandlerStateChangeEventSubscription = null;
|
|
}
|
|
}
|