image querying from within the frontend
All checks were successful
Build and release debug APK / Build APK (pull_request) Successful in 7m40s

This commit is contained in:
2024-11-06 14:45:43 +01:00
parent e18a9c63e6
commit d58ef2562d
12 changed files with 245 additions and 82 deletions

View File

@@ -1,3 +1,5 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:auto_size_text/auto_size_text.dart';
@@ -15,46 +17,60 @@ class CurrentTripLoadingIndicator extends StatefulWidget {
State<CurrentTripLoadingIndicator> createState() => _CurrentTripLoadingIndicatorState();
}
Widget bottomLoadingIndicator = Container(
height: 20.0, // Increase the height to take up more vertical space
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(
future: trip.cityName,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
Widget greeter;
if (snapshot.hasData) {
greeter = AutoSizeText(
maxLines: 1,
'Generating 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.',
style: greeterStyle,
);
} else {
greeter = AutoSizeText(
maxLines: 1,
'Generating your trip...',
style: greeterStyle,
);
}
return greeter;
}
);
class _CurrentTripLoadingIndicatorState extends State<CurrentTripLoadingIndicator> {
@override
Widget build(BuildContext context) => Center(
child: FutureBuilder(
future: widget.trip.cityName,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
Widget greeter;
Widget loadingIndicator = const Padding(
padding: EdgeInsets.only(top: 10),
child: CircularProgressIndicator()
);
if (snapshot.hasData) {
greeter = AutoSizeText(
maxLines: 1,
'Generating 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.',
style: greeterStyle,
);
} else {
greeter = AutoSizeText(
maxLines: 1,
'Generating your trip...',
style: greeterStyle,
);
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
greeter,
loadingIndicator,
],
);
}
)
Widget build(BuildContext context) => Stack(
fit: StackFit.expand,
children: [
Center(child: loadingText(widget.trip)),
Align(
alignment: Alignment.bottomCenter,
child: bottomLoadingIndicator,
)
],
);
}

View File

@@ -36,7 +36,7 @@ class _CurrentTripPanelState extends State<CurrentTripPanel> {
child: SizedBox(
// reuse the exact same height as the panel has when collapsed
// this way the greeter will be centered when the panel is collapsed
height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 20,
height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT,
child: CurrentTripErrorMessage(trip: widget.trip)
),
);
@@ -46,19 +46,20 @@ class _CurrentTripPanelState extends State<CurrentTripPanel> {
child: SizedBox(
// reuse the exact same height as the panel has when collapsed
// this way the greeter will be centered when the panel is collapsed
height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 20,
height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT,
child: CurrentTripLoadingIndicator(trip: widget.trip),
),
);
} else {
return ListView(
controller: widget.controller,
padding: const EdgeInsets.only(bottom: 30),
padding: const EdgeInsets.only(top: 10, left: 10, right: 10, bottom: 30),
children: [
SizedBox(
// reuse the exact same height as the panel has when collapsed
// this way the greeter will be centered when the panel is collapsed
height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 20,
// note that we need to account for the padding above
height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 10,
child: CurrentTripGreeter(trip: widget.trip),
),

View File

@@ -38,8 +38,6 @@ class _LandmarkCardState extends State<LandmarkCard> {
imageUrl: widget.landmark.imageURL ?? '',
placeholder: (context, url) => Center(child: CircularProgressIndicator()),
errorWidget: (context, error, stackTrace) => Icon(Icons.question_mark_outlined),
// TODO: make this a switch statement to load a placeholder if null
// cover the whole container meaning the image will be cropped
fit: BoxFit.cover,
),
),
@@ -103,15 +101,15 @@ class _LandmarkCardState extends State<LandmarkCard> {
icon: Icon(Icons.link),
label: Text('Website'),
),
if (widget.landmark.wikipediaURL != null)
TextButton.icon(
onPressed: () async {
// open a browser with the wikipedia link
await launchUrl(Uri.parse(widget.landmark.wikipediaURL!));
},
icon: Icon(Icons.book),
label: Text('Wikipedia'),
),
// if (widget.landmark.wikipediaURL != null)
// TextButton.icon(
// onPressed: () async {
// // open a browser with the wikipedia link
// await launchUrl(Uri.parse(widget.landmark.wikipediaURL!));
// },
// icon: Icon(Icons.book),
// label: Text('Wikipedia'),
// ),
],
),
),

View File

@@ -9,6 +9,15 @@ import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:shared_preferences/shared_preferences.dart';
const Map<String, List> debugLocations = {
'paris': [48.8575, 2.3514],
'london': [51.5074, -0.1278],
'new york': [40.7128, -74.0060],
'tokyo': [35.6895, 139.6917],
};
class NewTripLocationSearch extends StatefulWidget {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
Trip trip;
@@ -27,26 +36,35 @@ class _NewTripLocationSearchState extends State<NewTripLocationSearch> {
setTripLocation (String query) async {
List<Location> locations = [];
Location startLocation;
log('Searching for: $query');
try{
locations = await locationFromAddress(query);
} catch (e) {
log('No results found for: $query : $e');
if (GeocodingPlatform.instance != null) {
locations.addAll(await locationFromAddress(query));
}
if (locations.isNotEmpty) {
Location location = locations.first;
widget.trip.landmarks.clear();
widget.trip.addLandmark(
Landmark(
uuid: 'pending',
name: query,
location: [location.latitude, location.longitude],
type: typeStart
)
startLocation = locations.first;
} else {
log('No results found for: $query. Is geocoding available?');
log('Setting Fallback location');
List coordinates = debugLocations[query.toLowerCase()] ?? [48.8575, 2.3514];
startLocation = Location(
latitude: coordinates[0],
longitude: coordinates[1],
timestamp: DateTime.now(),
);
}
widget.trip.landmarks.clear();
widget.trip.addLandmark(
Landmark(
uuid: 'pending',
name: query,
location: [startLocation.latitude, startLocation.longitude],
type: typeStart
)
);
}
late Widget locationSearchBar = SearchBar(

View File

@@ -26,7 +26,7 @@ class _NewTripMapState extends State<NewTripMap> {
target: LatLng(48.8566, 2.3522),
zoom: 11.0,
);
late GoogleMapController _mapController;
GoogleMapController? _mapController;
final Set<Marker> _markers = <Marker>{};
_onLongPress(LatLng location) {
@@ -56,11 +56,15 @@ class _NewTripMapState extends State<NewTripMap> {
),
)
);
_mapController.moveCamera(
CameraUpdate.newLatLng(
LatLng(landmark.location[0], landmark.location[1])
)
);
// check if the controller is ready
if (_mapController != null) {
_mapController!.animateCamera(
CameraUpdate.newLatLng(
LatLng(landmark.location[0], landmark.location[1])
)
);
}
setState(() {});
}
}