Files
smart-city-digital-twin-mar…/smart-app-city/frontend/node_modules/react-native/Libraries/Inspector/ReactDevToolsOverlay.js
Eric FELIXINE e30ae8ed09 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
2026-06-01 18:00:35 -04:00

172 lines
4.5 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
import type {InspectedViewRef} from '../ReactNative/AppContainer-dev';
import type {PointerEvent} from '../Types/CoreEventTypes';
import type {PressEvent} from '../Types/CoreEventTypes';
import type {ReactDevToolsAgent} from '../Types/ReactDevToolsTypes';
import type {InspectedElement} from './Inspector';
import View from '../Components/View/View';
import ReactNativeFeatureFlags from '../ReactNative/ReactNativeFeatureFlags';
import StyleSheet from '../StyleSheet/StyleSheet';
import ElementBox from './ElementBox';
import * as React from 'react';
const {findNodeHandle} = require('../ReactNative/RendererProxy');
const getInspectorDataForViewAtPoint = require('./getInspectorDataForViewAtPoint');
const {useEffect, useState, useCallback} = React;
type Props = {
inspectedViewRef: InspectedViewRef,
reactDevToolsAgent: ReactDevToolsAgent,
};
export default function ReactDevToolsOverlay({
inspectedViewRef,
reactDevToolsAgent,
}: Props): React.Node {
const [inspected, setInspected] = useState<?InspectedElement>(null);
const [isInspecting, setIsInspecting] = useState(false);
useEffect(() => {
function cleanup() {
reactDevToolsAgent.removeListener('shutdown', cleanup);
reactDevToolsAgent.removeListener(
'startInspectingNative',
onStartInspectingNative,
);
reactDevToolsAgent.removeListener(
'stopInspectingNative',
onStopInspectingNative,
);
}
function onStartInspectingNative() {
setIsInspecting(true);
}
function onStopInspectingNative() {
setIsInspecting(false);
}
reactDevToolsAgent.addListener('shutdown', cleanup);
reactDevToolsAgent.addListener(
'startInspectingNative',
onStartInspectingNative,
);
reactDevToolsAgent.addListener(
'stopInspectingNative',
onStopInspectingNative,
);
return cleanup;
}, [reactDevToolsAgent]);
const findViewForLocation = useCallback(
(x: number, y: number) => {
getInspectorDataForViewAtPoint(
inspectedViewRef.current,
x,
y,
viewData => {
const {touchedViewTag, closestInstance, frame} = viewData;
if (closestInstance != null || touchedViewTag != null) {
// We call `selectNode` for both non-fabric(viewTag) and fabric(instance),
// this makes sure it works for both architectures.
reactDevToolsAgent.selectNode(findNodeHandle(touchedViewTag));
if (closestInstance != null) {
reactDevToolsAgent.selectNode(closestInstance);
}
setInspected({
frame,
});
return true;
}
return false;
},
);
},
[inspectedViewRef, reactDevToolsAgent],
);
const stopInspecting = useCallback(() => {
reactDevToolsAgent.stopInspectingNative(true);
setIsInspecting(false);
setInspected(null);
}, [reactDevToolsAgent]);
const onPointerMove = useCallback(
(e: PointerEvent) => {
findViewForLocation(e.nativeEvent.x, e.nativeEvent.y);
},
[findViewForLocation],
);
const onResponderMove = useCallback(
(e: PressEvent) => {
findViewForLocation(
e.nativeEvent.touches[0].locationX,
e.nativeEvent.touches[0].locationY,
);
},
[findViewForLocation],
);
const shouldSetResponder = useCallback(
(e: PressEvent): boolean => {
onResponderMove(e);
return true;
},
[onResponderMove],
);
const highlight = inspected ? <ElementBox frame={inspected.frame} /> : null;
if (isInspecting) {
const events =
// Pointer events only work on fabric
ReactNativeFeatureFlags.shouldEmitW3CPointerEvents()
? {
onPointerMove,
onPointerDown: onPointerMove,
onPointerUp: stopInspecting,
}
: {
onStartShouldSetResponder: shouldSetResponder,
onResponderMove: onResponderMove,
onResponderRelease: stopInspecting,
};
return (
<View
nativeID="devToolsInspectorOverlay"
style={styles.inspector}
{...events}>
{highlight}
</View>
);
}
return highlight;
}
const styles = StyleSheet.create({
inspector: {
backgroundColor: 'transparent',
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
},
});