using ClaudeDo.Ui.Localization; using ClaudeDo.Ui.Services; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace ClaudeDo.Ui.ViewModels.Modals.Settings; public sealed partial class OnlineInboxSettingsViewModel : ViewModelBase { private readonly IWorkerClient _worker; private readonly IOnlineLoginService _loginService; [ObservableProperty] private bool _enabled; [ObservableProperty] private string _apiBaseUrl = ""; [ObservableProperty] private string _authority = ""; [ObservableProperty] private string _clientId = ""; [ObservableProperty] private string _scopes = "openid offline_access"; [ObservableProperty] private string _redirectUri = "http://localhost:8765/callback"; [ObservableProperty] private int _pollIntervalSeconds = 60; [ObservableProperty] private bool _signedIn; [ObservableProperty] private bool _isBusy; [ObservableProperty] private string _statusMessage = ""; public OnlineInboxSettingsViewModel(IWorkerClient worker, IOnlineLoginService loginService) { _worker = worker; _loginService = loginService; } public async Task LoadAsync() { IsBusy = true; StatusMessage = ""; try { var dto = await _worker.GetOnlineInboxStateAsync(); if (dto is null) { StatusMessage = Loc.T("vm.onlineInbox.workerOffline"); return; } Enabled = dto.Enabled; ApiBaseUrl = dto.ApiBaseUrl; Authority = dto.Authority; ClientId = dto.ClientId; Scopes = dto.Scopes; RedirectUri = dto.RedirectUri; SignedIn = dto.SignedIn; PollIntervalSeconds = dto.PollIntervalSeconds; } finally { IsBusy = false; } } [RelayCommand] private async Task Save() { IsBusy = true; StatusMessage = ""; try { await _worker.SetOnlineInboxConfigAsync(new OnlineInboxConfigInputDto( Enabled, ApiBaseUrl, PollIntervalSeconds, Authority, ClientId, Scopes, RedirectUri)); StatusMessage = Loc.T("vm.onlineInbox.saved"); } catch (Exception ex) { StatusMessage = Loc.T("vm.onlineInbox.saveFailed", ex.Message); } finally { IsBusy = false; } } [RelayCommand] private async Task SignIn() { IsBusy = true; StatusMessage = ""; try { var result = await _loginService.LoginAsync(Authority, ClientId, Scopes, RedirectUri); if (!result.Success) { StatusMessage = Loc.T("vm.onlineInbox.signInFailed", result.Error ?? "Unknown error"); return; } await _worker.SetOnlineInboxAuthAsync(result.RefreshToken!); SignedIn = true; StatusMessage = result.Warning == "missing-user-role" ? Loc.T("vm.onlineInbox.signedInNoRole") : Loc.T("vm.onlineInbox.signedIn"); } catch (Exception ex) { StatusMessage = Loc.T("vm.onlineInbox.signInFailed", ex.Message); } finally { IsBusy = false; } } [RelayCommand] private async Task SignOut() { IsBusy = true; StatusMessage = ""; try { await _worker.ClearOnlineInboxAuthAsync(); SignedIn = false; StatusMessage = Loc.T("vm.onlineInbox.signedOut"); } catch (Exception ex) { StatusMessage = Loc.T("vm.onlineInbox.signOutFailed", ex.Message); } finally { IsBusy = false; } } }