Note: This release focuses on stability, crash diagnostics, and eliminating runtime errors. Upgrading from
<= 0.9.3still requires a fresh install.
Highlights
- Crash Log Service — Local ring-buffer error log (~500KB) captures all uncaught errors with timestamps and stack traces. Persists across sessions in app cache for post-mortem debugging.
- Export Error Log — New Settings entry shares the crash log via the system share sheet for easy bug reporting. Only visible when the log contains data.
- Overlay Priority Fix — All overlay scope classes now defer token release via
Future(), eliminating the Riverpod "cannot modify provider during widget tree build" crash that occurred on screen transitions. - Zone Alignment — Binding initialization and
runAppnow execute in the samerunZonedGuardedzone, eliminating the "Zone mismatch" startup warning.
Change Log
Added:
- Crash log service — local ring-buffer log file (~500KB) captures all uncaught errors with timestamps and stack traces; persists across sessions in app cache.
- Export Error Log — new Settings entry (under System) shares the crash log via the system share sheet for easy bug reporting; only visible when log contains data.
- Disk space pre-check — downloads are rejected with a clear error when device storage drops below 1 GB.
Improved:
- HTTP download depth guard — the resume-restart path now enforces a single-retry limit, preventing infinite recursion if the server keeps returning mismatched content lengths.
- FocusSyncManager index safety —
ensureFocusNodes()clamps_selectedIndexafter pruning disposed nodes;validateState()clamps_targetColumnwhen column count changes. - Zone alignment —
WidgetsFlutterBinding.ensureInitialized()andrunApp()now execute inside the samerunZonedGuardedzone. - Overlay priority release — all scope classes defer
release()viaFuture()indispose(), fixing the Riverpod state modification crash. - Detail screen layout — system name badge wrapped in
Flexiblewith ellipsis overflow, fixingRenderFlexoverflow on narrow screens. - ConfigModeScreen dispose — audio manager cached in
initStateto avoidref.read()after widget is disposed. - Download queue lookup —
getDownloadById()uses a simple loop instead offirstWhere+ try/catch, eliminating noisy log spam during queue restore.
Bug Fixes:
- Overlay priority crash — releasing overlay tokens during widget unmount no longer throws Riverpod state modification errors.
- FocusSyncManager focus loss — selected index could point to a disposed FocusNode after the item count decreased.
- RenderFlex overflow — system badge Row on game detail screen no longer overflows on narrow layouts.
- Zone mismatch warning — binding and app now share the same error zone.
- ConfigModeScreen "ref after disposed" — no longer crashes when navigating away quickly.
Technical Internal:
- New
CrashLogServicesingleton withlog(),logError(),getLogFile(),clearLog(),getLogContent(). crashLogServiceProviderinapp_providers.dart, overridden inmain.dart.- Global error handlers now write to crash log in addition to
debugPrint. - Removed spammy
debugPrintinFocusSyncManager._enforceFocus()for deferred focus.