Fix remote activities
This commit is contained in:
parent
40173c269f
commit
a560036265
4 changed files with 309 additions and 20 deletions
|
|
@ -75,23 +75,25 @@ public class TimelineService {
|
|||
|
||||
// 3. Fetch local activities from followed users (fetch more to account for merging)
|
||||
// We fetch double the page size to have enough items after merging
|
||||
// Explicitly sort by startedAt DESC (latest first)
|
||||
Pageable expandedPageable = PageRequest.of(0, pageable.getPageSize() * 2,
|
||||
// Explicitly sort by startedAt DESC (latest first) for local activities
|
||||
Pageable expandedPageableLocal = PageRequest.of(0, pageable.getPageSize() * 2,
|
||||
org.springframework.data.domain.Sort.by(org.springframework.data.domain.Sort.Direction.DESC, "startedAt"));
|
||||
Page<Activity> localActivities = activityRepository.findByUserIdInAndVisibilityInOrderByStartedAtDesc(
|
||||
followedUserIds,
|
||||
List.of(Activity.Visibility.PUBLIC, Activity.Visibility.FOLLOWERS),
|
||||
expandedPageable
|
||||
expandedPageableLocal
|
||||
);
|
||||
|
||||
// 4. Fetch remote activities from followed remote actors (if any)
|
||||
List<RemoteActivity> remoteActivities = new ArrayList<>();
|
||||
if (!remoteActorUris.isEmpty()) {
|
||||
// Use same pageable with explicit sort for remote activities
|
||||
// Use publishedAt for sorting remote activities (not startedAt)
|
||||
Pageable expandedPageableRemote = PageRequest.of(0, pageable.getPageSize() * 2,
|
||||
org.springframework.data.domain.Sort.by(org.springframework.data.domain.Sort.Direction.DESC, "publishedAt"));
|
||||
Page<RemoteActivity> remoteActivitiesPage = remoteActivityRepository.findByRemoteActorUriInAndVisibilityIn(
|
||||
remoteActorUris,
|
||||
List.of(RemoteActivity.Visibility.PUBLIC, RemoteActivity.Visibility.FOLLOWERS),
|
||||
expandedPageable
|
||||
expandedPageableRemote
|
||||
);
|
||||
remoteActivities = remoteActivitiesPage.getContent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,10 +210,10 @@ public class FitParser {
|
|||
}
|
||||
}
|
||||
|
||||
BigDecimal totalDistance = null;
|
||||
if (session.getTotalDistance() != null) {
|
||||
parsedData.setTotalDistance(
|
||||
BigDecimal.valueOf(session.getTotalDistance()).setScale(2, RoundingMode.HALF_UP)
|
||||
);
|
||||
totalDistance = BigDecimal.valueOf(session.getTotalDistance()).setScale(2, RoundingMode.HALF_UP);
|
||||
parsedData.setTotalDistance(totalDistance);
|
||||
}
|
||||
|
||||
if (session.getTotalAscent() != null) {
|
||||
|
|
@ -231,12 +231,6 @@ public class FitParser {
|
|||
// Extract metrics
|
||||
ActivityMetricsData metrics = new ActivityMetricsData();
|
||||
|
||||
if (session.getAvgSpeed() != null) {
|
||||
metrics.setAverageSpeed(
|
||||
BigDecimal.valueOf(session.getAvgSpeed() * MPS_TO_KPH).setScale(2, RoundingMode.HALF_UP)
|
||||
);
|
||||
}
|
||||
|
||||
if (session.getMaxSpeed() != null) {
|
||||
metrics.setMaxSpeed(
|
||||
BigDecimal.valueOf(session.getMaxSpeed() * MPS_TO_KPH).setScale(2, RoundingMode.HALF_UP)
|
||||
|
|
@ -275,17 +269,55 @@ public class FitParser {
|
|||
metrics.setCalories(session.getTotalCalories());
|
||||
}
|
||||
|
||||
Duration movingTime = null;
|
||||
if (session.getTotalMovingTime() != null) {
|
||||
metrics.setMovingTime(Duration.ofSeconds(session.getTotalMovingTime().longValue()));
|
||||
movingTime = Duration.ofSeconds(session.getTotalMovingTime().longValue());
|
||||
metrics.setMovingTime(movingTime);
|
||||
} else if (session.getTotalTimerTime() != null) {
|
||||
// Fallback to timer time if moving time is not available
|
||||
movingTime = Duration.ofSeconds(session.getTotalTimerTime().longValue());
|
||||
metrics.setMovingTime(movingTime);
|
||||
} else {
|
||||
// Fallback: Calculate moving time from track points if native value is not available
|
||||
Duration calculatedMovingTime = calculateMovingTimeFromTrackPoints(parsedData);
|
||||
if (calculatedMovingTime != null) {
|
||||
metrics.setMovingTime(calculatedMovingTime);
|
||||
log.debug("Calculated moving time from track points: {}", calculatedMovingTime);
|
||||
movingTime = calculateMovingTimeFromTrackPoints(parsedData);
|
||||
if (movingTime != null) {
|
||||
metrics.setMovingTime(movingTime);
|
||||
log.debug("Calculated moving time from track points: {}", movingTime);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate stopped time (elapsed - moving)
|
||||
if (parsedData.getTotalDuration() != null && movingTime != null) {
|
||||
Duration stoppedTime = parsedData.getTotalDuration().minus(movingTime);
|
||||
if (stoppedTime.isNegative()) {
|
||||
stoppedTime = Duration.ZERO;
|
||||
}
|
||||
metrics.setStoppedTime(stoppedTime);
|
||||
}
|
||||
|
||||
// Calculate average speed from distance and moving time (not from FIT SDK's avgSpeed)
|
||||
// This ensures consistency with GPX parser and correct calculation based on moving time only
|
||||
if (totalDistance != null && movingTime != null && movingTime.getSeconds() > 0) {
|
||||
// distance in meters / time in seconds = m/s, then * 3.6 = km/h
|
||||
double avgSpeedKmh = (totalDistance.doubleValue() / movingTime.getSeconds()) * 3.6;
|
||||
metrics.setAverageSpeed(
|
||||
BigDecimal.valueOf(avgSpeedKmh).setScale(2, RoundingMode.HALF_UP)
|
||||
);
|
||||
|
||||
// Calculate average pace (min/km) for running activities
|
||||
// pace = time (seconds) / distance (km)
|
||||
double distanceKm = totalDistance.doubleValue() / 1000.0;
|
||||
if (distanceKm > 0) {
|
||||
long paceSecondsPerKm = (long) (movingTime.getSeconds() / distanceKm);
|
||||
metrics.setAveragePace(Duration.ofSeconds(paceSecondsPerKm));
|
||||
}
|
||||
} else if (session.getAvgSpeed() != null) {
|
||||
// Fallback to FIT SDK's average speed if moving time is not available
|
||||
metrics.setAverageSpeed(
|
||||
BigDecimal.valueOf(session.getAvgSpeed() * MPS_TO_KPH).setScale(2, RoundingMode.HALF_UP)
|
||||
);
|
||||
}
|
||||
|
||||
if (session.getTotalStrides() != null) {
|
||||
metrics.setTotalSteps(session.getTotalStrides().intValue() * 2); // Strides to steps
|
||||
}
|
||||
|
|
|
|||
|
|
@ -414,8 +414,22 @@ public class GpxParser {
|
|||
parsedData.setElevationLoss(BigDecimal.valueOf(elevationLoss).setScale(2, RoundingMode.HALF_UP));
|
||||
|
||||
// Calculate average and max values
|
||||
// Calculate average speed from total distance and moving time (not from all speed values)
|
||||
if (totalDistance > 0 && movingTime.getSeconds() > 0) {
|
||||
// Convert: distance (meters) / time (seconds) = m/s, then * 3.6 = km/h
|
||||
double avgSpeedKmh = (totalDistance / movingTime.getSeconds()) * 3.6;
|
||||
metrics.setAverageSpeed(BigDecimal.valueOf(avgSpeedKmh).setScale(2, RoundingMode.HALF_UP));
|
||||
|
||||
// Calculate average pace (min/km) for running activities
|
||||
// pace = time (seconds) / distance (km)
|
||||
double distanceKm = totalDistance / 1000.0;
|
||||
if (distanceKm > 0) {
|
||||
long paceSecondsPerKm = (long) (movingTime.getSeconds() / distanceKm);
|
||||
metrics.setAveragePace(Duration.ofSeconds(paceSecondsPerKm));
|
||||
}
|
||||
}
|
||||
|
||||
if (!speeds.isEmpty()) {
|
||||
metrics.setAverageSpeed(calculateAverage(speeds));
|
||||
metrics.setMaxSpeed(speeds.stream().max(BigDecimal::compareTo).orElse(null));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue