search item with geographical search

This commit is contained in:
Valentin CZERYBA 2024-11-05 23:29:55 +01:00
parent b796d0206f
commit 3a0f24cc4c
2 changed files with 131 additions and 84 deletions

View File

@ -4,13 +4,11 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'ItemMenu.dart'; import 'ItemMenu.dart';
import 'Camera.dart'; import 'SearchDelegate.dart';
import '../classes/events.dart'; import '../classes/events.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart'; import 'package:intl/date_symbol_data_local.dart';
import 'package:camera/camera.dart';
import 'package:mapbox_gl/mapbox_gl.dart'; // Add this import
import 'dart:math'; import 'dart:math';
import '../variable/globals.dart' as globals; import '../variable/globals.dart' as globals;
@ -230,7 +228,7 @@ class _MyHomePageState extends State<ListItemMenu> {
onPressed: () { onPressed: () {
showSearch( showSearch(
context: context, context: context,
delegate: SearchDelegateExample(), delegate: SearchDelegateExample(geoQuery: inputGeo.text),
); );
}, },
), ),
@ -297,83 +295,3 @@ class _MyHomePageState extends State<ListItemMenu> {
); );
} }
} }
class SearchDelegateExample extends SearchDelegate {
@override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
query = '';
},
),
];
}
@override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
close(context, null);
},
);
}
@override
Widget buildResults(BuildContext context) {
// Perform the search and return the results
return FutureBuilder<List<Events>>(
future: searchPosts(query),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
final posts = snapshot.data!;
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return ListTile(
title: Text(post.name!),
subtitle: Text(post.place!),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ItemMenu(title: post.id!),
),
);
},
);
},
);
} else {
return const Center(child: Text("No results found"));
}
},
);
}
@override
Widget buildSuggestions(BuildContext context) {
return Container(); // Implement suggestions if needed
}
Future<List<Events>> searchPosts(String query) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
final List<Events> body = [];
if (accessToken.isNotEmpty) {
var url = Uri.parse("${globals.api}/events/search?item=$query");
final response = await http.get(url, headers: {
"Content-Type": "application/json",
HttpHeaders.cookieHeader: "access_token=${accessToken}"
});
final List body = json.decode(utf8.decode(response.bodyBytes));
return body.map((e) => Events.fromJson(e)).toList();
}
return body;
}
}

View File

@ -0,0 +1,129 @@
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:io';
import 'ItemMenu.dart';
import '../classes/events.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv
import 'dart:math';
import '../variable/globals.dart' as globals;
class SearchDelegateExample extends SearchDelegate {
final String geoQuery;
SearchDelegateExample({
required this.geoQuery,
});
@override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
query = '';
},
),
];
}
@override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
close(context, null);
},
);
}
@override
Widget buildResults(BuildContext context) {
// Perform the search and return the results
return FutureBuilder<List<Events>>(
future: searchPosts(query, geoQuery),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
final posts = snapshot.data!;
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return ListTile(
title: Text(post.name!),
subtitle: Text(post.place!),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ItemMenu(title: post.id!),
),
);
},
);
},
);
} else {
return const Center(child: Text("No results found"));
}
},
);
}
@override
Widget buildSuggestions(BuildContext context) {
return Container(); // Implement suggestions if needed
}
Future<List<Events>> searchPosts(String query, String geoQuery) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
final List<Events> body = [];
if (accessToken.isNotEmpty) {
var url = Uri.parse("${globals.api}/events/search?item=$query");
if (geoQuery.isNotEmpty) {
await dotenv.load(
fileName: ".env"); // Load your .env for the Mapbox access token
final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? '';
final geocodeUrl = Uri.parse(
'https://api.mapbox.com/geocoding/v5/mapbox.places/$geoQuery.json?access_token=$mapboxAccessToken');
final geocodeResponse = await http.get(geocodeUrl);
if (geocodeResponse.statusCode == 200) {
final geocodeData = json.decode(geocodeResponse.body);
if (geocodeData['features'].isNotEmpty) {
final coordinates =
geocodeData['features'][0]['geometry']['coordinates'];
final longitude = coordinates[0]; // Longitude
final latitude = coordinates[1]; // Latitude
// Now use the latitude and longitude to get events within a 50km radius
double radiusInKm = 50;
double latDistance = radiusInKm / 111.0;
double lonDistance =
radiusInKm / (111.0 * cos(latitude * pi / 180));
double minLat = latitude - latDistance;
double maxLat = latitude + latDistance;
double minLon = longitude - lonDistance;
double maxLon = longitude + lonDistance;
// Construct the search URL with the item query and latitude/longitude bounds
url = Uri.parse(
"${globals.api}/events/search?item=$query&min_lat=$minLat&max_lat=$maxLat&min_lon=$minLon&max_lon=$maxLon");
}
}
}
final response = await http.get(url, headers: {
"Content-Type": "application/json",
HttpHeaders.cookieHeader: "access_token=${accessToken}"
});
final List body = json.decode(utf8.decode(response.bodyBytes));
return body.map((e) => Events.fromJson(e)).toList();
}
return body;
}
}