find_remote_datasource
unknown
dart
5 months ago
7.2 kB
2
Indexable
import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:geocoding/geocoding.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../../../core/errors/exceptions.dart'; import '../../../../core/res/media_res.dart'; import '../../../../core/services/api.dart'; import '../../../../core/utils/constanst.dart'; import '../../../../core/utils/core_utils.dart'; import '../../../../core/utils/headers.dart'; import '../../presentation/widgets/custom_marker.dart'; import '../models/charge_station_model.dart'; abstract class FindRemoteDataSource { const FindRemoteDataSource(); Future<List<ChargerStationModel>> getChargeStations(); Future<void> openMapsNavigation(List<double> coordinates); Future<Set<Marker>> loadMarkers(List<ChargerStationModel> chargerStations); Future<List<ChargerStationModel>> getFavoriteChargeStations(String userId); // Future<void> postFavoriteChargeStation(List<ChargerStationModel> chargerStations) async {} } class FindRemoteDataSourceImpl implements FindRemoteDataSource { const FindRemoteDataSourceImpl({required Dio dio, required API api}) : _dio = dio, _api = api; final Dio _dio; final API _api; @override Future<List<ChargerStationModel>> getChargeStations() async { try { final result = await _dio.get(_api.find.chargeStations, options: Options( headers: ApiHeaders.getHeaders(token: kApiKey).headers, validateStatus: (status) { return status! < 500; }, ), queryParameters: { 'paginate_limit': 20, 'paginate_enabled': true, 'sort_by': 'createdAt', 'sort_order': 'desc', }); var chargeStations = result.data['result'] as List<dynamic>?; debugPrint('data: ${result.data}'); if (chargeStations == null) { throw const ServerException(message: "Result null", statusCode: "500"); } return await Future.wait(chargeStations.map((e) async { try { if (e['coordinates'] != null && e['coordinates'].length == 2) { double latitude = e['coordinates'][1]; double longitude = e['coordinates'][0]; List<Placemark> placemarks = await placemarkFromCoordinates(latitude, longitude); Placemark place = placemarks[0]; final addressText = "${CoreUtils.removeFirstWord(text: place.locality.toString())}, ${CoreUtils.removeFirstWord(text: place.subAdministrativeArea.toString())}"; e['location'] = addressText; } } catch (e, s) { debugPrintStack(stackTrace: s); debugPrint("Error while fetching address: $e"); } return ChargerStationModel.fromMap(e); }).toList()); } on DioException catch (e) { throw ServerException( message: e.response?.data['message'] ?? e.message, statusCode: e.response?.statusCode ?? 500); } on ServerException { rethrow; } catch (e, s) { debugPrintStack(stackTrace: s); throw ServerException(message: e.toString(), statusCode: 505); } } @override Future<void> openMapsNavigation(List<double> coordinates) async { try { final uri = Uri(scheme: "google.navigation", queryParameters: { 'q': '${coordinates[1]},${coordinates[0]}', 'mode': 'd' }); if (await canLaunchUrl(uri)) { await launchUrl(uri); } else { throw const ServerException( message: 'Could not launch Google Maps', statusCode: 505); } } on ServerException { rethrow; } catch (e, s) { debugPrintStack(stackTrace: s); throw ServerException(message: e.toString(), statusCode: 505); } } @override Future<Set<Marker>> loadMarkers( List<ChargerStationModel> chargerStations) async { try { final markers = <Marker>[]; for (var chargeStation in chargerStations) { // check if the charger in the station is available or full final chargeStatus = chargeStation.chargers .map((e) => e.chargerStatus) .contains('Available') ? 'Available' : 'Full'; final customMarker = await getCustomMarker( statusCharger: chargeStatus, width: 100, height: 100, icon: chargeStatus == 'Available' ? MediaRes.availableMarker : MediaRes.availableMarker, ); markers.add(Marker( markerId: MarkerId(chargeStation.id), position: LatLng( chargeStation.coordinates[1], chargeStation.coordinates[0], ), // BitmapDescriptor icon: customMarker, infoWindow: InfoWindow(title: chargeStation.name), )); } // debugPrint("markers: ${markers[0].icon}"); for (var marker in markers) { debugPrint("marker: ${marker.icon}"); } return markers.toSet(); } catch (e, s) { debugPrintStack(stackTrace: s); throw ServerException(message: e.toString(), statusCode: 505); } } @override Future<List<ChargerStationModel>> getFavoriteChargeStations( String userId) async { try { final result = await _dio.get( "$kParkingBaseUrl/get-user-fav-chargestation/$userId", ); var favoriteChargeStations = result.data['favourite'] as List<dynamic>?; debugPrint('data: ${result.data}'); if (favoriteChargeStations == null) { throw const ServerException(message: "Result null", statusCode: "500"); } return await Future.wait(favoriteChargeStations.map((e) async { try { if (e['coordinates'] != null && e['coordinates'].length == 2) { double latitude = e['coordinates'][1]; double longitude = e['coordinates'][0]; List<Placemark> placemarks = await placemarkFromCoordinates(latitude, longitude); Placemark place = placemarks[0]; final addressText = "${CoreUtils.removeFirstWord(text: place.locality.toString())}, ${CoreUtils.removeFirstWord(text: place.subAdministrativeArea.toString())}"; e['location'] = addressText; } } catch (e, s) { debugPrintStack(stackTrace: s); debugPrint("Error while fetching address: $e"); } return ChargerStationModel.fromMap(e); }).toList()); } on DioException catch (e) { throw ServerException( message: e.response?.data['message'] ?? e.message, statusCode: e.response?.statusCode ?? 500); } on ServerException { rethrow; } catch (e, s) { debugPrintStack(stackTrace: s); throw ServerException(message: e.toString(), statusCode: 505); } } }
Editor is loading...
Leave a Comment