248 lines
7.1 KiB
Dart
248 lines
7.1 KiB
Dart
import 'dart:async';
|
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import 'package:proxibuy/core/config/app_colors.dart';
|
|
import 'package:proxibuy/presentation/auth/bloc/auth_bloc.dart';
|
|
import 'package:proxibuy/presentation/pages/onboarding_page.dart';
|
|
import 'package:proxibuy/presentation/pages/offers_page.dart';
|
|
import 'package:proxibuy/core/gen/assets.gen.dart';
|
|
import 'package:proxibuy/services/mqtt_service.dart';
|
|
import 'package:proxibuy/services/background_service.dart';
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
|
|
class SplashScreen extends StatefulWidget {
|
|
const SplashScreen({super.key});
|
|
|
|
@override
|
|
State<SplashScreen> createState() => _SplashScreenState();
|
|
}
|
|
|
|
class _SplashScreenState extends State<SplashScreen> {
|
|
bool _showRetryUI = false;
|
|
String _errorMessage = "";
|
|
bool _isChecking = true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
Future.delayed(const Duration(seconds: 2), _startProcess);
|
|
}
|
|
|
|
Future<String?> getFcmToken() async {
|
|
FirebaseMessaging messaging = FirebaseMessaging.instance;
|
|
try {
|
|
String? token = await messaging.getToken();
|
|
debugPrint("🔥 Firebase Messaging Token: $token");
|
|
return token;
|
|
} catch(e) {
|
|
debugPrint("Error getting FCM token: $e");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
Future<void> _startProcess() async {
|
|
if (!mounted) return;
|
|
|
|
await _requestPermissions();
|
|
|
|
final hasInternet = await _checkInternet();
|
|
if (!hasInternet) {
|
|
setState(() {
|
|
_isChecking = false;
|
|
_showRetryUI = true;
|
|
_errorMessage = "اتصال به اینترنت برقرار نیست.";
|
|
});
|
|
return;
|
|
}
|
|
|
|
setState(() {
|
|
_isChecking = false;
|
|
});
|
|
}
|
|
|
|
Future<bool> _checkInternet() async {
|
|
final connectivityResult = await Connectivity().checkConnectivity();
|
|
return !connectivityResult.contains(ConnectivityResult.none);
|
|
}
|
|
|
|
Future<void> _connectAndNavigate() async {
|
|
if (!await _checkInternet()) {
|
|
setState(() {
|
|
_showRetryUI = true;
|
|
_errorMessage = "اتصال اینترنت قطع شد.";
|
|
});
|
|
return;
|
|
}
|
|
|
|
final String? fcmToken = await getFcmToken();
|
|
|
|
final mqttService = context.read<MqttService>();
|
|
final storage = const FlutterSecureStorage();
|
|
final token = await storage.read(key: 'accessToken');
|
|
|
|
if (token != null && token.isNotEmpty) {
|
|
|
|
if (fcmToken != null) {
|
|
context.read<AuthBloc>().add(SendFcmTokenEvent(fcmToken: fcmToken));
|
|
}
|
|
|
|
if (mqttService.isConnected) {
|
|
_navigateToOffers();
|
|
return;
|
|
}
|
|
try {
|
|
await mqttService.connect(token).timeout(const Duration(seconds: 10));
|
|
if (mounted && mqttService.isConnected) {
|
|
_navigateToOffers();
|
|
} else if (mounted) {
|
|
setState(() {
|
|
_showRetryUI = true;
|
|
_errorMessage = "خطا در اتصال به سرور.";
|
|
});
|
|
}
|
|
} catch (e) {
|
|
if (mounted) {
|
|
setState(() {
|
|
_showRetryUI = true;
|
|
_errorMessage = "خطای پیشبینی نشده در اتصال.";
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void _navigateToOffers() {
|
|
if (!mounted) return;
|
|
Navigator.of(context).pushReplacement(
|
|
MaterialPageRoute(builder: (_) => const OffersPage(showDialogsOnLoad: true)),
|
|
);
|
|
}
|
|
|
|
void _navigateToAuth() {
|
|
if (!mounted) return;
|
|
Navigator.of(context).pushReplacement(
|
|
MaterialPageRoute(builder: (_) => const OnboardingPage()),
|
|
);
|
|
}
|
|
|
|
void _onRetry() {
|
|
setState(() {
|
|
_showRetryUI = false;
|
|
_errorMessage = "";
|
|
_isChecking = true;
|
|
});
|
|
_startProcess();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.white,
|
|
body: BlocListener<AuthBloc, AuthState>(
|
|
listener: (context, state) {
|
|
if (_showRetryUI) return;
|
|
|
|
if (state is AuthSuccess) {
|
|
_connectAndNavigate();
|
|
} else if (state is AuthInitial || state is AuthFailure) {
|
|
_navigateToAuth();
|
|
}
|
|
},
|
|
child: Center(
|
|
child: _buildBody(),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildBody() {
|
|
if (_showRetryUI) {
|
|
return _buildRetryWidget();
|
|
} else {
|
|
return _buildLogo();
|
|
}
|
|
}
|
|
|
|
Widget _buildLogo() {
|
|
return Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Assets.icons.logo.svg(height: 160),
|
|
if (_isChecking) ...[
|
|
const SizedBox(height: 32),
|
|
const CircularProgressIndicator(),
|
|
]
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildRetryWidget() {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(Icons.wifi_off_rounded, size: 80, color: Colors.grey.shade400),
|
|
const SizedBox(height: 24),
|
|
Text(
|
|
_errorMessage,
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(fontSize: 18, color: Colors.black87, height: 1.5),
|
|
),
|
|
const SizedBox(height: 32),
|
|
ElevatedButton(
|
|
onPressed: _onRetry,
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColors.primary,
|
|
foregroundColor: Colors.white,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)),
|
|
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 12),
|
|
),
|
|
child: const Text(
|
|
"تلاش مجدد",
|
|
style: TextStyle(fontSize: 16),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _requestPermissions() async {
|
|
try {
|
|
// Request notification permission
|
|
await Permission.notification.request();
|
|
|
|
// Check and request location permission
|
|
LocationPermission permission = await Geolocator.checkPermission();
|
|
|
|
if (permission == LocationPermission.denied) {
|
|
permission = await Geolocator.requestPermission();
|
|
}
|
|
|
|
// Only request "always" permission if basic location is granted
|
|
if (permission == LocationPermission.whileInUse ||
|
|
permission == LocationPermission.always) {
|
|
// Request background location permission using permission_handler
|
|
await Permission.locationAlways.request();
|
|
}
|
|
|
|
debugPrint("Location permission status: $permission");
|
|
|
|
// حالا که permissions گرفته شد، background service را راهاندازی کنیم
|
|
try {
|
|
await initializeService();
|
|
debugPrint("Background Service initialized successfully");
|
|
} catch (e) {
|
|
debugPrint("Error initializing Background Service: $e");
|
|
}
|
|
} catch (e) {
|
|
debugPrint("Error requesting permissions: $e");
|
|
}
|
|
}
|
|
} |