diff --git a/mobile/App.tsx b/mobile/App.tsx index 7745614..719ec77 100644 --- a/mobile/App.tsx +++ b/mobile/App.tsx @@ -1,6 +1,9 @@ // MUST be the first import for react-navigation 7 + reanimated/gesture-handler // in release builds. Otherwise Hermes-bundled APK boots to a white screen. import 'react-native-gesture-handler'; +// Guard na Alert.alert (AppState==='active') — kill crasha "Adding window failed" / +// DeadObjectException gdy dialog leci na martwym oknie (Sentry ddec9d6b). Side-effect. +import './src/lib/alertGuard'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import * as Sentry from '@sentry/react-native'; diff --git a/mobile/src/changelog.ts b/mobile/src/changelog.ts index 433a5ed..2a38e4f 100644 --- a/mobile/src/changelog.ts +++ b/mobile/src/changelog.ts @@ -16,6 +16,13 @@ export type ChangelogEntry = { }; export const CHANGELOG: ChangelogEntry[] = [ + { + id: '2026-07-22', + date: 'July 2026', + items: [ + 'Fixed a rare crash that could happen when a pop-up (like the update prompt) tried to appear just as the app was being sent to the background.', + ], + }, { id: '2026-07-21', date: 'July 2026', diff --git a/mobile/src/lib/alertGuard.ts b/mobile/src/lib/alertGuard.ts new file mode 100644 index 0000000..f72d4e0 --- /dev/null +++ b/mobile/src/lib/alertGuard.ts @@ -0,0 +1,26 @@ +/** + * Fix natywnego crasha "RuntimeException: Adding window failed" / DeadObjectException + * (Sentry issue ddec9d6b, fatal, Android). RN `Alert.alert` pokazuje natywny + * DialogFragment przez WindowManager.addView. Gdy activity leci w tło albo jest + * ubijane (binder do WindowManagera martwy) w momencie `Dialog.show()`, add-window + * rzuca DeadObjectException → fatal crash. Typowy trigger: alert z async handlera + * (np. "Update available" na boocie, błąd playbacku/resolve) odpalony gdy user zdążył + * zbackgroundować apkę. + * + * Guard: nie pokazuj dialogu gdy apka NIE jest na wierzchu ('active'). Transientowe + * alerty w tle i tak nie mają sensu (user nie patrzy), a ważne (update) wrócą przy + * następnym foregroundzie/launchu. Patch globalny na Alert.alert — obejmuje WSZYSTKIE + * wywołania (obecne i przyszłe, też z bibliotek) bez owijania ~56 call-site'ów. + * + * Import jako side-effect NA GÓRZE App.tsx, przed pierwszym możliwym Alertem. + */ +import { Alert, AppState } from 'react-native'; + +const _origAlert = Alert.alert.bind(Alert); + +(Alert as { alert: typeof Alert.alert }).alert = (( + ...args: Parameters +) => { + if (AppState.currentState !== 'active') return; + return _origAlert(...args); +}) as typeof Alert.alert;