Files
LehrerApp/LehrerApp.Desktop/ViewModels/DevicePairingViewModel.cs
2026-03-29 23:47:31 +02:00

159 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LehrerApp.Data;
using LehrerApp.Sync;
using LehrerApp.Sync.Models;
namespace LehrerApp.Desktop.ViewModels;
/// <summary>
/// Steuert den Dialog zum Einrichten eines neuen Geräts.
///
/// Zwei Modi:
/// Sender → "Neues Gerät hinzufügen" erzeugt Snapshot und zeigt Code
/// Empfänger → "Mit bestehendem Account verbinden" Code eingeben, Restore
/// </summary>
public partial class DevicePairingViewModel : ObservableObject
{
private readonly SnapshotService _snapshotService;
// ── Gemeinsamer State ─────────────────────────────────────────────────────
[ObservableProperty] private PairingMode _mode = PairingMode.SelectMode;
[ObservableProperty] private bool _isBusy;
[ObservableProperty] private string _statusMessage = "";
[ObservableProperty] private int _progressPercent;
[ObservableProperty] private bool _isError;
[ObservableProperty] private bool _isComplete;
// ── Sender-State ─────────────────────────────────────────────────────────
[ObservableProperty] private string _generatedCode = "";
[ObservableProperty] private DateTime _codeExpiresAt;
[ObservableProperty] private string _codeExpiresText = "";
// ── Empfänger-State ───────────────────────────────────────────────────────
[ObservableProperty] private string _inputCode = "";
public DevicePairingViewModel(SnapshotService snapshotService)
{
_snapshotService = snapshotService;
_snapshotService.ProgressChanged += OnProgress;
}
// ── Navigation zwischen Modi ──────────────────────────────────────────────
[RelayCommand]
private void SelectSender() => Mode = PairingMode.Sender;
[RelayCommand]
private void SelectReceiver() => Mode = PairingMode.Receiver;
[RelayCommand]
private void Back()
{
Mode = PairingMode.SelectMode;
Reset();
}
// ── Sender: Snapshot erstellen ────────────────────────────────────────────
[RelayCommand(CanExecute = nameof(CanCreateSnapshot))]
private async Task CreateSnapshotAsync()
{
IsBusy = true;
IsError = false;
IsComplete = false;
try
{
var result = await _snapshotService.CreateAndUploadAsync();
GeneratedCode = result.Code;
CodeExpiresAt = result.ExpiresAt;
CodeExpiresText = $"Gültig bis {result.ExpiresAt:HH:mm} Uhr " +
$"({result.ExpiresAt:dd.MM.yyyy})";
Mode = PairingMode.SenderShowCode;
}
catch (Exception ex)
{
IsError = true;
StatusMessage = $"Fehler: {ex.Message}";
}
finally
{
IsBusy = false;
}
}
private bool CanCreateSnapshot() => !IsBusy;
// ── Empfänger: Snapshot wiederherstellen ──────────────────────────────────
[RelayCommand(CanExecute = nameof(CanRestore))]
private async Task RestoreAsync(string targetDbPath)
{
IsBusy = true;
IsError = false;
IsComplete = false;
try
{
// Schlüssel wird aus dem Code extrahiert und lokal gespeichert
// → App-Neustart lädt ihn automatisch
await _snapshotService.RestoreFromCodeAsync(
InputCode.Trim(), targetDbPath);
IsComplete = true;
StatusMessage = "Erfolgreich! Bitte die App neu starten.";
Mode = PairingMode.ReceiverDone;
}
catch (SnapshotNotFoundException ex)
{
IsError = true;
StatusMessage = ex.Message;
}
catch (Exception ex)
{
IsError = true;
StatusMessage = $"Fehler beim Wiederherstellen: {ex.Message}";
}
finally
{
IsBusy = false;
}
}
private bool CanRestore() =>
!IsBusy && InputCode.Trim().Length >= 5;
// ── Hilfsmethoden ─────────────────────────────────────────────────────────
private void OnProgress(SnapshotProgress progress)
{
StatusMessage = progress.Message;
ProgressPercent = progress.PercentComplete;
}
private void Reset()
{
StatusMessage = "";
ProgressPercent = 0;
IsError = false;
IsComplete = false;
GeneratedCode = "";
InputCode = "";
IsBusy = false;
}
}
public enum PairingMode
{
SelectMode, // Startbildschirm: Sender oder Empfänger wählen
Sender, // Sender bereit, Snapshot erstellen
SenderShowCode, // Code wird angezeigt
Receiver, // Code-Eingabe
ReceiverDone, // Erfolgreich wiederhergestellt
}