173 lines
5.7 KiB
Dart
173 lines
5.7 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:rogapp/features/data/checkpoint.dart';
|
|
import 'package:rogapp/features/data/data_provider.dart';
|
|
import 'package:rogapp/features/home/home_page.dart';
|
|
import 'package:rogapp/features/landing/denied_screen.dart';
|
|
import 'package:rogapp/features/initializer/app_initializer.dart';
|
|
import 'package:rogapp/features/services/checkpoint_repo.dart';
|
|
import 'package:rogapp/features/state/game_state.dart';
|
|
import 'package:rogapp/features/state/game_view_model.dart';
|
|
|
|
// LandingPage serves as the initial screen displayed by the application to perform necessary checks, initialize required values, and set up services essential for the app's functionality.
|
|
|
|
class LandingPage extends ConsumerStatefulWidget {
|
|
const LandingPage({super.key});
|
|
|
|
@override
|
|
ConsumerState<LandingPage> createState() => _LandingPageState();
|
|
}
|
|
|
|
class _LandingPageState extends ConsumerState<LandingPage> {
|
|
bool? _isInitialized;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
//load only if network available
|
|
ref.read(featureCheckpointCollectionProvider.future);
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
_initializeApp();
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
AsyncValue<FeatureCollection> featureCollection =
|
|
ref.watch(featureCheckpointCollectionProvider);
|
|
|
|
return featureCollection.when(
|
|
data: (data) {
|
|
if (_isInitialized == null) {
|
|
return const MaterialApp(
|
|
home: Scaffold(body: Center(child: CircularProgressIndicator())));
|
|
}
|
|
|
|
return _isInitialized! ? const HomePage() : const DeniedScreen();
|
|
},
|
|
loading: () => const MaterialApp(
|
|
home: Scaffold(body: Center(child: CircularProgressIndicator()))),
|
|
error: (error, stack) => ErrorScreen(error: error),
|
|
);
|
|
}
|
|
|
|
Future<void> _restoreAppState() async {
|
|
final dataProvider = ref.read(dataProviderProvider);
|
|
|
|
// Example values, replace these with actual values from user and event context
|
|
String userName =
|
|
"current_user"; // Fetch the current user's name or identifier
|
|
String teamName = "user_team"; // Fetch the current user's team
|
|
String eventCode = "event_code"; // Fetch the current event code
|
|
|
|
// Load and restore game state
|
|
String? gameStateKey = "current_game_state";
|
|
String? gameStateValue = await dataProvider.getGameState(
|
|
gameStateKey, userName, teamName, eventCode);
|
|
if (gameStateValue != null) {
|
|
Map<String, dynamic> gameStateData = jsonDecode(gameStateValue);
|
|
GameState gameState = GameState.fromMap(gameStateData);
|
|
ref.read(gameViewModelProvider.notifier).loadGameState(gameState);
|
|
}
|
|
|
|
// After restoring all necessary states, proceed with the app
|
|
setState(() {
|
|
_isInitialized = true;
|
|
});
|
|
}
|
|
|
|
// Future<void> _restoreAppState() async {
|
|
// await _initializeApp();
|
|
// // Add additional restoration logic if needed, for example:
|
|
// // Restore game state, user progress, etc., from the DataProvider.
|
|
// // Example:
|
|
// // var gameState = await _dataProvider.getGameState('current_state');
|
|
// // Use the gameState to decide what to do next, e.g., navigate to a specific screen.
|
|
|
|
// if (_isInitialized != true) {
|
|
// // If initialization is not done, try to initialize the app.
|
|
// _isInitialized = await _initializeApp();
|
|
// }
|
|
|
|
// if (!_isInitialized!) {
|
|
// await _showRetryCloseDialog();
|
|
// } else {
|
|
// setState(() {
|
|
// _isInitialized = true;
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
Future<bool> _initializeApp() async {
|
|
AppInitializer initializer = AppInitializer();
|
|
|
|
// Check if permissions are already granted
|
|
bool permissionsAlreadyGranted = await initializer.permissionStatus();
|
|
if (!permissionsAlreadyGranted) {
|
|
await _showPermissionRequestMessage();
|
|
}
|
|
|
|
// Initialize the app and return the success status.
|
|
return await initializer.initializeApp();
|
|
}
|
|
|
|
Future<void> _showPermissionRequestMessage() async {
|
|
return showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext context) => AlertDialog(
|
|
title: const Text('Permissions Required'),
|
|
content: const Text(
|
|
'This app requires certain permissions to function properly. Please grant these permissions in the next steps.'),
|
|
actions: <Widget>[
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Okay'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<bool> _requestPermissionsAndInitialize() async {
|
|
AppInitializer initializer = AppInitializer();
|
|
return await initializer.initializeApp();
|
|
}
|
|
|
|
Future<void> _showRetryCloseDialog() async {
|
|
await showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext context) => AlertDialog(
|
|
title: const Text('Initialization Failed'),
|
|
content: const Text(
|
|
'The app was unable to start properly due to missing permissions.'),
|
|
actions: <Widget>[
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Close'),
|
|
),
|
|
TextButton(
|
|
onPressed: () async {
|
|
Navigator.of(context).pop();
|
|
bool retrySuccess = await _requestPermissionsAndInitialize();
|
|
if (!retrySuccess) {
|
|
await _showRetryCloseDialog();
|
|
} else {
|
|
setState(() {
|
|
_isInitialized = true;
|
|
});
|
|
}
|
|
},
|
|
child: const Text('Retry'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
ErrorScreen({required Object error}) {}
|
|
}
|