205 lines
6.4 KiB
Dart
205 lines
6.4 KiB
Dart
import 'dart:ui';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:taxglide/consts/app_asstes.dart';
|
|
import 'package:taxglide/consts/app_colors.dart';
|
|
import 'package:taxglide/controller/api_contoller.dart';
|
|
import 'package:taxglide/router/consts_routers.dart';
|
|
import 'package:taxglide/consts/local_store.dart';
|
|
import 'package:taxglide/services/notification_service.dart';
|
|
import 'package:taxglide/view/Main_controller/main_controller.dart';
|
|
|
|
import 'package:taxglide/view/screens/history/detail_screen.dart'
|
|
show DetailScreen;
|
|
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
|
|
import 'Mahi_chat/live_chat_screen.dart';
|
|
|
|
class FlashScreen extends ConsumerStatefulWidget {
|
|
const FlashScreen({super.key});
|
|
|
|
@override
|
|
ConsumerState<FlashScreen> createState() => _FlashScreenState();
|
|
}
|
|
|
|
class _FlashScreenState extends ConsumerState<FlashScreen> {
|
|
final LocalStore _localStore = LocalStore();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_navigateNext();
|
|
}
|
|
|
|
Future<void> _navigateNext() async {
|
|
try {
|
|
await Future.delayed(const Duration(seconds: 3));
|
|
|
|
if (!mounted) return;
|
|
|
|
String? token;
|
|
String? role;
|
|
|
|
try {
|
|
token = await _localStore.getToken();
|
|
role = await _localStore.getRole();
|
|
} catch (e) {
|
|
debugPrint("⚠️ Error reading stored data: $e");
|
|
// Clear corrupted data
|
|
await _localStore.clearAll();
|
|
}
|
|
|
|
if (!mounted) return;
|
|
|
|
// Check if token and role are valid
|
|
if (token != null &&
|
|
token.isNotEmpty &&
|
|
token != 'null' &&
|
|
role != null &&
|
|
role.isNotEmpty &&
|
|
role != 'null') {
|
|
debugPrint("✅ User logged in → Checking for initial notification");
|
|
|
|
try {
|
|
// Trigger notification refresh
|
|
ref.read(notificationTriggerProvider.notifier).state++;
|
|
ref.invalidate(chatMessagesProvider);
|
|
|
|
// ✅ Check if app was opened from notification (terminated state)
|
|
final notificationService = Get.find<NotificationService>();
|
|
RemoteMessage? initialMessage = notificationService.initialMessage;
|
|
|
|
if (initialMessage != null) {
|
|
debugPrint("📥 Processing initial notification");
|
|
await _handleInitialNotification(initialMessage.data);
|
|
} else {
|
|
// Navigate to main controller normally
|
|
Get.offAll(() => MainController());
|
|
}
|
|
} catch (e) {
|
|
debugPrint("⚠️ Error checking initial notification: $e");
|
|
// If no initial notification or error, go to MainController
|
|
Get.offAll(() => MainController());
|
|
}
|
|
} else {
|
|
debugPrint("🔒 No valid login data → Navigating to Login");
|
|
// Clear any invalid stored data
|
|
await _localStore.clearAll();
|
|
Get.offNamed(ConstRouters.login);
|
|
}
|
|
} catch (e) {
|
|
debugPrint("❌ Critical error in splash screen: $e");
|
|
// Fallback: always go to login if there's any error
|
|
if (mounted) {
|
|
await _localStore.clearAll();
|
|
Get.offNamed(ConstRouters.login);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Handle notification when app was opened from terminated state
|
|
Future<void> _handleInitialNotification(Map<String, dynamic> data) async {
|
|
String? type = data['type'];
|
|
String? idStr = data['id']?.toString();
|
|
|
|
if (type == null || idStr == null) {
|
|
debugPrint("⚠️ Invalid initial notification data");
|
|
Get.offAll(() => MainController());
|
|
return;
|
|
}
|
|
|
|
debugPrint("📍 Initial notification type: $type, ID: $idStr");
|
|
|
|
if (type == 'chat') {
|
|
// Navigate to chat
|
|
Get.offAll(() => MainController());
|
|
await Future.delayed(const Duration(milliseconds: 300));
|
|
Get.to(() => LiveChatScreen(chatid: int.parse(idStr), fileid: '0'));
|
|
} else if (type == 'service') {
|
|
// Navigate to service detail
|
|
int serviceId = int.tryParse(idStr) ?? 0;
|
|
Get.offAll(
|
|
() => MainController(
|
|
initialIndex: 2,
|
|
child: DetailScreen(id: serviceId, sourceTabIndex: 2),
|
|
),
|
|
);
|
|
} else {
|
|
// Unknown type
|
|
Get.offAll(() => MainController());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFFFFF8F0),
|
|
body: Stack(
|
|
children: [
|
|
// Background gradient
|
|
Container(
|
|
decoration: const BoxDecoration(
|
|
gradient: LinearGradient(
|
|
begin: Alignment.topCenter,
|
|
end: Alignment.bottomCenter,
|
|
colors: [Color(0xFFFFF8F0), Color(0xFFF5F0FF)],
|
|
),
|
|
),
|
|
),
|
|
|
|
// Top blur circle
|
|
Positioned(
|
|
top: -431,
|
|
left: -256,
|
|
child: Container(
|
|
width: 582,
|
|
height: 582,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: AppColors.backgroundgrainetflashtop.withOpacity(0.9),
|
|
),
|
|
child: BackdropFilter(
|
|
filter: ImageFilter.blur(sigmaX: 368.3, sigmaY: 368.3),
|
|
child: Container(color: Colors.transparent),
|
|
),
|
|
),
|
|
),
|
|
|
|
// Bottom blur circle
|
|
Positioned(
|
|
top: 638,
|
|
left: 149,
|
|
child: Container(
|
|
width: 934,
|
|
height: 934,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: AppColors.backgroundgrainetflashbottom.withOpacity(0.94),
|
|
),
|
|
child: BackdropFilter(
|
|
filter: ImageFilter.blur(sigmaX: 591.0, sigmaY: 591.0),
|
|
child: Container(color: Colors.transparent),
|
|
),
|
|
),
|
|
),
|
|
|
|
// Center logo
|
|
Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
|
child: Image.asset(
|
|
AppAssets.taxgildelogo,
|
|
width: 361.09,
|
|
height: 333.94,
|
|
fit: BoxFit.contain,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|