first ui elements using the new structs
This commit is contained in:
parent
7e4538a1bf
commit
8bc7da0b3e
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fast_network_navigation/modules/overview.dart';
|
||||
import 'package:fast_network_navigation/modules/profile.dart';
|
||||
import 'package:fast_network_navigation/pages/overview.dart';
|
||||
import 'package:fast_network_navigation/pages/profile.dart';
|
||||
|
||||
|
||||
// BasePage is the scaffold that holds all other pages
|
||||
|
@ -1,40 +0,0 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
|
||||
class DestinationCard extends StatefulWidget {
|
||||
final String title;
|
||||
final String description;
|
||||
final String image;
|
||||
bool visited;
|
||||
|
||||
@override
|
||||
_DestinationCardState createState() => _DestinationCardState();
|
||||
|
||||
|
||||
DestinationCard(this.title, this.description, this.image, this.visited);
|
||||
|
||||
Widget build() {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.location_on),
|
||||
title: Text(title),
|
||||
subtitle: Text(description),
|
||||
onTap: () {
|
||||
// Navigator.pushNamed(context, '/destination');
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class _DestinationCardState extends State<DestinationCard> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card();
|
||||
}
|
||||
|
||||
}
|
44
frontend/lib/modules/greeter.dart
Normal file
44
frontend/lib/modules/greeter.dart
Normal file
@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Widget Greeter (ThemeData theme, {bool full = false}) {
|
||||
String greeterText = "";
|
||||
try {
|
||||
String cityName = getCityName();
|
||||
greeterText = "Welcome to $cityName!";
|
||||
} catch (e) {
|
||||
greeterText = "Welcome ...";
|
||||
}
|
||||
|
||||
Widget topGreeter = Text(
|
||||
greeterText,
|
||||
style: TextStyle(color: theme.primaryColor, fontSize: 24.0, fontWeight: FontWeight.bold),
|
||||
maxLines: 1,
|
||||
);
|
||||
|
||||
Widget bottomGreeter = Container();
|
||||
if (full) {
|
||||
bottomGreeter = Text(
|
||||
"Busy day ahead? Here is how to make the most of it!",
|
||||
style: TextStyle(color: Colors.black, fontSize: 18.0),
|
||||
maxLines: 1,
|
||||
);
|
||||
}
|
||||
Widget greeter = Center(
|
||||
child: Column(
|
||||
children: [
|
||||
if (!full) Padding(padding: EdgeInsets.only(top: 24.0)),
|
||||
topGreeter,
|
||||
if (full) bottomGreeter,
|
||||
Padding(padding: EdgeInsets.only(bottom: 24.0)),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
return greeter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
String getCityName() {
|
||||
return "Paris";
|
||||
}
|
73
frontend/lib/modules/landmark_card.dart
Normal file
73
frontend/lib/modules/landmark_card.dart
Normal file
@ -0,0 +1,73 @@
|
||||
import 'package:fast_network_navigation/structs/landmark.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class LandmarkCard extends StatefulWidget {
|
||||
final Landmark landmark;
|
||||
@override
|
||||
_LandmarkCardState createState() => _LandmarkCardState();
|
||||
|
||||
LandmarkCard(this.landmark);
|
||||
|
||||
}
|
||||
|
||||
class _LandmarkCardState extends State<LandmarkCard> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ThemeData theme = Theme.of(context);
|
||||
return Card(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 160,
|
||||
height: 160,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(15.0),
|
||||
bottomLeft: Radius.circular(15.0),
|
||||
),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage('https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Tour_Eiffel_Wikimedia_Commons.jpg/1037px-Tour_Eiffel_Wikimedia_Commons.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.landmark.name,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
"${widget.landmark.name} (${widget.landmark.type.name})",
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// Align(
|
||||
// alignment: Alignment.topRight,
|
||||
// child: Icon(Icons.push_pin, color: theme.primaryColor),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
101
frontend/lib/modules/landmarks_overview.dart
Normal file
101
frontend/lib/modules/landmarks_overview.dart
Normal file
@ -0,0 +1,101 @@
|
||||
import 'package:fast_network_navigation/modules/landmark_card.dart';
|
||||
import 'package:fast_network_navigation/structs/landmark.dart';
|
||||
import 'package:fast_network_navigation/utils/get_landmarks.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
|
||||
|
||||
class loadLandmarksOverview extends StatefulWidget {
|
||||
const loadLandmarksOverview({super.key});
|
||||
|
||||
@override
|
||||
State<loadLandmarksOverview> createState() => _loadLandmarksOverviewState();
|
||||
}
|
||||
|
||||
class _loadLandmarksOverviewState extends State<loadLandmarksOverview> {
|
||||
final Future<List<Landmark>> _landmarks = fetchLandmarks();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultTextStyle(
|
||||
style: Theme.of(context).textTheme.displayMedium!,
|
||||
textAlign: TextAlign.center,
|
||||
child: FutureBuilder<List<Landmark>>(
|
||||
future: _landmarks,
|
||||
builder: (BuildContext context, AsyncSnapshot<List<Landmark>> snapshot) {
|
||||
List<Widget> children;
|
||||
if (snapshot.hasData) {
|
||||
children = [landmarksWithSteps(snapshot.data!)];
|
||||
} else if (snapshot.hasError) {
|
||||
children = <Widget>[
|
||||
const Icon(
|
||||
Icons.error_outline,
|
||||
color: Colors.red,
|
||||
size: 60,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: Text('Error: ${snapshot.error}'),
|
||||
),
|
||||
];
|
||||
} else {
|
||||
children = [LandmarkCard(Landmark(name: "loading", location: [0,0], type: LandmarkType(name: "loading")))];
|
||||
}
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: children,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget landmarksWithSteps(List<Landmark> landmarks) {
|
||||
List<Widget> children = [];
|
||||
for (Landmark landmark in landmarks) {
|
||||
children.add(LandmarkCard(landmark));
|
||||
children.add(stepBetweenLandmarks());
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: children.sublist(0, children.length - 1)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget stepBetweenLandmarks() {
|
||||
// This is a simple widget that draws a line between landmark-cards
|
||||
// It's a vertical dotted line
|
||||
// Next to the line is the icon for the mode of transport (walking for now) and the estimated time
|
||||
// There is also a button to open the navigation instructions as a new intent
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
left: BorderSide(width: 1.0, color: Colors.black),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Icons.directions_walk),
|
||||
Text("5 min", style: TextStyle(fontSize: 10)),
|
||||
],
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
// Open navigation instructions
|
||||
},
|
||||
child: Text("Navigate"),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import 'package:fast_network_navigation/structs/landmark.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
class MapWidget extends StatefulWidget {
|
||||
@ -9,16 +9,37 @@ class MapWidget extends StatefulWidget {
|
||||
|
||||
class _MapWidgetState extends State<MapWidget> {
|
||||
late GoogleMapController mapController;
|
||||
|
||||
final LatLng _center = const LatLng(45.521563, -122.677433);
|
||||
// coordinates of Paris
|
||||
final LatLng _center = const LatLng(48.8566, 2.3522);
|
||||
|
||||
void _onMapCreated(GoogleMapController controller) {
|
||||
mapController = controller;
|
||||
addLandmarks();
|
||||
}
|
||||
void _onCameraIdle() {
|
||||
// print(mapController.getLatLng());
|
||||
}
|
||||
|
||||
void addLandmarks() {
|
||||
// // adds a marker for each landmark
|
||||
// List<Landmark> landmarks = [
|
||||
// Landmark(name: "Eiffel Tower", location: [48.8584, 2.2945], type: LandmarkType(name: "Type 1")),
|
||||
// Landmark(name: "Louvre Museum", location: [48.8606, 2.3376], type: LandmarkType(name: "Type 1")),
|
||||
// Landmark(name: "Notre-Dame Cathedral", location: [48.8529, 2.3499], type: LandmarkType(name: "Type 1")),
|
||||
// Landmark(name: "Arc de Triomphe", location: [48.8738, 2.2950], type: LandmarkType(name: "Type 1")),
|
||||
// Landmark(name: "Palace of Versailles", location: [48.8014, 2.1301], type: LandmarkType(name: "Type 1")),
|
||||
// ];
|
||||
|
||||
// for (Landmark landmark in landmarks) {
|
||||
// mapController.
|
||||
// mapController.addMarker(MarkerOptions(
|
||||
// position: LatLng(landmark.location[0], landmark.location[1]),
|
||||
// infoWindowText: InfoWindowText(landmark.name, landmark.type.name),
|
||||
// ));
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GoogleMap(
|
||||
@ -28,6 +49,8 @@ class _MapWidgetState extends State<MapWidget> {
|
||||
zoom: 11.0,
|
||||
),
|
||||
onCameraIdle: _onCameraIdle,
|
||||
// onLongPress: ,
|
||||
// markers: #,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
import 'package:fast_network_navigation/modules/destination_card.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
List<Widget> loadDestinations() {
|
||||
List<Widget> cities = [
|
||||
singleDestination(
|
||||
"New York",
|
||||
"The Big Apple",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/View_of_New_York_City.jpg/800px-View_of_New_York_City.jpg"
|
||||
),
|
||||
singleDestination(
|
||||
"Los Angeles",
|
||||
"City of Angels",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Los_Angeles_City_Hall_2013.jpg/800px-Los_Angeles_City_Hall_2013.jpg"
|
||||
),
|
||||
singleDestination(
|
||||
"Chicago",
|
||||
"The Windy City",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Chicago_skyline%2C_viewed_from_John_Hancock_Center.jpg/800px-Chicago_skyline%2C_viewed_from_John_Hancock_Center.jpg"
|
||||
),
|
||||
singleDestination(
|
||||
"San Francisco",
|
||||
"The Golden City",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/San_Francisco_City_Hall_2013.jpg/800px-San_Francisco_City_Hall_2013.jpg"
|
||||
),
|
||||
singleDestination(
|
||||
"Miami",
|
||||
"The Magic City",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Miami_collage.jpg/800px-Miami_collage.jpg"
|
||||
),
|
||||
singleDestination(
|
||||
"Las Vegas",
|
||||
"Sin City",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Las_Vegas_Strip.jpg/800px-Las_Vegas_Strip.jpg"
|
||||
),
|
||||
singleDestination(
|
||||
"Seattle",
|
||||
"Emerald City",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Seattle_Kerry_Park_Skyline.jpg/800px-Seattle_Kerry_Park_Skyline.jpg"
|
||||
),
|
||||
singleDestination(
|
||||
"Boston",
|
||||
"Beantown",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/0/0f/Boston_skyline_from_Longfellow_Bridge_September_2017_panorama_2.jpg/800px-Boston"
|
||||
)
|
||||
];
|
||||
cities.shuffle();
|
||||
return cities;
|
||||
}
|
||||
|
||||
Widget singleDestination(String title, String description, String image) {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.location_on),
|
||||
title: Text(title),
|
||||
subtitle: Text(description),
|
||||
onTap: () {
|
||||
// Navigator.pushNamed(context, '/destination');
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
import 'package:fast_network_navigation/modules/greeter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sliding_up_panel/sliding_up_panel.dart';
|
||||
import 'package:geocode/geocode.dart';
|
||||
import 'dart:async';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
import 'package:fast_network_navigation/modules/navigation.dart';
|
||||
import 'package:fast_network_navigation/modules/landmarks_overview.dart';
|
||||
import 'package:fast_network_navigation/modules/map.dart';
|
||||
|
||||
|
||||
@ -16,25 +14,6 @@ class NavigationOverview extends StatefulWidget {
|
||||
|
||||
|
||||
|
||||
class Debounce {
|
||||
Duration delay;
|
||||
Timer? _timer;
|
||||
|
||||
Debounce(
|
||||
this.delay,
|
||||
);
|
||||
|
||||
call(void Function() callback) {
|
||||
_timer?.cancel();
|
||||
_timer = Timer(delay, callback);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
_timer?.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class _NavigationOverviewState extends State<NavigationOverview> {
|
||||
|
||||
@override
|
||||
@ -53,9 +32,10 @@ class _NavigationOverviewState extends State<NavigationOverview> {
|
||||
decoration: BoxDecoration(
|
||||
color: theme.canvasColor,
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(24.0), topRight: Radius.circular(24.0)),
|
||||
boxShadow: []
|
||||
),
|
||||
|
||||
child: Greeting(theme)
|
||||
child: Greeter(theme)
|
||||
);
|
||||
}
|
||||
|
||||
@ -77,9 +57,8 @@ class _NavigationOverviewState extends State<NavigationOverview> {
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Greeting(theme),
|
||||
Text("Got a lot to do today! Here is a rundown:"),
|
||||
...loadDestinations(),
|
||||
Greeter(theme, full: true),
|
||||
loadLandmarksOverview(),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -88,12 +67,4 @@ class _NavigationOverviewState extends State<NavigationOverview> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget Greeting (ThemeData theme) {
|
||||
return Center(
|
||||
child: Text(
|
||||
"Explore #todo",
|
||||
style: TextStyle(color: theme.primaryColor, fontSize: 24.0, fontWeight: FontWeight.bold),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
class Destination {
|
||||
final double latitude;
|
||||
final double longitude;
|
||||
final String name;
|
||||
final String description;
|
||||
// final DestinationType type;
|
||||
final Duration duration;
|
||||
final bool visited;
|
||||
|
||||
const Destination({
|
||||
required this.latitude,
|
||||
required this.longitude,
|
||||
required this.name,
|
||||
required this.description,
|
||||
// required this.type,
|
||||
required this.duration,
|
||||
required this.visited,
|
||||
});
|
||||
|
||||
factory Destination.fromJson(Map<String, dynamic> json) {
|
||||
return switch (json) {
|
||||
{
|
||||
'lat': double latitude,
|
||||
'lon': double longitude,
|
||||
'name': String name,
|
||||
'description': String description,
|
||||
// 'type': String type,
|
||||
'duration': int duration,
|
||||
'visited': bool visited
|
||||
|
||||
} =>
|
||||
Destination(
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
name: name,
|
||||
description: description,
|
||||
// type: "DestinationType.values.firstWhere((element) => element.name == type)",
|
||||
duration: Duration(minutes: duration),
|
||||
visited: visited
|
||||
),
|
||||
_ => throw const FormatException('Failed to load destination.'),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class DestinationType {
|
||||
final String name;
|
||||
final String description;
|
||||
final Icon icon;
|
||||
|
||||
const DestinationType({
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.icon,
|
||||
});
|
||||
}
|
||||
|
||||
|
56
frontend/lib/structs/landmark.dart
Normal file
56
frontend/lib/structs/landmark.dart
Normal file
@ -0,0 +1,56 @@
|
||||
class Landmark {
|
||||
final String name;
|
||||
final List location;
|
||||
final LandmarkType type;
|
||||
// final String description;
|
||||
// final Duration duration;
|
||||
// final bool visited;
|
||||
|
||||
const Landmark({
|
||||
required this.name,
|
||||
required this.location,
|
||||
required this.type,
|
||||
// required this.description,
|
||||
// required this.duration,
|
||||
// required this.visited,
|
||||
});
|
||||
|
||||
factory Landmark.fromJson(Map<String, dynamic> json) {
|
||||
return switch (json) {
|
||||
{
|
||||
'loc': List location,
|
||||
'name': String name,
|
||||
'type': String type,
|
||||
// 'description': String description,
|
||||
// 'duration': int duration,
|
||||
// 'visited': bool visited
|
||||
|
||||
} =>
|
||||
Landmark(
|
||||
name: name,
|
||||
location: location,
|
||||
type: LandmarkType(name: type)
|
||||
// description: description,
|
||||
// duration: Duration(minutes: duration),
|
||||
// visited: visited
|
||||
),
|
||||
_ => throw const FormatException('Failed to load destination.'),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class LandmarkType {
|
||||
final String name;
|
||||
// final String description;
|
||||
// final Icon icon;
|
||||
|
||||
const LandmarkType({
|
||||
required this.name,
|
||||
// required this.description,
|
||||
// required this.icon,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
import "package:fast_network_navigation/structs/destination.dart";
|
||||
import "package:fast_network_navigation/structs/landmark.dart";
|
||||
|
||||
|
||||
class Route {
|
||||
final String name;
|
||||
final Duration duration;
|
||||
final List<Destination> destinations;
|
||||
final List<Landmark> landmarks;
|
||||
|
||||
Route({
|
||||
required this.name,
|
||||
required this.duration,
|
||||
required this.destinations
|
||||
required this.landmarks
|
||||
});
|
||||
}
|
25
frontend/lib/utils/get_landmarks.dart
Normal file
25
frontend/lib/utils/get_landmarks.dart
Normal file
@ -0,0 +1,25 @@
|
||||
import "package:fast_network_navigation/structs/landmark.dart";
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
|
||||
Future<List<Landmark>> fetchLandmarks() async {
|
||||
// final response = await http
|
||||
// .get(Uri.parse('https://nav.kluster.moll.re/v1/destination/1'));
|
||||
|
||||
// if (response.statusCode == 200) {
|
||||
// If the server did return a 200 OK response,
|
||||
// then parse the JSON.
|
||||
List<Landmark> landmarks = [
|
||||
Landmark(name: "Landmark 1", location: [0, 0], type: LandmarkType(name: "Type 1")),
|
||||
Landmark(name: "Landmark 2", location: [0, 0], type: LandmarkType(name: "Type 2")),
|
||||
Landmark(name: "Landmark 3", location: [0, 0], type: LandmarkType(name: "Type 3")),
|
||||
Landmark(name: "Landmark 4", location: [0, 0], type: LandmarkType(name: "Type 4")),
|
||||
Landmark(name: "Landmark 5", location: [0, 0], type: LandmarkType(name: "Type 5")),
|
||||
];
|
||||
return landmarks;
|
||||
// } else {
|
||||
// // If the server did not return a 200 OK response,
|
||||
// // then throw an exception.
|
||||
// throw Exception('Failed to load destination');
|
||||
// }
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import "package:fast_network_navigation/structs/destination.dart";
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
|
||||
Future<Destination> fetchDestination() async {
|
||||
final response = await http
|
||||
.get(Uri.parse('https://nav.kluster.moll.re/v1/destination/1'));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// If the server did return a 200 OK response,
|
||||
// then parse the JSON.
|
||||
return Destination.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
|
||||
} else {
|
||||
// If the server did not return a 200 OK response,
|
||||
// then throw an exception.
|
||||
throw Exception('Failed to load destination');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user