cleaner trip loading indicator
Some checks failed
Some checks failed
This commit is contained in:
@@ -1,11 +1,20 @@
|
||||
import 'dart:ui';
|
||||
|
||||
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({
|
||||
@@ -18,14 +27,52 @@ class CurrentTripLoadingIndicator extends StatefulWidget {
|
||||
}
|
||||
|
||||
|
||||
Widget bottomLoadingIndicator = Container(
|
||||
height: 20.0, // Increase the height to take up more vertical space
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
@@ -34,43 +81,82 @@ Widget loadingText(Trip trip) => FutureBuilder(
|
||||
Widget greeter;
|
||||
|
||||
if (snapshot.hasData) {
|
||||
greeter = AutoSizeText(
|
||||
maxLines: 1,
|
||||
'Generating your trip to ${snapshot.data}...',
|
||||
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 = AutoSizeText(
|
||||
maxLines: 1,
|
||||
'Error while loading trip.',
|
||||
greeter = AnimatedGradientText(
|
||||
text: 'Error while loading trip.',
|
||||
style: greeterStyle,
|
||||
);
|
||||
);
|
||||
} else {
|
||||
greeter = AutoSizeText(
|
||||
maxLines: 1,
|
||||
'Generating your trip...',
|
||||
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);
|
||||
|
||||
|
||||
class _CurrentTripLoadingIndicatorState extends State<CurrentTripLoadingIndicator> {
|
||||
@override
|
||||
Widget build(BuildContext context) => Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Center(child: loadingText(widget.trip)),
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: bottomLoadingIndicator,
|
||||
)
|
||||
],
|
||||
);
|
||||
|
||||
_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,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,7 @@ final Shader textGradient = APP_GRADIENT.createShader(Rect.fromLTWH(0.0, 0.0, 20
|
||||
TextStyle greeterStyle = TextStyle(
|
||||
foreground: Paint()..shader = textGradient,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 26
|
||||
fontSize: 25
|
||||
);
|
||||
|
||||
|
||||
|
@@ -125,7 +125,7 @@ class LandmarkType {
|
||||
LandmarkType({required this.name, this.icon = const Icon(Icons.location_on)}) {
|
||||
switch (name) {
|
||||
case 'sightseeing':
|
||||
icon = const Icon(Icons.church);
|
||||
icon = const Icon(Icons.castle);
|
||||
break;
|
||||
case 'nature':
|
||||
icon = const Icon(Icons.eco);
|
||||
|
Reference in New Issue
Block a user