a lot of work

This commit is contained in:
2025-11-15 17:17:52 +01:00
parent 336b6ad1fd
commit b9ddc20b7d
42 changed files with 1453 additions and 3346 deletions

View File

@@ -1,4 +1,4 @@
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager.Api;
public static class FeatureTypes public static class FeatureTypes
{ {

View File

@@ -1,12 +1,10 @@
using Avalonia.Controls; using Avalonia.Controls;
using ModpackUpdater.Apps.Manager.Ui.Models;
namespace ModpackUpdater.Apps.Manager.Api.Model; namespace ModpackUpdater.Apps.Manager.Api.Model;
public interface IMainApi public interface IMainApi
{ {
IWorkspace? CurWorkspace { get; }
IActionSetInfos? CurActionSet { get; }
Window MainWindow { get; } Window MainWindow { get; }
void UpdateItem(InstallAction action); MainWindowViewModel Model { get; }
void UpdateItem(IActionSetInfos actionSetInfos);
} }

View File

@@ -1,7 +1,7 @@
namespace ModpackUpdater.Apps.Manager.Api.Model; namespace ModpackUpdater.Apps.Manager.Api.Model;
public class WorkspaceContext(IMainApi mainApi, IWorkspace workspace) public class WorkspaceContext(IMainApi mainApi, IWorkspace? workspace)
{ {
public IMainApi MainApi => mainApi; public IMainApi MainApi => mainApi;
public IWorkspace Workspace { get; set; } = workspace; public IWorkspace? Workspace { get; set; } = workspace;
} }

View File

@@ -8,6 +8,7 @@
<FluentTheme DensityStyle="Normal" /> <FluentTheme DensityStyle="Normal" />
<!-- <FluentTheme DensityStyle="Compact" /> --> <!-- <FluentTheme DensityStyle="Compact" /> -->
<!-- <SimpleTheme /> --> <!-- <SimpleTheme /> -->
<StyleInclude Source="avares://ModpackUpdater.Apps.Manager/Assets/Styles/StylesEnhancedDefaults.axaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
<StyleInclude Source="avares://MinecraftModpackUpdateManager/Assets/Styles/StylesEnhancedDefaults.axaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

View File

@@ -2,6 +2,7 @@ using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features;
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager;
@@ -10,6 +11,8 @@ public partial class App : Application
public override void Initialize() public override void Initialize()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
AppGlobals.Initialize();
PluginFeatureController.Instance.RegisterAllOwn();
} }
public override void OnFrameworkInitializationCompleted() public override void OnFrameworkInitializationCompleted()

View File

@@ -0,0 +1 @@
[assembly: PropertyChanged.FilterType("ModpackUpdater.Apps.Manager.Ui.Models")]

View File

@@ -1,11 +0,0 @@
namespace ModpackUpdater.Apps.Manager;
internal static class Extensions
{
public static string? Nullify(this string? @this)
{
if (string.IsNullOrEmpty(@this))
return null;
return @this;
}
}

View File

@@ -1,8 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
@@ -12,19 +12,15 @@ internal class CheckSingleActionHealthyFeature : PluginFunction, IPluginFeatureP
public CheckSingleActionHealthyFeature() : base(FeatureTypes.ActionsContextMenu, "origin.checksingleactionhearlthy", FeatureNamesLangRes.CheckSingleActionHealthy) public CheckSingleActionHealthyFeature() : base(FeatureTypes.ActionsContextMenu, "origin.checksingleactionhearlthy", FeatureNamesLangRes.CheckSingleActionHealthy)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.heart_with_pulse, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.heart_with_pulse, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.SelectedGridRow is not { } row)
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| gridView.SelectedRows.FirstOrDefault() is not GridViewRowInfo row
|| row.Tag is not InstallAction)
return null; return null;
SharedFunctions.CheckActionHealthy(p.Api, row); Task.Run(() => SharedFunctions.CheckActionHealthy(p.Api, row)).Wait();
return null; return null;
} }

View File

@@ -1,8 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
@@ -12,18 +12,15 @@ internal class ClearDirectLinkFeature : PluginFunction, IPluginFeatureProvider<C
public ClearDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.cleardirectlink", FeatureNamesLangRes.ClearDirectLinkFeature) public ClearDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.cleardirectlink", FeatureNamesLangRes.ClearDirectLinkFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.SelectedGridRow is not { } row)
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| gridView.SelectedRows.FirstOrDefault()?.Tag is not InstallAction selectedAction)
return null; return null;
SharedFunctions.ClearDirectLinks(p.Api, selectedAction); SharedFunctions.ClearDirectLinks(row);
return null; return null;
} }

View File

@@ -1,9 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
internal class UpdateCollectorFeature : PluginFunction, IPluginFeatureProvider<UpdateCollectorFeature> internal class UpdateCollectorFeature : PluginFunction, IPluginFeatureProvider<UpdateCollectorFeature>
@@ -12,19 +11,15 @@ internal class UpdateCollectorFeature : PluginFunction, IPluginFeatureProvider<U
public UpdateCollectorFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatecollector", FeatureNamesLangRes.UpdateCollectorFeature) public UpdateCollectorFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatecollector", FeatureNamesLangRes.UpdateCollectorFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.search, SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.search, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.SelectedGridRow is not { } row)
|| p.Api.CurWorkspace?.UpdateInfos is null
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| gridView.SelectedRows.FirstOrDefault()?.Tag is not InstallAction selectedAction)
return null; return null;
SharedFunctions.CollectUpdates(p.Api, selectedAction); Task.Run(() => SharedFunctions.CollectUpdates(p.Api, row.Action)).Wait();
return null; return null;
} }

View File

@@ -1,8 +1,9 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui.Models;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
@@ -12,18 +13,15 @@ internal class UpdateDirectLinkFeature : PluginFunction, IPluginFeatureProvider<
public UpdateDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatedirectlink", FeatureNamesLangRes.UpdateDirectLinkFeature) public UpdateDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatedirectlink", FeatureNamesLangRes.UpdateDirectLinkFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.renew, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.renew, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.SelectedGridRow is not MainWindowGridRow row)
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| gridView.SelectedRows.FirstOrDefault()?.Tag is not InstallAction selectedAction)
return null; return null;
SharedFunctions.FindNewDirectLinks(p.Api, selectedAction); Task.Run(() => SharedFunctions.FindNewDirectLinks(row)).Wait();
return null; return null;
} }

View File

@@ -1,98 +1,71 @@
using ModpackUpdater.Apps.Manager.Api.Model; using System.Text;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using ModpackUpdater.Apps.Manager.Ui.Models;
using ModpackUpdater.Manager; using ModpackUpdater.Manager;
using MsBox.Avalonia;
using OfficeOpenXml; using OfficeOpenXml;
using Pilz.UI.WinForms.Extensions; using OfficeOpenXml.Table;
using System.Text; using Pilz.UI.AvaloniaUI.Dialogs;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features; namespace ModpackUpdater.Apps.Manager.Features;
internal static class SharedFunctions internal static class SharedFunctions
{ {
public static bool CheckActionHealthy(IMainApi api, params GridViewRowInfo[] selectedRows) public static async Task<bool> CheckActionHealthy(IMainApi api, params MainWindowGridRow[] rows)
{ {
if (api.MainWindow is not MainForm mainForm var rowsCount = rows.Length;
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| mainForm.Controls.Find("radWaitingBar_Actions", true).FirstOrDefault() is not RadWaitingBar rwb)
return false;
rwb.StartWaiting();
rwb.ShowText = true;
var rowsCount = selectedRows.Length;
rwb.Text = "0 / " + rowsCount;
gridView.BeginUpdate();
var failed = false; var failed = false;
var msg = default(string); var msg = default(string);
var factory = new ModpackFactory(); var factory = new ModpackFactory();
var rows = new Dictionary<GridViewRowInfo, InstallAction>(); for (var i = 0; i < rows.Length; i++)
for (var i = 0; i < selectedRows.Length; i++)
{ {
var row = selectedRows[i]; var row = rows[i];
if (row.Tag is InstallAction action)
{
Task.Run(async () =>
{
try try
{ {
var result = await factory.ResolveSourceUrl(action); var result = await factory.ResolveSourceUrl(row.Action);
failed = string.IsNullOrWhiteSpace(result); failed = string.IsNullOrWhiteSpace(result);
} }
catch (Exception ex) catch (Exception ex)
{ {
msg = ex.Message; msg = ex.Message;
} }
}).Wait();
row.IsValid = !failed;
// rwb.Text = $"{i} / {rowsCount}";
} }
foreach (var c in row.Cells)
{
c.Style.CustomizeFill = true;
c.Style.BackColor = failed ? Color.IndianRed : Color.ForestGreen;
}
rwb.Text = $"{i} / {rowsCount}";
Application.DoEvents();
}
gridView.EndUpdate();
rwb.ShowText = false;
rwb.StopWaiting();
if (rowsCount == 1 && failed && !string.IsNullOrWhiteSpace(msg)) if (rowsCount == 1 && failed && !string.IsNullOrWhiteSpace(msg))
MessageBox.Show(msg); _ = MessageBoxManager.GetMessageBoxStandard(string.Empty, msg).ShowAsPopupAsync(api.MainWindow);
return true; return true;
} }
public static bool CollectUpdates(IMainApi api, params InstallAction[] actions) public static async Task<bool> CollectUpdates(IMainApi api, params InstallAction[] actions)
{ {
if (api.CurWorkspace?.UpdateInfos is null) if (api.Model.CurrentWorkspace?.UpdateInfos is null || api.Model.CurrentTreeNodes is null)
return false; return false;
// Collect updates // Collect updates
var ucDialog = new UpdatesCollectorUi(api.CurWorkspace, actions); var result = await AvaloniaFlyoutBase.Show(new UpdatesCollectorView(api.Model.CurrentWorkspace, actions), api.MainWindow);
if (!ucDialog.ShowDialog(api.MainWindow).IsOk() || ucDialog.CurrentUpdates is null) if (result.Result is null || result.CurrentUpdates is null)
return false; return false;
// Collect versions with changes // Collect versions with changes
var updates = new List<UpdatesCollectorUi.ModUpdateInfo>(); var updates = result.CurrentUpdates.List.Where(update => update.Origin.SourceTag != update.AvailableVersions[update.NewVersion].Key).ToList();
foreach (var update in ucDialog.CurrentUpdates.List)
{
if (update.Origin.SourceTag != update.AvailableVersions[update.NewVersion].Key)
updates.Add(update);
}
// Path install actions // Path install actions
foreach (var update in updates) foreach (var update in updates)
{ {
update.Origin.SourceTag = update.AvailableVersions[update.NewVersion].Key; var sourceTag = update.AvailableVersions[update.NewVersion].Key;
api.UpdateItem(update.Origin); if (api.Model.CurrentGridRows?.FirstOrDefault(n => n.Action == update.Origin) is { } row)
row.SourceTag = sourceTag;
else
update.Origin.SourceTag = sourceTag;
} }
// Create update actions // Create update actions
@@ -104,67 +77,43 @@ internal static class SharedFunctions
InheritFrom = update.Origin.Id, InheritFrom = update.Origin.Id,
}); });
} }
api.CurWorkspace.UpdateInfos.Updates.Insert(0, updateSet); api.Model.CurrentWorkspace.UpdateInfos.Updates.Insert(0, updateSet);
api.UpdateItem(updateSet);
// Add update to ui
api.Model.CurrentTreeNodes[1].Nodes.Add(new ActionSetTreeNode(updateSet));
return true; return true;
} }
public static void FindNewDirectLinks(IMainApi api, params InstallAction[] actions) public static async Task FindNewDirectLinks(params MainWindowGridRow[] rows)
{ {
var mainForm = api.MainWindow as MainForm;
var gridView = mainForm?.Controls.Find("radGridView_Actions", true).FirstOrDefault() as RadGridView;
var rwb = mainForm?.Controls.Find("radWaitingBar_Actions", true).FirstOrDefault() as RadWaitingBar;
var factory = new ModpackFactory(); var factory = new ModpackFactory();
rwb?.StartWaiting(); foreach (var row in rows)
gridView?.BeginUpdate(); {
if (row.SourceType == SourceType.DirectLink)
continue;
foreach (var action in actions)
{
if (action.SourceType != SourceType.DirectLink)
{
try try
{ {
Task.Run(async () => row.SourceUrl = await factory.ResolveSourceUrl(row.Action);
{
action.SourceUrl = await factory.ResolveSourceUrl(action);
}).Wait();
} }
catch (Exception) catch (Exception)
{ {
// Fail silently // Fail silently
} }
api.UpdateItem(action);
} }
} }
gridView?.EndUpdate(); public static void ClearDirectLinks(params MainWindowGridRow[] rows)
rwb?.StopWaiting();
}
public static void ClearDirectLinks(IMainApi api, params InstallAction[] actions)
{ {
var mainForm = api.MainWindow as MainForm; foreach (var row in rows)
var gridView = mainForm?.Controls.Find("radGridView_Actions", true).FirstOrDefault() as RadGridView;
var rwb = mainForm?.Controls.Find("radWaitingBar_Actions", true).FirstOrDefault() as RadWaitingBar;
rwb?.StartWaiting();
gridView?.BeginUpdate();
foreach (var action in actions)
{ {
if (action.SourceType != SourceType.DirectLink) if (row.SourceType != SourceType.DirectLink)
{ row.SourceUrl = null;
action.SourceUrl = null;
api.UpdateItem(action);
} }
} }
gridView?.EndUpdate();
rwb?.StopWaiting();
}
public static string GenerateChangelog(InstallInfos installInfos, UpdateInfo updateInfos) public static string GenerateChangelog(InstallInfos installInfos, UpdateInfo updateInfos)
{ {
var log = new StringBuilder(); var log = new StringBuilder();
@@ -250,7 +199,7 @@ internal static class SharedFunctions
return sb.ToString().TrimEnd(); return sb.ToString().TrimEnd();
} }
public static ExcelPackage? GenerateModlistAsExcel(InstallInfos installInfos) public static ExcelPackage GenerateModlistAsExcel(InstallInfos installInfos)
{ {
var pkg = new ExcelPackage(); var pkg = new ExcelPackage();
var ws = pkg.Workbook.Worksheets.Add(string.Format(GeneralLangRes.ModlistForVersionX, installInfos.Version)); var ws = pkg.Workbook.Worksheets.Add(string.Format(GeneralLangRes.ModlistForVersionX, installInfos.Version));
@@ -301,7 +250,7 @@ internal static class SharedFunctions
ws.Column(cc++).Width = 20; ws.Column(cc++).Width = 20;
ws.Column(cc++).Width = 30; ws.Column(cc++).Width = 30;
var tableDef = ws.Tables.Add(ws.Cells[1, 1, cr - 1, cc - 1], "Table"); var tableDef = ws.Tables.Add(ws.Cells[1, 1, cr - 1, cc - 1], "Table");
tableDef.TableStyle = OfficeOpenXml.Table.TableStyles.Medium16; tableDef.TableStyle = TableStyles.Medium16;
tableDef.ShowHeader = true; tableDef.ShowHeader = true;
return pkg; return pkg;

View File

@@ -1,8 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -12,17 +12,15 @@ internal class CheckAllActionsHealthyFeature : PluginFunction, IPluginFeaturePro
public CheckAllActionsHealthyFeature() : base(FeatureTypes.Tools, "origin.checkallactionshearlthy", FeatureNamesLangRes.CheckAllActionsHealthy) public CheckAllActionsHealthyFeature() : base(FeatureTypes.Tools, "origin.checkallactionshearlthy", FeatureNamesLangRes.CheckAllActionsHealthy)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.heart_with_pulse, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.heart_with_pulse, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.CurrentGridRows is null)
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView)
return null; return null;
SharedFunctions.CheckActionHealthy(p.Api, [.. gridView.Rows]); Task.Run(() => SharedFunctions.CheckActionHealthy(p.Api, [.. p.Api.Model.CurrentGridRows])).Wait();
return null; return null;
} }

View File

@@ -1,5 +1,7 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui.Models;
using Pilz.Features; using Pilz.Features;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -10,15 +12,15 @@ internal class ClearDirectLinksFeature : PluginFunction, IPluginFeatureProvider<
public ClearDirectLinksFeature() : base(FeatureTypes.Tools, "origin.cleardirectlinks", FeatureNamesLangRes.ClearDirectLinksFeature) public ClearDirectLinksFeature() : base(FeatureTypes.Tools, "origin.cleardirectlinks", FeatureNamesLangRes.ClearDirectLinksFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentGridRows is null)
return null; return null;
SharedFunctions.ClearDirectLinks(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]); SharedFunctions.ClearDirectLinks([.. p.Api.Model.CurrentGridRows]);
return null; return null;
} }

View File

@@ -1,7 +1,11 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui.Models;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -11,20 +15,23 @@ internal class GenerateChangelogFeature : PluginFunction, IPluginFeatureProvider
public GenerateChangelogFeature() : base(FeatureTypes.Tools, "origin.genchangelog", FeatureNamesLangRes.GenerateChangelogFeature) public GenerateChangelogFeature() : base(FeatureTypes.Tools, "origin.genchangelog", FeatureNamesLangRes.GenerateChangelogFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.time_machine, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.time_machine, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurActionSet is not UpdateInfo updateInfos) if (@params is not MainApiParameters p
|| p.Api.Model.CurrentWorkspace?.InstallInfos is null
|| p.Api.Model.SelectedTreeNode is not ActionSetTreeNode node
|| node.Infos is not UpdateInfo updateInfo)
return null; return null;
var changelog = SharedFunctions.GenerateChangelog(p.Api.CurWorkspace.InstallInfos, updateInfos); var changelog = SharedFunctions.GenerateChangelog(p.Api.Model.CurrentWorkspace.InstallInfos, updateInfo);
if (!string.IsNullOrWhiteSpace(changelog)) if (string.IsNullOrWhiteSpace(changelog))
{ return null;
Clipboard.SetText(changelog);
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ChangelogCopiedToClipboard, MsgBoxLangRes.ChangelogCopiedToClipboard_Title, MessageBoxButtons.OK, RadMessageIcon.Info); p.Api.MainWindow.Clipboard?.SetTextAsync(changelog);
} MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.ChangelogCopiedToClipboard_Title, MsgBoxLangRes.ChangelogCopiedToClipboard, ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info).ShowAsPopupAsync(p.Api.MainWindow);
return null; return null;
} }

View File

@@ -1,8 +1,13 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using Avalonia.Controls;
using Avalonia.Platform.Storage;
using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Utils;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls; using Pilz.UI.Symbols;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class GenerateModlistAsExcelFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsExcelFeature> internal class GenerateModlistAsExcelFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsExcelFeature>
@@ -11,28 +16,28 @@ internal class GenerateModlistAsExcelFeature : PluginFunction, IPluginFeaturePro
public GenerateModlistAsExcelFeature() : base(FeatureTypes.Tools, "origin.genmodlist.xlsx", FeatureNamesLangRes.GenerateModlistAsExcelFeature) public GenerateModlistAsExcelFeature() : base(FeatureTypes.Tools, "origin.genmodlist.xlsx", FeatureNamesLangRes.GenerateModlistAsExcelFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.list_view, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.list_view, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentWorkspace?.InstallInfos is null)
return null; return null;
using var pkg = SharedFunctions.GenerateModlistAsExcel(p.Api.CurWorkspace.InstallInfos); // Generate excel
if (pkg is null) using var pkg = SharedFunctions.GenerateModlistAsExcel(p.Api.Model.CurrentWorkspace.InstallInfos);
return null;
using var sfd = new RadSaveFileDialog // Ask for save
var file = Task.Run(() => TopLevel.GetTopLevel(p.Api.MainWindow)!.StorageProvider.SaveFilePickerAsync(new()
{ {
Filter = "*.xlsx|*.xlsx|*|*" FileTypeChoices = [MyFilePickerFileTypes.Excel]
}; })).Result;
if (file is null)
return null;
if (sfd.ShowDialog(p.Api.MainWindow) == DialogResult.OK) // Save file
{ pkg.SaveAs(file.Path.AbsolutePath);
pkg.SaveAs(sfd.FileName); MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.ModlistGenerated_Title, MsgBoxLangRes.ModlistGenerated, ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info).ShowAsPopupAsync(p.Api.MainWindow);
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ModlistGenerated, MsgBoxLangRes.ModlistGenerated_Title, MessageBoxButtons.OK, RadMessageIcon.Info);
}
return null; return null;
} }

View File

@@ -1,26 +1,30 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class GenerateModlistAsMarkdownFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsMarkdownFeature> internal class GenerateModlistAsMarkdownFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsMarkdownFeature>
{ {
public static GenerateModlistAsMarkdownFeature Instance { get; } = new(); public static GenerateModlistAsMarkdownFeature Instance { get; } = new();
public GenerateModlistAsMarkdownFeature() : base(FeatureTypes.Tools, "origin.genmodlist.md", FeatureNamesLangRes.GenerateModlistAsMarkdownFeature) public GenerateModlistAsMarkdownFeature() : base(FeatureTypes.Tools, "origin.genmodlist.md", FeatureNamesLangRes.GenerateModlistAsMarkdownFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.list_view, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.list_view, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentWorkspace?.InstallInfos is null)
return null; return null;
Clipboard.SetText(SharedFunctions.GenerateModlistAsMarkdown(p.Api.CurWorkspace.InstallInfos)); p.Api.MainWindow.Clipboard?.SetTextAsync(SharedFunctions.GenerateModlistAsMarkdown(p.Api.Model.CurrentWorkspace.InstallInfos));
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ModlistCopiedToClipboard, MsgBoxLangRes.ModlistCopiedToClipboard_Title, MessageBoxButtons.OK, RadMessageIcon.Info); MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.ModlistCopiedToClipboard_Title, MsgBoxLangRes.ModlistCopiedToClipboard, ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info).ShowAsPopupAsync(p.Api.MainWindow);
return null; return null;
} }

View File

@@ -1,6 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -10,15 +12,15 @@ internal class UpdateDirectLinksFeature : PluginFunction, IPluginFeatureProvider
public UpdateDirectLinksFeature() : base(FeatureTypes.Tools, "origin.updatedirectlinks", FeatureNamesLangRes.UpdateDirectLinksFeature) public UpdateDirectLinksFeature() : base(FeatureTypes.Tools, "origin.updatedirectlinks", FeatureNamesLangRes.UpdateDirectLinksFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.renew, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.renew, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentGridRows is null)
return null; return null;
SharedFunctions.FindNewDirectLinks(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]); Task.Run(() => SharedFunctions.FindNewDirectLinks([.. p.Api.Model.CurrentGridRows])).Wait();
return null; return null;
} }

View File

@@ -1,4 +1,5 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
@@ -11,15 +12,15 @@ internal class UpdatesCollectorFeature : PluginFunction, IPluginFeatureProvider<
public UpdatesCollectorFeature() : base(FeatureTypes.Tools, "origin.updatescollector", FeatureNamesLangRes.UpdatesCollectorFeature) public UpdatesCollectorFeature() : base(FeatureTypes.Tools, "origin.updatescollector", FeatureNamesLangRes.UpdatesCollectorFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.search, SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.search, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentWorkspace?.InstallInfos is null)
return null; return null;
SharedFunctions.CollectUpdates(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]); Task.Run(() => SharedFunctions.CollectUpdates(p.Api, [.. p.Api.Model.CurrentWorkspace.InstallInfos.Actions])).Wait();
return null; return null;
} }

View File

@@ -12,6 +12,7 @@ public partial class GitLabRepoWorkspaceConfigEditorView : AvaloniaFlyoutBase
public GitLabRepoWorkspaceConfigEditorView(GitLabRepoWorkspaceConfig settings) public GitLabRepoWorkspaceConfigEditorView(GitLabRepoWorkspaceConfig settings)
{ {
Settings = settings; Settings = settings;
DataContext = settings;
InitializeComponent(); InitializeComponent();
} }
} }

View File

@@ -3,17 +3,15 @@ using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.AvaloniaUI.Dialogs; using Pilz.UI.AvaloniaUI.Dialogs;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo; namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspaceFeature : WorkspaceFeature, IPluginFeatureProvider<GitLabRepoWorkspaceFeature> internal class GitLabRepoWorkspaceFeature() : WorkspaceFeature("origin.gitlab", FeatureNamesLangRes.GitLabWorkspace), IPluginFeatureProvider<GitLabRepoWorkspaceFeature>
{ {
public static GitLabRepoWorkspaceFeature Instance { get; } = new(); public static GitLabRepoWorkspaceFeature Instance { get; } = new();
public GitLabRepoWorkspaceFeature() : base("origin.gitlab", FeatureNamesLangRes.GitLabWorkspace) public override object? Icon => AppGlobals.Symbols.GetImage(AppSymbols.gitlab, SymbolSize.Small);
{
Icon = AppGlobals.Symbols.GetImageSource(AppSymbols.gitlab);
}
protected override async Task OnConfigure(WorkspaceContext context) protected override async Task OnConfigure(WorkspaceContext context)
{ {

View File

@@ -1,3 +1,4 @@
<Weavers> <?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<PropertyChanged /> <PropertyChanged />
</Weavers> </Weavers>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="TriggerDependentProperties" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the Dependent properties feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EnableIsChangedProperty" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the IsChanged property feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EventInvokerNames" type="xs:string">
<xs:annotation>
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEquality" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="SuppressWarnings" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to turn off build warnings from this weaver.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="SuppressOnPropertyNameChangedWarning" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to turn off build warnings about mismatched On_PropertyName_Changed methods.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -14,7 +14,7 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class GeneralLangRes { public class GeneralLangRes {
private static System.Resources.ResourceManager resourceMan; private static System.Resources.ResourceManager resourceMan;
@@ -25,7 +25,7 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Resources.ResourceManager ResourceManager { public static System.Resources.ResourceManager ResourceManager {
get { get {
if (object.Equals(null, resourceMan)) { if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.GeneralLangRes", typeof(GeneralLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.GeneralLangRes", typeof(GeneralLangRes).Assembly);
@@ -36,7 +36,7 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Globalization.CultureInfo Culture { public static System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@@ -45,55 +45,55 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
internal static string Node_Install { public static string Node_Install {
get { get {
return ResourceManager.GetString("Node_Install", resourceCulture); return ResourceManager.GetString("Node_Install", resourceCulture);
} }
} }
internal static string Node_Update { public static string Node_Update {
get { get {
return ResourceManager.GetString("Node_Update", resourceCulture); return ResourceManager.GetString("Node_Update", resourceCulture);
} }
} }
internal static string ModlistForVersionX { public static string ModlistForVersionX {
get { get {
return ResourceManager.GetString("ModlistForVersionX", resourceCulture); return ResourceManager.GetString("ModlistForVersionX", resourceCulture);
} }
} }
internal static string GitLabInstanceUrl { public static string GitLabInstanceUrl {
get { get {
return ResourceManager.GetString("GitLabInstanceUrl", resourceCulture); return ResourceManager.GetString("GitLabInstanceUrl", resourceCulture);
} }
} }
internal static string GitLabApiToken { public static string GitLabApiToken {
get { get {
return ResourceManager.GetString("GitLabApiToken", resourceCulture); return ResourceManager.GetString("GitLabApiToken", resourceCulture);
} }
} }
internal static string RepositoryId { public static string RepositoryId {
get { get {
return ResourceManager.GetString("RepositoryId", resourceCulture); return ResourceManager.GetString("RepositoryId", resourceCulture);
} }
} }
internal static string FileLocationOfInstallJson { public static string FileLocationOfInstallJson {
get { get {
return ResourceManager.GetString("FileLocationOfInstallJson", resourceCulture); return ResourceManager.GetString("FileLocationOfInstallJson", resourceCulture);
} }
} }
internal static string FileLocationOfUpdateJson { public static string FileLocationOfUpdateJson {
get { get {
return ResourceManager.GetString("FileLocationOfUpdateJson", resourceCulture); return ResourceManager.GetString("FileLocationOfUpdateJson", resourceCulture);
} }
} }
internal static string ModpackConfigUrl { public static string ModpackConfigUrl {
get { get {
return ResourceManager.GetString("ModpackConfigUrl", resourceCulture); return ResourceManager.GetString("ModpackConfigUrl", resourceCulture);
} }

View File

@@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<ApplicationIcon>Assets\app.ico</ApplicationIcon> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<AssemblyName>MinecraftModpackUpdateManager</AssemblyName>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
@@ -10,10 +11,6 @@
<ItemGroup> <ItemGroup>
<Compile Include="..\Version.cs" /> <Compile Include="..\Version.cs" />
<Compile Update="App.axaml.cs">
<DependentUpon>App.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -42,7 +39,7 @@
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets> <IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets> <PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" /> <PackageReference Include="PropertyChanged.Fody" Version="4.1.0" PrivateAssets='All' />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -81,23 +78,23 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Update="LangRes\ActionsListLangRes.resx"> <EmbeddedResource Update="LangRes\ActionsListLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>ActionsListLangRes.Designer.cs</LastGenOutput> <LastGenOutput>ActionsListLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\FeatureNamesLangRes.resx"> <EmbeddedResource Update="LangRes\FeatureNamesLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>FeatureNamesLangRes.Designer.cs</LastGenOutput> <LastGenOutput>FeatureNamesLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\GeneralLangRes.resx"> <EmbeddedResource Update="LangRes\GeneralLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>GeneralLangRes.Designer.cs</LastGenOutput> <LastGenOutput>GeneralLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\MsgBoxLangRes.resx"> <EmbeddedResource Update="LangRes\MsgBoxLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput> <LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\TitlesLangRes.resx"> <EmbeddedResource Update="LangRes\TitlesLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>TitlesLangRes.Designer.cs</LastGenOutput> <LastGenOutput>TitlesLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>

View File

@@ -1,13 +1,13 @@
using Avalonia; using Avalonia;
using Castle.Core.Logging;
using OfficeOpenXml; using OfficeOpenXml;
using Pilz.Configuration; using Pilz.Configuration;
using Pilz.Features;
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager;
public static class Program public static class Program
{ {
private static readonly SettingsManager settingsManager; internal static readonly SettingsManager settingsManager;
public static ISettings Settings => settingsManager.Instance; public static ISettings Settings => settingsManager.Instance;
@@ -15,6 +15,7 @@ public static class Program
{ {
ExcelPackage.License.SetNonCommercialPersonal("Pilzinsel64"); ExcelPackage.License.SetNonCommercialPersonal("Pilzinsel64");
settingsManager = new(GetSettingsPath(), true); settingsManager = new(GetSettingsPath(), true);
settingsManager.Instance.Logger = new ConsoleLogger("Settings");
} }
/// <summary> /// <summary>
@@ -25,8 +26,6 @@ public static class Program
{ {
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
AppGlobals.Initialize();
PluginFeatureController.Instance.RegisterAllOwn();
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
} }

View File

@@ -1,405 +0,0 @@
namespace ModpackUpdater.Apps.Manager.Ui;
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
var tableViewDefinition2 = new Telerik.WinControls.UI.TableViewDefinition();
var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer();
splitPanel1 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel2 = new TableLayoutPanel();
radTreeView_Sets = new Telerik.WinControls.UI.RadTreeView();
splitPanel2 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel_ActionSet = new TableLayoutPanel();
radGridView_Actions = new Telerik.WinControls.UI.RadGridView();
tableLayoutPanel_ActionSetInfo = new TableLayoutPanel();
radLabel1 = new Telerik.WinControls.UI.RadLabel();
radTextBoxControl_Version = new Telerik.WinControls.UI.RadTextBoxControl();
radCheckBox_IsPublic = new Telerik.WinControls.UI.RadCheckBox();
radMenuItem_Workspace = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_WorkspacePreferences = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_SaveWorkspace = new Telerik.WinControls.UI.RadMenuItem();
radMenuSeparatorItem1 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
radMenuHeaderItem_NewWorkspace = new Telerik.WinControls.UI.RadMenuHeaderItem();
radMenuSeparatorItem3 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
radMenuHeaderItem_RecentWorkspaces = new Telerik.WinControls.UI.RadMenuHeaderItem();
radMenuItem_Tools = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_Updates = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_CreateUpdate = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_RemoveUpdate = new Telerik.WinControls.UI.RadMenuItem();
radWaitingBar_Updates = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement();
radWaitingBar_Actions = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement2 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement();
radMenu1 = new Telerik.WinControls.UI.RadMenu();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit();
radSplitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit();
splitPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radTreeView_Sets).BeginInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).BeginInit();
splitPanel2.SuspendLayout();
tableLayoutPanel_ActionSet.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).BeginInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).BeginInit();
tableLayoutPanel_ActionSetInfo.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_Version).BeginInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).BeginInit();
((System.ComponentModel.ISupportInitialize)radMenu1).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout();
//
// radSplitContainer1
//
radSplitContainer1.Controls.Add(splitPanel1);
radSplitContainer1.Controls.Add(splitPanel2);
radSplitContainer1.Dock = DockStyle.Fill;
radSplitContainer1.Location = new Point(0, 28);
radSplitContainer1.Name = "radSplitContainer1";
radSplitContainer1.Size = new Size(800, 422);
radSplitContainer1.TabIndex = 0;
radSplitContainer1.TabStop = false;
//
// splitPanel1
//
splitPanel1.Controls.Add(tableLayoutPanel2);
splitPanel1.Location = new Point(0, 0);
splitPanel1.Name = "splitPanel1";
splitPanel1.Size = new Size(232, 422);
splitPanel1.SizeInfo.AbsoluteSize = new Size(232, 200);
splitPanel1.SizeInfo.AutoSizeScale = new SizeF(-0.190954775F, 0F);
splitPanel1.SizeInfo.SizeMode = Telerik.WinControls.UI.Docking.SplitPanelSizeMode.Absolute;
splitPanel1.SizeInfo.SplitterCorrection = new Size(-120, 0);
splitPanel1.TabIndex = 0;
splitPanel1.TabStop = false;
//
// tableLayoutPanel2
//
tableLayoutPanel2.ColumnCount = 1;
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel2.Controls.Add(radTreeView_Sets, 0, 0);
tableLayoutPanel2.Dock = DockStyle.Fill;
tableLayoutPanel2.Location = new Point(0, 0);
tableLayoutPanel2.Name = "tableLayoutPanel2";
tableLayoutPanel2.RowCount = 1;
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
tableLayoutPanel2.Size = new Size(232, 422);
tableLayoutPanel2.TabIndex = 1;
//
// radTreeView_Sets
//
radTreeView_Sets.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radTreeView_Sets.ItemHeight = 24;
radTreeView_Sets.LineColor = Color.FromArgb(152, 152, 152);
radTreeView_Sets.LineStyle = Telerik.WinControls.UI.TreeLineStyle.Solid;
radTreeView_Sets.Location = new Point(3, 3);
radTreeView_Sets.Name = "radTreeView_Sets";
radTreeView_Sets.Size = new Size(226, 416);
radTreeView_Sets.TabIndex = 0;
radTreeView_Sets.SelectedNodeChanged += RadTreeView_Sets_SelectedNodeChanged;
//
// splitPanel2
//
splitPanel2.Controls.Add(tableLayoutPanel_ActionSet);
splitPanel2.Location = new Point(236, 0);
splitPanel2.Name = "splitPanel2";
splitPanel2.Size = new Size(564, 422);
splitPanel2.SizeInfo.AutoSizeScale = new SizeF(-0.0600000024F, 0F);
splitPanel2.SizeInfo.SplitterCorrection = new Size(120, 0);
splitPanel2.TabIndex = 1;
splitPanel2.TabStop = false;
//
// tableLayoutPanel_ActionSet
//
tableLayoutPanel_ActionSet.ColumnCount = 1;
tableLayoutPanel_ActionSet.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSet.Controls.Add(radGridView_Actions, 0, 1);
tableLayoutPanel_ActionSet.Controls.Add(tableLayoutPanel_ActionSetInfo, 0, 0);
tableLayoutPanel_ActionSet.Dock = DockStyle.Fill;
tableLayoutPanel_ActionSet.Location = new Point(0, 0);
tableLayoutPanel_ActionSet.Name = "tableLayoutPanel_ActionSet";
tableLayoutPanel_ActionSet.RowCount = 2;
tableLayoutPanel_ActionSet.RowStyles.Add(new RowStyle());
tableLayoutPanel_ActionSet.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSet.Size = new Size(564, 422);
tableLayoutPanel_ActionSet.TabIndex = 0;
//
// radGridView_Actions
//
radGridView_Actions.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radGridView_Actions.Location = new Point(3, 33);
//
//
//
radGridView_Actions.MasterTemplate.AddNewRowPosition = Telerik.WinControls.UI.SystemRowPosition.Bottom;
radGridView_Actions.MasterTemplate.AllowColumnChooser = false;
radGridView_Actions.MasterTemplate.AllowDragToGroup = false;
radGridView_Actions.MasterTemplate.AllowRowResize = false;
radGridView_Actions.MasterTemplate.AllowSearchRow = true;
radGridView_Actions.MasterTemplate.EnableGrouping = false;
radGridView_Actions.MasterTemplate.ViewDefinition = tableViewDefinition2;
radGridView_Actions.Name = "radGridView_Actions";
radGridView_Actions.Size = new Size(558, 386);
radGridView_Actions.TabIndex = 0;
radGridView_Actions.CellFormatting += RadGridView_Actions_CellFormatting;
radGridView_Actions.UserAddedRow += RadGridView_Actions_UserAddedRow;
radGridView_Actions.UserDeletingRow += RadGridView_Actions_UserDeletingRow;
radGridView_Actions.CellValueChanged += RadGridView_Actions_CellValueChanged;
radGridView_Actions.ContextMenuOpening += RadGridView_Actions_ContextMenuOpening;
//
// tableLayoutPanel_ActionSetInfo
//
tableLayoutPanel_ActionSetInfo.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel_ActionSetInfo.AutoSize = true;
tableLayoutPanel_ActionSetInfo.ColumnCount = 3;
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.Controls.Add(radLabel1, 0, 0);
tableLayoutPanel_ActionSetInfo.Controls.Add(radTextBoxControl_Version, 1, 0);
tableLayoutPanel_ActionSetInfo.Controls.Add(radCheckBox_IsPublic, 2, 0);
tableLayoutPanel_ActionSetInfo.Location = new Point(0, 0);
tableLayoutPanel_ActionSetInfo.Margin = new Padding(0);
tableLayoutPanel_ActionSetInfo.Name = "tableLayoutPanel_ActionSetInfo";
tableLayoutPanel_ActionSetInfo.RowCount = 1;
tableLayoutPanel_ActionSetInfo.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSetInfo.Size = new Size(564, 30);
tableLayoutPanel_ActionSetInfo.TabIndex = 1;
//
// radLabel1
//
radLabel1.Anchor = AnchorStyles.Left;
radLabel1.Location = new Point(3, 4);
radLabel1.Name = "radLabel1";
radLabel1.Size = new Size(58, 22);
radLabel1.TabIndex = 0;
radLabel1.Text = "Version:";
//
// radTextBoxControl_Version
//
radTextBoxControl_Version.Anchor = AnchorStyles.Left;
radTextBoxControl_Version.AutoSize = true;
radTextBoxControl_Version.Location = new Point(67, 3);
radTextBoxControl_Version.Name = "radTextBoxControl_Version";
radTextBoxControl_Version.NullText = "e.g. 1.2.5.0";
radTextBoxControl_Version.Size = new Size(150, 24);
radTextBoxControl_Version.TabIndex = 1;
radTextBoxControl_Version.TextChanged += RadTextBoxControl1_TextChanged;
//
// radCheckBox_IsPublic
//
radCheckBox_IsPublic.Anchor = AnchorStyles.Left;
radCheckBox_IsPublic.Location = new Point(223, 5);
radCheckBox_IsPublic.Name = "radCheckBox_IsPublic";
radCheckBox_IsPublic.Size = new Size(76, 20);
radCheckBox_IsPublic.TabIndex = 2;
radCheckBox_IsPublic.Text = "Is public";
radCheckBox_IsPublic.ToggleStateChanged += RadCheckBox1_ToggleStateChanged;
//
// radMenuItem_Workspace
//
radMenuItem_Workspace.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_WorkspacePreferences, radMenuItem_SaveWorkspace, radMenuSeparatorItem1, radMenuHeaderItem_NewWorkspace, radMenuSeparatorItem3, radMenuHeaderItem_RecentWorkspaces });
radMenuItem_Workspace.Name = "radMenuItem_Workspace";
radMenuItem_Workspace.Text = "Workspace";
//
// radMenuItem_WorkspacePreferences
//
radMenuItem_WorkspacePreferences.Name = "radMenuItem_WorkspacePreferences";
radMenuItem_WorkspacePreferences.Text = "Preferences";
radMenuItem_WorkspacePreferences.Click += RadMenuItem_WorkspacePreferences_Click;
//
// radMenuItem_SaveWorkspace
//
radMenuItem_SaveWorkspace.Name = "radMenuItem_SaveWorkspace";
radMenuItem_SaveWorkspace.Text = "Save";
radMenuItem_SaveWorkspace.Click += RadMenuItem_SaveWorkspace_Click;
//
// radMenuSeparatorItem1
//
radMenuSeparatorItem1.Name = "radMenuSeparatorItem1";
radMenuSeparatorItem1.Text = "radMenuSeparatorItem1";
radMenuSeparatorItem1.TextAlignment = ContentAlignment.MiddleLeft;
//
// radMenuHeaderItem_NewWorkspace
//
radMenuHeaderItem_NewWorkspace.Name = "radMenuHeaderItem_NewWorkspace";
radMenuHeaderItem_NewWorkspace.Text = "New workspace";
//
// radMenuSeparatorItem3
//
radMenuSeparatorItem3.Name = "radMenuSeparatorItem3";
radMenuSeparatorItem3.Text = "radMenuSeparatorItem3";
radMenuSeparatorItem3.TextAlignment = ContentAlignment.MiddleLeft;
//
// radMenuHeaderItem_RecentWorkspaces
//
radMenuHeaderItem_RecentWorkspaces.Name = "radMenuHeaderItem_RecentWorkspaces";
radMenuHeaderItem_RecentWorkspaces.Text = "Recent workspaces";
//
// radMenuItem_Tools
//
radMenuItem_Tools.Name = "radMenuItem_Tools";
radMenuItem_Tools.Text = "Tools";
//
// radMenuItem_Updates
//
radMenuItem_Updates.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_CreateUpdate, radMenuItem_RemoveUpdate });
radMenuItem_Updates.Name = "radMenuItem_Updates";
radMenuItem_Updates.Text = "Updates";
radMenuItem_Updates.DropDownOpening += RadMenuItem_Updates_DropDownOpening;
//
// radMenuItem_CreateUpdate
//
radMenuItem_CreateUpdate.Name = "radMenuItem_CreateUpdate";
radMenuItem_CreateUpdate.Text = "Create";
radMenuItem_CreateUpdate.Click += RadMenuItem_CreateUpdate_Click;
//
// radMenuItem_RemoveUpdate
//
radMenuItem_RemoveUpdate.Name = "radMenuItem_RemoveUpdate";
radMenuItem_RemoveUpdate.Text = "Remove";
radMenuItem_RemoveUpdate.Click += RadMenuItem_RemoveUpdate_Click;
//
// radWaitingBar_Updates
//
radWaitingBar_Updates.AssociatedControl = radTreeView_Sets;
radWaitingBar_Updates.Location = new Point(0, 78);
radWaitingBar_Updates.Name = "radWaitingBar_Updates";
radWaitingBar_Updates.Size = new Size(70, 70);
radWaitingBar_Updates.TabIndex = 2;
radWaitingBar_Updates.Text = "radWaitingBar1";
radWaitingBar_Updates.WaitingIndicators.Add(dotsRingWaitingBarIndicatorElement1);
radWaitingBar_Updates.WaitingIndicatorSize = new Size(100, 14);
radWaitingBar_Updates.WaitingSpeed = 50;
radWaitingBar_Updates.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsRing;
//
// dotsRingWaitingBarIndicatorElement1
//
dotsRingWaitingBarIndicatorElement1.Name = "dotsRingWaitingBarIndicatorElement1";
//
// radWaitingBar_Actions
//
radWaitingBar_Actions.AssociatedControl = radGridView_Actions;
radWaitingBar_Actions.ForeColor = Color.Black;
radWaitingBar_Actions.Location = new Point(0, 145);
radWaitingBar_Actions.Name = "radWaitingBar_Actions";
radWaitingBar_Actions.Size = new Size(70, 70);
radWaitingBar_Actions.TabIndex = 3;
radWaitingBar_Actions.WaitingIndicators.Add(dotsRingWaitingBarIndicatorElement2);
radWaitingBar_Actions.WaitingIndicatorSize = new Size(100, 14);
radWaitingBar_Actions.WaitingSpeed = 50;
radWaitingBar_Actions.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsRing;
//
// dotsRingWaitingBarIndicatorElement2
//
dotsRingWaitingBarIndicatorElement2.Name = "dotsRingWaitingBarIndicatorElement2";
//
// radMenu1
//
radMenu1.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_Workspace, radMenuItem_Updates, radMenuItem_Tools });
radMenu1.Location = new Point(0, 0);
radMenu1.Name = "radMenu1";
radMenu1.Size = new Size(800, 28);
radMenu1.TabIndex = 1;
//
// MainForm
//
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(radWaitingBar_Actions);
Controls.Add(radWaitingBar_Updates);
Controls.Add(radSplitContainer1);
Controls.Add(radMenu1);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "MainForm";
StartPosition = FormStartPosition.CenterScreen;
Text = "Minecraft Modpack Updates Manager";
WindowState = FormWindowState.Maximized;
Load += Form1_Load;
((System.ComponentModel.ISupportInitialize)radSplitContainer1).EndInit();
radSplitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit();
splitPanel1.ResumeLayout(false);
tableLayoutPanel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radTreeView_Sets).EndInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).EndInit();
splitPanel2.ResumeLayout(false);
tableLayoutPanel_ActionSet.ResumeLayout(false);
tableLayoutPanel_ActionSet.PerformLayout();
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).EndInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).EndInit();
tableLayoutPanel_ActionSetInfo.ResumeLayout(false);
tableLayoutPanel_ActionSetInfo.PerformLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_Version).EndInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).EndInit();
((System.ComponentModel.ISupportInitialize)radMenu1).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Telerik.WinControls.UI.RadSplitContainer radSplitContainer1;
private Telerik.WinControls.UI.SplitPanel splitPanel1;
private Telerik.WinControls.UI.SplitPanel splitPanel2;
private Telerik.WinControls.UI.RadMenu radMenu1;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Workspace;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_WorkspacePreferences;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Tools;
private TableLayoutPanel tableLayoutPanel2;
private TableLayoutPanel tableLayoutPanel_ActionSet;
private Telerik.WinControls.UI.RadGridView radGridView_Actions;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem1;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_SaveWorkspace;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Updates;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement1;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Actions;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement2;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Updates;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_CreateUpdate;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_RemoveUpdate;
private Telerik.WinControls.UI.RadMenuHeaderItem radMenuHeaderItem_NewWorkspace;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem3;
private Telerik.WinControls.UI.RadMenuHeaderItem radMenuHeaderItem_RecentWorkspaces;
private Telerik.WinControls.UI.RadTreeView radTreeView_Sets;
private TableLayoutPanel tableLayoutPanel_ActionSetInfo;
private Telerik.WinControls.UI.RadLabel radLabel1;
private Telerik.WinControls.UI.RadTextBoxControl radTextBoxControl_Version;
private Telerik.WinControls.UI.RadCheckBox radCheckBox_IsPublic;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -11,10 +11,12 @@
x:Class="ModpackUpdater.Apps.Manager.Ui.MainWindow" x:Class="ModpackUpdater.Apps.Manager.Ui.MainWindow"
x:DataType="vm:MainWindowViewModel" x:DataType="vm:MainWindowViewModel"
Title="Minecraft Modpack Manager" Title="Minecraft Modpack Manager"
Padding="3"> Padding="3"
Loaded="Window_OnLoaded">
<Grid <Grid
RowDefinitions="Auto,*"> RowDefinitions="Auto,*">
<Menu> <Menu>
<Menu.Items> <Menu.Items>
<MenuItem x:Name="MenuItemWorkspace" Header="Workspace"> <MenuItem x:Name="MenuItemWorkspace" Header="Workspace">
@@ -29,32 +31,94 @@
</MenuItem.Items> </MenuItem.Items>
</MenuItem> </MenuItem>
<MenuItem x:Name="MenuItemUpdates" Header="Updates">
<MenuItem.Items>
<MenuItem x:Name="MenuItemCreateUpdate" Header="Create update"/>
<MenuItem x:Name="MenuItemRemoveUpdate" Header="Remove update"/>
</MenuItem.Items>
</MenuItem>
<MenuItem x:Name="MenuItemTools" Header="Tools"/> <MenuItem x:Name="MenuItemTools" Header="Tools"/>
</Menu.Items> </Menu.Items>
</Menu> </Menu>
<Grid <Grid
x:Name="GridMain"
Grid.Row="1" Grid.Row="1"
ColumnDefinitions="Auto,*,*" ColumnDefinitions="300,*,300"
Margin="3"> Margin="3">
<TreeView <StackPanel
Grid.Column="0" Grid.Column="0"
Margin="3"/> Margin="3"
Spacing="6">
<Menu>
<Menu.Items>
<MenuItem x:Name="MenuItemCreateUpdate" Header="Create" Click="MenuItemCreateUpdate_OnClick"/>
<MenuItem x:Name="MenuItemEditUpdate" Header="Edit" Click="MenuItemEditUpdate_OnClick"/>
<MenuItem x:Name="MenuItemRemoveUpdate" Header="Remove" Click="MenuItemRemoveUpdate_OnClick"/>
</Menu.Items>
</Menu>
<ScrollViewer
VerticalScrollBarVisibility="Auto">
<StackPanel>
<TreeView
ItemsSource="{Binding CurrentTreeNodes}"
SelectedItem="{Binding SelectedTreeNode}">
<TreeView.ItemTemplate>
<TreeDataTemplate
ItemsSource="{Binding Nodes}">
<StackPanel Orientation="Horizontal" Spacing="6">
<Image Source="{Binding Image}" Width="16"/>
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</ScrollViewer>
</StackPanel>
<StackPanel
Grid.Column="1"
Margin="3"
Spacing="6">
<ContentControl
Content="{Binding SelectedTreeNode}">
<ContentControl.DataTemplates>
<DataTemplate
DataType="vm:ActionSetTreeNode">
<StackPanel
Orientation="Horizontal"
Spacing="6">
<Menu>
<Menu.Items>
<MenuItem x:Name="MenuItemAddAction" Header="Create" Click="MenuItemAddAction_OnClick"/>
<MenuItem x:Name="MenuItemRemoveAction" Header="Remove" Click="MenuItemRemoveAction_OnClick"/>
</Menu.Items>
</Menu>
<TextBox
Text="{Binding Version}"/>
<CheckBox
Content="Public"
IsChecked="{Binding IsPublic}"/>
</StackPanel>
</DataTemplate>
<DataTemplate
DataType="vm:MainWindowTreeNode"/>
</ContentControl.DataTemplates>
</ContentControl>
<DataGrid <DataGrid
x:Name="DataGridActions" x:Name="DataGridActions"
Grid.Column="1" VerticalAlignment="Stretch"
Margin="3" ItemsSource="{Binding CurrentGridRows}"
ItemsSource="{Binding Actions}" SelectedItem="{Binding SelectedGridRow}">
SelectedItem="{Binding SelectedAction}">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
@@ -79,12 +143,13 @@
Binding="{Binding InheritedDestPath}"/> Binding="{Binding InheritedDestPath}"/>
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
</StackPanel>
<ScrollViewer <ScrollViewer
x:Name="ScrollViewerInstallAction" x:Name="ScrollViewerInstallAction"
Grid.Column="2" Grid.Column="2"
Margin="3" Margin="3"
DataContext="{Binding SelectedAction}" DataContext="{Binding SelectedGridRow}"
VerticalScrollBarVisibility="Auto"> VerticalScrollBarVisibility="Auto">
<StackPanel <StackPanel
@@ -111,10 +176,10 @@
<Label Content="Source type" Target="ComboBoxUpdateActionSourceType"/> <Label Content="Source type" Target="ComboBoxUpdateActionSourceType"/>
<ComboBox <ComboBox
x:Name="ComboBoxUpdateActionSourceType" x:Name="ComboBoxUpdateActionSourceType"
ItemsSource="{x:Static vm:InstallActionViewModel.UpdateActionTypes}" ItemsSource="{x:Static vm:MainWindowGridRow.UpdateActionTypes}"
DisplayMemberBinding="{Binding Value}" DisplayMemberBinding="{Binding Value}"
SelectedValueBinding="{Binding Key}" SelectedValueBinding="{Binding Key}"
SelectedValue="{Binding Type}"/> SelectedValue="{Binding UpdateType}"/>
<!-- Is Directory --> <!-- Is Directory -->
<CheckBox <CheckBox
@@ -149,7 +214,7 @@
<Label Content="Side" Target="ComboBoxInstallActionSide"/> <Label Content="Side" Target="ComboBoxInstallActionSide"/>
<ComboBox <ComboBox
x:Name="ComboBoxInstallActionSide" x:Name="ComboBoxInstallActionSide"
ItemsSource="{x:Static vm:InstallActionViewModel.Sides}" ItemsSource="{x:Static vm:MainWindowGridRow.Sides}"
DisplayMemberBinding="{Binding Value}" DisplayMemberBinding="{Binding Value}"
SelectedValueBinding="{Binding Key}" SelectedValueBinding="{Binding Key}"
SelectedValue="{Binding Side}"/> SelectedValue="{Binding Side}"/>
@@ -191,7 +256,7 @@
<Label Content="Source type" Target="CheckBoxInstallActionSourceType"/> <Label Content="Source type" Target="CheckBoxInstallActionSourceType"/>
<ComboBox <ComboBox
x:Name="CheckBoxInstallActionSourceType" x:Name="CheckBoxInstallActionSourceType"
ItemsSource="{x:Static vm:InstallActionViewModel.SourceTypes}" ItemsSource="{x:Static vm:MainWindowGridRow.SourceTypes}"
DisplayMemberBinding="{Binding Value}" DisplayMemberBinding="{Binding Value}"
SelectedValueBinding="{Binding Key}" SelectedValueBinding="{Binding Key}"
SelectedValue="{Binding SourceType}"/> SelectedValue="{Binding SourceType}"/>

View File

@@ -1,18 +1,152 @@
using System.Collections.ObjectModel;
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Interactivity;
using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.Settings;
using ModpackUpdater.Apps.Manager.Ui.Models; using ModpackUpdater.Apps.Manager.Ui.Models;
using Pilz.Features;
using Pilz.UI.AvaloniaUI.Features;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Ui; namespace ModpackUpdater.Apps.Manager.Ui;
public partial class MainWindow : Window public partial class MainWindow : Window, IMainApi
{ {
private MainWindowViewModel viewModel = new(); private WorkspaceFeature? wsFeature;
public MainWindowViewModel Model { get; } = new();
Window IMainApi.MainWindow => this;
public IMainApi MainApi => this;
public MainWindow() public MainWindow()
{ {
DataContext = viewModel; DataContext = Model;
InitializeComponent(); InitializeComponent();
MenuItemWorkspace.Icon = AppGlobals.Symbols.GetImage(AppSymbols.workspace, SymbolSize.Small);
MenuItemWorkspacePreferences.Icon = AppGlobals.Symbols.GetImage(AppSymbols.settings, SymbolSize.Small);
MenuItemSaveWorkspace.Icon = AppGlobals.Symbols.GetImage(AppSymbols.save, SymbolSize.Small);
MenuItemNewWorkspace.Icon = AppGlobals.Symbols.GetImage(AppSymbols.new_window, SymbolSize.Small);
MenuItemRecentWorkspaces.Icon = AppGlobals.Symbols.GetImage(AppSymbols.time_machine, SymbolSize.Small);
// MenuItemUpdates.Icon = AppGlobals.Symbols.GetImage(AppSymbols.update_done, SymbolSize.Small);
MenuItemCreateUpdate.Icon = AppGlobals.Symbols.GetImage(AppSymbols.add, SymbolSize.Small);
MenuItemRemoveUpdate.Icon = AppGlobals.Symbols.GetImage(AppSymbols.remove, SymbolSize.Small);
MenuItemTools.Icon = AppGlobals.Symbols.GetImage(AppSymbols.tools, SymbolSize.Small);
PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).InsertItemsTo(MenuItemNewWorkspace.Items,
customClickHandler: MenuItemNewWorkspaceItem_Click,
insertPrioSplitters: true);
PluginFeatureController.Instance.Functions.Get(FeatureTypes.Tools).InsertItemsTo(MenuItemTools.Items,
customClickHandler: MenuItemToolsItem_Click,
insertPrioSplitters: true);
}
private async Task LoadNewWorkspace(IWorkspace? workspace, WorkspaceFeature feature)
{
if (workspace is null)
return;
if (!await workspace.Load())
{
// Error
return;
}
if (workspace != Model.CurrentWorkspace)
{
wsFeature = feature;
Model.CurrentWorkspace = workspace;
}
AddToRecentFiles(workspace);
LoadRecentWorkspaces();
}
private void LoadRecentWorkspaces()
{
var settings = Program.Settings.Get<WorkspaceSettings>();
MenuItemRecentWorkspaces.Items.Clear();
settings.Workspaces.ForEach(config =>
{
if (PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).OfType<WorkspaceFeature>().FirstOrDefault(n => n.Identifier == config.ProviderId) is not WorkspaceFeature feature)
return;
var item = new MenuItem
{
Header = config.DisplayText,
Icon = feature.Icon,
DataContext = new MainWindowRecentFilesItem(config, feature),
};
item.Click += MenuItemRecentWorkspaceItem_Click;
MenuItemRecentWorkspaces.Items.Add(item);
});
}
private static void AddToRecentFiles(IWorkspace workspace)
{
var settings = Program.Settings.Get<WorkspaceSettings>();
settings.Workspaces.Remove(workspace.Config);
settings.Workspaces.Insert(0, workspace.Config);
while (settings.Workspaces.Count > 20)
settings.Workspaces.RemoveAt(20);
}
private void Window_OnLoaded(object? sender, RoutedEventArgs e)
{
LoadRecentWorkspaces();
}
private async void MenuItemNewWorkspaceItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is not MenuItem item || item.Tag is not WorkspaceFeature feature)
return;
var context = new WorkspaceContext(MainApi, null);
await feature.Configure(context);
if (context.Workspace != null)
await LoadNewWorkspace(context.Workspace, feature);
}
private async void MenuItemRecentWorkspaceItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is MenuItem item && item.DataContext is MainWindowRecentFilesItem tag && tag.Feature.CreateFromConfig(tag.Config) is IWorkspace workspace)
await LoadNewWorkspace(workspace, tag.Feature);
}
private void MenuItemToolsItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is MenuItem item && item.Tag is PluginFunction func)
func.Execute(new MainApiParameters(this));
}
private void MenuItemCreateUpdate_OnClick(object? sender, RoutedEventArgs e)
{
// ...
}
private void MenuItemRemoveUpdate_OnClick(object? sender, RoutedEventArgs e)
{
// ...
}
private void MenuItemEditUpdate_OnClick(object? sender, RoutedEventArgs e)
{
// ...
}
private void MenuItemAddAction_OnClick(object? sender, RoutedEventArgs e)
{
// ...
}
private void MenuItemRemoveAction_OnClick(object? sender, RoutedEventArgs e)
{
// ...
} }
} }

View File

@@ -1,176 +0,0 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ModpackUpdater.Apps.Manager.Ui.Models;
public class InstallActionViewModel(InstallAction action, IActionSet baseActions) : INotifyPropertyChanged
{
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Implementation of INotifyPropertyChanged
public static Dictionary<SourceType, string> SourceTypes { get; } = Enum.GetValues<SourceType>().ToDictionary(n => n, n => Enum.GetName(n)!);
public static Dictionary<Side, string> Sides { get; } = Enum.GetValues<Side>().ToDictionary(n => n, n => Enum.GetName(n)!);
public static Dictionary<UpdateActionType, string> UpdateActionTypes { get; } = Enum.GetValues<UpdateActionType>().ToDictionary(n => n, n => Enum.GetName(n)!);
public InstallAction Action => action;
private InstallAction? Base => action is UpdateAction ua ? baseActions.Actions.FirstOrDefault(n => n.Id == ua.InheritFrom) : null;
private InstallAction Inherited => Base ?? action;
public bool IsUpdate => action is UpdateAction;
public string InheritedId => action is UpdateAction ua && !string.IsNullOrWhiteSpace(ua.InheritFrom) ? ua.InheritFrom : action.Id;
public string InheritedSide => Sides[Inherited.Side];
public string InheritedUpdateType => action is UpdateAction ua ? UpdateActionTypes[ua.Type] : string.Empty;
public string InheritedSourceType => SourceTypes[Inherited.SourceType];
public string InheritedDestPath => Inherited.DestPath;
public string Id
{
get => action.Id;
set
{
action.Id = value;
OnPropertyChanged(nameof(InheritedId));
}
}
public string Name
{
get => action.Name;
set => action.Name = value;
}
public string Website
{
get => action.Website;
set => action.Website = value;
}
public bool IsZip
{
get => action.IsZip;
set => action.IsZip = value;
}
public string ZipPath
{
get => action.ZipPath;
set => action.ZipPath = value;
}
public string DestPath
{
get => action.DestPath;
set
{
action.DestPath = value;
OnPropertyChanged(nameof(InheritedDestPath));
}
}
public string SourceUrl
{
get => action.SourceUrl;
set => action.SourceUrl = value;
}
public SourceType SourceType
{
get => action.SourceType;
set
{
action.SourceType = value;
OnPropertyChanged(nameof(InheritedSourceType));
}
}
public string SourceOwner
{
get => action.SourceOwner;
set => action.SourceOwner = value;
}
public string SourceName
{
get => action.SourceName;
set => action.SourceName = value;
}
public string SourceRegex
{
get => action.SourceRegex;
set => action.SourceRegex = value;
}
public string SourceTag
{
get => action.SourceTag;
set => action.SourceTag = value;
}
public Side Side
{
get => action.Side;
set
{
action.Side = value;
OnPropertyChanged(nameof(InheritedSide));
}
}
public bool IsExtra
{
get => action.IsExtra;
set => action.IsExtra = value;
}
public UpdateActionType Type
{
get => action is UpdateAction ua ? ua.Type : default;
set
{
if (action is UpdateAction ua)
ua.Type = value;
}
}
public string SrcPath
{
get => action is UpdateAction ua ? ua.SrcPath : string.Empty;
set
{
if (action is UpdateAction ua)
ua.SrcPath = value;
}
}
public bool IsDirectory
{
get => action is UpdateAction ua && ua.IsDirectory;
set
{
if (action is UpdateAction ua)
ua.IsDirectory = value;
}
}
public string InheritFrom
{
get => action is UpdateAction ua ? ua.InheritFrom : string.Empty;
set
{
if (action is UpdateAction ua)
ua.InheritFrom = value;
OnPropertyChanged();
OnPropertyChanged(nameof(InheritedId));
}
}
}

View File

@@ -0,0 +1,232 @@
using System.ComponentModel;
using ModpackUpdater.Apps.Manager.Utils;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models;
public class MainWindowGridRow : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private string? actionId;
private string? actionName;
private string? actionWebsite;
private string? actionZipPath;
private string? actionDestPath;
private string? actionSourceUrl;
private string? actionSourceOwner;
private string? actionSourceName;
private string? actionSourceRegEx;
private string? actionSourceTag;
private string? actionSrcPath;
private string? actionInheritFrom;
private readonly InstallAction action;
private readonly IActionSet baseActions;
public static Dictionary<SourceType, string> SourceTypes { get; } = Enum.GetValues<SourceType>().ToDictionary(n => n, n => Enum.GetName(n)!);
public static Dictionary<Side, string> Sides { get; } = Enum.GetValues<Side>().ToDictionary(n => n, n => Enum.GetName(n)!);
public static Dictionary<UpdateActionType, string> UpdateActionTypes { get; } = Enum.GetValues<UpdateActionType>().ToDictionary(n => n, n => Enum.GetName(n)!);
public InstallAction Action => action;
private InstallAction? Base => action is UpdateAction ua ? baseActions.Actions.FirstOrDefault(n => n.Id == actionInheritFrom) : null;
private InstallAction Inherited => Base ?? action;
public bool IsUpdate => action is UpdateAction;
public bool? IsValid { get; set; } = null;
[DependsOn(nameof(Id), nameof(InheritFrom))]
public string? InheritedId => action is UpdateAction ua && !string.IsNullOrWhiteSpace(actionInheritFrom) ? actionInheritFrom : actionId;
[DependsOn(nameof(Side), nameof(InheritedId), nameof(Id))]
public string InheritedSide => Sides[Inherited.Side];
[DependsOn(nameof(UpdateType), nameof(InheritedId), nameof(Id))]
public string InheritedUpdateType => action is UpdateAction ua ? UpdateActionTypes[ua.Type] : string.Empty;
[DependsOn(nameof(SourceType), nameof(InheritedId), nameof(Id))]
public string InheritedSourceType => SourceTypes[Inherited.SourceType];
[DependsOn(nameof(DestPath), nameof(InheritedId), nameof(Id))]
public string? InheritedDestPath => Base != null ? Base.DestPath : actionDestPath;
public MainWindowGridRow(InstallAction action, IActionSet baseActions)
{
this.action = action;
this.baseActions = baseActions;
Invalidate();
}
public void Invalidate()
{
actionId = action.Id;
actionName = action.Name;
actionWebsite = action.Website;
actionZipPath = action.ZipPath;
actionDestPath = action.DestPath;
actionSourceUrl = action.SourceUrl;
actionSourceOwner = action.SourceOwner;
actionSourceName = action.SourceName;
actionSourceRegEx = action.SourceRegex;
actionSourceTag = action.SourceTag;
actionSrcPath = (action as UpdateAction)?.SrcPath;
actionInheritFrom = (action as UpdateAction)?.InheritFrom;
}
public string? Id
{
get => action.Id;
set => action.Id = (actionId = value)?.Trim().Nullify();
}
public string? Name
{
get => actionName;
set
{
actionName = value;
action.Name = value?.Trim().Nullify();
}
}
public string? Website
{
get => actionWebsite;
set
{
actionWebsite = value;
action.Website = value?.Trim().Nullify();
}
}
public bool IsZip
{
get => action.IsZip;
set => action.IsZip = value;
}
public string? ZipPath
{
get => actionZipPath;
set
{
actionZipPath = value;
action.ZipPath = value?.Trim().Nullify();
}
}
public string? DestPath
{
get => actionDestPath;
set
{
actionDestPath = value;
action.DestPath = value?.Trim().Nullify();
}
}
public string? SourceUrl
{
get => actionSourceUrl;
set
{
actionSourceUrl = value;
action.SourceUrl = value?.Trim().Nullify();
}
}
public SourceType SourceType
{
get => action.SourceType;
set => action.SourceType = value;
}
public string? SourceOwner
{
get => actionSourceOwner;
set
{
actionSourceOwner = value;
action.SourceOwner = value?.Trim().Nullify();
}
}
public string? SourceName
{
get => actionSourceName;
set
{
actionSourceName = value;
action.SourceName = value?.Trim().Nullify();
}
}
public string? SourceRegex
{
get => actionSourceRegEx;
set
{
actionSourceRegEx = value;
action.SourceRegex = value?.Trim().Nullify();
}
}
public string? SourceTag
{
get => actionSourceTag;
set
{
actionSourceTag = value;
action.SourceTag = value?.Trim().Nullify();
}
}
public Side Side
{
get => action.Side;
set => action.Side = value;
}
public bool IsExtra
{
get => action.IsExtra;
set => action.IsExtra = value;
}
public UpdateActionType UpdateType
{
get => action is UpdateAction ua ? ua.Type : default;
set
{
if (action is UpdateAction ua)
ua.Type = value;
}
}
public string? SrcPath
{
get => actionSrcPath;
set
{
actionSrcPath = value;
if (action is UpdateAction ua)
ua.SrcPath = value?.Trim().Nullify();
}
}
public bool IsDirectory
{
get => action is UpdateAction ua && ua.IsDirectory;
set
{
if (action is UpdateAction ua)
ua.IsDirectory = value;
}
}
public string? InheritFrom
{
get => actionInheritFrom;
set
{
actionInheritFrom = value;
if (action is UpdateAction ua)
ua.InheritFrom = value?.Trim().Nullify();
}
}
}

View File

@@ -0,0 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
namespace ModpackUpdater.Apps.Manager.Ui.Models;
public record class MainWindowRecentFilesItem(WorkspaceConfig Config, WorkspaceFeature Feature);

View File

@@ -0,0 +1,57 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Avalonia.Media;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models;
public abstract class MainWindowTreeNode : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public abstract string DisplayText { get; }
public virtual IImage? Image { get; set; }
public ObservableCollection<MainWindowTreeNode> Nodes { get; init; } = [];
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
public class SimpleMainWindowTreeNode(string text) : MainWindowTreeNode
{
public override string DisplayText => text;
}
public class ActionSetTreeNode(IActionSetInfos infos) : MainWindowTreeNode
{
private string editVersion = infos.Version.ToString();
public override string DisplayText => infos.Version.ToString();
public IActionSetInfos Infos => infos;
public override IImage? Image => AppGlobals.Symbols.GetImageSource(infos.IsPublic ? AppSymbols.eye : AppSymbols.invisible);
[AlsoNotifyFor(nameof(DisplayText))]
public string Version
{
get => editVersion;
set => infos.Version = System.Version.TryParse(editVersion = value, out var v) ? v : new();
}
[AlsoNotifyFor(nameof(Image))]
public bool IsPublic
{
get => infos.IsPublic;
set => infos.IsPublic = value;
}
}

View File

@@ -1,24 +1,72 @@
using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Avalonia.Controls;
using ModpackUpdater.Apps.Manager.Api.Model;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models; namespace ModpackUpdater.Apps.Manager.Ui.Models;
public class MainWindowViewModel : INotifyPropertyChanged public class MainWindowViewModel : INotifyPropertyChanged
{ {
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) private ObservableCollection<MainWindowTreeNode>? currentTreeNodes;
private ObservableCollection<MainWindowGridRow>? currentGridRows;
private MainWindowTreeNode? selectedTreeNode;
private IWorkspace? currentWorkspace;
public bool IsUpdate => selectedTreeNode is ActionSetTreeNode node && node.Infos is UpdateInfo;
public MainWindowGridRow? SelectedGridRow { get; set; }
[AlsoNotifyFor(nameof(CurrentTreeNodes))]
public IWorkspace? CurrentWorkspace
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); get => currentWorkspace;
set
{
currentWorkspace = value;
currentTreeNodes = null;
}
} }
#endregion Implementation of INotifyPropertyChanged public ObservableCollection<MainWindowTreeNode>? CurrentTreeNodes
{
public bool IsUpdate { get; set; } get
{
public List<InstallActionViewModel> Actions { get; } = []; if (currentTreeNodes == null && currentWorkspace?.InstallInfos != null && currentWorkspace?.UpdateInfos != null)
currentTreeNodes =
public InstallActionViewModel? SelectedAction { get; set; } [
new ActionSetTreeNode(currentWorkspace.InstallInfos),
new SimpleMainWindowTreeNode("Updates")
{
Image = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done),
Nodes = [.. currentWorkspace.UpdateInfos.Updates.Select(n => new ActionSetTreeNode(n))],
},
];
return currentTreeNodes;
}
}
[AlsoNotifyFor(nameof(CurrentGridRows))]
public MainWindowTreeNode? SelectedTreeNode
{
get => selectedTreeNode;
set
{
selectedTreeNode = value;
currentGridRows = null;
}
}
public ObservableCollection<MainWindowGridRow>? CurrentGridRows
{
get
{
if (currentGridRows == null && CurrentWorkspace?.InstallInfos != null && selectedTreeNode is ActionSetTreeNode node)
currentGridRows = [.. node.Infos.Actions.Select(n => new MainWindowGridRow(n, CurrentWorkspace.InstallInfos))];
return currentGridRows;
}
}
} }

View File

@@ -2,7 +2,7 @@ using System.Collections;
using System.Globalization; using System.Globalization;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager.Utils;
public class DictionaryValueConverter : IValueConverter public class DictionaryValueConverter : IValueConverter
{ {

View File

@@ -0,0 +1,9 @@
namespace ModpackUpdater.Apps.Manager.Utils;
internal static class Extensions
{
public static string? Nullify(this string? @this)
{
return string.IsNullOrEmpty(@this) ? null : @this;
}
}

View File

@@ -0,0 +1,12 @@
using Avalonia.Platform.Storage;
namespace ModpackUpdater.Apps.Manager.Utils;
public class MyFilePickerFileTypes
{
public static FilePickerFileType Excel { get; } = new("Excel")
{
Patterns = ["*.xlsx"],
MimeTypes = ["application/vnd.ms-excel"]
};
}

View File

@@ -8,41 +8,41 @@ namespace ModpackUpdater;
public class InstallAction public class InstallAction
{ {
[DefaultValue(null)] [DefaultValue(null)]
public string Id { get; set; } public string? Id { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string Name { get; set; } public string? Name { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string Website { get; set; } public string? Website { get; set; }
[DefaultValue(false)] [DefaultValue(false)]
public bool IsZip { get; set; } public bool IsZip { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string ZipPath { get; set; } public string? ZipPath { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string DestPath { get; set; } public string? DestPath { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string SourceUrl { get; set; } public string? SourceUrl { get; set; }
[DefaultValue(SourceType.DirectLink)] [DefaultValue(SourceType.DirectLink)]
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public SourceType SourceType { get; set; } public SourceType SourceType { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string SourceOwner { get; set; } public string? SourceOwner { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string SourceName { get; set; } public string? SourceName { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string SourceRegex { get; set; } public string? SourceRegex { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string SourceTag { get; set; } public string? SourceTag { get; set; }
[DefaultValue(Side.Both)] [DefaultValue(Side.Both)]
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
@@ -52,7 +52,7 @@ public class InstallAction
public bool IsExtra { get; set; } public bool IsExtra { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string TargetOption { get; set; } public string? TargetOption { get; set; }
[JsonProperty, Obsolete] [JsonProperty, Obsolete]
private string DownloadUrl private string DownloadUrl

View File

@@ -11,11 +11,11 @@ public class UpdateAction : InstallAction
public UpdateActionType Type { get; set; } = UpdateActionType.Update; public UpdateActionType Type { get; set; } = UpdateActionType.Update;
[DefaultValue(null)] [DefaultValue(null)]
public string SrcPath { get; set; } public string? SrcPath { get; set; }
[DefaultValue(false)] [DefaultValue(false)]
public bool IsDirectory { get; set; } public bool IsDirectory { get; set; }
[DefaultValue(null)] [DefaultValue(null)]
public string InheritFrom { get; set; } public string? InheritFrom { get; set; }
} }