Resolve all lints and deprecation warnings

This commit is contained in:
2026-01-09 10:04:51 -06:00
parent 512577b092
commit a799e9cf59
56 changed files with 2819 additions and 3159 deletions

153
lib/app_startup.dart Normal file
View File

@@ -0,0 +1,153 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'main.dart'; // Import ChristianPeriodTrackerApp
import 'models/cycle_entry.dart';
import 'models/scripture.dart';
import 'models/user_profile.dart';
import 'screens/splash_screen.dart';
import 'services/notification_service.dart';
class AppStartupWidget extends StatefulWidget {
const AppStartupWidget({super.key});
@override
State<AppStartupWidget> createState() => _AppStartupWidgetState();
}
class _AppStartupWidgetState extends State<AppStartupWidget> {
bool _isInitialized = false;
String _status = 'Initializing...';
bool _showSkipButton = false;
final Duration _minSplashDuration = const Duration(milliseconds: 2000);
@override
void initState() {
super.initState();
_initializeApp();
// Show skip button if loading takes too long (e.g., 5 seconds)
Future.delayed(const Duration(seconds: 5), () {
if (mounted && !_isInitialized) {
setState(() => _showSkipButton = true);
}
});
}
Future<void> _initializeApp() async {
final stopwatch = Stopwatch()..start();
try {
setState(() => _status = 'Loading user profile...');
// Add timeout to prevent indefinite hanging
await Hive.openBox<UserProfile>('user_profile')
.timeout(const Duration(seconds: 5));
setState(() => _status = 'Loading cycle data...');
await Hive.openBox<CycleEntry>('cycle_entries')
.timeout(const Duration(seconds: 5));
setState(() => _status = 'Loading scriptures...');
// Wrap scripture loading in a try-catch specifically to allow app to start even if assets fail
try {
await ScriptureDatabase()
.loadScriptures()
.timeout(const Duration(seconds: 5));
} catch (e) {
debugPrint('Scripture loading failed (non-critical): $e');
setState(() => _status = 'Scripture loading skipped...');
}
setState(() => _status = 'Setting up notifications...');
try {
await NotificationService()
.initialize()
.timeout(const Duration(seconds: 3));
} catch (e) {
debugPrint('Notification init failed: $e');
}
} catch (e, stack) {
debugPrint('Initialization error: $e');
debugPrint(stack.toString());
setState(() => _status = 'Error: $e');
// On critical error, allow user to proceed manually via skip button
setState(() => _showSkipButton = true);
return;
}
final elapsed = stopwatch.elapsed;
if (elapsed < _minSplashDuration) {
await Future.delayed(_minSplashDuration - elapsed);
}
if (mounted) {
setState(() {
_isInitialized = true;
});
}
}
void _skipInitialization() {
setState(() => _isInitialized = true);
}
@override
Widget build(BuildContext context) {
if (!_isInitialized) {
return MaterialApp(
home: Scaffold(
body: Stack(
children: [
const SplashScreen(isStartup: true),
// Status Message (High Visibility)
Positioned(
bottom: 80,
left: 20,
right: 20,
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.9),
borderRadius: BorderRadius.circular(8),
),
child: Text(
_status,
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.black87,
fontSize: 14,
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
fontFamily: 'SansSerif'),
),
),
),
// Skip Button
if (_showSkipButton)
Positioned(
bottom: 30,
left: 0,
right: 0,
child: Center(
child: ElevatedButton(
onPressed: _skipInitialization,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.redAccent,
foregroundColor: Colors.white,
),
child: const Text('Skip Loading (Force Start)'),
),
),
),
],
),
),
debugShowCheckedModeBanner: false,
);
}
return const ChristianPeriodTrackerApp();
}
}