Skip to content

Commit 09b5904

Browse files
committed
adds guard to update distances in record field if necessary
- in some cases when heartrate data is missing intervalls with temperature and distance are contained in the recrodMesgs field - Strava shows a the old overall distance based on this field
1 parent 7c86975 commit 09b5904

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

swim_data_analyser/static/js/editView.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,54 @@ function prepareExportData(modifiedData) {
805805
return allMessages;
806806
}
807807

808+
// helper for Strava normalization
809+
function shouldNormalizeRecordDistances(recordMesgs) {
810+
if (!recordMesgs?.length) return false;
811+
812+
// Hard requirement: at least one record has distance
813+
return recordMesgs.some(r => r.distance != null);
814+
}
815+
816+
// helper for Strava normalization
817+
function normalizeRecordDistances(modifiedData) {
818+
const records = modifiedData.recordMesgs;
819+
const session = modifiedData.sessionMesgs?.[0];
820+
821+
if (!records || !session?.totalDistance) return;
822+
823+
if (!shouldNormalizeRecordDistances(records)) {
824+
return;
825+
}
826+
827+
// Use time-weighted interpolation
828+
const moving = records.filter(r =>
829+
r.timestamp &&
830+
(r.enhancedSpeed != null || r.cadence != null)
831+
);
832+
833+
if (moving.length < 2) return;
834+
835+
const t0 = new Date(moving[0].timestamp).getTime();
836+
const tN = new Date(moving.at(-1).timestamp).getTime();
837+
const totalTime = tN - t0;
838+
839+
if (totalTime <= 0) return;
840+
841+
let lastDistance = 0;
842+
843+
records.forEach(r => {
844+
if (r.timestamp && (r.enhancedSpeed != null || r.cadence != null)) {
845+
const t = new Date(r.timestamp).getTime();
846+
const frac = Math.min(Math.max((t - t0) / totalTime, 0), 1);
847+
lastDistance = frac * session.totalDistance;
848+
}
849+
r.distance = Math.round(lastDistance * 100) / 100;
850+
});
851+
852+
// Strave hard requirement
853+
records.at(-1).distance = session.totalDistance;
854+
}
855+
808856
// FIT export handler
809857
async function downloadFitFromJson() {
810858
try {
@@ -814,6 +862,11 @@ async function downloadFitFromJson() {
814862
if (!modifiedData) return alert("No modified data found in IndexedDB.");
815863

816864
ensureProfileDefinitions(mesgDefinitions);
865+
// In some cases where heartrate data is missing, instead
866+
// distances are encoded in the record field. These need to be
867+
// updated in order for Strava to show the correct overall
868+
// distance
869+
normalizeRecordDistances(modifiedData);
817870
const allMessages = prepareExportData(modifiedData);
818871

819872
const encoder = new Encoder({ fieldDescriptions });

0 commit comments

Comments
 (0)