refactored overlay loading indicator code

This commit is contained in:
2025-01-28 15:36:14 +01:00
parent 9c9992919d
commit 68b0d5834d
2 changed files with 121 additions and 79 deletions

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../model/flood_station.dart';
import '../services/overlay_service.dart';
import '../widgets/flood_station_list_view.dart';
import '../services/flood_station_provider.dart';
import '../widgets/loading_notifier.dart';
@@ -14,10 +16,14 @@ class LandingPage extends StatefulWidget {
State<LandingPage> createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
class _LandingPageState extends State<LandingPage> with OverlayService {
late FloodStationProvider floodStationProvider;
OverlayEntry? _overlayEntry;
int loadingTimes = 0;
@override
void dispose() {
super.dispose();
removeLoadingNotifier(); // Clean up overlay if needed
}
@override
Widget build(BuildContext context) {
@@ -25,91 +31,80 @@ class _LandingPageState extends State<LandingPage> {
return Column(
children: [
StationFilter(
onChanged: (filterText) {
if (filterText.isEmpty) {
floodStationProvider.filtered = false;
setState(() {});
return;
}
showLoadingNotifier(context: context, message: 'Loading');
floodStationProvider.loadFilteredStations(filterText);
floodStationProvider.filteredStationsFuture
?.then((_) => removeLoadingNotifier());
floodStationProvider.filtered = true;
},
onChanged: (filterText) => _handleFilterChange(filterText),
),
_shouldShowList()
? Expanded(
child: FloodStationListView(
stations: floodStationProvider.filtered
? floodStationProvider.filteredStations
: floodStationProvider.allStations,
onItemTapped: (station) {
floodStationProvider.selectedStation = station;
Navigator.of(context).pushNamed(FloodStationPage.routeName);
},
),
)
: Expanded(
child: Center(
child: ElevatedButton(
onPressed: () {
showLoadingNotifier(context: context, message: 'Loading');
floodStationProvider
.loadAllStations()
.whenComplete(() => removeLoadingNotifier());
},
child: Text('Load all Stations'),
),
),
),
_buildStationList(),
],
);
}
Widget _buildStationList() {
if (!_shouldShowList()) {
return Expanded(
child: Center(
child: ElevatedButton(
onPressed: _handleLoadAllStations,
child: const Text('Load all Stations'),
),
),
);
}
return Expanded(
child: FloodStationListView(
stations: floodStationProvider.filtered
? floodStationProvider.filteredStations
: floodStationProvider.allStations,
onItemTapped: _navigateToStationDetail,
),
);
}
void _handleFilterChange(String filterText) {
if (filterText.isEmpty) {
floodStationProvider.filtered = false;
setState(() {});
return;
}
showLoadingNotifier(
context: context,
message: 'Loading',
onDismiss: () {
floodStationProvider.cancelFilterLoading();
},
);
floodStationProvider.loadFilteredStations(filterText);
floodStationProvider.filteredStationsFuture
?.then((_) => removeLoadingNotifier());
floodStationProvider.filtered = true;
}
void _handleLoadAllStations() {
showLoadingNotifier(
context: context,
message: 'Loading',
onDismiss: () {
floodStationProvider.cancelFilterLoading();
},
);
floodStationProvider
.loadAllStations()
.whenComplete(() => removeLoadingNotifier());
}
void _navigateToStationDetail(FloodStation station) {
floodStationProvider.selectedStation = station;
Navigator.of(context).pushNamed(FloodStationPage.routeName);
}
bool _shouldShowList() {
if (!floodStationProvider.filtered &&
floodStationProvider.allStations.isNotEmpty) {
return true;
}
if (floodStationProvider.filtered) {
return true;
}
return false;
}
Future<void> showLoadingNotifier({
required BuildContext context,
required String message,
}) async {
if (_overlayEntry != null) return;
OverlayState? overlayState = Overlay.of(context);
_overlayEntry = OverlayEntry(
builder: (c) {
return Positioned(
bottom: 16,
left: 0,
right: 0,
child: Center(
child: LoadingNotifier(
message: 'Loading',
onDismissed: () {
floodStationProvider.cancelFilterLoading();
removeLoadingNotifier();
},
),
),
);
},
);
overlayState.insert(_overlayEntry!);
overlayState.setState(() {});
}
void removeLoadingNotifier() {
if (_overlayEntry != null) {
_overlayEntry?.remove();
_overlayEntry = null;
}
return floodStationProvider.filtered;
}
}