- 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
120 lines
4.4 KiB
JavaScript
120 lines
4.4 KiB
JavaScript
'use strict';
|
|
|
|
import { reportFatalErrorOnJS } from './errors';
|
|
import { isChromeDebugger, isJest, shouldBeUseWeb } from './PlatformChecker';
|
|
import { runOnJS, setupMicrotasks, callMicrotasks, runOnUIImmediately } from './threads';
|
|
import { mockedRequestAnimationFrame } from './mockedRequestAnimationFrame';
|
|
const IS_JEST = isJest();
|
|
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
|
|
const IS_CHROME_DEBUGGER = isChromeDebugger();
|
|
|
|
// callGuard is only used with debug builds
|
|
export function callGuardDEV(fn, ...args) {
|
|
'worklet';
|
|
|
|
try {
|
|
return fn(...args);
|
|
} catch (e) {
|
|
if (global.__ErrorUtils) {
|
|
global.__ErrorUtils.reportFatalError(e);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
export function setupCallGuard() {
|
|
'worklet';
|
|
|
|
global.__callGuardDEV = callGuardDEV;
|
|
global.__ErrorUtils = {
|
|
reportFatalError: error => {
|
|
runOnJS(reportFatalErrorOnJS)({
|
|
message: error.message,
|
|
stack: error.stack
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
// We really have to create a copy of console here. Function runOnJS we use on elements inside
|
|
// this object makes it not configurable
|
|
const capturableConsole = {
|
|
...console
|
|
};
|
|
export function setupConsole() {
|
|
'worklet';
|
|
|
|
if (!IS_CHROME_DEBUGGER) {
|
|
// @ts-ignore TypeScript doesn't like that there are missing methods in console object, but we don't provide all the methods for the UI runtime console version
|
|
global.console = {
|
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
assert: runOnJS(capturableConsole.assert),
|
|
debug: runOnJS(capturableConsole.debug),
|
|
log: runOnJS(capturableConsole.log),
|
|
warn: runOnJS(capturableConsole.warn),
|
|
error: runOnJS(capturableConsole.error),
|
|
info: runOnJS(capturableConsole.info)
|
|
/* eslint-enable @typescript-eslint/unbound-method */
|
|
};
|
|
}
|
|
}
|
|
function setupRequestAnimationFrame() {
|
|
'worklet';
|
|
|
|
// Jest mocks requestAnimationFrame API and it does not like if that mock gets overridden
|
|
// so we avoid doing requestAnimationFrame batching in Jest environment.
|
|
const nativeRequestAnimationFrame = global.requestAnimationFrame;
|
|
let animationFrameCallbacks = [];
|
|
let lastNativeAnimationFrameTimestamp = -1;
|
|
global.__flushAnimationFrame = frameTimestamp => {
|
|
const currentCallbacks = animationFrameCallbacks;
|
|
animationFrameCallbacks = [];
|
|
currentCallbacks.forEach(f => f(frameTimestamp));
|
|
callMicrotasks();
|
|
};
|
|
global.requestAnimationFrame = callback => {
|
|
animationFrameCallbacks.push(callback);
|
|
if (animationFrameCallbacks.length === 1) {
|
|
// We schedule native requestAnimationFrame only when the first callback
|
|
// is added and then use it to execute all the enqueued callbacks. Once
|
|
// the callbacks are run, we clear the array.
|
|
nativeRequestAnimationFrame(timestamp => {
|
|
if (lastNativeAnimationFrameTimestamp >= timestamp) {
|
|
// Make sure we only execute the callbacks once for a given frame
|
|
return;
|
|
}
|
|
lastNativeAnimationFrameTimestamp = timestamp;
|
|
global.__frameTimestamp = timestamp;
|
|
global.__flushAnimationFrame(timestamp);
|
|
global.__frameTimestamp = undefined;
|
|
});
|
|
}
|
|
// Reanimated currently does not support cancelling callbacks requested with
|
|
// requestAnimationFrame. We return -1 as identifier which isn't in line
|
|
// with the spec but it should give users better clue in case they actually
|
|
// attempt to store the value returned from rAF and use it for cancelling.
|
|
return -1;
|
|
};
|
|
}
|
|
export function initializeUIRuntime() {
|
|
if (IS_JEST) {
|
|
// requestAnimationFrame react-native jest's setup is incorrect as it polyfills
|
|
// the method directly using setTimeout, therefore the callback doesn't get the
|
|
// expected timestamp as the only argument: https://github.com/facebook/react-native/blob/main/packages/react-native/jest/setup.js#L28
|
|
// We override this setup here to make sure that callbacks get the proper timestamps
|
|
// when executed. For non-jest environments we define requestAnimationFrame in setupRequestAnimationFrame
|
|
// @ts-ignore TypeScript uses Node definition for rAF, setTimeout, etc which returns a Timeout object rather than a number
|
|
globalThis.requestAnimationFrame = mockedRequestAnimationFrame;
|
|
}
|
|
runOnUIImmediately(() => {
|
|
'worklet';
|
|
|
|
setupCallGuard();
|
|
setupConsole();
|
|
if (!SHOULD_BE_USE_WEB) {
|
|
setupMicrotasks();
|
|
setupRequestAnimationFrame();
|
|
}
|
|
})();
|
|
}
|
|
//# sourceMappingURL=initializers.js.map
|