Files
crosslangdevstudio/ViewModels/PackageManagerViewModel.cs
2025-10-22 17:31:32 -05:00

204 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using System.Web;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CrossLangDevStudio.Messages;
using CrossLangDevStudio.Models;
using CrossLangDevStudio.Views;
using Newtonsoft.Json;
namespace CrossLangDevStudio.ViewModels;
public partial class PackageManagerViewModel : ViewModelBase
{
public IPackageManager Packages { get; }
public ObservableCollection<Package> PackageList { get; } = new ObservableCollection<Package>();
public ObservableCollection<string> Servers { get; } = new ObservableCollection<string>();
[ObservableProperty]
private int _serverIndex = 0;
[ObservableProperty]
private string _search = "";
[ObservableProperty]
private int _page = 1;
public MainWindowViewModel Main { get; }
public PackageManagerViewModel(MainWindowViewModel mvm, IPackageManager pm)
{
Main = mvm;
Packages = pm;
foreach(var svr in CrossLangShell.GetServers())
this.Servers.Add(svr);
}
//
[RelayCommand]
private async Task SearchPackagesAsync()
{
var svr = Servers[ServerIndex].TrimEnd('/');
var body = await Main.Client.GetStringAsync($"{svr}/api/v1/search?q={HttpUtility.UrlEncode(Search)}&type={HttpUtility.UrlEncode(Packages.Filter)}&offset={Page-1}&limit=20");
var res = JsonConvert.DeserializeObject<SearchResult>(body);
PackageList.Clear();
if (res is not null)
{
foreach (var item in res.Packages)
{
Package pkg = new Package();
var date = DateTimeOffset.FromUnixTimeSeconds(item.UploadTime);
var date2 = date.ToLocalTime().DateTime;
pkg.Info = $"Version: {item.Version}\tAccount: {item.AccountName}\tUpdated: {date2.ToShortDateString()}\tLicense: {item.License}\tType: {item.Type}";
pkg.Version = item.Version;
pkg.Name = item.Name;
pkg.Description = item.Description.Summarize();
pkg.IsInstalled = Packages.IsPackageInstalled(item.Name);
pkg.Install = async() =>
{
var resp = await WeakReferenceMessenger.Default.Send(new InstallPackageMessage(Main.Client, item.Name, svr));
if (resp.HasValue)
{
await Packages.InstallPackageAsync(item.Name, resp.Value);
pkg.IsInstalled = true;
}
};
pkg.Uninstall = () =>
{
Packages.UninstallPackage(item.Name);
pkg.IsInstalled = false;
};
byte[] data = await Main.Client.GetByteArrayAsync($"{svr}/api/v1/package_icon.png?name={HttpUtility.UrlEncode(item.Name)}&version={item.Version.ToString()}");
using var ms = new MemoryStream(data, false);
pkg.Icon = Bitmap.DecodeToHeight(ms, 64);
PackageList.Add(pkg);
}
}
}
public class SearchPackage
{
[JsonProperty("packageName")]
public string Name { get; set; } = "";
[JsonProperty("version")]
public CrossLangVersion Version { get; set; }
[JsonProperty("uploadTime")]
public long UploadTime { get; set; }
[JsonProperty("license")]
public string License { get; set; } = "";
[JsonProperty("type")]
public string Type { get; set; } = "";
[JsonProperty("accountName")]
public string AccountName { get; set; } = "";
[JsonProperty("description")]
public string Description { get; set; } = "";
}
public partial class Package : ObservableObject
{
[ObservableProperty]
private string _name = "";
public CrossLangVersion Version { get; set; }
public Func<Task>? Install { get; set; }
public Func<Task>? GetInfo { get; set; }
[ObservableProperty]
private string _info = "";
[ObservableProperty]
private string _description = "";
[ObservableProperty]
private IImage? _icon = null;
[ObservableProperty]
private string _mainButtonText = "";
[ObservableProperty]
private string _subButton1Text = "";
private bool _isInstalled = false;
public bool IsInstalled
{
get => _isInstalled;
set
{
SetProperty(ref _isInstalled, value, nameof(IsInstalled));
MainButtonText = value ? "Uninstall" : "Install";
SubButton1Text = value ? "Change Version" : "Info";
}
}
public Action? Uninstall { get; set; }
[RelayCommand]
private async Task MainButtonAsync()
{
/*var i = Install;
if (i is not null) await i();*/
if (_isInstalled)
{
Uninstall?.Invoke();
}
else
{
var i = Install;
if (i is not null) await i();
}
}
[RelayCommand]
private async Task SubButton1Async()
{
if (_isInstalled)
{
var i = Install;
if (i is not null) await i();
}
else
{
var i = GetInfo;
if (i is not null) await i();
}
}
[RelayCommand]
private async Task SubButton2Async()
{
var i = GetInfo;
if (i is not null) await i();
}
}
public class SearchResult
{
[JsonProperty("packages")]
public List<SearchPackage> Packages { get; set; } = new List<SearchPackage>();
}
}