Implement plugin browser and downloader
This commit is contained in:
@@ -39,6 +39,10 @@
|
|||||||
<HintPath>..\GameBinaries\HavokWrapper.dll</HintPath>
|
<HintPath>..\GameBinaries\HavokWrapper.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.4.12\lib\net45\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net45\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -189,6 +193,7 @@
|
|||||||
<Compile Include="Session\ITorchSessionManager.cs" />
|
<Compile Include="Session\ITorchSessionManager.cs" />
|
||||||
<Compile Include="Session\TorchSessionState.cs" />
|
<Compile Include="Session\TorchSessionState.cs" />
|
||||||
<Compile Include="TorchGameState.cs" />
|
<Compile Include="TorchGameState.cs" />
|
||||||
|
<Compile Include="WebAPI\PluginQuery.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
159
Torch.API/WebAPI/PluginQuery.cs
Normal file
159
Torch.API/WebAPI/PluginQuery.cs
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI
|
||||||
|
{
|
||||||
|
public class PluginQuery
|
||||||
|
{
|
||||||
|
private const string ALL_QUERY = "https://torchapi.net/api/plugins";
|
||||||
|
private const string PLUGIN_QUERY = "https://torchapi.net/api/plugins/{0}";
|
||||||
|
private readonly HttpClient _client;
|
||||||
|
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
private static PluginQuery _instance;
|
||||||
|
public static PluginQuery Instance => _instance ?? (_instance = new PluginQuery());
|
||||||
|
|
||||||
|
private PluginQuery()
|
||||||
|
{
|
||||||
|
_client = new HttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PluginResponse> QueryAll()
|
||||||
|
{
|
||||||
|
var h = await _client.GetAsync(ALL_QUERY);
|
||||||
|
if (!h.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
Log.Error($"Plugin query returned response {h.StatusCode}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = await h.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
PluginResponse response;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response = JsonConvert.DeserializeObject<PluginResponse>(r);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Failed to deserialize plugin query response!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PluginFullItem> QueryOne(Guid guid)
|
||||||
|
{
|
||||||
|
return await QueryOne(guid.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PluginFullItem> QueryOne(string guid)
|
||||||
|
{
|
||||||
|
|
||||||
|
var h = await _client.GetAsync(string.Format(PLUGIN_QUERY, guid));
|
||||||
|
if (!h.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
Log.Error($"Plugin query returned response {h.StatusCode}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = await h.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
PluginFullItem response;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response = JsonConvert.DeserializeObject<PluginFullItem>(r);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Failed to deserialize plugin query response!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DownloadPlugin(Guid guid)
|
||||||
|
{
|
||||||
|
return await DownloadPlugin(guid.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DownloadPlugin(string guid)
|
||||||
|
{
|
||||||
|
var item = await QueryOne(guid);
|
||||||
|
return await DownloadPlugin(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DownloadPlugin(PluginFullItem item)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var h = await _client.GetAsync(string.Format(PLUGIN_QUERY, item.ID));
|
||||||
|
string res = await h.Content.ReadAsStringAsync();
|
||||||
|
var response = JsonConvert.DeserializeObject<PluginFullItem>(res);
|
||||||
|
if (response.Versions.Length == 0)
|
||||||
|
{
|
||||||
|
Log.Error($"Selected plugin {item.Name} does not have any versions to download!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var version = response.Versions.FirstOrDefault(v => v.Version == response.LatestVersion);
|
||||||
|
if (version == null)
|
||||||
|
{
|
||||||
|
Log.Error($"Could not find latest version for selected plugin {item.Name}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var s = await _client.GetStreamAsync(version.URL);
|
||||||
|
using (var f = new FileStream($"Plugins\\{item.Name}.zip", FileMode.Create))
|
||||||
|
{
|
||||||
|
await s.CopyToAsync(f);
|
||||||
|
await f.FlushAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Failed to download plugin!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PluginResponse
|
||||||
|
{
|
||||||
|
public PluginItem[] Plugins;
|
||||||
|
public int Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PluginItem
|
||||||
|
{
|
||||||
|
public string ID;
|
||||||
|
public string Name;
|
||||||
|
public string Author;
|
||||||
|
public string Description;
|
||||||
|
public string LatestVersion;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PluginFullItem : PluginItem
|
||||||
|
{
|
||||||
|
public VersionItem[] Versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VersionItem
|
||||||
|
{
|
||||||
|
public string Version;
|
||||||
|
public string Note;
|
||||||
|
public bool IsBeta;
|
||||||
|
public string URL;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Mono.TextTransform" version="1.0.0" targetFramework="net461" />
|
<package id="Mono.TextTransform" version="1.0.0" targetFramework="net461" />
|
||||||
|
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
|
||||||
<package id="NLog" version="4.4.12" targetFramework="net461" />
|
<package id="NLog" version="4.4.12" targetFramework="net461" />
|
||||||
</packages>
|
</packages>
|
@@ -51,7 +51,6 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
<DocumentationFile>$(SolutionDir)\bin\x64\Release\Torch.Server.xml</DocumentationFile>
|
<DocumentationFile>$(SolutionDir)\bin\x64\Release\Torch.Server.xml</DocumentationFile>
|
||||||
<NoWarn>1591</NoWarn>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<StartupObject>Torch.Server.Program</StartupObject>
|
<StartupObject>Torch.Server.Program</StartupObject>
|
||||||
@@ -71,6 +70,9 @@
|
|||||||
<Reference Include="MahApps.Metro, Version=1.6.1.4, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="MahApps.Metro, Version=1.6.1.4, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\MahApps.Metro.1.6.1\lib\net45\MahApps.Metro.dll</HintPath>
|
<HintPath>..\packages\MahApps.Metro.1.6.1\lib\net45\MahApps.Metro.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Markdown.Xaml, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Markdown.Xaml.1.0.0\lib\net45\Markdown.Xaml.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.CodeAnalysis, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.CodeAnalysis, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\GameBinaries\Microsoft.CodeAnalysis.dll</HintPath>
|
<HintPath>..\GameBinaries\Microsoft.CodeAnalysis.dll</HintPath>
|
||||||
@@ -273,6 +275,9 @@
|
|||||||
<Compile Include="Views\ModListControl.xaml.cs">
|
<Compile Include="Views\ModListControl.xaml.cs">
|
||||||
<DependentUpon>ModListControl.xaml</DependentUpon>
|
<DependentUpon>ModListControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Views\PluginBrowser.xaml.cs">
|
||||||
|
<DependentUpon>PluginBrowser.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Views\ThemeControl.xaml.cs">
|
<Compile Include="Views\ThemeControl.xaml.cs">
|
||||||
<DependentUpon>ThemeControl.xaml</DependentUpon>
|
<DependentUpon>ThemeControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -437,6 +442,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Views\PluginBrowser.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Views\PluginsControl.xaml">
|
<Page Include="Views\PluginsControl.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@@ -492,6 +501,7 @@
|
|||||||
<Install>false</Install>
|
<Install>false</Install>
|
||||||
</BootstrapperPackage>
|
</BootstrapperPackage>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="$(SolutionDir)\TransformOnBuild.targets" />
|
<Import Project="$(SolutionDir)\TransformOnBuild.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
124
Torch.Server/Views/PluginBrowser.xaml
Normal file
124
Torch.Server/Views/PluginBrowser.xaml
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<Window x:Class="Torch.Server.Views.PluginBrowser"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
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:local="clr-namespace:Markdown.Xaml;assembly=Markdown.Xaml"
|
||||||
|
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||||
|
xmlns:views="clr-namespace:Torch.Server.Views"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="PluginBrowser" Height="400" Width="600"
|
||||||
|
DataContext="{Binding RelativeSource={RelativeSource Self}}">
|
||||||
|
|
||||||
|
<Window.Resources>
|
||||||
|
<Style TargetType="FlowDocument" x:Key="DocumentStyle">
|
||||||
|
<Setter Property="FontFamily"
|
||||||
|
Value="Calibri" />
|
||||||
|
<Setter Property="TextAlignment"
|
||||||
|
Value="Left" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="H1Style"
|
||||||
|
TargetType="Paragraph">
|
||||||
|
<Setter Property="FontSize"
|
||||||
|
Value="42" />
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="#ff000000" />
|
||||||
|
<Setter Property="FontWeight"
|
||||||
|
Value="Light" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="H2Style"
|
||||||
|
TargetType="Paragraph">
|
||||||
|
<Setter Property="FontSize"
|
||||||
|
Value="20" />
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="#ff000000" />
|
||||||
|
<Setter Property="FontWeight"
|
||||||
|
Value="Light" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="H3Style"
|
||||||
|
TargetType="Paragraph">
|
||||||
|
<Setter Property="FontSize"
|
||||||
|
Value="20" />
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="#99000000" />
|
||||||
|
<Setter Property="FontWeight"
|
||||||
|
Value="Light" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="H4Style"
|
||||||
|
TargetType="Paragraph">
|
||||||
|
<Setter Property="FontSize"
|
||||||
|
Value="14" />
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="#99000000" />
|
||||||
|
<Setter Property="FontWeight"
|
||||||
|
Value="Light" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="LinkStyle"
|
||||||
|
TargetType="Hyperlink">
|
||||||
|
<Setter Property="TextDecorations"
|
||||||
|
Value="None" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="ImageStyle"
|
||||||
|
TargetType="Image">
|
||||||
|
<Setter Property="RenderOptions.BitmapScalingMode"
|
||||||
|
Value="NearestNeighbor" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="Tag"
|
||||||
|
Value="imageright">
|
||||||
|
<Setter Property="Margin"
|
||||||
|
Value="20,0,0,0" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="SeparatorStyle"
|
||||||
|
TargetType="Line">
|
||||||
|
<Setter Property="X2"
|
||||||
|
Value="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=FlowDocumentScrollViewer}}" />
|
||||||
|
<Setter Property="Stroke"
|
||||||
|
Value="#99000000" />
|
||||||
|
<Setter Property="StrokeThickness"
|
||||||
|
Value="2" />
|
||||||
|
</Style>
|
||||||
|
<local:Markdown x:Key="Markdown"
|
||||||
|
DocumentStyle="{StaticResource DocumentStyle}"
|
||||||
|
Heading1Style="{StaticResource H1Style}"
|
||||||
|
Heading2Style="{StaticResource H2Style}"
|
||||||
|
Heading3Style="{StaticResource H3Style}"
|
||||||
|
Heading4Style="{StaticResource H4Style}"
|
||||||
|
LinkStyle="{StaticResource LinkStyle}"
|
||||||
|
ImageStyle="{StaticResource ImageStyle}"
|
||||||
|
SeparatorStyle="{StaticResource SeparatorStyle}"
|
||||||
|
AssetPathRoot="{x:Static system:Environment.CurrentDirectory}"/>
|
||||||
|
|
||||||
|
<local:TextToFlowDocumentConverter x:Key="TextToFlowDocumentConverter"
|
||||||
|
Markdown="{StaticResource Markdown}"/>
|
||||||
|
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<ListView Name="PluginsList" Width="150" Height="Auto" Margin="3" ItemsSource="{Binding Plugins}" SelectionChanged="PluginsList_SelectionChanged">
|
||||||
|
|
||||||
|
</ListView>
|
||||||
|
<Button Name="DownloadButton" Grid.Row ="1" Content="Download" Margin="3" Height="30" Click="DownloadButton_OnClick" IsEnabled="False"/>
|
||||||
|
</Grid>
|
||||||
|
<FlowDocumentScrollViewer Grid.Column="1" Name="MarkdownFlow" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="3" Document="{Binding CurrentDescription, Converter={StaticResource TextToFlowDocumentConverter}}"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
|
|
||||||
|
|
90
Torch.Server/Views/PluginBrowser.xaml.cs
Normal file
90
Torch.Server/Views/PluginBrowser.xaml.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NLog;
|
||||||
|
using Torch.API.WebAPI;
|
||||||
|
using Torch.Collections;
|
||||||
|
using Torch.Server.Annotations;
|
||||||
|
|
||||||
|
namespace Torch.Server.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for PluginBrowser.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class PluginBrowser : Window, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public MtObservableList<PluginItem> Plugins { get; set; } = new MtObservableList<PluginItem>();
|
||||||
|
public PluginItem CurrentItem { get; set; }
|
||||||
|
|
||||||
|
private string _description = "Loading data from server, please wait..";
|
||||||
|
public string CurrentDescription
|
||||||
|
{
|
||||||
|
get { return _description; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_description = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginBrowser()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var res = await PluginQuery.Instance.QueryAll();
|
||||||
|
if (res == null)
|
||||||
|
return;
|
||||||
|
foreach(var item in res.Plugins)
|
||||||
|
Plugins.Add(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PluginsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
CurrentItem = (PluginItem)PluginsList.SelectedItem;
|
||||||
|
CurrentDescription = CurrentItem.Description;
|
||||||
|
DownloadButton.IsEnabled = !string.IsNullOrEmpty(CurrentItem.LatestVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DownloadButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var item = CurrentItem;
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var result = await PluginQuery.Instance.DownloadPlugin(item.ID);
|
||||||
|
MessageBox.Show(result ? "Plugin downloaded successfully! Please restart the server to load changes."
|
||||||
|
: "Plugin failed to download! See log for details.",
|
||||||
|
"Plugin Downloader",
|
||||||
|
MessageBoxButton.OK);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
[NotifyPropertyChangedInvocator]
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -26,7 +26,14 @@
|
|||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
</ListView>
|
</ListView>
|
||||||
<Button Grid.Row="1" Content="Open Folder" Margin="3" DockPanel.Dock="Bottom" Click="OpenFolder_OnClick"/>
|
<Grid Grid.Row="1">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Button Grid.Row="0" Grid.Column="0" Content="Open Folder" Margin="3" Click="OpenFolder_OnClick"/>
|
||||||
|
<Button Grid.Row="0" Grid.Column="1" Content="Browse Plugins" Margin="3" Click="BrowsPlugins_OnClick"/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<ScrollViewer Name="PScroll" Grid.Column="1" Margin="3">
|
<ScrollViewer Name="PScroll" Grid.Column="1" Margin="3">
|
||||||
<Frame NavigationUIVisibility="Hidden" Content="{Binding SelectedPlugin.Control}"/>
|
<Frame NavigationUIVisibility="Hidden" Content="{Binding SelectedPlugin.Control}"/>
|
||||||
|
@@ -71,5 +71,11 @@ namespace Torch.Server.Views
|
|||||||
if (_plugins?.PluginDir != null)
|
if (_plugins?.PluginDir != null)
|
||||||
Process.Start(_plugins.PluginDir);
|
Process.Start(_plugins.PluginDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BrowsPlugins_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var browser = new PluginBrowser();
|
||||||
|
browser.Show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="ControlzEx" version="3.0.2.4" targetFramework="net461" />
|
<package id="ControlzEx" version="3.0.2.4" targetFramework="net461" />
|
||||||
<package id="MahApps.Metro" version="1.6.1" targetFramework="net461" />
|
<package id="MahApps.Metro" version="1.6.1" targetFramework="net461" />
|
||||||
|
<package id="Markdown.Xaml" version="1.0.0" targetFramework="net461" />
|
||||||
<package id="Microsoft.Win32.Registry" version="4.4.0" targetFramework="net461" />
|
<package id="Microsoft.Win32.Registry" version="4.4.0" targetFramework="net461" />
|
||||||
<package id="Mono.TextTransform" version="1.0.0" targetFramework="net461" />
|
<package id="Mono.TextTransform" version="1.0.0" targetFramework="net461" />
|
||||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
|
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
|
||||||
|
Reference in New Issue
Block a user