find_remote_datasource
unknown
dart
a year ago
7.2 kB
6
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