You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMG_QLine/lib/views/splash_screen/splash_screen.dart

246 lines
7.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:hmg_qline/config/routes.dart';
import 'package:hmg_qline/utilities/extensions.dart';
import 'package:hmg_qline/view_models/queuing_view_model.dart';
import 'package:hmg_qline/view_models/screen_config_view_model.dart';
import 'package:hmg_qline/views/common_widgets/ip_config_dialog.dart';
import 'package:provider/provider.dart';
import 'package:hmg_qline/utilities/enums.dart';
import 'dart:developer';
import 'package:universal_html/html.dart' as html;
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
Future<void>? _initializationFuture;
bool _showIpDialog = false;
@override
void initState() {
super.initState();
_initializationFuture = _loadData();
}
Future<void> _loadData() async {
try {
final screenConfigViewModel = context.read<ScreenConfigViewModel>();
final queuingViewModel = context.read<QueuingViewModel>();
await screenConfigViewModel.waitForIPAndInitializeConfigVM();
await queuingViewModel.initializeQueueingVM();
} catch (e) {
if (e.toString().contains('IP_CONFIGURATION_REQUIRED')) {
setState(() => _showIpDialog = true);
rethrow;
}
rethrow;
}
}
void _reloadWithIp(String ip) {
if (kIsWeb) {
// Ensure IP is saved to localStorage
log('💾 Attempting to save IP to localStorage: $ip');
try {
html.window.localStorage['device_ip'] = ip;
final saved = html.window.localStorage['device_ip'];
log('💾 Saved IP to localStorage in splash: $saved');
log(' Verify: saved == ip: ${saved == ip}');
log(' localStorage keys: ${html.window.localStorage.keys.toList()}');
if (saved != ip) {
log('⚠️ WARNING: Verification mismatch! Expected: $ip, Got: $saved');
}
} catch (e) {
log('❌ Error saving to localStorage: $e');
}
}
final screenConfigViewModel = context.read<ScreenConfigViewModel>();
screenConfigViewModel.currentScreenIP = ip;
log('✅ IP configured in viewModel: ${screenConfigViewModel.currentScreenIP}');
log('✅ IP configured: $ip - Reloading...');
setState(() {
_showIpDialog = false;
_initializationFuture = _loadData();
});
}
@override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future: _initializationFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(height: 16),
Text(
kIsWeb ? 'Detecting device IP...' : 'Initializing...',
style: const TextStyle(fontSize: 16),
),
if (kIsWeb) const SizedBox(height: 8),
if (kIsWeb)
const Text(
'Please wait',
style: TextStyle(fontSize: 12, color: Colors.grey),
),
],
),
),
);
}
// If an error occurs
if (snapshot.hasError) {
final error = snapshot.error.toString();
// Check if error is due to missing IP on web
if (kIsWeb &&
(error.contains('IP_CONFIGURATION_REQUIRED') || _showIpDialog)) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!_showIpDialog) {
setState(() => _showIpDialog = true);
_showIpConfigDialog();
}
});
return _buildIpConfigScreen();
}
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.error_outline,
color: Colors.red,
size: 64,
),
const SizedBox(height: 16),
const Text(
'Initialization Error',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
Text(
snapshot.error.toString(),
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.red),
),
const SizedBox(height: 24),
ElevatedButton.icon(
onPressed: () {
setState(() {
_initializationFuture = _loadData();
});
},
icon: const Icon(Icons.refresh),
label: const Text('Retry'),
),
],
),
),
),
);
}
// If the data is loaded successfully
if (snapshot.connectionState == ConnectionState.done) {
Future.delayed(const Duration(seconds: 1)).whenComplete(() {
if (mounted) {
if (context.read<ScreenConfigViewModel>().currentScreenTypeEnum ==
ScreenTypeEnum.kioskScreen) {
context.navigateReplaceTo(AppRoutes.kioskMainScreen);
} else {
context.navigateReplaceTo(AppRoutes.mainQueueScreen);
}
}
});
}
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
},
);
}
Widget _buildIpConfigScreen() {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.settings_ethernet,
size: 64,
color: Colors.blue,
),
const SizedBox(height: 24),
const Text(
'Device IP Configuration Required',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 32),
child: Text(
'Please configure the device IP address to continue',
style: TextStyle(fontSize: 14, color: Colors.grey),
textAlign: TextAlign.center,
),
),
const SizedBox(height: 32),
ElevatedButton.icon(
onPressed: _showIpConfigDialog,
icon: const Icon(Icons.router),
label: const Text('Configure IP Address'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 32,
vertical: 16,
),
),
),
],
),
),
);
}
void _showIpConfigDialog() {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => IpConfigDialog(
onIpSubmitted: (ip) {
Navigator.of(context).pop();
_reloadWithIp(ip);
},
),
);
}
}