Skip to content

Commit

Permalink
Fix steady location issue (#106)
Browse files Browse the repository at this point in the history
* fix journey break issue

* add 10 meter check to update location

* add grace period and check time interval

* journey ui updates

* add cache for last five location storage and remove location table db

* show steady duration in steady location in journey

* add log in firebase for journey

* change algorithm for journey tracking

* set location on home screen to fix location updates on creating new acc after delete with deleting app

* fix lint

* revert day change call and update create_at and update_at

* update ios deploy
  • Loading branch information
cp-ishita-g authored Oct 1, 2024
1 parent a2193f4 commit b91dad6
Show file tree
Hide file tree
Showing 30 changed files with 643 additions and 997 deletions.
4 changes: 3 additions & 1 deletion app/assets/locales/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -280,5 +280,7 @@
"journey_timeline_empty_screen_text": "No location history found!",
"journey_timeline_Since_text": "Since {date}",
"journey_timeline_today_text": "Today {date}",
"journey_timeline_date_picker_select_text": "Select"
"journey_timeline_date_picker_select_text": "Select",

"journey_detail_getting_address_text": "Getting the address..."
}
44 changes: 30 additions & 14 deletions app/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ import CoreLocation

@main
@objc class AppDelegate: FlutterAppDelegate {

var geofencePlugin: GeofenceService?
var locationManager: CLLocationManager?
var previousLocation: CLLocation?

let minimumDistance: Double = 10.0 // 10 meters


override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
Expand All @@ -23,15 +21,16 @@ import CoreLocation
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
}

setUpLocation()

let key = Bundle.main.object(forInfoDictionaryKey: "ApiMapKey")
GMSServices.provideAPIKey(key as! String)

geofencePluginRegistration()

GeneratedPluginRegistrant.register(with: self)
setUpFlutterMethodChannelForInvokeLocation()
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

Expand All @@ -46,9 +45,9 @@ extension AppDelegate {
private func geofencePluginRegistration() {
let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
let geofenceChannel = FlutterMethodChannel(name: "geofence_plugin", binaryMessenger: controller.binaryMessenger)

geofencePlugin = GeofenceService(channel: geofenceChannel)

geofenceChannel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) in
guard let self = self else { return }
if call.method == "startMonitoring" {
Expand Down Expand Up @@ -79,18 +78,35 @@ extension AppDelegate: CLLocationManagerDelegate {
private func setUpLocation() {
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.distanceFilter = 10
locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager?.allowsBackgroundLocationUpdates = true
locationManager?.pausesLocationUpdatesAutomatically = false
locationManager?.startMonitoringSignificantLocationChanges()
}

private func setUpFlutterMethodChannelForInvokeLocation() {
let controller = window?.rootViewController as! FlutterViewController
let locationChannel = FlutterMethodChannel(name: "com.yourspace/set_up_location", binaryMessenger: controller.binaryMessenger)

locationChannel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) in
guard let self = self else { return }
if call.method == "setUpLocation" {
self.setUpLocation()
result(nil)
} else {
result(FlutterMethodNotImplemented)
}
}
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let currentLocation = locations.last else { return }

if let previousLocation = previousLocation {
let distance = currentLocation.distance(from: previousLocation)
if distance < minimumDistance {
if let lastLocation = previousLocation {
let distance = currentLocation.distance(from: lastLocation)

if distance < 10 {
return
}
}
Expand Down
5 changes: 1 addition & 4 deletions app/lib/domain/extenstions/date_formatter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ enum DateFormatType {
relativeDate,
relativeDateWeekday,
serverIso,
dayTime,
shortDayMonth
}

Expand Down Expand Up @@ -71,8 +70,6 @@ extension DateFormatter on DateTime {
return _formattedPastTime(context);
case DateFormatType.serverIso:
return DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(toUtc());
case DateFormatType.dayTime:
return DateFormat('dd MMMM hh:mm a').format(this);
case DateFormatType.shortDayMonth:
return DateFormat('d MMMM').format(this);
}
Expand Down Expand Up @@ -118,7 +115,7 @@ extension DateFormatter on DateTime {
} else if (isSameDay(yesterday)) {
return context.l10n.common_yesterday;
} else if (year == today.year) {
return DateFormat('${includeWeekday ? 'EEEE, ' : ''}d MMMM').format(this);
return DateFormat('${includeWeekday ? 'EEEE, ' : ''}d MMM').format(this);
} else {
return DateFormat('${includeWeekday ? 'EEEE, ' : ''}d MMM yyyy')
.format(this);
Expand Down
29 changes: 10 additions & 19 deletions app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:io';

import 'package:battery_plus/battery_plus.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:data/api/location/journey/api_journey_service.dart';
import 'package:data/api/location/location.dart';
import 'package:data/log/logger.dart';
import 'package:data/repository/journey_repository.dart';
Expand Down Expand Up @@ -32,6 +33,7 @@ import 'domain/fcm/notification_handler.dart';
const platform = MethodChannel('com.yourspace/location');
late final LocationService locationService;
late final JourneyRepository journeyRepository;
late final ApiJourneyService journeyService;

void main() async {
WidgetsFlutterBinding.ensureInitialized();
Expand Down Expand Up @@ -78,7 +80,8 @@ void updateCurrentUserState(RemoteMessage message, NetworkService networkService
Future<ProviderContainer> _initContainer() async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
locationService = LocationService(FirebaseFirestore.instance);
journeyRepository = JourneyRepository(FirebaseFirestore.instance);
journeyService = ApiJourneyService(FirebaseFirestore.instance);
journeyRepository = JourneyRepository(journeyService);

final prefs = await SharedPreferences.getInstance();

Expand Down Expand Up @@ -138,7 +141,6 @@ StreamSubscription<Position>? positionSubscription;
Timer? _timer;
Position? _position;
Position? _previousPosition;
LocationData? _iOSPreviousPosition;
int? _batteryLevel;

@pragma('vm:entry-point')
Expand All @@ -157,7 +159,8 @@ Future<void> onStart(ServiceInstance service) async {

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
locationService = LocationService(FirebaseFirestore.instance);
journeyRepository = JourneyRepository(FirebaseFirestore.instance);
journeyService = ApiJourneyService(FirebaseFirestore.instance);
journeyRepository = JourneyRepository(journeyService);
final batteryService = BatteryService(FirebaseFirestore.instance);
final userId = await _getUserIdFromPreferences();
final battery = Battery();
Expand Down Expand Up @@ -194,23 +197,14 @@ void _startLocationUpdates() {
Future<void> _updateUserLocationWithIOS(LocationData locationPosition) async {
final userId = await _getUserIdFromPreferences();
if (userId != null) {
final isSame = _iOSPreviousPosition?.latitude == locationPosition.latitude &&
_iOSPreviousPosition?.longitude == locationPosition.longitude;

if (isSame) return;
_iOSPreviousPosition = locationPosition;

try {
final userState = await journeyRepository.getUserState(userId, locationPosition);

await locationService.saveCurrentLocation(
userId,
LatLng(locationPosition.latitude, locationPosition.longitude),
DateTime.now().millisecondsSinceEpoch,
userState,
DateTime.now().millisecondsSinceEpoch
);

await journeyRepository.saveUserJourney(userState, userId, locationPosition);
await journeyRepository.saveLocationJourney(locationPosition, userId);
} catch (error, stack) {
logger.e(
'Error while updating user location and journey from native iOS location data',
Expand All @@ -225,6 +219,7 @@ void _updateUserLocation(
String userId,
Position? position,
) async {
if (Platform.isIOS) return;
final isSame = _previousPosition?.latitude == position?.latitude &&
_previousPosition?.longitude == position?.longitude;

Expand All @@ -237,17 +232,13 @@ void _updateUserLocation(
longitude: position.longitude,
timestamp: position.timestamp,
);

final userState = await journeyRepository.getUserState(userId, locationData);

await locationService.saveCurrentLocation(
userId,
LatLng(position.latitude, position.longitude),
DateTime.now().millisecondsSinceEpoch,
userState,
);

await journeyRepository.saveUserJourney(userState, userId, locationData);
await journeyRepository.saveLocationJourney(locationData, userId);
} catch (error, stack) {
logger.e(
'Main: error while getting ot update user location and journey',
Expand Down
14 changes: 13 additions & 1 deletion app/lib/ui/flow/home/home_screen_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import 'package:data/log/logger.dart';
import 'package:data/service/permission_service.dart';
import 'package:data/service/space_service.dart';
import 'package:data/storage/app_preferences.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'home_screen_viewmodel.freezed.dart';

const platform = MethodChannel('com.yourspace/set_up_location');

final homeViewStateProvider =
StateNotifierProvider.autoDispose<HomeViewNotifier, HomeViewState>(
(ref) => HomeViewNotifier(
Expand All @@ -32,6 +35,7 @@ class HomeViewNotifier extends StateNotifier<HomeViewState> {
final ApiUser? _currentUser;
final ApiUserService userService;
final ApiSession? _userSession;
static const platform = MethodChannel('com.yourspace/set_up_location');

HomeViewNotifier(
this.spaceService,
Expand All @@ -47,13 +51,21 @@ class HomeViewNotifier extends StateNotifier<HomeViewState> {

if (_currentUser == null && _userSession == null) return;
listenUserSession(_currentUser!.id, _userSession!.id);
_setupLocationOnIOS();
}

String? get currentSpaceId => _currentSpaceIdController.state;

Future<void> _setupLocationOnIOS() async {
try {
await platform.invokeMethod('setUpLocation');
} on PlatformException catch (e) {
logger.e('HomeViewNotifier: error while invoke update location in iOS', error: e);
}
}

void listenSpaceMember() async {
if (state.loading) return;

try {
state = state.copyWith(loading: true);
spaceService.streamAllSpace().listen((spaces) {
Expand Down
16 changes: 15 additions & 1 deletion app/lib/ui/flow/journey/components/journey_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class _JourneyMapState extends State<JourneyMap> {

final longDistanceLatLng = _getLongDistanceCoordinate();
final centerLatLng = _getCenterCoordinate(_fromLatLng, longDistanceLatLng);
final zoom = _calculateZoomLevel(journey.route_distance ?? 0);
final zoom = _calculateZoomLevel(_getDistanceString(journey));
return (polyline, centerLatLng, zoom);
}

Expand Down Expand Up @@ -197,4 +197,18 @@ class _JourneyMapState extends State<JourneyMap> {
}
});
}

double _getDistanceString(ApiLocationJourney location) {
final steadyLocation = location.toPositionFromSteadyJourney();
final movingLocation = location.toPositionFromMovingJourney();

final routeDistance = steadyLocation.distanceTo(movingLocation);

if (routeDistance < 1000) {
return routeDistance.round().ceilToDouble();
} else {
final distanceInKm = routeDistance / 1000;
return distanceInKm.round().ceilToDouble();
}
}
}
Loading

0 comments on commit b91dad6

Please sign in to comment.