189 lines
5.2 KiB
Dart
189 lines
5.2 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: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';
|
|
|
|
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<void> _startProcess() async {
|
|
if (!mounted) return;
|
|
|
|
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 mqttService = context.read<MqttService>();
|
|
final storage = const FlutterSecureStorage();
|
|
final token = await storage.read(key: 'accessToken');
|
|
|
|
if (token != null && token.isNotEmpty) {
|
|
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),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
} |