Polish navigation, Quran flows, and sharing UX
This commit is contained in:
@@ -1,16 +1,80 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ui' show ViewFocusEvent, ViewFocusState;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../core/providers/theme_provider.dart';
|
||||
import '../features/dashboard/data/prayer_times_provider.dart';
|
||||
import 'router.dart';
|
||||
import 'theme/app_theme.dart';
|
||||
|
||||
/// Root MaterialApp.router wired to GoRouter + ThemeMode from Riverpod.
|
||||
class App extends ConsumerWidget {
|
||||
class App extends ConsumerStatefulWidget {
|
||||
const App({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
ConsumerState<App> createState() => _AppState();
|
||||
}
|
||||
|
||||
class _AppState extends ConsumerState<App> with WidgetsBindingObserver {
|
||||
Timer? _midnightResyncTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
HardwareKeyboard.instance.syncKeyboardState();
|
||||
});
|
||||
_scheduleMidnightResync();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_midnightResyncTimer?.cancel();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed ||
|
||||
state == AppLifecycleState.inactive) {
|
||||
// Resync stale pressed-key state to avoid repeated KeyDown assertions.
|
||||
HardwareKeyboard.instance.syncKeyboardState();
|
||||
}
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
ref.invalidate(prayerTimesProvider);
|
||||
unawaited(ref.read(prayerTimesProvider.future));
|
||||
_scheduleMidnightResync();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeViewFocus(ViewFocusEvent event) {
|
||||
if (event.state == ViewFocusState.focused) {
|
||||
HardwareKeyboard.instance.syncKeyboardState();
|
||||
}
|
||||
}
|
||||
|
||||
void _scheduleMidnightResync() {
|
||||
_midnightResyncTimer?.cancel();
|
||||
final now = DateTime.now();
|
||||
final nextRun = DateTime(now.year, now.month, now.day, 0, 5).isAfter(now)
|
||||
? DateTime(now.year, now.month, now.day, 0, 5)
|
||||
: DateTime(now.year, now.month, now.day + 1, 0, 5);
|
||||
final delay = nextRun.difference(now);
|
||||
_midnightResyncTimer = Timer(delay, () {
|
||||
ref.invalidate(prayerTimesProvider);
|
||||
unawaited(ref.read(prayerTimesProvider.future));
|
||||
_scheduleMidnightResync();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeMode = ref.watch(themeProvider);
|
||||
|
||||
return MaterialApp.router(
|
||||
|
||||
Reference in New Issue
Block a user