Skip to content

Commit

Permalink
Located user on map
Browse files Browse the repository at this point in the history
  • Loading branch information
Jorge Andrés Díaz authored and Jorge Andrés Díaz committed Feb 9, 2024
1 parent 496c99e commit a669bba
Show file tree
Hide file tree
Showing 15 changed files with 426 additions and 18 deletions.
4 changes: 3 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ android {
applicationId "com.example.solar_energy_prediction"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
minSdkVersion 20
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

multiDexEnabled true
}

buildTypes {
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
android:label="solar_energy_prediction"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">

<meta-data android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCRMiXi_Z1VkKKK76jPVHkH1mnKx1F3oxg"/>

<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
2 changes: 2 additions & 0 deletions ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("AIzaSyD61dJZf7ccYxnzYaLNtpsnN6zTLnv_Bv0")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
Expand Down
6 changes: 5 additions & 1 deletion lib/core/config/l10n/intl/messages_en_US.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ class MessageLookup extends MessageLookupByLibrary {
"app_requires_location_services_and_permission_title":
MessageLookupByLibrary.simpleMessage(
"This app requires GPS enabled and location permission granted"),
"locating_user_on_map_text":
MessageLookupByLibrary.simpleMessage("Locating user on map..."),
"request_gps_services_button":
MessageLookupByLibrary.simpleMessage("Request GPS services")
MessageLookupByLibrary.simpleMessage("Request GPS services"),
"user_location_is_unknown_text":
MessageLookupByLibrary.simpleMessage("User location is unknown!")
};
}
6 changes: 3 additions & 3 deletions lib/core/config/l10n/intl_en_US.arb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"@@locale": "en_US",

"app_name": "Solar Energy Prediction",

"app_requires_location_services_and_permission_title": "This app requires GPS enabled and location permission granted",
"request_gps_services_button": "Request GPS services"

"request_gps_services_button": "Request GPS services",
"locating_user_on_map_text": "Locating user on map...",
"user_location_is_unknown_text": "User location is unknown!"
}
20 changes: 20 additions & 0 deletions lib/core/config/l10n/l10n.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions lib/core/extensions/location_extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:google_maps_flutter/google_maps_flutter.dart';

extension LocationExtension on LatLng {
bool isDefaultPoint() {
return longitude == 0 && latitude == 0;
}
}
2 changes: 1 addition & 1 deletion lib/core/theme/app_colors.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';

class AppColors {
static const purpleMedium = Color(0xFF8A05BE);
static const caribbeanGreen = Color(0xFF00D180);
static const pinkSalmon = Color(0xFFFF99AA);
static const grayEmperor = Color(0xFF524F52);
}
2 changes: 1 addition & 1 deletion lib/core/theme/app_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:solar_energy_prediction/core/theme/app_colors.dart';
class AppTheme {
ThemeData getTheme() => ThemeData(
useMaterial3: true,
colorSchemeSeed: AppColors.purpleMedium,
colorSchemeSeed: AppColors.caribbeanGreen,
brightness: Brightness.light,
);
}
130 changes: 130 additions & 0 deletions lib/core/theme/map_theme.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const mapTheme = [
{
"featureType": "all",
"elementType": "geometry.fill",
"stylers": [
{"weight": "2.00"}
]
},
{
"featureType": "all",
"elementType": "geometry.stroke",
"stylers": [
{"color": "#9c9c9c"}
]
},
{
"featureType": "all",
"elementType": "labels.text",
"stylers": [
{"visibility": "on"}
]
},
{
"featureType": "landscape",
"elementType": "all",
"stylers": [
{"color": "#f2f2f2"}
]
},
{
"featureType": "landscape",
"elementType": "geometry.fill",
"stylers": [
{"color": "#ffffff"}
]
},
{
"featureType": "landscape.man_made",
"elementType": "geometry.fill",
"stylers": [
{"color": "#ffffff"}
]
},
{
"featureType": "poi",
"elementType": "all",
"stylers": [
{"visibility": "off"}
]
},
{
"featureType": "road",
"elementType": "all",
"stylers": [
{"saturation": -100},
{"lightness": 45}
]
},
{
"featureType": "road",
"elementType": "geometry.fill",
"stylers": [
{"color": "#eeeeee"}
]
},
{
"featureType": "road",
"elementType": "labels.text.fill",
"stylers": [
{"color": "#7b7b7b"}
]
},
{
"featureType": "road",
"elementType": "labels.text.stroke",
"stylers": [
{"color": "#ffffff"}
]
},
{
"featureType": "road.highway",
"elementType": "all",
"stylers": [
{"visibility": "simplified"}
]
},
{
"featureType": "road.arterial",
"elementType": "labels.icon",
"stylers": [
{"visibility": "off"}
]
},
{
"featureType": "transit",
"elementType": "all",
"stylers": [
{"visibility": "off"}
]
},
{
"featureType": "water",
"elementType": "all",
"stylers": [
{"color": "#46bcec"},
{"visibility": "on"}
]
},
{
"featureType": "water",
"elementType": "geometry.fill",
"stylers": [
{"color": "#c8d7d4"}
]
},
{
"featureType": "water",
"elementType": "labels.text.fill",
"stylers": [
{"color": "#070707"}
]
},
{
"featureType": "water",
"elementType": "labels.text.stroke",
"stylers": [
{"color": "#ffffff"}
]
}
];
29 changes: 21 additions & 8 deletions lib/features/map/presentation/screens/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:solar_energy_prediction/core/use_cases/use_cases.dart';
import 'package:solar_energy_prediction/core/widgets/overlays/snackbar_overlay.dart';
import 'package:solar_energy_prediction/features/map/domain/use_cases/is_gps_service_enabled_use_case.dart';
import 'package:solar_energy_prediction/features/map/domain/use_cases/request_gps_service_use_case.dart';
import 'package:solar_energy_prediction/features/map/presentation/view_models/map_view_model.dart';
import 'package:solar_energy_prediction/features/map/presentation/view_models/request_gps_services_view_model.dart';
import 'package:solar_energy_prediction/features/map/presentation/views/map_view.dart';
import 'package:solar_energy_prediction/features/map/presentation/views/request_gps_services_view.dart';
Expand All @@ -16,15 +17,23 @@ class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeNotifierProvider(
create: _createRequestGpsServicesViewModel,
child: SafeArea(
body: SafeArea(
child: MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => _createRequestGpsServicesViewModel()..checkGpsStatus(),
),
ChangeNotifierProvider(
create: (_) => _createMapViewModel()..updateLastKnownLocation(),
),
],
child: Consumer<RequestGpsServicesViewModel>(
builder: (_, viewModel, ___) {
builder: (_, requestGpsServicesViewModel, __) {
return SnackbarOverlay(
snackBarStatus: viewModel.snackBarStatus,
child:
viewModel.gpsServiceEnabledAndGranted ? const MapView() : const RequestGpsServicesView(),
snackBarStatus: requestGpsServicesViewModel.snackBarStatus,
child: requestGpsServicesViewModel.gpsServiceEnabledAndGranted
? const MapView()
: const RequestGpsServicesView(),
);
},
),
Expand All @@ -33,7 +42,7 @@ class HomeScreen extends StatelessWidget {
);
}

RequestGpsServicesViewModel _createRequestGpsServicesViewModel(_) => RequestGpsServicesViewModel(
RequestGpsServicesViewModel _createRequestGpsServicesViewModel() => RequestGpsServicesViewModel(
location: serviceLocator<Location>(),
isGpsServiceEnabledUseCase: serviceLocator<FutureUseCase<bool, void>>(
instanceName: '$IsGpsServiceEnabledUseCase',
Expand All @@ -42,4 +51,8 @@ class HomeScreen extends StatelessWidget {
instanceName: '$RequestGpsServiceUseCase',
),
);

MapViewModel _createMapViewModel() => MapViewModel(
location: serviceLocator<Location>(),
);
}
48 changes: 48 additions & 0 deletions lib/features/map/presentation/view_models/map_view_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:solar_energy_prediction/core/config/l10n/l10n.dart';
import 'package:solar_energy_prediction/core/extensions/location_extensions.dart';
import 'package:solar_energy_prediction/core/notifier_helpers/snackbar_status_notifier.dart';
import 'package:solar_energy_prediction/core/theme/map_theme.dart';

class MapViewModel extends ChangeNotifier with SnackbarStatusMixin {
final Location _location;

Location get location => _location;

LatLng _lastKnownLocation;

LatLng get lastKnownLocation => _lastKnownLocation;

GoogleMapController? _mapController;

GoogleMapController? get mapController => _mapController;

MapViewModel({
required Location location,
}) : _location = location,
_lastKnownLocation = const LatLng(0, 0);

Future<void> updateLastKnownLocation() async {
final currentLocation = await location.getLocation();
_lastKnownLocation = LatLng(currentLocation.latitude ?? 0, currentLocation.longitude ?? 0);
notifyListeners();
}

void onMapInitialized(GoogleMapController mapController) {
_mapController = mapController;
_mapController?.setMapStyle(jsonEncode(mapTheme));
}

void locateUserOnMap() {
if (_lastKnownLocation.isDefaultPoint()) {
snackBarStatus.postError(S.current.user_location_is_unknown_text);
} else {
final cameraUpdate = CameraUpdate.newLatLng(_lastKnownLocation);
_mapController?.animateCamera(cameraUpdate);
}
}
}
Loading

0 comments on commit a669bba

Please sign in to comment.