6 Commits

Author SHA1 Message Date
billisdead 67c132d88b fix: add mic to service field, refresh list on screen focus
Release APK / build (push) Has been cancelled
new.tsx: service field was missing its mic button — VoiceField type
excluded "service" and the label used a plain Text instead of labelRow().

index.tsx: incident list only loaded on mount; router.back() does not
remount the screen so new incidents never appeared. useFocusEffect
replaces the one-shot useEffect so the list reloads on every focus.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:51:43 +02:00
billisdead f1a4b58234 refactor: remove crash reporter from _layout.tsx
Release APK / build (push) Has been cancelled
CrashBoundary and ErrorUtils debug handler were temporary scaffolding
to identify the launch crash (react version mismatch). Removing now
that the root cause is fixed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:50:15 +02:00
billisdead dca76ea394 fix: add npm overrides to align react + react-dom to 19.2.3
Release APK / build (push) Has been cancelled
react-dom@19.2.7 has a hard peer dep on react@^19.2.7, breaking
npm ci when react is pinned to 19.2.3. npm overrides force both
packages to 19.2.3 so the lock file resolves cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:20:49 +02:00
billisdead af8ec98bb4 fix: pin react to 19.2.3 to match react-native-renderer
Release APK / build (push) Has been cancelled
react-native@0.85.3 bundles react-native-renderer@19.2.3. Having
react@19.2.7 in package.json caused a version mismatch error at
runtime ("Incompatible React versions") that killed the process
before any JS could render, appearing as a native crash.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:18:03 +02:00
billisdead c43b913dde fix: exclude reanimated/worklets native build, disable New Architecture
Release APK / build (push) Has been cancelled
react-native.config.js excludes react-native-reanimated and
react-native-worklets from Android native linking — neither is used in
the app and react-native-gesture-handler has a dedicated noreanimated
codepath for exactly this case.

build-apk.sh step 4.6 forces newArchEnabled=false in gradle.properties
after expo prebuild, as a fallback for New Architecture init issues
on Android 15.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 15:16:37 +02:00
billisdead 256b338ae3 fix: patch worklets and reanimated for Android 15 16KB page size support
Release APK / build (push) Has been cancelled
react-native-worklets and react-native-reanimated compile .so files
without -Wl,-z,max-page-size=16384, causing a native crash at startup
on Android 15 devices that use 16KB memory pages (Pixel 9+, Galaxy S25+).
Patch applied in build-apk.sh and CI workflow after npm install, before
the Gradle build. Guard prevents double-patching on repeated runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 14:23:38 +02:00
8 changed files with 212 additions and 229 deletions
+11
View File
@@ -89,6 +89,17 @@ jobs:
[ -n "$KEYSTORE_STORE_PASSWORD" ] && echo "KEYSTORE_STORE_PASSWORD: set" || echo "KEYSTORE_STORE_PASSWORD: EMPTY"
[ -n "$KEYSTORE_KEY_PASSWORD" ] && echo "KEYSTORE_KEY_PASSWORD: set" || echo "KEYSTORE_KEY_PASSWORD: EMPTY"
- name: Patch native modules for Android 15 16KB page size
run: |
WORKLETS="node_modules/react-native-worklets/android/CMakeLists.txt"
REANIMATED="node_modules/react-native-reanimated/android/CMakeLists.txt"
if [ -f "$WORKLETS" ] && ! grep -q "max-page-size" "$WORKLETS"; then
printf '\ntarget_link_options(worklets PRIVATE "-Wl,-z,max-page-size=16384")\n' >> "$WORKLETS"
fi
if [ -f "$REANIMATED" ] && ! grep -q "max-page-size" "$REANIMATED"; then
printf '\ntarget_link_options(reanimated PRIVATE "-Wl,-z,max-page-size=16384")\n' >> "$REANIMATED"
fi
- name: Build signed APK
run: ./build-apk.sh
+1 -60
View File
@@ -1,55 +1,13 @@
import { useEffect, useState, Component } from "react";
import type { ReactNode } from "react";
import { useEffect } from "react";
import { Stack, router } from "expo-router";
import { StatusBar } from "expo-status-bar";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { View, Text, ScrollView } from "react-native";
import "../global.css";
import { Colors } from "@/constants/theme";
import { useSettings } from "@/hooks/useSettings";
// Catch JS errors in release mode and show them on-screen instead of
// silently crashing to desktop. Remove once the crash is identified.
class CrashBoundary extends Component<
{ children: ReactNode },
{ error: Error | null }
> {
state = { error: null };
static getDerivedStateFromError(e: Error) {
return { error: e };
}
render() {
const { error } = this.state;
if (error) {
return (
<View style={{ flex: 1, backgroundColor: "#0f1117", padding: 20, paddingTop: 60 }}>
<Text style={{ color: "#ef4444", fontSize: 16, fontWeight: "700", marginBottom: 12 }}>
CRASH copie ce texte
</Text>
<ScrollView>
<Text style={{ color: "#fff", fontSize: 11, fontFamily: "monospace" }}>
{String(error)}{"\n\n"}{(error as any).stack}
</Text>
</ScrollView>
</View>
);
}
return this.props.children;
}
}
export default function RootLayout() {
const { settings, ready } = useSettings();
const [jsError, setJsError] = useState<string | null>(null);
useEffect(() => {
const prev = (ErrorUtils as any).getGlobalHandler();
(ErrorUtils as any).setGlobalHandler((e: Error, isFatal: boolean) => {
if (isFatal) setJsError(`${String(e)}\n\n${(e as any).stack ?? ""}`);
prev?.(e, isFatal);
});
return () => (ErrorUtils as any).setGlobalHandler(prev);
}, []);
useEffect(() => {
if (!ready) return;
@@ -58,23 +16,7 @@ export default function RootLayout() {
}
}, [ready, settings.onboardingDone]);
if (jsError) {
return (
<View style={{ flex: 1, backgroundColor: "#0f1117", padding: 20, paddingTop: 60 }}>
<Text style={{ color: "#ef4444", fontSize: 16, fontWeight: "700", marginBottom: 12 }}>
FATAL JS ERROR copie ce texte
</Text>
<ScrollView>
<Text style={{ color: "#fff", fontSize: 11, fontFamily: "monospace" }}>
{jsError}
</Text>
</ScrollView>
</View>
);
}
return (
<CrashBoundary>
<GestureHandlerRootView style={{ flex: 1, backgroundColor: Colors.bg }}>
<StatusBar style="light" />
<Stack
@@ -93,6 +35,5 @@ export default function RootLayout() {
<Stack.Screen name="onboarding" options={{ headerShown: false }} />
</Stack>
</GestureHandlerRootView>
</CrashBoundary>
);
}
+6 -4
View File
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import {
View,
Text,
@@ -6,7 +6,7 @@ import {
Pressable,
ActivityIndicator,
} from "react-native";
import { router } from "expo-router";
import { router, useFocusEffect } from "expo-router";
import { getIncidents } from "@/lib/db";
import { useSettings } from "@/hooks/useSettings";
import type { Incident } from "@/types/incident";
@@ -26,9 +26,11 @@ export default function HomeScreen() {
}
}, [ready, settings.homeView]);
useEffect(() => {
useFocusEffect(
useCallback(() => {
loadIncidents();
}, []);
}, [])
);
async function loadIncidents() {
setLoading(true);
+2 -2
View File
@@ -46,7 +46,7 @@ const LABEL_STYLE = {
letterSpacing: 0.5,
} as const;
type VoiceField = "title" | "symptom" | "rootCause" | "fix";
type VoiceField = "title" | "service" | "symptom" | "rootCause" | "fix";
export default function NewIncidentScreen() {
const { editId } = useLocalSearchParams<{ editId?: string }>();
@@ -224,7 +224,7 @@ export default function NewIncidentScreen() {
returnKeyType="next"
/>
<Text style={[LABEL_STYLE, { marginBottom: 6 }]}>Service</Text>
{labelRow("Service", "service")}
<TextInput
style={FIELD_STYLE}
value={form.service}
+26
View File
@@ -77,6 +77,32 @@ info "Running expo prebuild (Android)…"
cd "$SCRIPT_DIR"
npx expo prebuild --platform android --clean --no-install
# ─── 4.5. Patch native modules — 16KB page size (Android 15) ──────────────
info "Patching native modules for 16KB page size support (Android 15)…"
WORKLETS_CMAKE="$SCRIPT_DIR/node_modules/react-native-worklets/android/CMakeLists.txt"
REANIMATED_CMAKE="$SCRIPT_DIR/node_modules/react-native-reanimated/android/CMakeLists.txt"
if [ -f "$WORKLETS_CMAKE" ] && ! grep -q "max-page-size" "$WORKLETS_CMAKE"; then
printf '\ntarget_link_options(worklets PRIVATE "-Wl,-z,max-page-size=16384")\n' >> "$WORKLETS_CMAKE"
info "Patched react-native-worklets for 16KB pages"
fi
if [ -f "$REANIMATED_CMAKE" ] && ! grep -q "max-page-size" "$REANIMATED_CMAKE"; then
printf '\ntarget_link_options(reanimated PRIVATE "-Wl,-z,max-page-size=16384")\n' >> "$REANIMATED_CMAKE"
info "Patched react-native-reanimated for 16KB pages"
fi
# ─── 4.6. Disable New Architecture (Android 15 compat) ────────────────────
GRADLE_PROPS_NEWARCH="$SCRIPT_DIR/android/gradle.properties"
if [ -f "$GRADLE_PROPS_NEWARCH" ]; then
sed -i 's/^newArchEnabled=true/newArchEnabled=false/' "$GRADLE_PROPS_NEWARCH"
if ! grep -q "^newArchEnabled=" "$GRADLE_PROPS_NEWARCH"; then
echo "newArchEnabled=false" >> "$GRADLE_PROPS_NEWARCH"
fi
info "New Architecture disabled in gradle.properties"
fi
# ─── 5. Patch build.gradle — inject release signingConfig ──────────────────
info "Patching android/app/build.gradle for release signing…"
+129 -143
View File
@@ -19,7 +19,7 @@
"expo-sqlite": "~56.0.5",
"expo-status-bar": "~56.0.4",
"nativewind": "~4.2.5",
"react": "19.2.7",
"react": "19.2.3",
"react-native": "0.85.3",
"react-native-gesture-handler": "~3.0.2",
"react-native-reanimated": "~4.4.1",
@@ -1154,99 +1154,6 @@
"integrity": "sha512-IJkBtN1o8u9BW5fvSii1MyHPQ7Q0HxbWcVBvOrOzgMLpVtZw7R2w94wBTVR7kZwv3w1JNTESMmLA5Sqn1+Z36A==",
"license": "MIT AND Apache-2.0"
},
"node_modules/@expo/cli": {
"version": "56.1.16",
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-56.1.16.tgz",
"integrity": "sha512-VBQn0mqAwc67b9Cn0RVXyeodghomAx5xGRhA/bXaQzuxDjMQk0zIOb6pXMZX7yiIwJW66UZt/zQiJNSv6aWJYw==",
"license": "MIT",
"dependencies": {
"@expo/code-signing-certificates": "^0.0.6",
"@expo/config": "~56.0.9",
"@expo/config-plugins": "~56.0.9",
"@expo/devcert": "^1.2.1",
"@expo/env": "~2.3.0",
"@expo/image-utils": "^0.10.1",
"@expo/inline-modules": "^0.0.12",
"@expo/json-file": "^10.2.0",
"@expo/log-box": "^56.0.13",
"@expo/metro": "~56.0.0",
"@expo/metro-config": "~56.0.14",
"@expo/metro-file-map": "^56.0.3",
"@expo/osascript": "^2.6.0",
"@expo/package-manager": "^1.12.1",
"@expo/plist": "^0.7.0",
"@expo/prebuild-config": "^56.0.16",
"@expo/require-utils": "^56.1.3",
"@expo/router-server": "^56.0.14",
"@expo/schema-utils": "^56.0.0",
"@expo/spawn-async": "^1.8.0",
"@expo/ws-tunnel": "^2.0.0",
"@expo/xcpretty": "^4.4.4",
"@react-native/dev-middleware": "0.85.3",
"accepts": "^1.3.8",
"arg": "^5.0.2",
"bplist-creator": "0.1.0",
"bplist-parser": "^0.3.1",
"chalk": "^4.0.0",
"ci-info": "^3.3.0",
"compression": "^1.7.4",
"connect": "^3.7.0",
"debug": "^4.3.4",
"dnssd-advertise": "^1.1.4",
"expo-server": "^56.0.5",
"fetch-nodeshim": "^0.4.10",
"getenv": "^2.0.0",
"glob": "^13.0.0",
"lan-network": "^0.2.1",
"multitars": "^1.0.0",
"node-forge": "^1.3.3",
"npm-package-arg": "^11.0.0",
"ora": "^3.4.0",
"picomatch": "^4.0.4",
"pretty-format": "^29.7.0",
"progress": "^2.0.3",
"prompts": "^2.3.2",
"resolve-from": "^5.0.0",
"semver": "^7.6.0",
"send": "^0.19.0",
"slugify": "^1.3.4",
"stacktrace-parser": "^0.1.10",
"structured-headers": "^0.4.1",
"terminal-link": "^2.1.1",
"toqr": "^0.1.1",
"wrap-ansi": "^7.0.0",
"ws": "^8.12.1",
"zod": "^3.25.76"
},
"bin": {
"expo-internal": "main.js"
},
"peerDependencies": {
"expo": "*",
"expo-router": "*",
"react-native": "*"
},
"peerDependenciesMeta": {
"expo-router": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/@expo/cli/node_modules/semver": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
"integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@expo/code-signing-certificates": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz",
@@ -1659,9 +1566,9 @@
}
},
"node_modules/@expo/prebuild-config/node_modules/semver": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
"integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
"version": "7.8.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -1689,40 +1596,6 @@
}
}
},
"node_modules/@expo/router-server": {
"version": "56.0.14",
"resolved": "https://registry.npmjs.org/@expo/router-server/-/router-server-56.0.14.tgz",
"integrity": "sha512-2UCTtZfcq1ZPgp3wk8/+sq9DvFI9UxrPr1jcEKMAF2DGAJLosnpc8GWNNg2hkjt6SHUOdFHIPxujWPYyho2y3A==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.4"
},
"peerDependencies": {
"@expo/metro-runtime": "^56.0.15",
"expo": "*",
"expo-constants": "^56.0.18",
"expo-font": "^56.0.6",
"expo-router": "*",
"expo-server": "^56.0.5",
"react": "*",
"react-dom": "*",
"react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1"
},
"peerDependenciesMeta": {
"@expo/metro-runtime": {
"optional": true
},
"expo-router": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-server-dom-webpack": {
"optional": true
}
}
},
"node_modules/@expo/schema-utils": {
"version": "56.0.1",
"resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-56.0.1.tgz",
@@ -4306,6 +4179,121 @@
"react-native": "*"
}
},
"node_modules/expo/node_modules/@expo/cli": {
"version": "56.1.16",
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-56.1.16.tgz",
"integrity": "sha512-VBQn0mqAwc67b9Cn0RVXyeodghomAx5xGRhA/bXaQzuxDjMQk0zIOb6pXMZX7yiIwJW66UZt/zQiJNSv6aWJYw==",
"license": "MIT",
"dependencies": {
"@expo/code-signing-certificates": "^0.0.6",
"@expo/config": "~56.0.9",
"@expo/config-plugins": "~56.0.9",
"@expo/devcert": "^1.2.1",
"@expo/env": "~2.3.0",
"@expo/image-utils": "^0.10.1",
"@expo/inline-modules": "^0.0.12",
"@expo/json-file": "^10.2.0",
"@expo/log-box": "^56.0.13",
"@expo/metro": "~56.0.0",
"@expo/metro-config": "~56.0.14",
"@expo/metro-file-map": "^56.0.3",
"@expo/osascript": "^2.6.0",
"@expo/package-manager": "^1.12.1",
"@expo/plist": "^0.7.0",
"@expo/prebuild-config": "^56.0.16",
"@expo/require-utils": "^56.1.3",
"@expo/router-server": "^56.0.14",
"@expo/schema-utils": "^56.0.0",
"@expo/spawn-async": "^1.8.0",
"@expo/ws-tunnel": "^2.0.0",
"@expo/xcpretty": "^4.4.4",
"@react-native/dev-middleware": "0.85.3",
"accepts": "^1.3.8",
"arg": "^5.0.2",
"bplist-creator": "0.1.0",
"bplist-parser": "^0.3.1",
"chalk": "^4.0.0",
"ci-info": "^3.3.0",
"compression": "^1.7.4",
"connect": "^3.7.0",
"debug": "^4.3.4",
"dnssd-advertise": "^1.1.4",
"expo-server": "^56.0.5",
"fetch-nodeshim": "^0.4.10",
"getenv": "^2.0.0",
"glob": "^13.0.0",
"lan-network": "^0.2.1",
"multitars": "^1.0.0",
"node-forge": "^1.3.3",
"npm-package-arg": "^11.0.0",
"ora": "^3.4.0",
"picomatch": "^4.0.4",
"pretty-format": "^29.7.0",
"progress": "^2.0.3",
"prompts": "^2.3.2",
"resolve-from": "^5.0.0",
"semver": "^7.6.0",
"send": "^0.19.0",
"slugify": "^1.3.4",
"stacktrace-parser": "^0.1.10",
"structured-headers": "^0.4.1",
"terminal-link": "^2.1.1",
"toqr": "^0.1.1",
"wrap-ansi": "^7.0.0",
"ws": "^8.12.1",
"zod": "^3.25.76"
},
"bin": {
"expo-internal": "main.js"
},
"peerDependencies": {
"expo": "*",
"expo-router": "*",
"react-native": "*"
},
"peerDependenciesMeta": {
"expo-router": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/expo/node_modules/@expo/cli/node_modules/@expo/router-server": {
"version": "56.0.14",
"resolved": "https://registry.npmjs.org/@expo/router-server/-/router-server-56.0.14.tgz",
"integrity": "sha512-2UCTtZfcq1ZPgp3wk8/+sq9DvFI9UxrPr1jcEKMAF2DGAJLosnpc8GWNNg2hkjt6SHUOdFHIPxujWPYyho2y3A==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.4"
},
"peerDependencies": {
"@expo/metro-runtime": "^56.0.15",
"expo": "*",
"expo-constants": "^56.0.18",
"expo-font": "^56.0.6",
"expo-router": "*",
"expo-server": "^56.0.5",
"react": "*",
"react-dom": "*",
"react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1"
},
"peerDependenciesMeta": {
"@expo/metro-runtime": {
"optional": true
},
"expo-router": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-server-dom-webpack": {
"optional": true
}
}
},
"node_modules/expo/node_modules/expo-modules-core": {
"version": "56.0.17",
"resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-56.0.17.tgz",
@@ -4359,8 +4347,6 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
"integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
"license": "ISC",
"optional": true,
"peer": true,
"bin": {
"semver": "bin/semver.js"
},
@@ -6124,9 +6110,9 @@
}
},
"node_modules/npm-package-arg/node_modules/semver": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
"integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
"version": "7.8.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -6722,9 +6708,9 @@
}
},
"node_modules/react": {
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
"integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -6762,16 +6748,16 @@
}
},
"node_modules/react-dom": {
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
"integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
"peerDependencies": {
"react": "^19.2.7"
"react": "^19.2.3"
}
},
"node_modules/react-fast-compare": {
+5 -1
View File
@@ -19,7 +19,7 @@
"expo-sqlite": "~56.0.5",
"expo-status-bar": "~56.0.4",
"nativewind": "~4.2.5",
"react": "19.2.7",
"react": "19.2.3",
"react-native": "0.85.3",
"react-native-gesture-handler": "~3.0.2",
"react-native-reanimated": "~4.4.1",
@@ -27,6 +27,10 @@
"react-native-screens": "~4.25.2",
"tailwindcss": "~3.4.19"
},
"overrides": {
"react": "19.2.3",
"react-dom": "19.2.3"
},
"devDependencies": {
"@babel/core": "^7.25.0",
"@expo/metro-config": "~56.0.14",
+13
View File
@@ -0,0 +1,13 @@
// Exclude native build for packages not used in this project.
// react-native-gesture-handler detects their absence and falls back to its
// noreanimated codepath, so GestureHandlerRootView continues to work.
module.exports = {
dependencies: {
'react-native-reanimated': {
platforms: { android: null },
},
'react-native-worklets': {
platforms: { android: null },
},
},
};