159 lines
5.4 KiB
C#
159 lines
5.4 KiB
C#
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
|
||
}
|