@using RackPeek.Domain.Git @using RackPeek.Domain.Git.UseCases @using RackPeek.Domain.Persistence @inject InitRepoUseCase InitRepo @inject CommitAllUseCase CommitAll @inject RestoreAllUseCase RestoreAll @inject PushUseCase PushUseCase @inject PullUseCase PullUseCase @inject AddRemoteUseCase AddRemoteUseCase @inject IGitRepository GitRepo @inject IResourceCollection Resources @implements IDisposable
@if (_status == GitRepoStatus.Clean) { Saved } else if (_status == GitRepoStatus.Dirty) { · · } @if (!_hasRemote) { · @if (_showAddRemote) { } else { } } else { · @if (_syncStatus.Ahead > 0) { · } @if (_syncStatus.Behind > 0) { · } } @if (_errorMessage is not null) { @_errorMessage }
@code { private GitRepoStatus _status = GitRepoStatus.NotAvailable; private bool _isCommitting; private bool _isRestoring; private bool _showAddRemote; private bool _hasRemote; private bool _isFetching; private bool _isPushing; private bool _isPulling; private string? _errorMessage; private string _remoteUrl = ""; private PeriodicTimer? _timer; private CancellationTokenSource? _cts; private GitSyncStatus _syncStatus = new(0, 0, false); private bool _isBusy => _isCommitting || _isRestoring || _isSyncing; private bool _isSyncing => _isPushing || _isPulling || _isFetching; protected override async Task OnInitializedAsync() { _status = await Task.Run(() => GitRepo.GetStatus()); if (_status == GitRepoStatus.NotAvailable) return; _hasRemote = await Task.Run(() => GitRepo.HasRemote()); _cts = new CancellationTokenSource(); _timer = new PeriodicTimer(TimeSpan.FromSeconds(15)); _ = PollStatusAsync(_cts.Token); } private async Task PollStatusAsync(CancellationToken ct) { try { while (_timer != null && await _timer.WaitForNextTickAsync(ct)) { if (_isBusy) continue; var newStatus = await Task.Run(() => GitRepo.GetStatus(), ct); if (newStatus != _status) { _status = newStatus; await InvokeAsync(StateHasChanged); } } } catch (OperationCanceledException) {} } private void CancelAddRemote() { _showAddRemote = false; _remoteUrl = ""; } private async Task AddRemoteAsync() { _errorMessage = null; try { var error = await AddRemoteUseCase.ExecuteAsync(_remoteUrl); if (error != null) { _errorMessage = error; return; } _hasRemote = true; _showAddRemote = false; _remoteUrl = ""; _syncStatus = await Task.Run(() => GitRepo.FetchAndGetSyncStatus()); if (_syncStatus.Behind > 0) await PullAsync(); } catch (Exception ex) { _errorMessage = $"Remote error: {ex.Message}"; } } private async Task CommitAsync() { _errorMessage = null; _isCommitting = true; try { var error = await CommitAll.ExecuteAsync( $"rackpeek: save config {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC"); if (error != null) _errorMessage = error; _status = await Task.Run(() => GitRepo.GetStatus()); await Resources.LoadAsync(); } catch (Exception ex) { _errorMessage = $"Commit error: {ex.Message}"; } finally { _isCommitting = false; } } private async Task ToggleSyncAsync() { _isFetching = true; try { _syncStatus = await Task.Run(() => GitRepo.FetchAndGetSyncStatus()); } finally { _isFetching = false; } } private async Task PushAsync() { _errorMessage = null; _isPushing = true; try { var error = await PushUseCase.ExecuteAsync(); if (error != null) _errorMessage = error; _syncStatus = await Task.Run(() => GitRepo.FetchAndGetSyncStatus()); } catch (Exception ex) { _errorMessage = $"Push error: {ex.Message}"; } finally { _isPushing = false; } } private async Task PullAsync() { _errorMessage = null; _isPulling = true; try { var error = await PullUseCase.ExecuteAsync(); if (error != null) _errorMessage = error; _syncStatus = await Task.Run(() => GitRepo.FetchAndGetSyncStatus()); _status = await Task.Run(() => GitRepo.GetStatus()); await Resources.LoadAsync(); } catch (Exception ex) { _errorMessage = $"Pull error: {ex.Message}"; } finally { _isPulling = false; } } private async Task DiscardAsync() { _errorMessage = null; _isRestoring = true; try { var error = await RestoreAll.ExecuteAsync(); if (error != null) _errorMessage = error; _status = await Task.Run(() => GitRepo.GetStatus()); await Resources.LoadAsync(); } catch (Exception ex) { _errorMessage = $"Discard error: {ex.Message}"; } finally { _isRestoring = false; } } public void Dispose() { _cts?.Cancel(); _cts?.Dispose(); _timer?.Dispose(); } }