livia-test/Livia/ViewModels/DataBlockTableViewModel.cs
2025-03-28 14:31:53 +08:00

213 lines
7.7 KiB
C#

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Livia.Models;
using Livia.Models.Data;
using Livia.Properties;
using Livia.Utility;
using Livia.Utility.DependencyInjection;
using Livia.Views.Utility;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Livia.ViewModels;
public sealed class DataBlockTableViewModel : ObservableRecipient, IRecipient<LogoutMessage>, IRecipient<SearchQueryMessage>, IPagingControlRecipient
{
public int SequenceColumnNum { get => _sequenceColumnNum; private set => SetProperty(ref _sequenceColumnNum, value); }
public ObservableCollection<ServerJobData> ServerJobList { get; } = [];
public PagingControlViewModel DataBlockPagingViewModel { get; }
public IServerHandler ServerHandler { get; }
private int _sequenceColumnNum;
private readonly IWarningSystem _warningSystem;
private readonly ILogger _logger;
private readonly IDataBlockLoader _dataBlockLoader;
private SearchQueryCondition _currentSearch;
private bool _isSearchResult;
public DataBlockTableViewModel(IServerHandler serverHandler, IWarningSystem warningSystem, ILogger logger, IDataBlockLoader dataBlockLoader)
{
WeakReferenceMessenger.Default.Register<LogoutMessage>(this);
DataBlockPagingViewModel = ActivatorUtilities.CreateInstance<PagingControlViewModel>(ServiceProviderFactory.ServiceProvider);
DataBlockPagingViewModel.SetRecipient(this);
ServerHandler = serverHandler;
_warningSystem = warningSystem;
_logger = logger;
_dataBlockLoader = dataBlockLoader;
//only if we are using this module
if (!Settings.Default.AutoRefreshServerJobList)
return;
DispatcherTimer dispatcherTimer = new();
dispatcherTimer.Tick += Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
dispatcherTimer.Start();
Tick(null, null);
}
private void Tick(object? sender, EventArgs? e)
{
Task.Run(UpdateServerJobList);
}
public void SetSearchResult()
{
_isSearchResult = true;
WeakReferenceMessenger.Default.Register<SearchQueryMessage>(this);
}
private async Task<bool> SearchData(SearchQueryCondition condition)
{
SearchQueryJson json = new()
{
Conditions = condition,
Limit = PagingControlViewModel.ItemPerPage,
Offset = DataBlockPagingViewModel.Offset
};
_currentSearch = condition;
(List<ServerJobData> list, int count) = await ServerHandler.SearchData(json).ConfigureAwait(false);
DataBlockPagingViewModel.SetItemNumber(count);
int maxSequenceCount = list.Select(data => data.Sequence?.Count ?? 0).DefaultIfEmpty().Max();
SequenceColumnNum = (1 + maxSequenceCount) / 2;
Application.Current.Dispatcher.Invoke(delegate
{
ServerJobList.Clear();
ServerJobList.AddRange(list);
});
return true;
}
public async Task<bool> UpdateServerJobList()
{
//TODO::check for success here
(List<ServerJobData> list, int count) = await ServerHandler.CheckServerJobList(PagingControlViewModel.ItemPerPage, DataBlockPagingViewModel.Offset).ConfigureAwait(false);
//_logger.LogInformation("SelectedCount is {count}", count);
DataBlockPagingViewModel.SetItemNumber(count);
int maxSequenceCount = list.Select(data => data.Sequence?.Count ?? 0).DefaultIfEmpty().Max();
SequenceColumnNum = (1 + maxSequenceCount) / 2;
Application.Current.Dispatcher.Invoke(delegate
{
ServerJobList.Clear();
ServerJobList.AddRange(list);
});
await ServerHandler.UpdateDongleInfo().ConfigureAwait(false);
return true;
}
public Task LoadData(ServerJobData dataContext)
{
return _dataBlockLoader.LoadServerData(dataContext);
}
public Task CancelData(ServerJobData dataContext)
{
return dataContext.Key == null ? Task.CompletedTask : ServerHandler.Cancel(dataContext.Key);
}
public async Task DownloadArchive(ServerJobData data, string savePath, CancellationToken cancellationToken)
{
_logger.LogInformation("Downloading archive to {path}", savePath);
if (string.IsNullOrEmpty(data.Key))
{
_warningSystem.ShowDialog(WarningWindowKind.Warning, true, "ProcessingError");
}
(bool success, string messageIndex) = await ServerHandler.DownloadArchive(data.Key, savePath, cancellationToken);
if (!success)
{
if (!cancellationToken.IsCancellationRequested)
_warningSystem.ShowDialog(WarningWindowKind.Warning, true, messageIndex);
}
else
{
_warningSystem.ShowDialog(WarningWindowKind.Info, false, "DataProcessComplete");
}
}
public async Task DownloadSorted(ServerJobData data, string savePath, CancellationToken cancellationToken)
{
_logger.LogInformation("Downloading sorted to {path}", savePath);
if (string.IsNullOrEmpty(data.Key))
{
_warningSystem.ShowDialog(WarningWindowKind.Warning, true, "ProcessingError");
}
(bool success, string messageIndex) = await ServerHandler.DownloadSorted(data.Key, savePath, cancellationToken);
if (!success)
{
if (!cancellationToken.IsCancellationRequested)
_warningSystem.ShowDialog(WarningWindowKind.Warning, true, messageIndex);
}
else
{
_warningSystem.ShowDialog(WarningWindowKind.Info, false, "DataProcessComplete");
}
}
public void Receive(LogoutMessage message)
{
Application.Current.Dispatcher.Invoke(delegate
{
ServerJobList.Clear();
});
DataBlockPagingViewModel.CurrentPage = 1;
DataBlockPagingViewModel.SetItemNumber(0);
}
public void Receive(SearchQueryMessage message)
{
DataBlockPagingViewModel.CurrentPage = 1;
Task.Run(() => SearchData(message.Value));
}
public async Task<bool> Refresh()
{
return _isSearchResult ? await SearchData(_currentSearch).ConfigureAwait(false) : await UpdateServerJobList().ConfigureAwait(false);
}
public async Task DeleteData(ServerJobData data, CancellationToken cancellationToken)
{
_logger.LogInformation("Deleting data {id}", data.Id);
(bool success, string messageIndex) = _isSearchResult ? await ServerHandler.DeleteData(data.Id, cancellationToken) : await ServerHandler.DeleteHistory(data.Key, cancellationToken);
if (!success)
{
if (!cancellationToken.IsCancellationRequested)
_warningSystem.ShowDialog(WarningWindowKind.Warning, true, messageIndex);
}
else
{
DataBlockPagingViewModel.RefreshCurrentPage();
_warningSystem.ShowDialog(WarningWindowKind.Info, false, messageIndex);
}
await Refresh();
}
public async Task DeleteHistory(DataHistory data, CancellationToken cancellationToken)
{
_logger.LogInformation("Deleting data {id}", data.Key);
(bool success, string messageIndex) = await ServerHandler.DeleteHistory(data.Key, cancellationToken);
if (!success)
{
if (!cancellationToken.IsCancellationRequested)
_warningSystem.ShowDialog(WarningWindowKind.Warning, true, messageIndex);
}
else
{
DataBlockPagingViewModel.RefreshCurrentPage();
_warningSystem.ShowDialog(WarningWindowKind.Info, false, messageIndex);
}
await Refresh();
}
}