diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..fa0b357 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/lib/Widgets/flood_station_list_view.dart b/lib/Widgets/flood_station_list_view.dart index f846b46..24807d7 100644 --- a/lib/Widgets/flood_station_list_view.dart +++ b/lib/Widgets/flood_station_list_view.dart @@ -1,13 +1,16 @@ import 'package:flutter/material.dart'; import '../model/flood_station.dart'; -import '../pages/flood_station_page.dart'; class FloodStationListView extends StatelessWidget { - const FloodStationListView({super.key, required List stations}) + const FloodStationListView( + {super.key, + required List stations, + required this.onItemTapped}) : _stations = stations; final List _stations; + final void Function(FloodStation) onItemTapped; @override Widget build(BuildContext context) { @@ -20,9 +23,7 @@ class FloodStationListView extends StatelessWidget { final item = _stations.elementAt(index); return ListTile( isThreeLine: true, - onTap: () => Navigator.of(context).push(MaterialPageRoute( - builder: (context) => FloodStationPage(floodStation: item), - )), + onTap: () => onItemTapped(item), title: Text(item.label), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/main.dart b/lib/main.dart index 1e3dd72..35743ab 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'pages/flood_station_page.dart'; import 'pages/landing_page.dart'; +import 'services/flood_station_provider.dart'; void main() { - runApp(const MyApp()); + runApp( + ChangeNotifierProvider( + create: (context) => FloodStationProvider(), + child: const MyApp(), + ), + ); } class MyApp extends StatelessWidget { @@ -20,6 +28,7 @@ class MyApp extends StatelessWidget { initialRoute: LandingPage.routeName, routes: { LandingPage.routeName: (context) => LandingPage(), + FloodStationPage.routeName: (context) => FloodStationPage(), }, ); } diff --git a/lib/pages/flood_station_page.dart b/lib/pages/flood_station_page.dart index 22fbb2e..16697d1 100644 --- a/lib/pages/flood_station_page.dart +++ b/lib/pages/flood_station_page.dart @@ -1,22 +1,37 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../Widgets/reading_graph.dart'; import '../model/flood_station.dart'; import '../model/reading.dart'; import '../services/api.dart'; +import '../services/flood_station_provider.dart'; + +class FloodStationPage extends StatefulWidget { + const FloodStationPage({super.key}); + static const String routeName = '/station'; + + @override + State createState() => _FloodStationPageState(); +} + +class _FloodStationPageState extends State { + @override + void deactivate() { + context.read().selectedStation = null; + super.deactivate(); + } -class FloodStationPage extends StatelessWidget { - const FloodStationPage({super.key, required FloodStation floodStation}) - : _floodStation = floodStation; - final FloodStation _floodStation; @override Widget build(BuildContext context) { + final FloodStation? station = + context.read().selectedStation; return Scaffold( appBar: AppBar( - title: Text(_floodStation.label), + title: Text(station?.label ?? ''), ), body: FutureBuilder>( - future: Api.fetchReadingsFromStation(_floodStation.id), + future: Api.fetchReadingsFromStation(station?.id ?? ''), builder: (context, snapshot) { if (snapshot.hasData) { if (snapshot.data!.isEmpty) { diff --git a/lib/pages/landing_page.dart b/lib/pages/landing_page.dart index 2684e6c..44e0266 100644 --- a/lib/pages/landing_page.dart +++ b/lib/pages/landing_page.dart @@ -1,33 +1,39 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../Widgets/flood_station_list_view.dart'; -import '../model/flood_station.dart'; -import '../services/api.dart'; +import '../services/flood_station_provider.dart'; +import 'flood_station_page.dart'; -class LandingPage extends StatelessWidget { +class LandingPage extends StatefulWidget { const LandingPage({super.key}); static const routeName = '/'; - Widget builder( - BuildContext context, AsyncSnapshot> snapshot) { - if (!snapshot.hasData) { - return CircularProgressIndicator(); - } else if (snapshot.hasData) { - return FloodStationListView(stations: snapshot.data!); - } else if (snapshot.hasError) { - return Text(snapshot.error.toString()); - } else { - return Text('An unknown error occured.'); - } + @override + State createState() => _LandingPageState(); +} + +class _LandingPageState extends State { + late FloodStationProvider floodStationProvider; + + @override + initState() { + super.initState(); + WidgetsBinding.instance + .addPostFrameCallback((_) => floodStationProvider.loadAllStations()); } @override Widget build(BuildContext context) { + floodStationProvider = context.watch(); return Scaffold( - body: FutureBuilder>( - future: Api.fetchStations(), - builder: builder, + body: FloodStationListView( + stations: floodStationProvider.allStations, + onItemTapped: (station) { + floodStationProvider.selectedStation = station; + Navigator.of(context).pushNamed(FloodStationPage.routeName); + }, ), ); } diff --git a/lib/services/flood_station_provider.dart b/lib/services/flood_station_provider.dart new file mode 100644 index 0000000..82202c8 --- /dev/null +++ b/lib/services/flood_station_provider.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +import '../model/flood_station.dart'; +import 'api.dart'; + +class FloodStationProvider extends ChangeNotifier { + List _allStations = []; + FloodStation? selectedStation; + + List get allStations => _allStations; + + Future loadAllStations({silent = false}) { + return Api.fetchStations().then( + (value) { + _allStations = value; + if (!silent) { + notifyListeners(); + } + }, + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 41d8b76..0f3bbf9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: fl_chart: ^0.70.2 http: ^1.3.0 intl: ^0.20.2 + provider: ^6.1.2 dev_dependencies: flutter_test: