New UI page

This commit is contained in:
2024-03-07 14:15:50 +02:00
parent 29ecdb6883
commit e8822deeac
9 changed files with 168 additions and 12 deletions

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DiscordBotUI.ViewModels
{
public class OnlinePlugin
{
public string Name { get; set; }
public string Description { get; set; }
public string Version { get; set; }
public OnlinePlugin(string name, string description, string version) {
Name = name;
Description = description;
Version = version;
}
}
}

View File

@@ -9,7 +9,8 @@
<DockPanel LastChildFill="True">
<Menu DockPanel.Dock="Top">
<MenuItem Header="Settings" Click="SettingsMenuClick"></MenuItem>
<MenuItem Header="Plugins" Click="PluginsMenuClick"></MenuItem>
<MenuItem Header="Installed Plugins" Click="PluginsMenuClick"></MenuItem>
<MenuItem Header="New Plugins" Click="NewPluginsMenuClick"></MenuItem>
</Menu>
<Border Width="500" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Right">

View File

@@ -59,11 +59,18 @@ public partial class HomePage : Window
private async void SettingsMenuClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
await new SettingsPage().ShowDialog(this);
//await new SettingsPage().ShowDialog(this);
new SettingsPage().Show();
}
private async void PluginsMenuClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
await new PluginsPage().ShowDialog(this);
//await new PluginsPage().ShowDialog(this);
new PluginsPage().Show();
}
private void NewPluginsMenuClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
new PluginInstaller().Show();
}
}

View File

@@ -0,0 +1,33 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:DiscordBotUI.Views;assembly=DiscordBotUI"
xmlns:viewmodels="using:DiscordBotUI.ViewModels"
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="300"
x:Class="DiscordBotUI.Views.PluginInstaller"
x:DataType="views:PluginInstaller"
Title="PluginInstaller"
Name="PluginInstallerWindow"
>
<DataGrid Name="dataGridInstallablePlugins" ItemsSource="{Binding Plugins}">
<DataGrid.Columns>
<DataGridTextColumn Header="Plugin Name" Foreground="Aquamarine" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Plugin Version" Binding="{Binding Version}"/>
<DataGridTextColumn Header="Plugin Description" Binding="{Binding Description}" Width="*"/>
<DataGridTemplateColumn Header="Download">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="viewmodels:OnlinePlugin">
<Button Content="Download"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Command="{Binding InstallPlugin, RelativeSource={RelativeSource AncestorType=views:PluginInstaller}}"
CommandParameter="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Window>

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml.Templates;
using Avalonia.Media;
using DiscordBotUI.ViewModels;
using PluginManager;
using PluginManager.Plugin;
namespace DiscordBotUI.Views;
public partial class PluginInstaller : Window
{
public ObservableCollection<OnlinePlugin> Plugins { get; private set; }
public PluginInstaller()
{
InitializeComponent();
Loaded += OnPageLoaded;
}
private async void OnPageLoaded(object? sender, RoutedEventArgs e)
{
if (Config.PluginsManager is null) return;
List<PluginOnlineInfo>? onlineInfos = await Config.PluginsManager.GetPluginsList();
if(onlineInfos is null) return;
List<OnlinePlugin> plugins = new List<OnlinePlugin>();
foreach(PluginOnlineInfo onlinePlugin in onlineInfos)
{
plugins.Add(new OnlinePlugin(onlinePlugin.Name, onlinePlugin.Description, onlinePlugin.Version.ToShortString()));
}
Plugins = new ObservableCollection<OnlinePlugin>(plugins);
dataGridInstallablePlugins.ItemsSource = Plugins;
}
public async void InstallPlugin(string name)
{
PluginOnlineInfo? info = await Config.PluginsManager.GetPluginDataByName(name);
if(info is null) return;
await Config.PluginsManager.InstallPlugin(info, null);
}
}

View File

@@ -15,6 +15,7 @@
GridLinesVisibility="All"
AutoGenerateColumns="False"
BorderThickness="1" BorderBrush="Gray">
<DataGrid.Columns>
<DataGridTextColumn Header="Plugin Name" Foreground="Aquamarine" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Plugin Version" Binding="{Binding Version}"/>

View File

@@ -3,11 +3,11 @@ using System.Collections.ObjectModel;
using Avalonia.Controls;
using Avalonia.Interactivity;
using DiscordBotUI.ViewModels;
using PluginManager;
namespace DiscordBotUI.Views;
@@ -19,12 +19,13 @@ public partial class PluginsPage: Window
public PluginsPage()
{
InitializeComponent();
Loaded += OnPageLoaded;
}
private async void OnPageLoaded(object? sender, RoutedEventArgs e)
{
if (Config.PluginsManager is null) return;
var plugins = await Config.PluginsManager.GetInstalledPlugins();
var localList = new List<Plugin>();
foreach (var plugin in plugins)

View File

@@ -43,10 +43,10 @@ public class PluginsManager
Branch = _DefaultBranch;
}
public async Task<List<PluginOnlineInfo?>> GetPluginsList()
public async Task<List<PluginOnlineInfo>?> GetPluginsList()
{
var jsonText = await ServerCom.GetAllTextFromUrl(PluginsLink);
List<PluginOnlineInfo?> result = await JsonManager.ConvertFromJson<List<PluginOnlineInfo?>>(jsonText);
List<PluginOnlineInfo> result = await JsonManager.ConvertFromJson<List<PluginOnlineInfo>>(jsonText);
var currentOS = OperatingSystem.IsWindows() ? OSType.WINDOWS :
OperatingSystem.IsLinux() ? OSType.LINUX : OSType.MACOSX;
@@ -56,8 +56,8 @@ public class PluginsManager
public async Task<PluginOnlineInfo?> GetPluginDataByName(string pluginName)
{
List<PluginOnlineInfo?> plugins = await GetPluginsList();
var result = plugins.Find(p => p.Name == pluginName);
List<PluginOnlineInfo>? plugins = await GetPluginsList();
var result = plugins?.Find(p => p.Name == pluginName);
return result;
}
@@ -136,5 +136,29 @@ public class PluginsManager
await RemovePluginFromDatabase(pluginInfo.PluginName);
}
public async Task InstallPlugin(PluginOnlineInfo pluginData, IProgress<float>? installProgress)
{
installProgress?.Report(0f);
int totalSteps = pluginData.HasDependencies ? pluginData.Dependencies.Count + 1 : 1;
float stepProgress = 1f / totalSteps;
float currentProgress = 0f;
IProgress<float> progress = new Progress<float>((p) => {
installProgress?.Report(currentProgress + stepProgress * p);
});
await ServerCom.DownloadFileAsync(pluginData.DownLoadLink, $"{Config.AppSettings["PluginFolder"]}/{pluginData.Name}.dll", progress);
foreach (var dependency in pluginData.Dependencies)
{
await ServerCom.DownloadFileAsync(dependency.DownloadLink, dependency.DownloadLocation, progress);
currentProgress += stepProgress;
}
}
}

View File

@@ -41,7 +41,7 @@ public static class ServerCom
/// <param name="progress">The <see cref="IProgress{T}" /> to track the download</param>
/// <returns></returns>
public static async Task DownloadFileAsync(
string URL, string location, IProgress<float> progress,
string URL, string location, IProgress<float>? progress,
IProgress<long>? downloadedBytes)
{
using (var client = new HttpClient())
@@ -60,6 +60,11 @@ public static class ServerCom
await DownloadFileAsync(URl, location, progress, null);
}
public static async Task DownloadFileAsync(string url, string location)
{
await DownloadFileAsync(url, location, null, null);
}
public static Task CreateDownloadTask(string URl, string location)
{
return DownloadFileAsync(URl, location, null, null);