Aidra Driver 1.3.5+68
Aidra Driver - Your path to green energy
Loading...
Searching...
No Matches
animated_splash_screen.dart
Go to the documentation of this file.
1import 'package:flutter/material.dart';
2import 'package:flutter_bloc/flutter_bloc.dart';
3import 'package:flutter_screenutil/flutter_screenutil.dart';
4import 'package:flutter_svg/svg.dart';
5import 'package:go_router/go_router.dart';
6
7import '../../../features/auth/presentation/bloc/authentication_bloc/authentication_bloc.dart';
8import '../../../features/home/presentation/bloc/home_bloc.dart';
9import '../../../features/home/domain/entities/res/res_schedule_status_entity.dart';
10import '../../constants/assets.dart';
11import '../../router/routes.dart';
12import '../../services/check_in_service.dart';
13// import '../../services/user_info_service.dart';
14import '../theme/color_palette.dart';
15import '../widgets/splash_screen_circles_painter.dart';
16
17class AnimatedSplashScreen extends StatefulWidget {
18 const AnimatedSplashScreen({super.key});
19
20 @override
21 State<AnimatedSplashScreen> createState() => _AnimatedSplashScreenState();
22}
23
24class _AnimatedSplashScreenState extends State<AnimatedSplashScreen> with TickerProviderStateMixin {
25 late AnimationController _logoController;
26 late AnimationController _backgroundController;
27 late AnimationController _fadeController;
28 late Animation<double> _logoScaleAnimation;
29 late Animation<double> _backgroundAnimation;
30 late Animation<double> _fadeAnimation;
31
32 @override
33 void initState() {
34 super.initState();
35
36 _logoController = AnimationController(
37 vsync: this,
38 duration: const Duration(milliseconds: 1500),
39 );
40
41 _backgroundController = AnimationController(
42 vsync: this,
43 duration: const Duration(milliseconds: 2000),
44 );
45
46 _fadeController = AnimationController(
47 vsync: this,
48 duration: const Duration(milliseconds: 800),
49 );
50
51 _logoScaleAnimation = TweenSequence<double>([
52 TweenSequenceItem(
53 tween: Tween<double>(begin: 0.0, end: 1.2)
54 .chain(CurveTween(curve: Curves.easeOut)),
55 weight: 60,
56 ),
57 TweenSequenceItem(
58 tween: Tween<double>(begin: 1.2, end: 1.0)
59 .chain(CurveTween(curve: Curves.easeInOut)),
60 weight: 40,
61 ),
62 ]).animate(_logoController);
63
64 _backgroundAnimation = Tween<double>(
65 begin: 0.0,
66 end: 1.0,
67 ).animate(
68 CurvedAnimation(
70 curve: Curves.easeInOut,
71 ),
72 );
73
74 _fadeAnimation = Tween<double>(
75 begin: 0.0,
76 end: 1.0,
77 ).animate(_fadeController);
78
79 _backgroundController.forward();
80 _logoController.forward();
81 _fadeController.forward();
82
84 }
85
86 Future<void> _initializeApp() async {
87 await Future.delayed(const Duration(milliseconds: 1200));
88 if (mounted) {
89 context.read<AuthenticationBloc>().add(LoadSessionEvent());
90 }
91 }
92
93 @override
94 void dispose() {
95 _logoController.dispose();
96 _backgroundController.dispose();
97 _fadeController.dispose();
98 super.dispose();
99 }
100
101 @override
102 Widget build(BuildContext context) {
103 return MultiBlocListener(
104 listeners: [
105 BlocListener<AuthenticationBloc, AuthenticationState>(
106 listener: (listenerContext, state) async {
107 if (state is AuthenticatedState) {
108 // final uid = state.session.uid ?? 0;
109 // await UserInfoService.instance.fetchAndSaveUserInfo(uid);
110
111 // Check user role and redirect accordingly
112 final userRole = state.session.role;
113 if (userRole != null && userRole != "Driver") {
114 if (listenerContext.mounted) {
115 context.go(Routes.driverRequestsScreen.route);
116 }
117 return;
118 }
119
120 final checkIn = await CheckInService().isUserCheckedIn();
121 if (listenerContext.mounted){
122 if(checkIn == false) {
123 context.go(Routes.checkInScreen.route);
124 } else {
125 // User is checked in, check schedule status
126 final now = DateTime.now();
127 final dateString = '${now.day.toString().padLeft(2, '0')}/${now.month.toString().padLeft(2, '0')}/${now.year}';
128 context.read<HomeBloc>().add(LoadScheduleStatusEvent(
129 driverId: state.session.uid ?? 0,
130 date: dateString,
131 ));
132 }
133 }
134 } else if (state is UnauthenticatedState) {
135 context.go(Routes.signInScreen.route);
136 }
137 },
138 ),
139 BlocListener<HomeBloc, HomeState>(
140 listener: (listenerContext, state) {
141 if (state is ScheduleStatusLoaded) {
142 if (state.status == ScheduleStatus.empty) {
143 context.go(Routes.startLocationChooserScreen.route);
144 } else if (state.status == ScheduleStatus.validated) {
145 context.go(Routes.homeScreen.route);
146 } else if (state.status == ScheduleStatus.draft) {
147 context.go(Routes.scheduleConfirmationScreen.route);
148 }
149 } else if (state is ScheduleStatusError) {
150 context.go(Routes.homeScreen.route);
151 }
152 },
153 ),
154 ],
155 child: Scaffold(
156 body: AnimatedBuilder(
157 animation: Listenable.merge([
161 ]),
162 builder: (context, child) {
163 return Stack(
164 children: [
165 AnimatedContainer(
166 duration: const Duration(milliseconds: 1500),
167 decoration: BoxDecoration(
168 gradient: LinearGradient(
169 begin: Alignment.topLeft,
170 end: Alignment.bottomRight,
171 colors: [
172 ColorPalette.darkGreen,
173 Color.lerp(
174 ColorPalette.darkGreen,
175 ColorPalette.lightGreen,
176 _backgroundAnimation.value,
177 )!,
178 ],
179 ),
180 ),
181 ),
182
183 Positioned.fill(
184 child: Opacity(
185 opacity: _fadeAnimation.value * 0.7,
186 child: CustomPaint(
187 painter: SplashScreenCirclesPainter(
188 progress: _backgroundAnimation.value,
189 ),
190 ),
191 ),
192 ),
193
194 Center(
195 child: Transform.scale(
196 scale: _logoScaleAnimation.value,
197 child: FadeTransition(
198 opacity: _fadeAnimation,
199 child: SvgPicture.asset(
200 Assets.logo,
201 colorFilter: const ColorFilter.mode(
202 ColorPalette.white,
203 BlendMode.srcIn,
204 ),
205 width: 200.sp,
206 ),
207 ),
208 ),
209 ),
210
211 Positioned(
212 bottom: 100.sp,
213 left: 0,
214 right: 0,
215 child: FadeTransition(
216 opacity: _fadeAnimation,
217 child: Center(
218 child: Column(
219 children: [
220 Text(
221 'Sustainability Matters',
222 style: TextStyle(
223 fontStyle: FontStyle.italic,
224 color: ColorPalette.white.withValues(alpha: 0.8),
225 fontSize: 16.sp,
226 letterSpacing: 1,
227 ),
228 ),
229 ],
230 ),
231 ),
232 ),
233 ),
234
235 Positioned(
236 bottom: 50.sp,
237 left: 0,
238 right: 0,
239 child: FadeTransition(
240 opacity: _fadeAnimation,
241 child: Center(
242 child: SizedBox(
243 width: 150.sp,
244 child: LinearProgressIndicator(
245 value: _backgroundAnimation.value,
246 backgroundColor: ColorPalette.white.withValues(alpha: 0.2),
247 valueColor: const AlwaysStoppedAnimation<Color>(
248 ColorPalette.white,
249 ),
250 borderRadius: BorderRadius.circular(10),
251 ),
252 ),
253 ),
254 ),
255 ),
256 ],
257 );
258 },
259 ),
260 ),
261 );
262 }
263}
late Animation< double > _logoScaleAnimation
class AnimatedSplashScreen extends StatefulWidget _logoController
late AnimationController _backgroundController
late AnimationController _fadeController
late Animation< double > _backgroundAnimation
override void initState()
Future< void > _initializeApp() async
override void dispose()
late Animation< double > _fadeAnimation
class App extends StatefulWidget build(BuildContext context)
Definition app.dart:31
Future< bool > isUserCheckedIn() async
const AnimatedSplashScreen({super.key})
override State< AnimatedSplashScreen > createState()
final Widget child
const LoadScheduleStatusEvent({ required this.driverId, required this.date, })
final String date
const ScheduleStatusLoaded({required this.status})
Routes
Definition routes.dart:30