diff --git a/Mobile/lib/api.dart b/Mobile/lib/api.dart index 496e157..25b6bdc 100644 --- a/Mobile/lib/api.dart +++ b/Mobile/lib/api.dart @@ -57,7 +57,7 @@ Future request(BuildContext context, ApiService service, String method, return null; } - return response.body; + return utf8.decode(response.bodyBytes); } Future isLoggedIn(BuildContext context) async { diff --git a/Mobile/lib/main.dart b/Mobile/lib/main.dart index 74af895..d3f8bd9 100644 --- a/Mobile/lib/main.dart +++ b/Mobile/lib/main.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:latlong2/latlong.dart'; @@ -49,6 +50,7 @@ class _MyHomePageState extends State { final GlobalKey _scaffoldKey = GlobalKey(); List _favorites = []; LatLng? _selectedPoint; + double _zoom = 7.0; void _onTap(TapPosition _, LatLng point) async { setState(() => _selectedPoint = point); @@ -56,12 +58,13 @@ class _MyHomePageState extends State { final dynamic location; try { final response = await http.get( - Uri.parse('https://nominatim.openstreetmap.org/reverse.php?lat=${point.latitude}&lon=${point.longitude}&zoom=18&format=jsonv2'), + Uri.parse('https://nominatim.openstreetmap.org/reverse.php?lat=${point.latitude}&lon=${point.longitude}&zoom=${max(12, _zoom.ceil())}&format=jsonv2'), headers: {'User-Agent': 'SkanTravels/1.0'}, ); if (mounted && response.statusCode != 200) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Unable to fetch information about this location (HTTP ${response.statusCode})'))); + debugPrint(response.body); return; } @@ -136,12 +139,19 @@ class _MyHomePageState extends State { if (!context.mounted) return; if (favorite == null) { - if (await api.request(context, api.ApiService.app, 'POST', '/favorites', {'lat': point.latitude, 'lng': point.longitude}) == null) { + final newFavorite = await api.request( + context, api.ApiService.app, 'POST', '/favorites', + {'lat': point.latitude, 'lng': point.longitude, 'name': name, 'description': description}, + ); + + if (newFavorite == null) { navigator.pop(); return; } - await _fetchFavorites(); + setState(() { + _favorites.add(Favorite.fromJson(jsonDecode(newFavorite))); + }); setModalState(() {}); return; @@ -164,7 +174,7 @@ class _MyHomePageState extends State { final List favorites = jsonDecode(response); setState(() { - _favorites = favorites.map((favorite) => Favorite(favorite['id'], favorite['user_id'], favorite['lat'], favorite['lng'], favorite['name'], favorite['description'])).toList(); + _favorites = favorites.map((favorite) => Favorite.fromJson(favorite)).toList(); }); } @@ -189,8 +199,9 @@ class _MyHomePageState extends State { body: FlutterMap( options: MapOptions( initialCenter: const LatLng(55.9397, 9.5156), - initialZoom: 7.0, + initialZoom: _zoom, onTap: _onTap, + onPositionChanged: (pos, _) => _zoom = pos.zoom, ), children: [ openStreetMapTileLayer, diff --git a/Mobile/lib/models.dart b/Mobile/lib/models.dart index 665387c..78fb075 100644 --- a/Mobile/lib/models.dart +++ b/Mobile/lib/models.dart @@ -7,6 +7,17 @@ class Favorite { String description; Favorite(this.id, this.userId, this.lat, this.lng, this.name, this.description); + + factory Favorite.fromJson(Map json) { + return Favorite( + json['id'], + json['user_id'], + json['lat'], + json['lng'], + json['name'], + json['description'], + ); + } } class Login { diff --git a/rust-backend/src/main.rs b/rust-backend/src/main.rs index 815df0d..f059c3a 100644 --- a/rust-backend/src/main.rs +++ b/rust-backend/src/main.rs @@ -56,39 +56,33 @@ fn get_favorites(db: MutexGuard<'_, rusqlite::Connection>, user_id: String) -> O struct CreateFavoriteRequest { lat: f64, lng: f64, -} - -#[derive(Deserialize, Debug)] -struct ReverseLookupResponse { name: String, - display_name: String, + description: String, } #[post("/favorites")] async fn create_favorite(auth: AuthorizedUser, data: web::Data, input: web::Json) -> impl Responder { let db = data.database.lock().unwrap(); - let Ok(response) = reqwest::Client::new() - .get(format!("https://nominatim.openstreetmap.org/reverse.php?lat={}&lon={}&zoom=18&format=jsonv2", input.lat, input.lng)) - .header("User-Agent", "SkanTravels/1.0") - .send().await - else { return HttpResponse::InternalServerError(); }; - - let Ok(response) = response.json::().await - else { return HttpResponse::InternalServerError(); }; - match db.execute( "INSERT INTO favorites (user_id, lat, lng, name, description) VALUES (:user_id, :lat, :lng, :name, :description)", &[ (":user_id", &auth.user_id), (":lat", &input.lat.to_string()), (":lng", &input.lng.to_string()), - (":name", &response.name), - (":description", &response.display_name), + (":name", &input.name), + (":description", &input.description), ], ) { - Ok(_) => HttpResponse::Created(), - Err(_) => HttpResponse::InternalServerError(), + Ok(_) => HttpResponse::Created().json(Favorite { + id: db.last_insert_rowid(), + user_id: auth.user_id, + lat: input.lat, + lng: input.lng, + name: input.name.clone(), + description: input.description.clone(), + }), + Err(_) => HttpResponse::InternalServerError().finish(), } } diff --git a/rust-backend/src/models.rs b/rust-backend/src/models.rs index a9fa37d..4892d0b 100644 --- a/rust-backend/src/models.rs +++ b/rust-backend/src/models.rs @@ -4,7 +4,7 @@ use rusqlite::{Row, Error}; #[derive(Serialize)] pub struct Favorite { - pub id: usize, + pub id: i64, pub user_id: String, pub lat: f64, pub lng: f64,