import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:anyway/structs/trip.dart'; import 'package:anyway/pages/current_trip.dart'; class CurrentTripLoadingIndicator extends StatefulWidget { final Trip trip; const CurrentTripLoadingIndicator({ super.key, required this.trip, }); @override State createState() => _CurrentTripLoadingIndicatorState(); } Widget bottomLoadingIndicator = Container( height: 20.0, // Increase the height to take up more vertical space child: ImageFiltered( imageFilter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), // Apply blur effect child: Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator(),) ), ); Widget loadingText(Trip trip) => FutureBuilder( future: trip.cityName, builder: (BuildContext context, AsyncSnapshot snapshot) { Widget greeter; if (snapshot.hasData) { greeter = AnimatedGradientText( text: 'Generating your trip to ${snapshot.data}...', style: greeterStyle, ); } else if (snapshot.hasError) { // the exact error is shown in the central part of the trip overview. No need to show it here greeter = AnimatedGradientText( text: 'Error while loading trip.', style: greeterStyle, ); } else { greeter = AnimatedGradientText( text: 'Generating your trip...', style: greeterStyle, ); } return greeter; } ); class AnimatedGradientText extends StatefulWidget { final String text; final TextStyle style; const AnimatedGradientText({ Key? key, required this.text, required this.style, }) : super(key: key); @override _AnimatedGradientTextState createState() => _AnimatedGradientTextState(); } class _AnimatedGradientTextState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(seconds: 1), vsync: this, )..repeat(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { return ShaderMask( shaderCallback: (bounds) { return LinearGradient( colors: [Colors.blue, Colors.red, Colors.blue], stops: [ _controller.value - 1.0, _controller.value, _controller.value + 1.0, ], tileMode: TileMode.mirror, ).createShader(bounds); }, child: Text( widget.text, style: widget.style, ), ); }, ); } } class _CurrentTripLoadingIndicatorState extends State { @override Widget build(BuildContext context) => Stack( fit: StackFit.expand, children: [ Center(child: loadingText(widget.trip)), Align( alignment: Alignment.bottomCenter, child: bottomLoadingIndicator, ) ], ); }