Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'automatic' screenshot collection #182

Merged
merged 14 commits into from
Jun 29, 2024
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: 4 additions & 0 deletions LiftLog.App/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ public static MauiApp CreateMauiApp()
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
builder.Logging.AddDebug();
builder.Services.AddSingleton<
Ui.Pages.Screenshot.IScreenshotStatsImportsProvider,
AppScreenshotStatsImportsProvider
>();
#endif
// Add this section anywhere on the builder:
builder.Logging.AddSentry(options =>
Expand Down
11 changes: 11 additions & 0 deletions LiftLog.App/Services/AppDataFileStorageKeyValueStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ public async ValueTask SetItemAsync(string key, byte[] value)
await File.WriteAllBytesAsync(GetFileName(key), value);
}

public ValueTask RemoveItemAsync(string key)
{
var fileName = GetFileName(key);
var exists = File.Exists(fileName);
if (exists)
{
File.Delete(fileName);
}
return ValueTask.CompletedTask;
}

private string GetFileName(string key)
{
var dataDir = FileSystem.Current.AppDataDirectory;
Expand Down
17 changes: 17 additions & 0 deletions LiftLog.App/Services/AppScreenshotStatsImportsProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#if DEBUG
using LiftLog.Ui.Pages.Screenshot;

namespace LiftLog.App.Services;

public class AppScreenshotStatsImportsProvider : IScreenshotStatsImportsProvider
{
public async Task<Stream> GetImportBytesAsync()
{
var result = await FileSystem.OpenAppPackageFileAsync(
"wwwroot/_content/LiftLog.Ui/export.liftlogbackup.gz"
);
return result;
}
}

#endif
10 changes: 8 additions & 2 deletions LiftLog.Lib/Models/ImmutableListValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ public ImmutableListValue(List<T> items)

private int? _precomputedHashcode;

public int Count => ((IReadOnlyCollection<T>)Items).Count;
public int Count => Items.Count;

public T this[int index] => ((IReadOnlyList<T>)Items)[index];
public T this[int index] => Items[index];

public ImmutableListValue<T> this[Range range] =>
Items.GetRange(
range.GetOffsetAndLength(Count).Offset,
range.GetOffsetAndLength(Count).Length
);

public static implicit operator ImmutableListValue<T>(ImmutableList<T> source)
{
Expand Down
2 changes: 2 additions & 0 deletions LiftLog.Ui/LiftLog.Ui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
<Content Remove="wwwroot\load-tailwind.js"/>
<Content Remove="wwwroot\tailwind.js"/>
<Content Remove="wwwroot\twconf.json"/>
<Content Remove="wwwroot\export.liftlogbackup.gz"/>
<Content Remove="Pages\Screenshot\ScreenshotCollectorPage.razor"/>
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions LiftLog.Ui/Pages/History/HistoryEditPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@using LiftLog.Ui.Store.App
@using LiftLog.Ui.Store.Program
@using Fluxor;

@inherits Fluxor.Blazor.Web.Components.FluxorComponent

@inject IState<CurrentSessionState> CurrentSessionState
Expand Down
16 changes: 16 additions & 0 deletions LiftLog.Ui/Pages/Screenshot/ScreenshotCollectorPage.Ai.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#if DEBUG
using LiftLog.Lib.Models;
using LiftLog.Ui.Store.App;
using LiftLog.Ui.Store.CurrentSession;

namespace LiftLog.Ui.Pages.Screenshot;

public partial class ScreenshotCollectorPage
{
private async Task HandleAiPageScreenshotCollection()
{
Dispatcher.Dispatch(new NavigateAction("/settings/ai-planner"));
await Task.Yield();
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#if DEBUG
using LiftLog.Lib.Models;
using LiftLog.Ui.Store.App;
using LiftLog.Ui.Store.CurrentSession;
using LiftLog.Ui.Store.Program;

namespace LiftLog.Ui.Pages.Screenshot;

public partial class ScreenshotCollectorPage
{
private async Task HandleExerciseEditorScreenshotCollection()
{
Dispatcher.Dispatch(
new SetProgramSessionsAction(ProgramState.Value.ActivePlanId, [demoSessionBlueprint])
);
Dispatcher.Dispatch(
new NavigateAction(
$"/settings/manage-workouts/manage-session/0?editingExercise=0&planId={ProgramState.Value.ActivePlanId}"
)
);
await Task.Yield();
}
}
#endif
59 changes: 59 additions & 0 deletions LiftLog.Ui/Pages/Screenshot/ScreenshotCollectorPage.Home.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#if DEBUG
using LiftLog.Lib.Models;
using LiftLog.Ui.Services;
using LiftLog.Ui.Store.App;
using LiftLog.Ui.Store.CurrentSession;
using LiftLog.Ui.Store.Program;

namespace LiftLog.Ui.Pages.Screenshot;

public partial class ScreenshotCollectorPage
{
private SessionBlueprint demoSessionBlueprint =
new(
Name: "Session 1",
Exercises:
[
new ExerciseBlueprint(
Name: "Squat",
Sets: 3,
RepsPerSet: 10,
WeightIncreaseOnSuccess: 2.5m,
RestBetweenSets: Rest.Medium,
SupersetWithNext: false
),
new ExerciseBlueprint(
Name: "Bench Press",
Sets: 3,
RepsPerSet: 10,
WeightIncreaseOnSuccess: 2.5m,
RestBetweenSets: Rest.Medium,
SupersetWithNext: false
),
new ExerciseBlueprint(
Name: "Deadlift",
Sets: 3,
RepsPerSet: 10,
WeightIncreaseOnSuccess: 2.5m,
RestBetweenSets: Rest.Medium,
SupersetWithNext: false
)
]
);

private async Task HandleHomeScreenshotCollection()
{
var builtInProgram = BuiltInProgramService.BuiltInPrograms.First();
Dispatcher.Dispatch(new SetCurrentSessionAction(SessionTarget.WorkoutSession, null));
Dispatcher.Dispatch(new SetActiveProgramAction(builtInProgram.Key));
Dispatcher.Dispatch(
new SetProgramSessionsAction(
ProgramState.Value.ActivePlanId,
builtInProgram.Value.Sessions
)
);
Dispatcher.Dispatch(new NavigateAction($"/"));
await Task.Yield();
}
}
#endif
50 changes: 50 additions & 0 deletions LiftLog.Ui/Pages/Screenshot/ScreenshotCollectorPage.Stats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#if DEBUG
using System.IO.Compression;
using LiftLog.Lib.Models;
using LiftLog.Ui.Store.App;
using LiftLog.Ui.Store.CurrentSession;
using LiftLog.Ui.Store.Settings;
using LiftLog.Ui.Store.Stats;
using Microsoft.AspNetCore.Components;

namespace LiftLog.Ui.Pages.Screenshot;

public partial class ScreenshotCollectorPage
{
[Inject]
public HttpClient HttpClient { get; set; } = null!;

[Inject]
public IScreenshotStatsImportsProvider ScreenshotStatsImportsProvider { get; set; } = null!;

private async Task HandleStatsScreenshotCollection()
{
var imported = await ScreenshotStatsImportsProvider.GetImportBytesAsync();
using GZipStream gzip = new(imported, CompressionMode.Decompress);
using MemoryStream memoryStream = new();
await gzip.CopyToAsync(memoryStream);
var bytes = memoryStream.ToArray();
Dispatcher.Dispatch(new ImportDataBytesAction(bytes));
var latestSession = await ProgressRepository.GetOrderedSessions().FirstAsync();
var dateDiffToNow = (
DateTime.Now - latestSession.Date.ToDateTime(TimeOnly.FromDateTime(DateTime.Now))
).Days;

var remappedToTodaySessions = await ProgressRepository
.GetOrderedSessions()
.Select(session => session with { Date = session.Date.AddDays(dateDiffToNow) })
.ToListAsync();

await ProgressRepository.SaveCompletedSessionsAsync(remappedToTodaySessions);

Dispatcher.Dispatch(new SetPinnedExerciseStatsAction([new("Bench Press")]));
Dispatcher.Dispatch(new SetShowBodyweightAction(false));
Dispatcher.Dispatch(new NavigateAction("/stats"));
}
}

public interface IScreenshotStatsImportsProvider
{
Task<Stream> GetImportBytesAsync();
}
#endif
23 changes: 23 additions & 0 deletions LiftLog.Ui/Pages/Screenshot/ScreenshotCollectorPage.WorkoutPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#if DEBUG
using LiftLog.Lib.Models;
using LiftLog.Ui.Store.App;
using LiftLog.Ui.Store.CurrentSession;

namespace LiftLog.Ui.Pages.Screenshot;

public partial class ScreenshotCollectorPage
{
private async Task HandleWorkoutPageScreenshotCollection()
{
var demoSession = demoSessionBlueprint.GetEmptySession();
Dispatcher.Dispatch(new SetCurrentSessionAction(SessionTarget.WorkoutSession, demoSession));
Dispatcher.Dispatch(new UpdateExerciseWeightAction(SessionTarget.WorkoutSession, 0, 100));
Dispatcher.Dispatch(new UpdateExerciseWeightAction(SessionTarget.WorkoutSession, 1, 60));
Dispatcher.Dispatch(new UpdateExerciseWeightAction(SessionTarget.WorkoutSession, 2, 120));
Dispatcher.Dispatch(new UpdateBodyweightAction(SessionTarget.WorkoutSession, 85));
Dispatcher.Dispatch(new CycleExerciseRepsAction(SessionTarget.WorkoutSession, 0, 0));
Dispatcher.Dispatch(new NavigateAction("/session"));
await Task.Yield();
}
}
#endif
1 change: 1 addition & 0 deletions LiftLog.Ui/Pages/Screenshot/ScreenshotCollectorPage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@page "/screenshot-collection"
61 changes: 61 additions & 0 deletions LiftLog.Ui/Pages/Screenshot/ScreenshotCollectorPage.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#if DEBUG
using Fluxor;
using LiftLog.Ui.Services;
using LiftLog.Ui.Store.Program;
using LiftLog.Ui.Store.Settings;
using Microsoft.AspNetCore.Components;

namespace LiftLog.Ui.Pages.Screenshot;

public partial class ScreenshotCollectorPage : ComponentBase
{
[Inject]
public IDispatcher Dispatcher { get; set; } = null!;

[Inject]
public ProgressRepository ProgressRepository { get; set; } = null!;

[Inject]
public IState<ProgramState> ProgramState { get; set; } = null!;

[Parameter]
[SupplyParameterFromQuery(Name = "type")]
public string ScreenshotCollectionType { get; set; } = "";

protected override async Task OnInitializedAsync()
{
await ProgressRepository.ClearAsync();
Dispatcher.Dispatch(new SetProgramSessionsAction(ProgramState.Value.ActivePlanId, []));
Dispatcher.Dispatch(new SetUseImperialUnitsAction(false));
Dispatcher.Dispatch(new SetShowBodyweightAction(true));
Dispatcher.Dispatch(new SetShowFeedAction(true));
Dispatcher.Dispatch(new SetShowTipsAction(false));
Dispatcher.Dispatch(
new SetThemeAction(
uint.Parse("00AA00", System.Globalization.NumberStyles.HexNumber),
ThemePreference.Light
)
);

switch (ScreenshotCollectionType.ToLower())
{
case "workoutpage":
await HandleWorkoutPageScreenshotCollection();
break;
case "home":
await HandleHomeScreenshotCollection();
break;
case "exerciseeditor":
await HandleExerciseEditorScreenshotCollection();
break;
case "stats":
await HandleStatsScreenshotCollection();
break;
case "ai":
await HandleAiPageScreenshotCollection();
break;
}
await base.OnInitializedAsync();
}
}
#endif
1 change: 1 addition & 0 deletions LiftLog.Ui/Pages/Settings/AiSessionCreatorPage.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@page "/settings/ai-session-creator"
@inherits Fluxor.Blazor.Web.Components.FluxorComponent

@using LiftLog.Lib.Services;

@inject NavigationManager NavigationManager
Expand Down
11 changes: 10 additions & 1 deletion LiftLog.Ui/Pages/Settings/ManageSessionPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@


@code {

[Parameter][SupplyParameterFromQuery(Name="editingExercise")] public int? EditingExerciseIndexParam { get; set; }
[Parameter] public int SessionIndex { get; set; }

[SupplyParameterFromQuery(Name = "planId")]
Expand All @@ -73,6 +73,15 @@

private FullScreenDialog? editDialog;

protected override void OnAfterRender(bool firstRender)
{
if (firstRender && EditingExerciseIndexParam is not null && SessionEditorState is {Value: {SessionBlueprint: not null}})
{
BeginEditExercise(SessionEditorState.Value.SessionBlueprint.Exercises[EditingExerciseIndexParam.Value], EditingExerciseIndexParam.Value);
}
base.OnAfterRender(firstRender);
}


void MoveExerciseUp(ExerciseBlueprint exerciseBlueprint)
{
Expand Down
8 changes: 7 additions & 1 deletion LiftLog.Ui/Pages/StatsPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ else if (!StatsState.Value.IsLoading && StatsState.Value.OverallView is not null
</SingleValueStatisticsCard>
</div>
<div class="flex flex-col gap-2">
@foreach(var pinnedStat in StatsState.Value.GetPinnedExercises().IndexedTuples())
{
<Card>
<StatGraphCardContent Title="@pinnedStat.Item.ExerciseName" Statistics="[pinnedStat.Item.Statistics, pinnedStat.Item.OneRepMaxStatistics]" RenderDelay="TimeSpan.FromMilliseconds(200 + pinnedStat.Index * 200)"/>
</Card>
}
@if (SettingsState.Value.ShowBodyweight && overallStats.BodyweightStats.Statistics.Any())
{
<Card class="mx-2">
Expand All @@ -70,7 +76,7 @@ else if (!StatsState.Value.IsLoading && StatsState.Value.OverallView is not null
<Card class="mx-2">
<StatGraphCardContent Title="Sessions" Statistics="overallStats.SessionStats" RenderDelay="TimeSpan.FromMilliseconds(200)"/>
</Card>
<CardList Items="@(overallStats.ExerciseStats.IndexedTuples())">
<CardList Items="@(overallStats.ExerciseStats.Where(x=>!StatsState.Value.IsExercisePinned(x)).IndexedTuples())">
<StatGraphCardContent Title="@context.Item.ExerciseName" Statistics="[context.Item.Statistics, context.Item.OneRepMaxStatistics]" RenderDelay="TimeSpan.FromMilliseconds(200 + context.Index * 200)"/>
</CardList>
</div>
Expand Down
3 changes: 3 additions & 0 deletions LiftLog.Ui/ServiceRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public static IServiceCollection RegisterUiServices<
#endif
);

services.AddScoped<CurrentProgramRepository>();
services.AddScoped<ProgressRepository>();
services.AddScoped<PreferencesRepository>();
services.AddSingleton<NavigationManagerProvider>();

services.AddSingleton<CurrentProgramRepository>();
Expand Down
1 change: 1 addition & 0 deletions LiftLog.Ui/Services/IKeyValueStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public interface IKeyValueStore
{
ValueTask<string?> GetItemAsync(string key);
ValueTask<byte[]?> GetItemBytesAsync(string key);
ValueTask RemoveItemAsync(string key);
ValueTask SetItemAsync(string key, string value);
ValueTask SetItemAsync(string key, byte[] value);
}
Loading
Loading