163 lines
4.0 KiB
Dart
163 lines
4.0 KiB
Dart
import 'package:anyway/constants.dart';
|
|
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';
|
|
|
|
|
|
final List<String> statusTexts = [
|
|
'Parsing your preferences...',
|
|
'Finding the best places...',
|
|
'Crunching the numbers...',
|
|
'Calculating the best route...',
|
|
'Making sure you have a great time...',
|
|
];
|
|
|
|
|
|
class CurrentTripLoadingIndicator extends StatefulWidget {
|
|
final Trip trip;
|
|
const CurrentTripLoadingIndicator({
|
|
super.key,
|
|
required this.trip,
|
|
});
|
|
|
|
@override
|
|
State<CurrentTripLoadingIndicator> createState() => _CurrentTripLoadingIndicatorState();
|
|
}
|
|
|
|
|
|
class _CurrentTripLoadingIndicatorState extends State<CurrentTripLoadingIndicator> {
|
|
@override
|
|
Widget build(BuildContext context) => Stack(
|
|
fit: StackFit.expand,
|
|
children: [
|
|
// In the very center of the panel, show the greeter which tells the user that the trip is being generated
|
|
Center(child: loadingText(widget.trip)),
|
|
// As a gimmick, and a way to show that the app is still working, show a few loading dots
|
|
Align(
|
|
alignment: Alignment.bottomCenter,
|
|
child: statusText(),
|
|
)
|
|
],
|
|
);
|
|
}
|
|
|
|
// automatically cycle through the greeter texts
|
|
class statusText extends StatefulWidget {
|
|
const statusText({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
_statusTextState createState() => _statusTextState();
|
|
}
|
|
|
|
class _statusTextState extends State<statusText> {
|
|
int statusIndex = 0;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
Future.delayed(Duration(seconds: 5), () {
|
|
setState(() {
|
|
statusIndex = (statusIndex + 1) % statusTexts.length;
|
|
});
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AutoSizeText(
|
|
statusTexts[statusIndex],
|
|
style: Theme.of(context).textTheme.labelSmall,
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Widget loadingText(Trip trip) => FutureBuilder(
|
|
future: trip.cityName,
|
|
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
|
|
Widget greeter;
|
|
|
|
if (snapshot.hasData) {
|
|
greeter = AnimatedGradientText(
|
|
text: 'Creating 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: 'Creating 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<AnimatedGradientText> 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: [GRADIENT_START, GRADIENT_END, GRADIENT_START],
|
|
stops: [
|
|
_controller.value - 1.0,
|
|
_controller.value,
|
|
_controller.value + 1.0,
|
|
],
|
|
tileMode: TileMode.mirror,
|
|
).createShader(bounds);
|
|
},
|
|
child: Text(
|
|
widget.text,
|
|
style: widget.style,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|