A more robust self hosted OTA updates implementation
This commit is contained in:
+55
-15
@@ -4,12 +4,14 @@ import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdfrx/pdfrx.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'screens/update_check_screen.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'firebase_options.dart';
|
||||
// removed unused imports
|
||||
import 'app.dart';
|
||||
import 'theme/app_theme.dart';
|
||||
import 'providers/notifications_provider.dart';
|
||||
import 'providers/notification_navigation_provider.dart';
|
||||
import 'utils/app_time.dart';
|
||||
@@ -19,6 +21,7 @@ import 'services/notification_service.dart';
|
||||
import 'services/notification_bridge.dart';
|
||||
import 'services/background_location_service.dart';
|
||||
import 'services/app_update_service.dart';
|
||||
import 'models/app_version.dart';
|
||||
import 'widgets/update_dialog.dart';
|
||||
import 'utils/navigation.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
@@ -593,29 +596,66 @@ Future<void> main() async {
|
||||
runApp(
|
||||
UncontrolledProviderScope(
|
||||
container: _globalProviderContainer,
|
||||
child: const NotificationBridge(child: TasqApp()),
|
||||
child: const UpdateCheckWrapper(),
|
||||
),
|
||||
);
|
||||
|
||||
// perform update check once the first frame has rendered; errors are
|
||||
// intentionally swallowed so a network outage doesn't block startup.
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
// Post-startup registration removed: token registration is handled
|
||||
// centrally in the auth state change listener to avoid duplicate inserts.
|
||||
}
|
||||
|
||||
/// Wrapper shown at app launch; performs update check and displays
|
||||
/// [UpdateCheckingScreen] until complete.
|
||||
class UpdateCheckWrapper extends StatefulWidget {
|
||||
const UpdateCheckWrapper({super.key});
|
||||
|
||||
@override
|
||||
State<UpdateCheckWrapper> createState() => _UpdateCheckWrapperState();
|
||||
}
|
||||
|
||||
class _UpdateCheckWrapperState extends State<UpdateCheckWrapper> {
|
||||
bool _done = false;
|
||||
AppUpdateInfo? _info;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_performCheck();
|
||||
}
|
||||
|
||||
Future<void> _performCheck() async {
|
||||
try {
|
||||
final info = await AppUpdateService.instance.checkForUpdate();
|
||||
if (info.isUpdateAvailable) {
|
||||
showDialog(
|
||||
context: globalNavigatorKey.currentContext!,
|
||||
barrierDismissible: !info.isForceUpdate,
|
||||
builder: (_) => UpdateDialog(info: info),
|
||||
);
|
||||
}
|
||||
_info = await AppUpdateService.instance.checkForUpdate();
|
||||
} catch (e) {
|
||||
debugPrint('update check failed: $e');
|
||||
}
|
||||
});
|
||||
if (mounted) {
|
||||
setState(() => _done = true);
|
||||
if (_info?.isUpdateAvailable == true) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
showDialog(
|
||||
context: globalNavigatorKey.currentContext!,
|
||||
barrierDismissible: !_info!.isForceUpdate,
|
||||
builder: (_) => UpdateDialog(info: _info!),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Post-startup registration removed: token registration is handled
|
||||
// centrally in the auth state change listener to avoid duplicate inserts.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!_done) {
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: AppTheme.light(),
|
||||
darkTheme: AppTheme.dark(),
|
||||
themeMode: ThemeMode.system,
|
||||
home: const UpdateCheckingScreen(),
|
||||
);
|
||||
}
|
||||
return const NotificationBridge(child: TasqApp());
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationSoundObserver extends ProviderObserver {
|
||||
|
||||
Reference in New Issue
Block a user