Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
<Nullable>disable</Nullable>
<LangVersion>latest</LangVersion>

<VersionPrefix>5.7.6</VersionPrefix>
<BuildIncrement>48</BuildIncrement>
<VersionPrefix>5.8.0</VersionPrefix>
<BuildIncrement>46</BuildIncrement>
<VersionSuffix></VersionSuffix>
<Product>FitEdit</Product>
<Copyright>EnduraByte LLC 2024</Copyright>
Expand Down
1 change: 0 additions & 1 deletion FitEdit.sln
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ Global
{9B06A0E5-9409-4D7C-B532-364C12264BE1}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{9B06A0E5-9409-4D7C-B532-364C12264BE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B06A0E5-9409-4D7C-B532-364C12264BE1}.Release|Any CPU.Build.0 = Release|Any CPU
{9B06A0E5-9409-4D7C-B532-364C12264BE1}.Release|Any CPU.Deploy.0 = Release|Any CPU
{21ECAE7A-E6E1-4857-9631-F24951E3CA17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21ECAE7A-E6E1-4857-9631-F24951E3CA17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21ECAE7A-E6E1-4857-9631-F24951E3CA17}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
12 changes: 6 additions & 6 deletions Infrastructure/FitEdit.Adapters.Fit/Decode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,17 +283,17 @@ public void DecodeNextMessage(Stream fitStream)
long sourceIndex = fitStream.Position;

byte nextByte = br.ReadByte();
Log.Debug($"Message header: {nextByte:X2}");
//Log.Debug($"Message header: {nextByte:X2}");

bool isCompressedHeader = (nextByte & Fit.CompressedHeaderMask) == Fit.CompressedHeaderMask;
bool isMesgDefinition = (nextByte & Fit.MesgDefinitionMask) == Fit.MesgDefinitionMask;
bool isDataMessage = (nextByte & Fit.MesgDefinitionMask) == Fit.MesgHeaderMask;
bool isDevData = (nextByte & Fit.DevDataMask) == Fit.DevDataMask;

Log.Debug($" Compressed: {isCompressedHeader}");
Log.Debug($" Definition: {isMesgDefinition}");
Log.Debug($" Data: {isDataMessage}");
Log.Debug($" DevData: {isDevData}");
//Log.Debug($" Compressed: {isCompressedHeader}");
//Log.Debug($" Definition: {isMesgDefinition}");
//Log.Debug($" Data: {isDataMessage}");
//Log.Debug($" DevData: {isDevData}");

// Is it a compressed timestamp mesg?
if (isCompressedHeader)
Expand Down Expand Up @@ -331,7 +331,7 @@ private void ReadDataMesg(Stream fitStream, BinaryReader br, long sourceIndex, b
}

MesgDefinition def = _localMesgDefs[localMesgNum];
Log.Debug($" (global, local) message num: ({localMesgNum}, {def.GlobalMesgNum})");
//Log.Debug($" (global, local) message num: ({localMesgNum}, {def.GlobalMesgNum})");
int fieldsSize = def.GetMesgSize() - 1;

if (FitConfig.Discard.DataMessages.OfLargeSize
Expand Down
58 changes: 58 additions & 0 deletions Infrastructure/FitEdit.Data/Fit/Edits/RemoveGapsEdit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace FitEdit.Data.Fit.Edits;

public class RemoveGapsEdit(FitFile fit) : IEdit
{
public FitFile Apply()
{
var minGap = TimeSpan.FromSeconds(60);

var copy = new FitFile(fit);
var records = copy.Records;

// Algorithm:
// For each pair of successive records i and i + 1
// where time span between them differs by more than the min gap,
// make the time span between them 1s and update all later timestamps accordingly.
foreach (int i in Enumerable.Range(0, records.Count - 1))
{
DateTime start = records[i].GetTimestamp().GetDateTime();
DateTime end = records[i + 1].GetTimestamp().GetDateTime();
TimeSpan gap = end - start;

if (gap < minGap)
continue;

SetRecordStartTimeCascading(records, i + 1, start + TimeSpan.FromSeconds(1));
}

copy.BackfillEvents();

return copy;
}

/// <summary>
/// Set record i to the given start time, and shift all subsequent record timestamps by the time diff.
/// </summary>
private static void SetRecordStartTimeCascading(List<Dynastream.Fit.RecordMesg> records, int i, DateTime start)
{
// Set record i to the given start time. Keep track of the time diff.
DateTime oldEnd = records[i].GetTimestamp().GetDateTime();
records[i].SetTimestamp(new Dynastream.Fit.DateTime(start));
DateTime newEnd = records[i].GetTimestamp().GetDateTime();

TimeSpan diff = oldEnd - newEnd;

// Shift all subsequent record timestamps
ShiftTimestamps(records, i + 1, diff);
}

private static void ShiftTimestamps(List<Dynastream.Fit.RecordMesg> records, int i, TimeSpan diff)
{
for (int j = i; j < records.Count - 1; j++)
{
DateTime start = records[j].GetTimestamp().GetDateTime();

records[j].SetTimestamp(new Dynastream.Fit.DateTime(start - diff));
}
}
}
2 changes: 1 addition & 1 deletion Infrastructure/FitEdit.Data/Fit/FitFileExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ private static List<Mesg> FindAll(this FitFile f, Type t) => f.Events.OfType<Mes
}

return false;
});
}).ToList();

dest.Events.AddRange(filteredEvents);
dest.ForwardfillEvents();
Expand Down
4 changes: 2 additions & 2 deletions Infrastructure/FitEdit.Data/Fit/Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public bool TryGetDecoder(Stream stream, out List<FitFile> fits, out Decode deco

decoder.FitFileRead += () =>
{
Log.Debug($"Read FIT file with {tmp.Events.Count} messages");
//Log.Debug($"Read FIT file with {tmp.Events.Count} messages");
tmp = new FitFile();
};

Expand Down Expand Up @@ -143,4 +143,4 @@ public bool TryGetDecoder(Stream stream, out List<FitFile> fits, out Decode deco

public static class FitLog
{
}
}
2 changes: 1 addition & 1 deletion Infrastructure/FitEdit.Data/Fit/Writer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ public void Write(FitFile fitFile, Stream dest)
Log.Info($"Wrote {fitFile.Messages.Count} messages and {fitFile.MessageDefinitions.Count} definitions");
encoder.Close();
}
}
}
2 changes: 1 addition & 1 deletion Ui/FitEdit.Ui.Infra/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"Default": "Information",
"Override": {
"Microsoft": "Warning"
//"CompositionRoot": "Debug"
//, "CompositionRoot": "Debug"
}
},
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Debug" ],
Expand Down
5 changes: 3 additions & 2 deletions Ui/FitEdit.Ui.iOS/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleIdentifier</key>
<string>com.endurabyte.fitedit</string>
<key>CFBundleShortVersionString</key>
<string>5.7.5</string>
<string>5.8.0</string>
<key>LSRequiresIPhoneOS</key>
<true />
<key>MinimumOSVersion</key>
Expand Down Expand Up @@ -57,5 +57,6 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>46</string>
</dict>
</plist>
</plist>
16 changes: 16 additions & 0 deletions Ui/FitEdit.Ui/ViewModels/FileViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using FitEdit.Adapters.Strava;
using FitEdit.Data;
using FitEdit.Data.Fit;
using FitEdit.Data.Fit.Edits;
using FitEdit.Model;
using FitEdit.Model.Extensions;
using FitEdit.Model.GarminConnect;
Expand All @@ -17,6 +18,7 @@
using FitEdit.Ui.Infra;
using FitEdit.Ui.Model.Supabase;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json.Bson;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;

Expand Down Expand Up @@ -735,6 +737,20 @@ public void HandleRepairBackfillClicked(UiFile uif)
));
}

public void HandleRemoveGapsClicked(UiFile file)
{
FitFile? fit = new RemoveGapsEdit(file.FitFile).Apply();

Task.Run(async () =>
{
await Persist(new FileReference
(
$"(No Gaps) {file.Activity?.Name}",
fit.GetBytes()
));
});
}

public async Task HandleOpenGarminUploadPageClicked() => await browser_.OpenAsync("https://connect.garmin.com/modern/import-data");
public async Task HandleOpenStravaUploadPageClicked() => await browser_.OpenAsync("https://www.strava.com/upload/select");

Expand Down
2 changes: 1 addition & 1 deletion Ui/FitEdit.Ui/ViewModels/PlotViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ protected void Add(UiFile file)

foreach (var record in fit.Records)
{
var speed = (double?)record.GetEnhancedSpeed() ?? 0;
var speed = (double?)(record.GetSpeed() ?? record.GetEnhancedSpeed()) ?? 0;
var hr = (double?)record.GetHeartRate() ?? 0;
var cadence = (double?)record.GetCadence() ?? 0;
var time = record.InstantOfTime();
Expand Down
11 changes: 11 additions & 0 deletions Ui/FitEdit.Ui/Views/FileView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@

</MenuItem>

<MenuItem Header ="Remove Gaps"
IsEnabled="{Binding SelectedFile.IsLoaded}"
Command="{Binding HandleRemoveGapsClicked}"
CommandParameter="{Binding SelectedFile}">
<ToolTip.Tip>
<TextBlock TextWrapping="Wrap">
Remove gaps > 60s from the file. This makes it look like e.g. you didn't take a break during your workout. This adjusts the timestamps of all records that follow a gap.
</TextBlock>
</ToolTip.Tip>

</MenuItem>
<MenuItem Header="Repair" IsEnabled="{Binding SelectedFile.IsLoaded}">
<MenuItem Header="Subtractively"
Command="{Binding HandleRepairSubtractivelyClicked}"
Expand Down
2 changes: 1 addition & 1 deletion Ui/FitEdit.Ui/Views/RecordView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
Command="{Binding SaveChanges}"
IsVisible="{Binding HaveUnsavedChanges}">
<ToolTip.Tip>
Creates a new activity with all of the changes applied.
Write all changes to the current FIT file.
</ToolTip.Tip>
</Button>

Expand Down
2 changes: 1 addition & 1 deletion units
Submodule units updated from ee9a80 to a58fde