Compare commits

...

2 Commits

Author SHA1 Message Date
Tim Krampitz
f54b177441 Merge branch 'master' of https://git.krampitz.win/tim/SlipItIn
All checks were successful
Build / build (push) Successful in 2m9s
2026-10-04 18:13:05 +02:00
Tim Krampitz
bab624c61b Windows: optional ohne lokale Speicherung
Fügt für Windows den Startmodus `--no-storage` hinzu, der Token-, Benutzer-, Spiel-, Hand- und Queue-Daten nur im Speicher hält; passt die Registrierung in `MauiProgram.cs` an, setzt das Profil **Windows Machine** standardmäßig darauf, erweitert `LocalStorageService` um den deaktivierten Modus und dokumentiert den Start in der README.
2026-10-03 17:31:46 +02:00
4 changed files with 59 additions and 9 deletions

View File

@@ -24,6 +24,14 @@ dotnet run --project SlipItIn.AppHost/SlipItIn.AppHost.csproj
Der AppHost startet PostgreSQL (Container), wendet EF-Migrationen automatisch an und seedet Testdaten. Die MAUI-App verbindet sich standardmäßig mit `https://localhost:7274` (Android-Emulator: `http://10.0.2.2:5234`).
Für Windows-Entwicklung kann die Client-App ohne persistente lokale Speicherung gestartet werden:
```powershell
dotnet run --project SlipItIn\SlipItIn.csproj -f net10.0-windows10.0.19041.0 -- --no-storage
```
In diesem Modus werden weder Token noch lokale Benutzer-, Spiel- oder Offline-Daten gelesen oder geschrieben. Die Sitzung bleibt nur im Arbeitsspeicher der laufenden App erhalten und geht beim Beenden verloren.
## Konfiguration
| Key | Zweck |

View File

@@ -20,7 +20,14 @@ public static class MauiProgram
});
builder.Services.AddSingleton<IAppConfigurationService, AppConfigurationService>();
#if WINDOWS
var storageDisabled = Environment.GetCommandLineArgs().Any(
arg => string.Equals(arg, "--no-storage", StringComparison.OrdinalIgnoreCase));
builder.Services.AddSingleton<ILocalStorageService>(
_ => new LocalStorageService(storageDisabled));
#else
builder.Services.AddSingleton<ILocalStorageService, LocalStorageService>();
#endif
builder.Services.AddSingleton<IAuthSessionService, AuthSessionService>();
builder.Services.AddSingleton<IApiService, ApiService>();
builder.Services.AddSingleton<ISignalRService, SignalRService>();

View File

@@ -2,6 +2,7 @@
"profiles": {
"Windows Machine": {
"commandName": "Project",
"commandLineArgs": "--no-storage",
"nativeDebugging": false
}
}

View File

@@ -14,34 +14,53 @@ public class LocalStorageService : ILocalStorageService
private const string QueuedActionsKey = "queued_actions";
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
private readonly bool _storageDisabled;
public Task SaveAuthTokenAsync(string token) => SecureStorage.SetAsync(AuthTokenKey, token);
public LocalStorageService(bool storageDisabled = false)
{
_storageDisabled = storageDisabled;
}
public Task<string?> GetAuthTokenAsync() => SecureStorage.GetAsync(AuthTokenKey);
public Task SaveAuthTokenAsync(string token) =>
_storageDisabled ? Task.CompletedTask : SecureStorage.SetAsync(AuthTokenKey, token);
public Task<string?> GetAuthTokenAsync() =>
_storageDisabled ? Task.FromResult<string?>(null) : SecureStorage.GetAsync(AuthTokenKey);
public Task ClearAuthTokenAsync()
{
SecureStorage.Remove(AuthTokenKey);
if (!_storageDisabled)
SecureStorage.Remove(AuthTokenKey);
return Task.CompletedTask;
}
public Task SaveAuthUserAsync(AuthResponseDto authResponse)
{
if (_storageDisabled)
return Task.CompletedTask;
var json = JsonSerializer.Serialize(authResponse, JsonOptions);
Preferences.Default.Set(AuthUserKey, json);
return Task.CompletedTask;
}
public Task<AuthResponseDto?> GetAuthUserAsync() => ReadFromPreferencesAsync<AuthResponseDto>(AuthUserKey);
public Task<AuthResponseDto?> GetAuthUserAsync() =>
ReadFromPreferencesAsync<AuthResponseDto>(AuthUserKey);
public Task ClearAuthUserAsync()
{
Preferences.Default.Remove(AuthUserKey);
if (!_storageDisabled)
Preferences.Default.Remove(AuthUserKey);
return Task.CompletedTask;
}
public Task SaveGameStateAsync(GameStateDto state)
{
if (_storageDisabled)
return Task.CompletedTask;
var json = JsonSerializer.Serialize(state, JsonOptions);
Preferences.Default.Set(GameStateKey, json);
return Task.CompletedTask;
@@ -51,12 +70,17 @@ public class LocalStorageService : ILocalStorageService
public Task ClearGameStateAsync()
{
Preferences.Default.Remove(GameStateKey);
if (!_storageDisabled)
Preferences.Default.Remove(GameStateKey);
return Task.CompletedTask;
}
public Task SavePlayerHandAsync(PlayerHandDto hand)
{
if (_storageDisabled)
return Task.CompletedTask;
var json = JsonSerializer.Serialize(hand, JsonOptions);
Preferences.Default.Set(PlayerHandKey, json);
return Task.CompletedTask;
@@ -66,12 +90,17 @@ public class LocalStorageService : ILocalStorageService
public Task ClearPlayerHandAsync()
{
Preferences.Default.Remove(PlayerHandKey);
if (!_storageDisabled)
Preferences.Default.Remove(PlayerHandKey);
return Task.CompletedTask;
}
public Task SaveQueuedActionsAsync(IReadOnlyCollection<QueuedGameAction> actions)
{
if (_storageDisabled)
return Task.CompletedTask;
var json = JsonSerializer.Serialize(actions, JsonOptions);
Preferences.Default.Set(QueuedActionsKey, json);
return Task.CompletedTask;
@@ -85,12 +114,17 @@ public class LocalStorageService : ILocalStorageService
public Task ClearQueuedActionsAsync()
{
Preferences.Default.Remove(QueuedActionsKey);
if (!_storageDisabled)
Preferences.Default.Remove(QueuedActionsKey);
return Task.CompletedTask;
}
private static Task<T?> ReadFromPreferencesAsync<T>(string key)
private Task<T?> ReadFromPreferencesAsync<T>(string key)
{
if (_storageDisabled)
return Task.FromResult<T?>(default);
if (!Preferences.Default.ContainsKey(key))
return Task.FromResult<T?>(default);