Skip to content

Commit

Permalink
show current date journey only
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-ishita-g committed Oct 28, 2024
1 parent f971269 commit bca5fb7
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 63 deletions.
4 changes: 2 additions & 2 deletions app/lib/ui/app_route.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand Down Expand Up @@ -168,7 +170,7 @@ class _SelectedMemberDetailViewState extends State<SelectedMemberDetailView> {
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(
Expand Down
1 change: 1 addition & 0 deletions app/lib/ui/flow/home/map/components/space_user_footer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class _SpaceUserFooterState extends State<SpaceUserFooter> {
child: widget.selectedUser != null
? SelectedMemberDetailView(
key: const ValueKey('detailView'),
groupCreatedDate: widget.selectedSpace?.space.created_at ?? 0,
userInfo: widget.selectedUser,
onDismiss: widget.onDismiss,
)
Expand Down
6 changes: 3 additions & 3 deletions app/lib/ui/flow/home/map/map_view_model.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) &&
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions app/lib/ui/flow/journey/components/journey_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ class _JourneyMapState extends State<JourneyMap> {
}

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);

Expand Down
19 changes: 3 additions & 16 deletions app/lib/ui/flow/journey/timeline/journey_timeline_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<JourneyTimelineScreen> createState() =>
Expand Down Expand Up @@ -56,8 +57,6 @@ class _JourneyTimelineScreenState extends ConsumerState<JourneyTimelineScreen> {
: context.l10n.journey_timeline_title_other_user(
state.selectedUser?.first_name ?? '');

final selectedDate = _onSelectDatePickerDate(state.selectedTimeFrom);

_observeShowDatePicker(state);

return AppPage(
Expand All @@ -68,11 +67,6 @@ class _JourneyTimelineScreenState extends ConsumerState<JourneyTimelineScreen> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
selectedDate,
style: AppTextStyle.body1
.copyWith(color: context.colorScheme.textPrimary),
),
actionButton(
context: context,
onPressed: () => notifier.showDatePicker(true),
Expand Down Expand Up @@ -465,13 +459,6 @@ class _JourneyTimelineScreenState extends ConsumerState<JourneyTimelineScreen> {
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),
Expand All @@ -483,7 +470,7 @@ class _JourneyTimelineScreenState extends ConsumerState<JourneyTimelineScreen> {
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,
);
Expand Down
24 changes: 16 additions & 8 deletions app/lib/ui/flow/journey/timeline/journey_timeline_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -45,7 +46,6 @@ class JourneyTimelineViewModel extends StateNotifier<JourneyTimelineState> {
spaceId: _currentSpaceId.state,
);
_loadJourney();
journeyService.uploadLogFileToFirebase();
}

void _loadJourney({bool loadMore = false}) async {
Expand All @@ -54,22 +54,30 @@ class JourneyTimelineViewModel extends StateNotifier<JourneyTimelineState> {
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);
Expand Down Expand Up @@ -111,7 +119,7 @@ class JourneyTimelineViewModel extends StateNotifier<JourneyTimelineState> {
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,
Expand Down
6 changes: 3 additions & 3 deletions data/lib/api/location/journey/journey.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
54 changes: 35 additions & 19 deletions data/lib/repository/journey_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -54,26 +58,30 @@ 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;
}

_steadyLocationTimer = Timer(const Duration(minutes: 5), () async {
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<void> _saveSteadyLocation(LocationData position, String userId) async {
Expand All @@ -89,23 +97,31 @@ class JourneyRepository {
}
}

Future<void> addJourneyOnDayChange(LocationData? extractedLocation, ApiLocationJourney lasKnownJourney, String userId) async {
bool isDayChanged = this.isDayChanged(extractedLocation, lasKnownJourney);
Future<void> 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);
return;
}
}

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<void> _saveJourneyOnDayChanged(
Expand Down Expand Up @@ -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()),
Expand All @@ -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) {
Expand Down

0 comments on commit bca5fb7

Please sign in to comment.