Refactor LoginViewModel to use IAppSettings; improve settings management and update dependency injection.

This commit is contained in:
2025-12-26 13:54:51 +01:00
parent 4d5b093ea0
commit e2ffc24131
3 changed files with 44 additions and 19 deletions

View File

@@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging;
using ZXing.Net.Maui.Controls; using ZXing.Net.Maui.Controls;
using System.Net.Http; using System.Net.Http;
using Jugenddienst_Stunden.ViewModels; using Jugenddienst_Stunden.ViewModels;
using Jugenddienst_Stunden.Views;
using System.Net; using System.Net;
namespace Jugenddienst_Stunden; namespace Jugenddienst_Stunden;
@@ -112,12 +113,12 @@ public static class MauiProgram {
builder.Services.AddSingleton<IAuthService, AuthService>(); builder.Services.AddSingleton<IAuthService, AuthService>();
// DI: Views/ViewModels // DI: Views/ViewModels
builder.Services.AddTransient<ViewModels.StundenViewModel>(); builder.Services.AddTransient<StundenViewModel>();
builder.Services.AddTransient<Views.StundenPage>(); builder.Services.AddTransient<StundenPage>();
builder.Services.AddTransient<ViewModels.StundeViewModel>(); builder.Services.AddTransient<StundeViewModel>();
builder.Services.AddTransient<Views.StundePage>(); builder.Services.AddTransient<StundePage>();
builder.Services.AddTransient<ViewModels.LoginViewModel>(); builder.Services.AddTransient<LoginViewModel>();
builder.Services.AddTransient<Views.LoginPage>(); builder.Services.AddTransient<LoginPage>();
return builder.Build(); return builder.Build();
} }

View File

@@ -11,6 +11,7 @@ namespace Jugenddienst_Stunden.ViewModels;
public partial class LoginViewModel : ObservableObject { public partial class LoginViewModel : ObservableObject {
private readonly IAuthService _auth; private readonly IAuthService _auth;
private readonly IAlertService? _alerts; private readonly IAlertService? _alerts;
private readonly IAppSettings _settings;
private DateTime _lastDetectionTime = DateTime.MinValue; private DateTime _lastDetectionTime = DateTime.MinValue;
private readonly TimeSpan _detectionInterval = TimeSpan.FromSeconds(5); private readonly TimeSpan _detectionInterval = TimeSpan.FromSeconds(5);
@@ -38,7 +39,7 @@ public partial class LoginViewModel : ObservableObject {
private string? serverLabel; private string? serverLabel;
[ObservableProperty] [ObservableProperty]
private string title = Preferences.Default.Get("name", "Nicht") + " " + Preferences.Default.Get("surname", "eingeloggt"); private string title = "Nicht eingeloggt";
[ObservableProperty] [ObservableProperty]
private string? username; private string? username;
@@ -58,8 +59,9 @@ public partial class LoginViewModel : ObservableObject {
// Explizite Command-Property für den QR-Scanner-Event, damit das Binding in XAML zuverlässig greift // Explizite Command-Property für den QR-Scanner-Event, damit das Binding in XAML zuverlässig greift
public IAsyncRelayCommand<object?> QrDetectedCommand { get; } public IAsyncRelayCommand<object?> QrDetectedCommand { get; }
public LoginViewModel(IAuthService auth) { public LoginViewModel(IAuthService auth, IAppSettings settings) {
_auth = auth; _auth = auth;
_settings = settings;
// gespeicherte Präferenz für Logintyp laden // gespeicherte Präferenz für Logintyp laden
var lt = Preferences.Default.Get("logintype", "qr"); var lt = Preferences.Default.Get("logintype", "qr");
@@ -68,22 +70,36 @@ public partial class LoginViewModel : ObservableObject {
IsDetecting = !isManualMode; IsDetecting = !isManualMode;
// Serveranzeige vorbereiten // Serveranzeige vorbereiten
var apiUrl = Preferences.Default.Get("apiUrl", string.Empty); RefreshSettings();
if (!string.IsNullOrWhiteSpace(apiUrl)) {
Server = apiUrl.Replace("/appapi", "").Replace("https://", "").Replace("http://", "");
ServerLabel = "Server: " + Server;
}
// Command initialisieren // Command initialisieren
QrDetectedCommand = new AsyncRelayCommand<object?>(QrDetectedAsync); QrDetectedCommand = new AsyncRelayCommand<object?>(QrDetectedAsync);
} }
// DI-Konstruktor: AlertService anbinden und Alerts an VM-Event weiterreichen (analog StundeViewModel) // DI-Konstruktor: AlertService anbinden und Alerts an VM-Event weiterreichen (analog StundeViewModel)
internal LoginViewModel(IAuthService auth, IAlertService alertService) : this(auth) { internal LoginViewModel(IAuthService auth, IAlertService alertService,IAppSettings settings) : this(auth,settings) {
_alerts = alertService; _alerts = alertService;
_settings = settings;
if (alertService is not null) { if (alertService is not null) {
alertService.AlertRaised += (s, msg) => AlertEvent?.Invoke(this, msg); alertService.AlertRaised += (s, msg) => AlertEvent?.Invoke(this, msg);
} }
RefreshSettings();
}
/// <summary>
/// Aktualisiert die Serveranzeige aus den aktuellen AppSettings.
/// </summary>
public void RefreshSettings() {
var apiUrl = _settings.ApiUrl;
if (!string.IsNullOrWhiteSpace(apiUrl)) {
Server = apiUrl.Replace("/appapi", "").Replace("https://", "").Replace("http://", "");
ServerLabel = "Server: " + Server;
} else {
Server = string.Empty;
ServerLabel = "Server: Nicht konfiguriert";
}
Title = $"{_settings.Name} {_settings.Surname}";
} }
partial void OnIsManualModeChanged(bool value) { partial void OnIsManualModeChanged(bool value) {

View File

@@ -64,13 +64,21 @@ public partial class LoginPage : ContentPage {
base.OnDisappearing(); base.OnDisappearing();
barcodeScannerView.CameraLocation = CameraLocation.Front; barcodeScannerView.CameraLocation = CameraLocation.Front;
// IsDetecting wird via Binding vom ViewModel gesteuert // Scanner deaktivieren, wenn Seite verlassen wird
if (BindingContext is LoginViewModel vm) {
vm.IsDetecting = false;
}
} }
protected override void OnAppearing() { protected override void OnAppearing() {
base.OnAppearing(); base.OnAppearing();
// IsDetecting wird via Binding vom ViewModel gesteuert if (BindingContext is LoginViewModel vm) {
vm.RefreshSettings();
// Scanner wieder aktivieren, wenn QR-Modus aktiv ist
vm.IsDetecting = !vm.IsManualMode;
}
barcodeScannerView.CameraLocation = CameraLocation.Rear; barcodeScannerView.CameraLocation = CameraLocation.Rear;
} }