diff --git a/lib/pages/landing_page.dart b/lib/pages/landing_page.dart index f8dd066..0a0f052 100644 --- a/lib/pages/landing_page.dart +++ b/lib/pages/landing_page.dart @@ -3,6 +3,7 @@ import 'package:provider/provider.dart'; import '../widgets/flood_station_list_view.dart'; import '../services/flood_station_provider.dart'; +import '../widgets/loading_notifier.dart'; import '../widgets/station_filter.dart'; import 'flood_station_page.dart'; @@ -17,11 +18,19 @@ class LandingPage extends StatefulWidget { class _LandingPageState extends State { late FloodStationProvider floodStationProvider; + bool _isLoading = false; + OverlayEntry? _overlayEntry; + @override initState() { super.initState(); - WidgetsBinding.instance - .addPostFrameCallback((_) => floodStationProvider.loadAllStations()); + WidgetsBinding.instance.addPostFrameCallback((_) { + _isLoading = true; + showLoadingNotifier(context: context, message: 'Loading'); + floodStationProvider + .loadAllStations() + .whenComplete(() => removeLoadingNotifier()); + }); } @override @@ -46,4 +55,35 @@ class _LandingPageState extends State { ), ); } + + Future showLoadingNotifier({ + required BuildContext context, + required String message, + }) async { + OverlayState? overlayState = Overlay.of(context); + _overlayEntry = OverlayEntry( + builder: (c) { + return Positioned( + bottom: 16, + left: 0, + right: 0, + child: Center( + child: LoadingNotifier( + message: 'Loading', + onDismissed: () => removeLoadingNotifier(), + ), + ), + ); + }, + ); + overlayState.insert(_overlayEntry!); + overlayState.setState(() {}); + } + + void removeLoadingNotifier() { + if (_overlayEntry != null) { + _overlayEntry?.remove(); + _overlayEntry = null; + } + } } diff --git a/lib/widgets/loading_notifier.dart b/lib/widgets/loading_notifier.dart new file mode 100644 index 0000000..29626fa --- /dev/null +++ b/lib/widgets/loading_notifier.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +class LoadingNotifier extends StatelessWidget { + const LoadingNotifier( + {super.key, required this.onDismissed, required this.message}); + final void Function() onDismissed; + final String message; + + @override + Widget build(BuildContext context) { + return Card( + color: Theme.of(context).colorScheme.primaryContainer, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(45)), + child: SizedBox( + width: 500, + height: 60, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + SizedBox( + width: 25, + height: 25, + child: CircularProgressIndicator(), + ), + Text( + message, + style: Theme.of(context).textTheme.titleSmall, + ), + IconButton( + onPressed: () => onDismissed(), + icon: Icon(Icons.close), + ) + ], + ), + ), + ), + ); + } +}