From bca5fb7485c37670582f29c80c381bac4ab8bbbe Mon Sep 17 00:00:00 2001 From: cp-ishita-g Date: Mon, 28 Oct 2024 17:46:30 +0530 Subject: [PATCH] show current date journey only --- app/lib/ui/app_route.dart | 4 +- .../locate_on_map_view_model.freezed.dart | 18 +++---- .../selected_member_detail_view.dart | 4 +- .../map/components/space_user_footer.dart | 1 + .../flow/home/map/map_view_model.freezed.dart | 6 +-- .../flow/journey/components/journey_map.dart | 4 +- .../timeline/journey_timeline_screen.dart | 19 ++----- .../timeline/journey_timeline_view_model.dart | 24 ++++++--- data/lib/api/location/journey/journey.dart | 6 +-- data/lib/repository/journey_repository.dart | 54 ++++++++++++------- 10 files changed, 77 insertions(+), 63 deletions(-) diff --git a/app/lib/ui/app_route.dart b/app/lib/ui/app_route.dart index 554e24f1..19f1ebf6 100644 --- a/app/lib/ui/app_route.dart +++ b/app/lib/ui/app_route.dart @@ -222,9 +222,9 @@ class AppRoute { ); } - static AppRoute journeyTimeline(ApiUser user) { + static AppRoute journeyTimeline(ApiUser user, int groupCreatedDate) { return AppRoute(pathJourneyTimeline, - builder: (_) => JourneyTimelineScreen(selectedUser: user)); + builder: (_) => JourneyTimelineScreen(selectedUser: user, groupCreatedDate: groupCreatedDate)); } static AppRoute journeyDetail(ApiLocationJourney journey) { diff --git a/app/lib/ui/flow/geofence/add/locate/locate_on_map_view_model.freezed.dart b/app/lib/ui/flow/geofence/add/locate/locate_on_map_view_model.freezed.dart index 3c7d853d..31e2d4fd 100644 --- a/app/lib/ui/flow/geofence/add/locate/locate_on_map_view_model.freezed.dart +++ b/app/lib/ui/flow/geofence/add/locate/locate_on_map_view_model.freezed.dart @@ -232,13 +232,13 @@ class _$LocateOnMapStateImpl implements _LocateOnMapState { .equals(other.addingPlace, addingPlace) && const DeepCollectionEquality() .equals(other.gettingAddress, gettingAddress) && - const DeepCollectionEquality() - .equals(other.currentLatLng, currentLatLng) && - const DeepCollectionEquality() - .equals(other.cameraLatLng, cameraLatLng) && + (identical(other.currentLatLng, currentLatLng) || + other.currentLatLng == currentLatLng) && + (identical(other.cameraLatLng, cameraLatLng) || + other.cameraLatLng == cameraLatLng) && (identical(other.address, address) || other.address == address) && - const DeepCollectionEquality() - .equals(other.centerPosition, centerPosition) && + (identical(other.centerPosition, centerPosition) || + other.centerPosition == centerPosition) && (identical(other.popToPlaceList, popToPlaceList) || other.popToPlaceList == popToPlaceList) && const DeepCollectionEquality().equals(other.error, error)); @@ -250,10 +250,10 @@ class _$LocateOnMapStateImpl implements _LocateOnMapState { const DeepCollectionEquality().hash(loading), const DeepCollectionEquality().hash(addingPlace), const DeepCollectionEquality().hash(gettingAddress), - const DeepCollectionEquality().hash(currentLatLng), - const DeepCollectionEquality().hash(cameraLatLng), + currentLatLng, + cameraLatLng, address, - const DeepCollectionEquality().hash(centerPosition), + centerPosition, popToPlaceList, const DeepCollectionEquality().hash(error)); diff --git a/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart b/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart index 33065f4e..63b86bcc 100644 --- a/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart +++ b/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart @@ -18,11 +18,13 @@ import '../../../../../gen/assets.gen.dart'; import '../../../../components/user_battery_status.dart'; class SelectedMemberDetailView extends StatefulWidget { + final int groupCreatedDate; final ApiUserInfo? userInfo; final void Function() onDismiss; const SelectedMemberDetailView({ super.key, + required this.groupCreatedDate, required this.userInfo, required this.onDismiss, }); @@ -168,7 +170,7 @@ class _SelectedMemberDetailViewState extends State { Widget _timeLineButtonView() { return OnTapScale( onTap: () { - AppRoute.journeyTimeline(widget.userInfo!.user).push(context); + AppRoute.journeyTimeline(widget.userInfo!.user, widget.groupCreatedDate).push(context); }, child: Container( decoration: BoxDecoration( diff --git a/app/lib/ui/flow/home/map/components/space_user_footer.dart b/app/lib/ui/flow/home/map/components/space_user_footer.dart index 2f4c1eba..ab1c1137 100644 --- a/app/lib/ui/flow/home/map/components/space_user_footer.dart +++ b/app/lib/ui/flow/home/map/components/space_user_footer.dart @@ -65,6 +65,7 @@ class _SpaceUserFooterState extends State { child: widget.selectedUser != null ? SelectedMemberDetailView( key: const ValueKey('detailView'), + groupCreatedDate: widget.selectedSpace?.space.created_at ?? 0, userInfo: widget.selectedUser, onDismiss: widget.onDismiss, ) diff --git a/app/lib/ui/flow/home/map/map_view_model.freezed.dart b/app/lib/ui/flow/home/map/map_view_model.freezed.dart index 2ab4e615..1c46e1df 100644 --- a/app/lib/ui/flow/home/map/map_view_model.freezed.dart +++ b/app/lib/ui/flow/home/map/map_view_model.freezed.dart @@ -374,8 +374,8 @@ class _$MapViewStateImpl implements _MapViewState { const DeepCollectionEquality().equals(other._markers, _markers) && (identical(other.selectedUser, selectedUser) || other.selectedUser == selectedUser) && - const DeepCollectionEquality() - .equals(other.defaultPosition, defaultPosition) && + (identical(other.defaultPosition, defaultPosition) || + other.defaultPosition == defaultPosition) && (identical(other.spaceInvitationCode, spaceInvitationCode) || other.spaceInvitationCode == spaceInvitationCode) && const DeepCollectionEquality().equals(other.error, error) && @@ -396,7 +396,7 @@ class _$MapViewStateImpl implements _MapViewState { const DeepCollectionEquality().hash(_places), const DeepCollectionEquality().hash(_markers), selectedUser, - const DeepCollectionEquality().hash(defaultPosition), + defaultPosition, spaceInvitationCode, const DeepCollectionEquality().hash(error), showLocationDialog); diff --git a/app/lib/ui/flow/journey/components/journey_map.dart b/app/lib/ui/flow/journey/components/journey_map.dart index fdeff265..ec073cc2 100644 --- a/app/lib/ui/flow/journey/components/journey_map.dart +++ b/app/lib/ui/flow/journey/components/journey_map.dart @@ -172,8 +172,8 @@ class _JourneyMapState extends State { } double _getDistanceString(ApiLocationJourney location) { - final steadyLocation = location.toPositionFromSteadyJourney(); - final movingLocation = location.toPositionFromMovingJourney(); + final steadyLocation = location.toLocationFromSteadyJourney(); + final movingLocation = location.toLocationFromMovingJourney(); final routeDistance = steadyLocation.distanceTo(movingLocation); diff --git a/app/lib/ui/flow/journey/timeline/journey_timeline_screen.dart b/app/lib/ui/flow/journey/timeline/journey_timeline_screen.dart index cf67d9f8..a8ab31e5 100644 --- a/app/lib/ui/flow/journey/timeline/journey_timeline_screen.dart +++ b/app/lib/ui/flow/journey/timeline/journey_timeline_screen.dart @@ -25,8 +25,9 @@ import '../components/journey_map.dart'; class JourneyTimelineScreen extends ConsumerStatefulWidget { final ApiUser selectedUser; + final int groupCreatedDate; - const JourneyTimelineScreen({super.key, required this.selectedUser}); + const JourneyTimelineScreen({super.key, required this.selectedUser, required this.groupCreatedDate}); @override ConsumerState createState() => @@ -56,8 +57,6 @@ class _JourneyTimelineScreenState extends ConsumerState { : context.l10n.journey_timeline_title_other_user( state.selectedUser?.first_name ?? ''); - final selectedDate = _onSelectDatePickerDate(state.selectedTimeFrom); - _observeShowDatePicker(state); return AppPage( @@ -68,11 +67,6 @@ class _JourneyTimelineScreenState extends ConsumerState { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Text( - selectedDate, - style: AppTextStyle.body1 - .copyWith(color: context.colorScheme.textPrimary), - ), actionButton( context: context, onPressed: () => notifier.showDatePicker(true), @@ -465,13 +459,6 @@ class _JourneyTimelineScreenState extends ConsumerState { return markers; } - String _onSelectDatePickerDate(int? timestamp) { - if (timestamp == null) return ''; - final dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp); - final date = dateTime.format(context, DateFormatType.dayMonthFull); - return date.toString(); - } - void _observeShowDatePicker(JourneyTimelineState state) { ref.listen( journeyTimelineStateProvider.select((state) => state.showDatePicker), @@ -483,7 +470,7 @@ class _JourneyTimelineScreenState extends ConsumerState { final pickedDate = await showDatePicker( context: context, initialDate: dateTime, - firstDate: DateTime(2023), + firstDate: DateTime.fromMillisecondsSinceEpoch(widget.groupCreatedDate), lastDate: DateTime.now(), confirmText: context.l10n.journey_timeline_date_picker_select_text, ); diff --git a/app/lib/ui/flow/journey/timeline/journey_timeline_view_model.dart b/app/lib/ui/flow/journey/timeline/journey_timeline_view_model.dart index 9a0f4e74..d28af6f6 100644 --- a/app/lib/ui/flow/journey/timeline/journey_timeline_view_model.dart +++ b/app/lib/ui/flow/journey/timeline/journey_timeline_view_model.dart @@ -9,6 +9,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:geocoding/geocoding.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:style/extenstions/date_extenstions.dart'; import 'package:yourspace_flutter/domain/extenstions/lat_lng_extenstion.dart'; import '../../../components/no_internet_screen.dart'; @@ -45,7 +46,6 @@ class JourneyTimelineViewModel extends StateNotifier { spaceId: _currentSpaceId.state, ); _loadJourney(); - journeyService.uploadLogFileToFirebase(); } void _loadJourney({bool loadMore = false}) async { @@ -54,22 +54,30 @@ class JourneyTimelineViewModel extends StateNotifier { state = state.copyWith( isLoading: state.sortedJourney.isEmpty, appending: loadMore); final userId = state.selectedUser!.id; - final from = state.selectedTimeFrom; - final to = state.selectedTimeTo; + final from = state.selectedTimeFrom ?? DateTime.now().startOfDay.millisecondsSinceEpoch; + final to = state.selectedTimeTo ?? DateTime.now().endOfDay.millisecondsSinceEpoch; final lastJourneyTime = _getEarliestJourneyTime(state.sortedJourney); + + // Fetch journey history based on loadMore status final journeys = (loadMore) ? await journeyService.getMoreJourneyHistory(userId, lastJourneyTime) : await journeyService.getJourneyHistory(userId, from, to); - final allJourney = [...state.sortedJourney, ...journeys]; + // Filter by date range + final filteredJourneys = journeys.where((journey) { + return journey.created_at! >= from && journey.created_at! <= to; + }).toList(); - final sortJourney = _sortJourneysByUpdateAt(allJourney); + // Combine all journeys and sort + final allJourney = [...state.sortedJourney, ...filteredJourneys]; + final sortedJourney = _sortJourneysByUpdateAt(allJourney); + // Update state with final data state = state.copyWith( isLoading: false, appending: false, - hasMore: journeys.isNotEmpty && from == null && to == null, - sortedJourney: sortJourney, + hasMore: filteredJourneys.isNotEmpty, + sortedJourney: sortedJourney, ); } catch (error, stack) { state = state.copyWith(error: error, isLoading: false, appending: false); @@ -111,7 +119,7 @@ class JourneyTimelineViewModel extends StateNotifier { if (isNetworkOff) return; final fromTimeStamp = pickedDate.millisecondsSinceEpoch; - final toTimeStamp = pickedDate.copyWith(hour: 23).millisecondsSinceEpoch; + final toTimeStamp = pickedDate.endOfDay.millisecondsSinceEpoch; state = state.copyWith( selectedTimeFrom: fromTimeStamp, selectedTimeTo: toTimeStamp, diff --git a/data/lib/api/location/journey/journey.dart b/data/lib/api/location/journey/journey.dart index 685fd043..e4b81363 100644 --- a/data/lib/api/location/journey/journey.dart +++ b/data/lib/api/location/journey/journey.dart @@ -52,15 +52,15 @@ class ApiLocationJourney with _$ApiLocationJourney { return to_latitude == null && to_longitude == null; } - LocationData toPositionFromSteadyJourney() { + LocationData toLocationFromSteadyJourney() { return LocationData(latitude: from_latitude, longitude: from_longitude, timestamp: DateTime.now()); } - LocationData toPositionFromMovingJourney() { + LocationData toLocationFromMovingJourney() { return LocationData(latitude: to_latitude ?? 0, longitude: to_longitude ?? 0, timestamp: DateTime.now()); } - static ApiLocationJourney fromPosition(LocationData pos, String userId, String newJourneyId) { + static ApiLocationJourney toLocationJourney(LocationData pos, String userId, String newJourneyId) { return ApiLocationJourney( id: newJourneyId, user_id: userId, diff --git a/data/lib/repository/journey_repository.dart b/data/lib/repository/journey_repository.dart index 6ab35826..a241c990 100644 --- a/data/lib/repository/journey_repository.dart +++ b/data/lib/repository/journey_repository.dart @@ -30,13 +30,17 @@ class JourneyRepository { String userId, ) async { try { + var lastKnownJourney = + await getLastKnownLocation(userId, extractedLocation); + _cancelSteadyLocationTimer(); _startSteadyLocationTimer(extractedLocation, userId); - var lastKnownJourney = await getLastKnownLocation(userId, extractedLocation); + // Check and save location journey on day changed addJourneyOnDayChange(extractedLocation, lastKnownJourney, userId); - locationCache.addLocation(extractedLocation, userId); // to get all route position between location a -> b for moving user journey + // to get all route position between location a -> b for moving user journey + locationCache.addLocation(extractedLocation, userId); // Check add add extracted location to last five locations to calculate geometric median await _checkAndSaveLastFiveLocations(extractedLocation, userId); @@ -54,9 +58,12 @@ class JourneyRepository { /// Start or restart the 5-minute timer when the user is steady. void _startSteadyLocationTimer(LocationData position, String userId) { - var lastLocation = locationCache.getLastJourney(userId)?.toPositionFromSteadyJourney(); + var lastLocation = + locationCache.getLastJourney(userId)?.toLocationFromSteadyJourney(); var lastLocationJourney = locationCache.getLastJourney(userId); - if (lastLocation != null && _isSameLocation(position, lastLocation) && lastLocationJourney!.isSteadyLocation()) { + if (lastLocation != null && + _isSameLocation(position, lastLocation) || + lastLocationJourney!.isSteadyLocation()) { return; } @@ -64,16 +71,17 @@ class JourneyRepository { try { await _saveSteadyLocation(position, userId); _cancelSteadyLocationTimer(); - locationCache.clearLocationCache(); // removing previous journey routes to get latest location route for next journey from start point to end + locationCache + .clearLocationCache(); // removing previous journey routes to get latest location route for next journey from start point to end } catch (e, stack) { - logger.e('Error saving steady location for user $userId: $e', stackTrace: stack); + logger.e('Error saving steady location for user $userId: $e', + stackTrace: stack); } }); } bool _isSameLocation(LocationData loc1, LocationData loc2) { - return loc1.latitude == loc2.latitude && - loc1.longitude == loc2.longitude; + return loc1.latitude == loc2.latitude && loc1.longitude == loc2.longitude; } Future _saveSteadyLocation(LocationData position, String userId) async { @@ -89,10 +97,11 @@ class JourneyRepository { } } - Future addJourneyOnDayChange(LocationData? extractedLocation, ApiLocationJourney lasKnownJourney, String userId) async { - bool isDayChanged = this.isDayChanged(extractedLocation, lasKnownJourney); + Future addJourneyOnDayChange(LocationData? extractedLocation, + ApiLocationJourney lasKnownJourney, String userId) async { + bool dayChanged = isDayChanged(extractedLocation, lasKnownJourney); - if (isDayChanged) { + if (dayChanged) { // Day is changed between last known journey and current location // Just save again the last known journey in remote database with updated day i.e., current time await _saveJourneyOnDayChanged(userId, lasKnownJourney); @@ -100,12 +109,19 @@ class JourneyRepository { } } - bool isDayChanged(LocationData? extractedLocation, ApiLocationJourney lastKnownJourney) { - var lastKnownDate = - DateTime.fromMillisecondsSinceEpoch(lastKnownJourney.update_at!); - var extractedDate = DateTime.fromMillisecondsSinceEpoch(extractedLocation?.timestamp.millisecondsSinceEpoch ?? DateTime.now().millisecondsSinceEpoch); + bool isDayChanged( + LocationData? extractedLocation, ApiLocationJourney lastKnownJourney) { + DateTime lastKnownDate = DateTime.fromMillisecondsSinceEpoch( + lastKnownJourney.update_at ?? DateTime.now().millisecondsSinceEpoch); + int lastKnownDay = lastKnownDate.day; + + DateTime currentDate = extractedLocation != null + ? DateTime.fromMillisecondsSinceEpoch( + extractedLocation.timestamp.millisecondsSinceEpoch) + : DateTime.now(); + int currentDay = currentDate.day; - return lastKnownDate.day != extractedDate.day; + return lastKnownDay != currentDay; } Future _saveJourneyOnDayChanged( @@ -162,7 +178,7 @@ class JourneyRepository { fromLongitude: extractedLocation?.longitude ?? 0, created_at: DateTime.now().millisecondsSinceEpoch, ); - var locationJourney = ApiLocationJourney.fromPosition( + var locationJourney = ApiLocationJourney.toLocationJourney( extractedLocation ?? LocationData( latitude: 0, longitude: 0, timestamp: DateTime.now()), @@ -186,9 +202,9 @@ class JourneyRepository { double distance = lastKnownJourney.isSteadyLocation() ? _distanceBetween(geometricMedian ?? extractedLocation, - lastKnownJourney.toPositionFromSteadyJourney()) + lastKnownJourney.toLocationFromSteadyJourney()) : _distanceBetween(geometricMedian ?? extractedLocation, - lastKnownJourney.toPositionFromMovingJourney()); + lastKnownJourney.toLocationFromMovingJourney()); if (lastKnownJourney.isSteadyLocation()) { if (distance > MIN_DISTANCE) {