69 Commits

Author SHA1 Message Date
3b79335e85 more logging 2024-12-05 07:22:01 +01:00
3e1ab72162 update deps & enable console logging 2024-12-05 07:06:06 +01:00
a83d109f24 fix first install includes ALL updates 2024-12-05 06:56:45 +01:00
e50d5f4874 v1.6.2 2024-10-31 21:16:00 +01:00
72b765e6fd final fix 2024-10-31 21:15:15 +01:00
26347ca9a4 wtf? 2024-10-19 22:05:06 +02:00
9c8eb4a9a8 v1.6.1 2024-10-19 22:01:45 +02:00
f8801cc861 probably fix install key not saving on first installation 2024-10-19 22:01:20 +02:00
97bf2b1323 showdialog 2024-10-14 16:55:14 +02:00
8fae2a2c9d improvements for first installation 2024-10-13 11:54:36 +02:00
334b9583c6 allow remove updates from update collector 2024-10-13 09:31:43 +02:00
8561fdb09b add simple generate changelog feature 2024-10-13 09:22:19 +02:00
ee69d8af56 some fixes 2024-10-03 15:46:06 +02:00
cd929485d0 bump settings version 2024-10-03 12:46:39 +02:00
2fddf23e6a show correct app version 2024-10-03 12:46:20 +02:00
d8847a8a0e client: bump version 2024-10-03 12:43:20 +02:00
e321c66f72 minor fixes 2024-10-03 11:51:05 +02:00
ac146900d0 use CurrentUpdates property 2024-10-03 11:43:40 +02:00
5fc97ed522 only load modpack config if url is provided 2024-10-03 11:42:42 +02:00
9694ba56fd use modpack config for finding updates 2024-10-03 11:36:29 +02:00
2a389ae5d4 make ModpackConfig.ConfigUrl private 2024-10-03 11:31:27 +02:00
6a0bf70e97 add modloader to modpackconfig 2024-10-03 11:30:31 +02:00
a329d21feb add modpack config to workspace (read-only via url) 2024-10-03 11:28:34 +02:00
c07ba7fc28 optimize updatescollectorui 2024-10-03 11:17:27 +02:00
07a94cfa5f add icons to new features 2024-10-03 10:51:30 +02:00
690355266c add options to update and clear direct links 2024-10-03 10:46:16 +02:00
3ec94fa22d add option to prefer directlinks 2024-10-03 10:03:40 +02:00
95a81a9306 move actions to separated code & add sinlge update search action 2024-10-03 09:54:22 +02:00
934b8db71b some fixes 2024-09-29 09:58:32 +02:00
31f557cc8d finish healthy check & other sources implemtation 2024-09-28 14:08:30 +02:00
6f8ac996fd minor fixes 2024-09-26 10:18:29 +02:00
a420e7bf74 fix wrong menu item for tools features 2024-09-26 09:33:59 +02:00
12c00841ff add pluginfeatureprovider for updatescollectorfeature 2024-09-26 09:32:55 +02:00
f64c8cdba0 proper finish updates collector 2024-09-26 09:30:12 +02:00
2f9d60f1a8 some more work 2024-09-25 12:08:38 +02:00
bc6c483ba6 allow curseforge and modrinth as source 2024-09-22 09:41:09 +02:00
7e5acd413e add/remove action rows 2024-09-09 09:20:24 +02:00
333f5011de check against Id instead of Name 2024-09-09 08:58:16 +02:00
c6153488cd fix namepsace of Modpack Features 2024-09-09 08:57:29 +02:00
32d9212edc add/edit/delete updates 2024-09-09 08:54:53 +02:00
1747083c99 change treeview to listcontrol 2024-09-08 17:16:02 +02:00
f2a78a462c reorder columns 2024-09-08 17:11:28 +02:00
4c54f592d3 remove unused using 2024-09-08 17:04:48 +02:00
27879f15c3 allow edit 2024-09-08 17:04:13 +02:00
a02f275577 disable icon for now due performance 2024-09-08 10:01:47 +02:00
4b964e548f add icon for source type & minor fixes 2024-09-08 09:57:03 +02:00
8087c0539a make list 2024-09-08 09:12:39 +02:00
19fccd8af9 add icon to manager form 2024-09-07 09:49:41 +02:00
043b14e9a9 some work 2024-09-07 09:45:38 +02:00
f6219c0aa8 use AssemblyAppVersion for Client 2024-09-07 09:30:13 +02:00
f453e85956 update nuget packages & minor fixes 2024-09-06 20:08:40 +02:00
5e678db077 some work for loading a workspace 2024-09-06 16:55:04 +02:00
f0f63a1895 add icons to manager window 2024-09-06 16:19:49 +02:00
0276f11a8a use Win11 as default theme for Updater 2024-09-06 16:13:14 +02:00
5083af5fd1 fix 2024-09-06 16:01:10 +02:00
86b7ec67fc finish editor for gitlab repo workspace config 2024-09-06 15:59:13 +02:00
3239fb5431 add cancel icon 2024-09-06 15:58:48 +02:00
9bfd83ee4a some background code for manager workspaces 2024-09-06 15:16:19 +02:00
ebc57e05d5 some work on Manager 2024-09-06 09:44:24 +02:00
5bccd070f4 more refactoring 2024-09-06 09:14:25 +02:00
3625962a27 re-organze namespace 2024-09-06 08:45:36 +02:00
939c87820f begin finding assets from bottom to top 2024-09-05 15:17:01 +02:00
b4f0d43b46 add GitHub as source & allow inheritance 2024-09-05 15:03:53 +02:00
46179463e1 migration due nuget updates 2024-09-05 14:53:39 +02:00
7c4dae8c8d update nuget packages 2024-09-05 14:27:18 +02:00
6427ce4726 stop shipping whole framework on publication 2024-08-24 09:08:28 +02:00
b35e3d5187 update help texts 2024-08-10 09:35:40 +02:00
deeee34f87 v1.5.2.2 2024-08-10 09:27:13 +02:00
f254ac03e1 draw help always even if not noui is set 2024-08-10 09:27:09 +02:00
147 changed files with 8836 additions and 918 deletions

1
.gitignore vendored
View File

@@ -348,3 +348,4 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
*.json

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="TelerikWinFormsThemeName" value="Office2019Dark" />
<add key="TelerikWinFormsThemeName" value="Windows11CompactDark" />
</appSettings>
</configuration>

View File

@@ -1,7 +1,7 @@
using Newtonsoft.Json;
using Pilz.Configuration;
namespace ModpackUpdater;
namespace ModpackUpdater.Apps.Client;
public class AppConfig : IChildSettings, ISettingsIdentifier
{

View File

@@ -1,8 +1,9 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Pilz.Extensions;
using System.Reflection;
namespace ModpackUpdater;
namespace ModpackUpdater.Apps.Client;
public class AppUpdater
{
@@ -23,8 +24,8 @@ public class AppUpdater
try
{
var appVersion = Assembly.GetExecutingAssembly().GetName().Version;
string result = await httpClient.GetStringAsync(UPDATE_URL);
var appVersion = Assembly.GetExecutingAssembly().GetAppVersion().Version;
var result = await httpClient.GetStringAsync(UPDATE_URL);
info = JsonConvert.DeserializeObject<UpdateInfo>(result);
if (info is not null && info.Version > appVersion)
@@ -41,7 +42,7 @@ public class AppUpdater
{
var client = new HttpClient();
var tempFileName = Path.GetTempFileName();
var appFileName = Pilz.IO.Extensions.GetExecutablePath();
var appFileName = Pilz.Win32.NativeTools.GetExecutablePath();
var oldFileName = appFileName + ".old";
// Delete old file

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.My.Resources {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class FiledialogFilters {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal FiledialogFilters() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Client.FiledialogFilters", typeof(FiledialogFilters).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Json files (*.json) ähnelt.
/// </summary>
internal static string JSON_Display {
get {
return ResourceManager.GetString("JSON_Display", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die *.json ähnelt.
/// </summary>
internal static string JSON_Filter {
get {
return ResourceManager.GetString("JSON_Filter", resourceCulture);
}
}
}
}

View File

@@ -3,7 +3,7 @@ using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace ModpackUpdater
namespace ModpackUpdater.Apps.Client
{
[Microsoft.VisualBasic.CompilerServices.DesignerGenerated()]
@@ -34,35 +34,35 @@ namespace ModpackUpdater
[DebuggerStepThrough()]
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
var resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
RadLabel1 = new Telerik.WinControls.UI.RadLabel();
RadLabel2 = new Telerik.WinControls.UI.RadLabel();
RadLabel3 = new Telerik.WinControls.UI.RadLabel();
RadLabel_Status = new Telerik.WinControls.UI.RadLabel();
RadTextBoxControl_MinecraftProfileFolder = new Telerik.WinControls.UI.RadTextBoxControl();
RadTextBoxControl_ModpackConfig = new Telerik.WinControls.UI.RadTextBoxControl();
RadTextBox_MinecraftProfileFolder = new Telerik.WinControls.UI.RadTextBox();
RadTextBox_ModpackConfig = new Telerik.WinControls.UI.RadTextBox();
RadButton_Install = new Telerik.WinControls.UI.RadButton();
RadButton_CheckForUpdates = new Telerik.WinControls.UI.RadButton();
RadButton_PasteModpackConfig = new Telerik.WinControls.UI.RadButton();
RadButton_SearchMinecraftProfileFolder = new Telerik.WinControls.UI.RadButton();
tableLayoutPanel1 = new TableLayoutPanel();
radLabel4 = new Telerik.WinControls.UI.RadLabel();
radTextBoxControl_InstallKey = new Telerik.WinControls.UI.RadTextBoxControl();
radTextBox_InstallKey = new Telerik.WinControls.UI.RadTextBox();
radButton_PasteInstallKey = new Telerik.WinControls.UI.RadButton();
radButton_RefreshConfig = new Telerik.WinControls.UI.RadButton();
((System.ComponentModel.ISupportInitialize)RadLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel2).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel3).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_MinecraftProfileFolder).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_ModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_MinecraftProfileFolder).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_ModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_PasteModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).BeginInit();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel4).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_InstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radButton_PasteInstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radButton_RefreshConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
@@ -70,31 +70,31 @@ namespace ModpackUpdater
//
// RadLabel1
//
RadLabel1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
RadLabel1.AutoSize = false;
RadLabel1.Location = new Point(3, 3);
RadLabel1.Name = "RadLabel1";
RadLabel1.Size = new Size(144, 22);
RadLabel1.Size = new Size(144, 24);
RadLabel1.TabIndex = 0;
RadLabel1.Text = "Minecraft profile folder:";
//
// RadLabel2
//
RadLabel2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel2.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
RadLabel2.AutoSize = false;
RadLabel2.Location = new Point(3, 61);
RadLabel2.Location = new Point(3, 63);
RadLabel2.Name = "RadLabel2";
RadLabel2.Size = new Size(144, 22);
RadLabel2.Size = new Size(144, 24);
RadLabel2.TabIndex = 1;
RadLabel2.Text = "Modpack config:";
//
// RadLabel3
//
RadLabel3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel3.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
RadLabel3.AutoSize = false;
RadLabel3.Location = new Point(3, 177);
RadLabel3.Location = new Point(3, 183);
RadLabel3.Name = "RadLabel3";
RadLabel3.Size = new Size(144, 22);
RadLabel3.Size = new Size(144, 24);
RadLabel3.TabIndex = 2;
RadLabel3.Text = "Status:";
//
@@ -103,41 +103,41 @@ namespace ModpackUpdater
RadLabel_Status.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel_Status.AutoSize = false;
tableLayoutPanel1.SetColumnSpan(RadLabel_Status, 6);
RadLabel_Status.Location = new Point(153, 177);
RadLabel_Status.Location = new Point(153, 183);
RadLabel_Status.Name = "RadLabel_Status";
RadLabel_Status.Size = new Size(266, 22);
RadLabel_Status.Size = new Size(266, 24);
RadLabel_Status.TabIndex = 3;
RadLabel_Status.Text = "-";
RadLabel_Status.TextImageRelation = TextImageRelation.ImageBeforeText;
//
// RadTextBoxControl_MinecraftProfileFolder
// RadTextBox_MinecraftProfileFolder
//
RadTextBoxControl_MinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBoxControl_MinecraftProfileFolder, 6);
RadTextBoxControl_MinecraftProfileFolder.IsReadOnly = true;
RadTextBoxControl_MinecraftProfileFolder.Location = new Point(153, 3);
RadTextBoxControl_MinecraftProfileFolder.Name = "RadTextBoxControl_MinecraftProfileFolder";
RadTextBoxControl_MinecraftProfileFolder.NullText = "No file loaded!";
RadTextBoxControl_MinecraftProfileFolder.Size = new Size(266, 22);
RadTextBoxControl_MinecraftProfileFolder.TabIndex = 4;
RadTextBox_MinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBox_MinecraftProfileFolder, 6);
RadTextBox_MinecraftProfileFolder.Location = new Point(153, 3);
RadTextBox_MinecraftProfileFolder.Name = "RadTextBox_MinecraftProfileFolder";
RadTextBox_MinecraftProfileFolder.NullText = "No file loaded!";
RadTextBox_MinecraftProfileFolder.ReadOnly = true;
RadTextBox_MinecraftProfileFolder.Size = new Size(266, 24);
RadTextBox_MinecraftProfileFolder.TabIndex = 4;
//
// RadTextBoxControl_ModpackConfig
// RadTextBox_ModpackConfig
//
RadTextBoxControl_ModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBoxControl_ModpackConfig, 6);
RadTextBoxControl_ModpackConfig.IsReadOnly = true;
RadTextBoxControl_ModpackConfig.Location = new Point(153, 61);
RadTextBoxControl_ModpackConfig.Name = "RadTextBoxControl_ModpackConfig";
RadTextBoxControl_ModpackConfig.NullText = "No config url provided.";
RadTextBoxControl_ModpackConfig.Size = new Size(266, 22);
RadTextBoxControl_ModpackConfig.TabIndex = 5;
RadTextBox_ModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBox_ModpackConfig, 6);
RadTextBox_ModpackConfig.Location = new Point(153, 63);
RadTextBox_ModpackConfig.Name = "RadTextBox_ModpackConfig";
RadTextBox_ModpackConfig.NullText = "No config url provided.";
RadTextBox_ModpackConfig.ReadOnly = true;
RadTextBox_ModpackConfig.Size = new Size(266, 24);
RadTextBox_ModpackConfig.TabIndex = 5;
//
// RadButton_Install
//
RadButton_Install.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_Install, 2);
RadButton_Install.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_Install.Location = new Point(325, 205);
RadButton_Install.Location = new Point(325, 213);
RadButton_Install.Name = "RadButton_Install";
RadButton_Install.Size = new Size(94, 24);
RadButton_Install.TabIndex = 10;
@@ -151,7 +151,7 @@ namespace ModpackUpdater
RadButton_CheckForUpdates.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_CheckForUpdates, 3);
RadButton_CheckForUpdates.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_CheckForUpdates.Location = new Point(175, 205);
RadButton_CheckForUpdates.Location = new Point(175, 213);
RadButton_CheckForUpdates.Name = "RadButton_CheckForUpdates";
RadButton_CheckForUpdates.Size = new Size(144, 24);
RadButton_CheckForUpdates.TabIndex = 0;
@@ -165,7 +165,7 @@ namespace ModpackUpdater
RadButton_PasteModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_PasteModpackConfig, 2);
RadButton_PasteModpackConfig.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_PasteModpackConfig.Location = new Point(325, 89);
RadButton_PasteModpackConfig.Location = new Point(325, 93);
RadButton_PasteModpackConfig.Name = "RadButton_PasteModpackConfig";
RadButton_PasteModpackConfig.Size = new Size(94, 24);
RadButton_PasteModpackConfig.TabIndex = 7;
@@ -179,7 +179,7 @@ namespace ModpackUpdater
RadButton_SearchMinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_SearchMinecraftProfileFolder, 2);
RadButton_SearchMinecraftProfileFolder.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_SearchMinecraftProfileFolder.Location = new Point(325, 31);
RadButton_SearchMinecraftProfileFolder.Location = new Point(325, 33);
RadButton_SearchMinecraftProfileFolder.Name = "RadButton_SearchMinecraftProfileFolder";
RadButton_SearchMinecraftProfileFolder.Size = new Size(94, 24);
RadButton_SearchMinecraftProfileFolder.TabIndex = 6;
@@ -190,6 +190,8 @@ namespace ModpackUpdater
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel1.ColumnCount = 7;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
@@ -201,14 +203,14 @@ namespace ModpackUpdater
tableLayoutPanel1.Controls.Add(RadButton_CheckForUpdates, 2, 7);
tableLayoutPanel1.Controls.Add(RadLabel1, 0, 0);
tableLayoutPanel1.Controls.Add(RadLabel2, 0, 2);
tableLayoutPanel1.Controls.Add(RadTextBoxControl_MinecraftProfileFolder, 1, 0);
tableLayoutPanel1.Controls.Add(RadTextBoxControl_ModpackConfig, 1, 2);
tableLayoutPanel1.Controls.Add(RadTextBox_MinecraftProfileFolder, 1, 0);
tableLayoutPanel1.Controls.Add(RadTextBox_ModpackConfig, 1, 2);
tableLayoutPanel1.Controls.Add(RadLabel_Status, 1, 6);
tableLayoutPanel1.Controls.Add(RadLabel3, 0, 6);
tableLayoutPanel1.Controls.Add(RadButton_SearchMinecraftProfileFolder, 5, 1);
tableLayoutPanel1.Controls.Add(RadButton_Install, 5, 7);
tableLayoutPanel1.Controls.Add(radLabel4, 0, 4);
tableLayoutPanel1.Controls.Add(radTextBoxControl_InstallKey, 1, 4);
tableLayoutPanel1.Controls.Add(radTextBox_InstallKey, 1, 4);
tableLayoutPanel1.Controls.Add(radButton_PasteInstallKey, 5, 5);
tableLayoutPanel1.Controls.Add(RadButton_PasteModpackConfig, 5, 3);
tableLayoutPanel1.Controls.Add(radButton_RefreshConfig, 4, 3);
@@ -224,36 +226,36 @@ namespace ModpackUpdater
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(422, 232);
tableLayoutPanel1.Size = new Size(422, 249);
tableLayoutPanel1.TabIndex = 7;
//
// radLabel4
//
radLabel4.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radLabel4.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radLabel4.AutoSize = false;
radLabel4.Location = new Point(3, 119);
radLabel4.Location = new Point(3, 123);
radLabel4.Name = "radLabel4";
radLabel4.Size = new Size(144, 22);
radLabel4.Size = new Size(144, 24);
radLabel4.TabIndex = 12;
radLabel4.Text = "Installation key:";
//
// radTextBoxControl_InstallKey
// radTextBox_InstallKey
//
radTextBoxControl_InstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radTextBoxControl_InstallKey, 6);
radTextBoxControl_InstallKey.IsReadOnly = true;
radTextBoxControl_InstallKey.Location = new Point(153, 119);
radTextBoxControl_InstallKey.Name = "radTextBoxControl_InstallKey";
radTextBoxControl_InstallKey.NullText = "No key provided. Only for private servers.";
radTextBoxControl_InstallKey.Size = new Size(266, 22);
radTextBoxControl_InstallKey.TabIndex = 13;
radTextBox_InstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radTextBox_InstallKey, 6);
radTextBox_InstallKey.Location = new Point(153, 123);
radTextBox_InstallKey.Name = "radTextBox_InstallKey";
radTextBox_InstallKey.NullText = "No key provided. Only for private servers.";
radTextBox_InstallKey.ReadOnly = true;
radTextBox_InstallKey.Size = new Size(266, 24);
radTextBox_InstallKey.TabIndex = 13;
//
// radButton_PasteInstallKey
//
radButton_PasteInstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radButton_PasteInstallKey, 2);
radButton_PasteInstallKey.ImageAlignment = ContentAlignment.MiddleRight;
radButton_PasteInstallKey.Location = new Point(325, 147);
radButton_PasteInstallKey.Location = new Point(325, 153);
radButton_PasteInstallKey.Name = "radButton_PasteInstallKey";
radButton_PasteInstallKey.Size = new Size(94, 24);
radButton_PasteInstallKey.TabIndex = 14;
@@ -267,7 +269,7 @@ namespace ModpackUpdater
radButton_RefreshConfig.Anchor = AnchorStyles.Top | AnchorStyles.Right;
radButton_RefreshConfig.DisplayStyle = Telerik.WinControls.DisplayStyle.Image;
radButton_RefreshConfig.ImageAlignment = ContentAlignment.MiddleCenter;
radButton_RefreshConfig.Location = new Point(295, 89);
radButton_RefreshConfig.Location = new Point(295, 93);
radButton_RefreshConfig.Name = "radButton_RefreshConfig";
radButton_RefreshConfig.Size = new Size(24, 24);
radButton_RefreshConfig.TabIndex = 11;
@@ -279,10 +281,13 @@ namespace ModpackUpdater
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(422, 232);
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
ClientSize = new Size(422, 249);
Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
MinimumSize = new Size(430, 0);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Minecraft Modpack Updater";
@@ -293,27 +298,29 @@ namespace ModpackUpdater
((System.ComponentModel.ISupportInitialize)RadLabel2).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel3).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_MinecraftProfileFolder).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_ModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_MinecraftProfileFolder).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_ModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_PasteModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).EndInit();
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)radLabel4).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_InstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)radButton_PasteInstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)radButton_RefreshConfig).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
PerformLayout();
}
internal Telerik.WinControls.UI.RadLabel RadLabel1;
internal Telerik.WinControls.UI.RadLabel RadLabel2;
internal Telerik.WinControls.UI.RadLabel RadLabel3;
internal Telerik.WinControls.UI.RadLabel RadLabel_Status;
internal Telerik.WinControls.UI.RadTextBoxControl RadTextBoxControl_MinecraftProfileFolder;
internal Telerik.WinControls.UI.RadTextBoxControl RadTextBoxControl_ModpackConfig;
internal Telerik.WinControls.UI.RadTextBox RadTextBox_MinecraftProfileFolder;
internal Telerik.WinControls.UI.RadTextBox RadTextBox_ModpackConfig;
internal Telerik.WinControls.UI.RadButton RadButton_Install;
internal Telerik.WinControls.UI.RadButton RadButton_CheckForUpdates;
internal Telerik.WinControls.UI.RadButton RadButton_SearchMinecraftProfileFolder;
@@ -321,7 +328,7 @@ namespace ModpackUpdater
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadButton radButton_RefreshConfig;
internal Telerik.WinControls.UI.RadLabel radLabel4;
internal Telerik.WinControls.UI.RadTextBoxControl radTextBoxControl_InstallKey;
internal Telerik.WinControls.UI.RadTextBox radTextBox_InstallKey;
internal Telerik.WinControls.UI.RadButton radButton_PasteInstallKey;
}
}

View File

@@ -1,13 +1,13 @@
using ModpackUpdater.Manager;
using ModpackUpdater.Model;
using ModpackUpdater.My.Resources;
using Pilz.UI.Telerik;
using Pilz.Extensions;
using Pilz.UI.Symbols;
using System.Diagnostics;
using System.Reflection;
using Telerik.WinControls;
using Telerik.WinControls.UI;
namespace ModpackUpdater;
namespace ModpackUpdater.Apps.Client;
public partial class Form1
{
@@ -32,32 +32,32 @@ public partial class Form1
{
InitializeComponent();
Text = $"{Text} (v{Assembly.GetExecutingAssembly().GetName().Version})";
Text = $"{Text} (v{Assembly.GetExecutingAssembly().GetAppVersion()})";
RadButton_Install.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small);
RadButton_CheckForUpdates.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.update_done, SvgImageSize.Small);
radButton_RefreshConfig.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.refresh, SvgImageSize.Small);
RadButton_SearchMinecraftProfileFolder.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.opened_folder, SvgImageSize.Small);
radButton_PasteInstallKey.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.paste, SvgImageSize.Small);
RadButton_PasteModpackConfig.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.paste, SvgImageSize.Small);
RadButton_Install.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small);
RadButton_CheckForUpdates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small);
radButton_RefreshConfig.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.refresh, SymbolSize.Small);
RadButton_SearchMinecraftProfileFolder.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.opened_folder, SymbolSize.Small);
radButton_PasteInstallKey.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.paste, SymbolSize.Small);
RadButton_PasteModpackConfig.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.paste, SymbolSize.Small);
}
private void LoadMinecraftProfile(string folderPath)
{
RadTextBoxControl_MinecraftProfileFolder.Text = folderPath;
RadTextBox_MinecraftProfileFolder.Text = folderPath;
AppConfig.Instance.LastMinecraftProfilePath = folderPath;
CheckStatusAndUpdate(loadedProfile: true);
}
private void LoadUpdateConfigFile(string filePath)
{
RadTextBoxControl_ModpackConfig.Text = filePath;
RadTextBox_ModpackConfig.Text = filePath;
CheckStatusAndUpdate();
}
private void LoadInstallKey(string installKey)
{
radTextBoxControl_InstallKey.Text = modpackInfo.ExtrasKey = installKey;
radTextBox_InstallKey.Text = installKey;
CheckStatusAndUpdate();
}
@@ -83,12 +83,14 @@ public partial class Form1
{
try
{
modpackInfo = ModpackInfo.TryLoad(RadTextBoxControl_MinecraftProfileFolder.Text.Trim());
modpackInfo = ModpackInfo.TryLoad(RadTextBox_MinecraftProfileFolder.Text.Trim());
if (loadedProfile)
{
RadTextBoxControl_ModpackConfig.Text = modpackInfo.ConfigUrl;
radTextBoxControl_InstallKey.Text = modpackInfo.ExtrasKey;
RadTextBox_ModpackConfig.Text = modpackInfo.ConfigUrl;
radTextBox_InstallKey.Text = modpackInfo.ExtrasKey;
}
else
modpackInfo.ExtrasKey = radTextBox_InstallKey.Text;
}
catch
{
@@ -96,7 +98,7 @@ public partial class Form1
try
{
updateConfig = ModpackConfig.LoadFromUrl(RadTextBoxControl_ModpackConfig.Text);
updateConfig = ModpackConfig.LoadFromUrl(RadTextBox_ModpackConfig.Text);
}
catch (Exception)
{
@@ -105,18 +107,18 @@ public partial class Form1
if (modpackInfo != null)
features = new(updateConfig);
if (modpackInfo == null || string.IsNullOrWhiteSpace(RadTextBoxControl_MinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
if (modpackInfo == null || string.IsNullOrWhiteSpace(RadTextBox_MinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
{
SetStatus(LangRes.StatusText_MinecraftProfileWarning, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.general_warning_sign, SvgImageSize.Small));
SetStatus(LangRes.StatusText_MinecraftProfileWarning, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small));
RadButton_PasteModpackConfig.Enabled = false;
radButton_PasteInstallKey.Enabled = false;
RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false;
return false;
}
else if (updateConfig == null || string.IsNullOrWhiteSpace(RadTextBoxControl_ModpackConfig.Text))
else if (updateConfig == null || string.IsNullOrWhiteSpace(RadTextBox_ModpackConfig.Text))
{
SetStatus(LangRes.StatusText_ConfigIncompleteOrNotLoaded, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.general_warning_sign, SvgImageSize.Small));
SetStatus(LangRes.StatusText_ConfigIncompleteOrNotLoaded, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small));
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = false;
RadButton_CheckForUpdates.Enabled = false;
@@ -125,7 +127,7 @@ public partial class Form1
}
else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance)
{
SetStatus(LangRes.StatusText_Maintenance, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.services, SvgImageSize.Small));
SetStatus(LangRes.StatusText_Maintenance, AppGlobals.Symbols.GetSvgImage(AppSymbols.services, SymbolSize.Small));
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = true;
RadButton_CheckForUpdates.Enabled = false;
@@ -148,28 +150,28 @@ public partial class Form1
void error()
{
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.close, SvgImageSize.Small));
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.close, SymbolSize.Small));
currentUpdating = false;
}
void installing()
{
SetStatus(LangRes.StatusText_Installing, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
SetStatus(LangRes.StatusText_Installing, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
currentUpdating = true;
}
void updatesAvailable()
{
SetStatus(LangRes.StatusText_UpdateAvailable, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
SetStatus(LangRes.StatusText_UpdateAvailable, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
}
void everythingOk()
{
SetStatus(LangRes.StatusTest_EverythingOk, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.done, SvgImageSize.Small));
SetStatus(LangRes.StatusTest_EverythingOk, AppGlobals.Symbols.GetSvgImage(AppSymbols.done, SymbolSize.Small));
currentUpdating = false;
}
// Check only if not pressed "install", not really needed otherwise.
if (lastUpdateCheckResult is null || !doInstall)
{
SetStatus(LangRes.StatusText_CheckingForUpdates, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.update_done, SvgImageSize.Small));
SetStatus(LangRes.StatusText_CheckingForUpdates, AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small));
// Check for extras once again
updateOptions.IncludeExtras = features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(modpackInfo));
@@ -238,12 +240,12 @@ public partial class Form1
private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs)
{
int actionCount = result.Actions.Count;
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
}
private void Updated_CheckingProgresssUpdated(int toCheck, int processed)
{
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppSymbolFactory.Instance.GetSvgImage(AppSymbols.update_done, SvgImageSize.Small));
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small));
}
private void ButtonX_SearchMinecraftProfile_Click(object sender, EventArgs e)
@@ -265,7 +267,7 @@ public partial class Form1
private void RadButton_RefreshConfig_Click(object sender, EventArgs e)
{
LoadUpdateConfigFile(RadTextBoxControl_ModpackConfig.Text);
LoadUpdateConfigFile(RadTextBox_ModpackConfig.Text);
}
private async void ButtonX_CheckForUpdates_Click(object sender, EventArgs e)
@@ -285,7 +287,7 @@ public partial class Form1
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
AppConfig.Instance.LastMinecraftProfilePath = RadTextBoxControl_MinecraftProfileFolder.Text;
AppConfig.Instance.LastMinecraftProfilePath = RadTextBox_MinecraftProfileFolder.Text;
}
private void Form1_Load(object sender, EventArgs e)
@@ -299,7 +301,7 @@ public partial class Form1
var updater = new AppUpdater();
if (!updateOptions.NoUpdate && await updater.Check() && RadMessageBox.Show(LangRes.MsgBox_UpdateAvailable, LangRes.MsgBox_UpdateAvailable_Title, MessageBoxButtons.YesNo, RadMessageIcon.Info) == DialogResult.Yes)
{
SetStatus(LangRes.StatusText_InstallingAppUpdate, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
SetStatus(LangRes.StatusText_InstallingAppUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
Enabled = false;
await updater.Install();
Application.Restart();

View File

@@ -39,7 +39,7 @@ namespace ModpackUpdater.My.Resources {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.LangRes", typeof(LangRes).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Client.LangRes", typeof(LangRes).Assembly);
resourceMan = temp;
}
return resourceMan;

View File

@@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>icons8_download_from_ftp.ico</ApplicationIcon>
<AssemblyName>Minecraft Modpack Updater</AssemblyName>
<ImplicitUsings>true</ImplicitUsings>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
</PropertyGroup>
<ItemGroup>
<Compile Update="FiledialogFilters.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>FiledialogFilters.resx</DependentUpon>
</Compile>
<Compile Update="LangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>LangRes.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="FiledialogFilters.resx">
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>FiledialogFilters.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>LangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Pilz.Configuration" Version="3.2.0" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.1" />
<PackageReference Include="Pilz.IO" Version="2.1.0" />
<PackageReference Include="Pilz.UI" Version="2.3.14" />
<PackageReference Include="Pilz.UI.Telerik" Version="2.8.1" />
<PackageReference Include="Pilz.Win32" Version="2.1.0" />
<PackageReference Include="UI.for.WinForms.Common" Version="2024.3.806" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Apps\ModpackUpdater.Apps.csproj" />
<ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" />
<ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,7 +1,6 @@
using ModpackUpdater.Model;
using Mono.Options;
using Mono.Options;
namespace ModpackUpdater;
namespace ModpackUpdater.Apps.Client;
internal class Options
{
@@ -18,15 +17,16 @@ internal class Options
{
options = new OptionSet
{
{ "silent", "Do not output anything.", s => Silent = s != null },
{ "h|help", "Writes the help text as output.", h => Help = h != null },
{ "n|noui", "Install without user interface.", n => NoUi = n != null },
{ "silent", "Do not output anything.", s => Silent = true },
{ "h|help", "Writes the help text as output.", h => Help = true },
{ "n|noui", "Install without user interface.", n => NoUi = true },
{ "p|profile=", "Sets the minecraft profile folder.", p => UpdateOptions.ProfileFolder = p },
{ "c|config=", "Sets the minecraft profile folder.", c => UpdateOptions.ModpackConfig = c },
{ "s|side=", "Sets the minecraft profile folder.\nDefault side is Client.\nAvailable: Client, Server", s => UpdateOptions.Side = Enum.Parse<Side>(s)},
{ "u|uai", "Allow an update directly after install. This only has affect if there is no existing installation.", uai => UpdateOptions.AllowUpdaterAfterInstall = uai != null},
{ "noupdate", "Skip the update check.", noupdate => UpdateOptions.NoUpdate = noupdate != null},
{ "m|maintenance", "Ignores the maintenance mode.", m => UpdateOptions.IgnoreMaintenance = m != null},
{ "c|config=", "Sets the modpack update info url.", c => UpdateOptions.ModpackConfig = c },
{ "s|side=", "Sets the installation side.\nDefault side is Client.\nAvailable: Client, Server", s => UpdateOptions.Side = Enum.Parse<Side>(s)},
{ "u|uai", "Disallow an update directly after install. This only has effect if there is no existing installation.", uai => UpdateOptions.AllowUpdaterAfterInstall = false},
{ "noupdate", "Skip the update check.", noupdate => UpdateOptions.NoUpdate = true},
{ "m|maintenance", "Ignores the maintenance mode.", m => UpdateOptions.IgnoreMaintenance = true},
{ "i|nonpublic", "Include non public (currently hidden) updates.", i => UpdateOptions.IncludeNonPublic = true},
{ "k|key=", "An key for retriving extra files on updates.", k => UpdateOptions.ExtrasKey = k},
};

View File

@@ -1,23 +1,28 @@
using ModpackUpdater.Manager;
using ModpackUpdater.Model;
using Castle.Core.Logging;
using ModpackUpdater.Manager;
using Newtonsoft.Json;
using Pilz;
using Pilz.Configuration;
using System.Runtime.InteropServices;
using Telerik.WinControls;
namespace ModpackUpdater;
[assembly: AssemblyAppVersion("1.6.3.0")]
namespace ModpackUpdater.Apps.Client;
public static class Program
{
private static readonly SettingsManager settingsManager;
private static readonly ILogger log = new ConsoleLogger();
public static ISettings Settings => settingsManager.Instance;
public static ILogger Log => log;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
static extern nint GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
static extern bool ShowWindow(nint hWnd, int nCmdShow);
static Program()
{
@@ -29,13 +34,10 @@ public static class Program
internal static void Main(string[] args)
{
var options = new Options(args);
if (options.NoUi)
{
if (options.Help)
options.DrawHelp();
else
else if (options.NoUi)
InstallWithoutGui(options.UpdateOptions, options.Silent);
}
else
{
ShowWindow(GetConsoleWindow(), 0);
@@ -48,14 +50,11 @@ public static class Program
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
if (ThemeResolutionService.LoadPackageResource("ModpackUpdater.CustomThemes.Office2019DarkBluePurple.tssp"))
ThemeResolutionService.ApplicationThemeName = "Office2019DarkBluePurple";
AppGlobals.Initialize();
Application.Run(new Form1(updateOptions));
}
private static string GetSettingsPath(int? settingsVersion = 2)
private static string GetSettingsPath(int? settingsVersion = 3)
{
const string AppDataDirectoryName = "MinecraftModpackUpdater";
var fileNamePostfix = settingsVersion == null ? string.Empty : $"V{settingsVersion}";
@@ -79,11 +78,8 @@ public static class Program
newConfig.LastMinecraftProfilePath = legacyConfig.LastMinecraftProfilePath;
if (ModpackInfo.TryLoad(legacyConfig.LastMinecraftProfilePath) is ModpackInfo info)
{
#pragma warning disable CS0612 // Typ oder Element ist veraltet
info.ConfigUrl = legacyConfig.ConfigFilePath;
#pragma warning restore CS0612 // Typ oder Element ist veraltet
}
// Ensure save settings
settingsManager.Save();
@@ -105,20 +101,23 @@ public static class Program
updateOptions.IncludeExtras = features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(info));
// Check for update
var installer = new ModpackInstaller(config, info);
var installer = new ModpackInstaller(config, info)
{
Log = Log,
};
var result = installer.Check(updateOptions).Result;
if (!silent && !updateOptions.NoUpdate && new AppUpdater().Check().Result)
Console.WriteLine("A new version is available!");
Log.Info("A new version is available!");
if (result.HasUpdates)
{
var success = installer.Install(result).Result;
if (!silent)
Console.WriteLine($"Installation {(success ?? false ? "completed successfully" : "failed")}!");
Log.Info($"Installation {(success ?? false ? "completed successfully" : "failed")}!");
}
else if (!silent)
Console.WriteLine("No updates available");
Log.Info("No updates available");
}
private static string CheckModpackConfigUrl(string configUrl, ModpackInfo info)

View File

@@ -11,7 +11,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0-windows</TargetFramework>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>

View File

@@ -1,6 +1,6 @@
using ModpackUpdater.Manager;
namespace ModpackUpdater;
namespace ModpackUpdater.Apps.Client;
public class UpdateCheckOptionsAdv : UpdateCheckOptions
{

View File

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -0,0 +1,14 @@
namespace ModpackUpdater.Apps.Manager.Api.Model;
public interface IMainApi
{
IWorkspace? CurWorkspace { get; }
IActionSetInfos? CurActionSet { get; }
Form MainWindow { get; }
void UpdateItem(InstallAction action);
void UpdateItem(IActionSetInfos actionSetInfos);
}

View File

@@ -0,0 +1,19 @@
using System.Diagnostics.CodeAnalysis;
namespace ModpackUpdater.Apps.Manager.Api.Model;
public interface IWorkspace
{
WorkspaceConfig Config { get; }
ModpackConfig? ModpackConfig { get; }
InstallInfos? InstallInfos { get; }
UpdateInfos? UpdateInfos { get; }
[MemberNotNullWhen(true, nameof(InstallInfos), nameof(UpdateInfos))]
Task<bool> Load();
Task<bool> Save();
}

View File

@@ -0,0 +1,14 @@
using Newtonsoft.Json;
namespace ModpackUpdater.Apps.Manager.Api.Model;
public abstract class WorkspaceConfig
{
[JsonProperty]
public string ProviderId { get; internal set; } = "origin.unknown";
[JsonIgnore]
public abstract string DisplayText { get; }
public string? ModpackConfigUrl { get; set; }
}

View File

@@ -0,0 +1,34 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using Pilz.Plugins.Advanced;
namespace ModpackUpdater.Apps.Manager.Api.Plugins.Features;
public abstract class WorkspaceFeature(string identifier, string name) : PluginFeature(FeatureTypes.Workspace, identifier, name)
{
public virtual bool CanConfigure(IWorkspace workspace)
{
return workspace?.Config == null || workspace.Config.ProviderId == Identifier;
}
public virtual bool Configure(ref IWorkspace? workspace)
{
OnConfigure(ref workspace);
if (workspace?.Config is null)
return false;
workspace.Config.ProviderId = Identifier;
return true;
}
public virtual IWorkspace CreateFromConfig(WorkspaceConfig config)
{
OnCreate(out var workspace, config);
return workspace;
}
protected abstract void OnCreate(out IWorkspace workspace, WorkspaceConfig config);
protected abstract bool OnConfigure(ref IWorkspace? workspace);
}

View File

@@ -0,0 +1,9 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using Pilz.Plugins.Advanced;
namespace ModpackUpdater.Apps.Manager.Api.Plugins.Params;
public class MainApiParameters(IMainApi api) : PluginFunctionParameter
{
public IMainApi Api { get; } = api;
}

View File

@@ -0,0 +1,11 @@
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

@@ -0,0 +1,8 @@
namespace ModpackUpdater.Apps.Manager;
public static class FeatureTypes
{
public static string Workspace => "workspace";
public static string Tools => "tools";
public static string ActionsContextMenu => "cm.actions";
}

View File

@@ -0,0 +1,31 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM;
internal class CheckSingleActionHealthyFeature : PluginFunction, IPluginFeatureProvider<CheckSingleActionHealthyFeature>
{
public static CheckSingleActionHealthyFeature Instance { get; } = new();
public CheckSingleActionHealthyFeature() : base(FeatureTypes.ActionsContextMenu, "origin.checksingleactionhearlthy", FeatureNamesLangRes.CheckSingleActionHealthy)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.heart_with_pulse, Pilz.UI.Symbols.SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p
|| 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;
SharedFunctions.CheckActionHealthy(p.Api, row);
return null;
}
}

View File

@@ -0,0 +1,30 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM;
internal class ClearDirectLinkFeature : PluginFunction, IPluginFeatureProvider<ClearDirectLinkFeature>
{
public static ClearDirectLinkFeature Instance { get; } = new();
public ClearDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.cleardirectlink", FeatureNamesLangRes.ClearDirectLinkFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p
|| 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;
SharedFunctions.ClearDirectLinks(p.Api, selectedAction);
return null;
}
}

View File

@@ -0,0 +1,31 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced;
using Pilz.UI.Symbols;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM;
internal class UpdateCollectorFeature : PluginFunction, IPluginFeatureProvider<UpdateCollectorFeature>
{
public static UpdateCollectorFeature Instance { get; } = new();
public UpdateCollectorFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatecollector", FeatureNamesLangRes.UpdateCollectorFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.search, SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p
|| 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;
SharedFunctions.CollectUpdates(p.Api, selectedAction);
return null;
}
}

View File

@@ -0,0 +1,30 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM;
internal class UpdateDirectLinkFeature : PluginFunction, IPluginFeatureProvider<UpdateDirectLinkFeature>
{
public static UpdateDirectLinkFeature Instance { get; } = new();
public UpdateDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatedirectlink", FeatureNamesLangRes.UpdateDirectLinkFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.renew, Pilz.UI.Symbols.SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p
|| 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;
SharedFunctions.FindNewDirectLinks(p.Api, selectedAction);
return null;
}
}

View File

@@ -0,0 +1,205 @@
using Microsoft.Extensions.Primitives;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Ui;
using ModpackUpdater.Manager;
using Pilz.UI.Extensions;
using System.Text;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features;
internal static class SharedFunctions
{
public static bool CheckActionHealthy(IMainApi api, params GridViewRowInfo[] selectedRows)
{
if (api.MainWindow is not MainForm mainForm
|| 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 msg = default(string);
var factory = new ModpackFactory();
var rows = new Dictionary<GridViewRowInfo, InstallAction>();
for (var i = 0; i < selectedRows.Length; i++)
{
var row = selectedRows[i];
if (row.Tag is InstallAction action)
{
Task.Run(async () =>
{
try
{
var result = await factory.ResolveSourceUrl(action);
failed = string.IsNullOrWhiteSpace(result);
}
catch (Exception ex)
{
msg = ex.Message;
}
}).Wait();
}
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))
MessageBox.Show(msg);
return true;
}
public static bool CollectUpdates(IMainApi api, params InstallAction[] actions)
{
if (api.CurWorkspace?.UpdateInfos is null)
return false;
// Collect updates
var ucDialog = new UpdatesCollectorUi(api.CurWorkspace, actions);
if (!ucDialog.ShowDialog(api.MainWindow).IsOk() || ucDialog.CurrentUpdates is null)
return false;
// Collect versions with changes
var updates = new List<UpdatesCollectorUi.ModUpdateInfo>();
foreach (var update in ucDialog.CurrentUpdates.List)
{
if (update.Origin.SourceTag != update.AvailableVersions[update.NewVersion].Value)
updates.Add(update);
}
// Path install actions
foreach (var update in updates)
{
update.Origin.SourceTag = update.AvailableVersions[update.NewVersion].Value;
api.UpdateItem(update.Origin);
}
// Create update actions
var updateSet = new UpdateInfo();
foreach (var update in updates)
{
updateSet.Actions.Add(new()
{
InheritFrom = update.Origin.Id,
});
}
api.CurWorkspace.UpdateInfos.Updates.Insert(0, updateSet);
api.UpdateItem(updateSet);
return true;
}
public static void FindNewDirectLinks(IMainApi api, params InstallAction[] actions)
{
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();
rwb?.StartWaiting();
gridView?.BeginUpdate();
foreach (var action in actions)
{
if (action.SourceType != SourceType.DirectLink)
{
Task.Run(async () =>
{
action.SourceUrl = await factory.ResolveSourceUrl(action);
}).Wait();
api.UpdateItem(action);
}
}
gridView?.EndUpdate();
rwb?.StopWaiting();
}
public static void ClearDirectLinks(IMainApi api, params InstallAction[] actions)
{
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;
rwb?.StartWaiting();
gridView?.BeginUpdate();
foreach (var action in actions)
{
if (action.SourceType != SourceType.DirectLink)
{
action.SourceUrl = null;
api.UpdateItem(action);
}
}
gridView?.EndUpdate();
rwb?.StopWaiting();
}
public static string GenerateChangelog(InstallInfos installInfos, UpdateInfo updateInfos)
{
var log = new StringBuilder();
foreach (var action in updateInfos.Actions.OrderBy(n => n.Type))
{
// Create copy
var copy = new UpdateAction();
ModpackInstaller.DuplicateTo(action, copy);
// Resolve inherit
if (!string.IsNullOrWhiteSpace(copy.InheritFrom))
ModpackInstaller.ResolveInherit(copy, installInfos);
if (string.IsNullOrWhiteSpace(copy.Name) || copy.Type != UpdateActionType.Update)
continue;
// Append bullet
log.Append('-');
// Append action indicator
log.Append(' ');
log.Append("⚒️");
// Append name
log.Append(' ');
log.Append("**");
log.Append(copy.Name);
log.Append("**");
// Append new version
if (!string.IsNullOrWhiteSpace(copy.SourceTag))
{
log.Append(' ');
log.Append('`');
log.Append(copy.SourceTag);
log.Append('`');
}
// Append new line
log.AppendLine();
}
return log.ToString().TrimEnd();
}
}

View File

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

View File

@@ -0,0 +1,25 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced;
namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class ClearDirectLinksFeature : PluginFunction, IPluginFeatureProvider<ClearDirectLinksFeature>
{
public static ClearDirectLinksFeature Instance { get; } = new();
public ClearDirectLinksFeature() : base(FeatureTypes.Tools, "origin.cleardirectlinks", FeatureNamesLangRes.ClearDirectLinksFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null)
return null;
SharedFunctions.ClearDirectLinks(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]);
return null;
}
}

View File

@@ -0,0 +1,31 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced;
using Telerik.WinControls;
namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class GenerateChangelogFeature : PluginFunction, IPluginFeatureProvider<GenerateChangelogFeature>
{
public static GenerateChangelogFeature Instance { get; } = new();
public GenerateChangelogFeature() : base(FeatureTypes.Tools, "origin.genchangelog", FeatureNamesLangRes.GenerateChangelogFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.time_machine, Pilz.UI.Symbols.SymbolSize.Small);
}
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)
return null;
var changelog = SharedFunctions.GenerateChangelog(p.Api.CurWorkspace.InstallInfos, updateInfos);
if (!string.IsNullOrWhiteSpace(changelog))
{
Clipboard.SetText(changelog);
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ChangelogCopiedToClipboard, MsgBoxLangRes.ChangelogCopiedToClipboard_Title, MessageBoxButtons.OK, RadMessageIcon.Info);
}
return null;
}
}

View File

@@ -0,0 +1,25 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced;
namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class UpdateDirectLinksFeature : PluginFunction, IPluginFeatureProvider<UpdateDirectLinksFeature>
{
public static UpdateDirectLinksFeature Instance { get; } = new();
public UpdateDirectLinksFeature() : base(FeatureTypes.Tools, "origin.updatedirectlinks", FeatureNamesLangRes.UpdateDirectLinksFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.renew, Pilz.UI.Symbols.SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null)
return null;
SharedFunctions.FindNewDirectLinks(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]);
return null;
}
}

View File

@@ -0,0 +1,26 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class UpdatesCollectorFeature : PluginFunction, IPluginFeatureProvider<UpdatesCollectorFeature>
{
public static UpdatesCollectorFeature Instance { get; } = new();
public UpdatesCollectorFeature() : base(FeatureTypes.Tools, "origin.updatescollector", FeatureNamesLangRes.UpdatesCollectorFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.search, SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null)
return null;
SharedFunctions.CollectUpdates(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]);
return null;
}
}

View File

@@ -0,0 +1,93 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using NGitLab;
using NGitLab.Models;
using System.Text.Encodings.Web;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspace
{
private string? rawInstallInfos = null;
private string? rawUpdateInfos = null;
public WorkspaceConfig Config => ConfigX;
public GitLabRepoWorkspaceConfig ConfigX { get; } = config;
public IGitLabClient Gitlab { get; } = new GitLabClient(config.InstanceUrl, config.ApiToken);
public ModpackConfig? ModpackConfig { get; private set; }
public InstallInfos? InstallInfos { get; private set; }
public UpdateInfos? UpdateInfos { get; private set; }
public async Task<bool> Load()
{
if (!string.IsNullOrWhiteSpace(Config.ModpackConfigUrl))
ModpackConfig = ModpackConfig.LoadFromUrl(Config.ModpackConfigUrl);
rawInstallInfos = await GetContent(ConfigX.FileLocationInstallJson);
InstallInfos = InstallInfos.Parse(rawInstallInfos);
rawUpdateInfos = await GetContent(ConfigX.FileLocationUpdateJson);
UpdateInfos = UpdateInfos.Parse(rawUpdateInfos);
ConfigX.RepoName = (await Gitlab.Projects.GetByIdAsync((int)ConfigX.RepoId, new())).Name;
return InstallInfos != null && UpdateInfos != null;
}
public async Task<bool> Save()
{
if (InstallInfos != null)
{
var newInstallInfos = InstallInfos.ToString();
if (newInstallInfos != rawInstallInfos)
{
await SaveContent(ConfigX.FileLocationInstallJson, newInstallInfos);
rawInstallInfos = newInstallInfos;
}
}
if (UpdateInfos != null)
{
var newUpdateInfos = UpdateInfos.ToString();
if (newUpdateInfos != rawUpdateInfos)
{
await SaveContent(ConfigX.FileLocationUpdateJson, newUpdateInfos);
rawUpdateInfos = newUpdateInfos;
}
}
return true;
}
private async Task<string> GetContent(string path)
{
var repoId = new ProjectId(ConfigX.RepoId);
var repo = Gitlab.GetRepository(repoId);
var data = await repo.Files.GetAsync(path, ConfigX.RepoBranche);
return data.DecodedContent;
}
private Task<bool> SaveContent(string path, string content)
{
var repoId = new ProjectId(ConfigX.RepoId);
var repo = Gitlab.GetRepository(repoId);
var update = new FileUpsert
{
Branch = ConfigX.RepoBranche,
CommitMessage = "update " + Path.GetFileName(path),
RawContent = content,
Path = path,
};
if (repo.Files.FileExists(path, ConfigX.RepoBranche))
repo.Files.Update(update);
else
repo.Files.Create(update);
return Task.FromResult(true);
}
}

View File

@@ -0,0 +1,22 @@
using ModpackUpdater.Apps.Manager.Api.Model;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspaceConfig : WorkspaceConfig
{
public override string DisplayText => $"{RepoName ?? "?"} | {RepoBranche} | {InstanceUrl}";
public string? RepoName { get; set; }
public string InstanceUrl { get; set; } = "https://gitlab.com";
public string? ApiToken { get; set; }
public long RepoId { get; set; } = 0L;
public string RepoBranche { get; set; } = "master";
public string FileLocationInstallJson { get; set; } = "install.json";
public string FileLocationUpdateJson { get; set; } = "updates.json";
}

View File

@@ -0,0 +1,266 @@
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
partial class GitLabRepoWorkspaceConfigEditor
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
tableLayoutPanel1 = new TableLayoutPanel();
radTextBox_FileLocUpdateJson = new Telerik.WinControls.UI.RadTextBox();
radTextBox_FileLocInstallJson = new Telerik.WinControls.UI.RadTextBox();
radTextBox_RepoBranche = new Telerik.WinControls.UI.RadTextBox();
radSpinEditor_RepoId = new Telerik.WinControls.UI.RadSpinEditor();
radTextBox_ApiToken = new Telerik.WinControls.UI.RadTextBox();
radTextBox_InstanceUrl = new Telerik.WinControls.UI.RadTextBox();
radLabel1 = new Telerik.WinControls.UI.RadLabel();
radLabel2 = new Telerik.WinControls.UI.RadLabel();
radLabel3 = new Telerik.WinControls.UI.RadLabel();
radLabel4 = new Telerik.WinControls.UI.RadLabel();
radLabel5 = new Telerik.WinControls.UI.RadLabel();
radLabel6 = new Telerik.WinControls.UI.RadLabel();
radLabel7 = new Telerik.WinControls.UI.RadLabel();
radTextBox_ModpackConfigUrl = new Telerik.WinControls.UI.RadTextBox();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocUpdateJson).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocInstallJson).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_RepoBranche).BeginInit();
((System.ComponentModel.ISupportInitialize)radSpinEditor_RepoId).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ApiToken).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstanceUrl).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel2).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel3).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel4).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel5).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel6).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel7).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ModpackConfigUrl).BeginInit();
SuspendLayout();
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(radTextBox_FileLocUpdateJson, 0, 11);
tableLayoutPanel1.Controls.Add(radTextBox_FileLocInstallJson, 0, 9);
tableLayoutPanel1.Controls.Add(radTextBox_RepoBranche, 0, 7);
tableLayoutPanel1.Controls.Add(radSpinEditor_RepoId, 0, 5);
tableLayoutPanel1.Controls.Add(radTextBox_ApiToken, 0, 3);
tableLayoutPanel1.Controls.Add(radTextBox_InstanceUrl, 0, 1);
tableLayoutPanel1.Controls.Add(radLabel1, 0, 0);
tableLayoutPanel1.Controls.Add(radLabel2, 0, 2);
tableLayoutPanel1.Controls.Add(radLabel3, 0, 4);
tableLayoutPanel1.Controls.Add(radLabel4, 0, 6);
tableLayoutPanel1.Controls.Add(radLabel5, 0, 8);
tableLayoutPanel1.Controls.Add(radLabel6, 0, 10);
tableLayoutPanel1.Controls.Add(radLabel7, 0, 12);
tableLayoutPanel1.Controls.Add(radTextBox_ModpackConfigUrl, 0, 13);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 30);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 14;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(300, 406);
tableLayoutPanel1.TabIndex = 4;
//
// radTextBox_FileLocUpdateJson
//
radTextBox_FileLocUpdateJson.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_FileLocUpdateJson.Location = new Point(3, 321);
radTextBox_FileLocUpdateJson.Name = "radTextBox_FileLocUpdateJson";
radTextBox_FileLocUpdateJson.Size = new Size(294, 24);
radTextBox_FileLocUpdateJson.TabIndex = 4;
//
// radTextBox_FileLocInstallJson
//
radTextBox_FileLocInstallJson.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_FileLocInstallJson.Location = new Point(3, 263);
radTextBox_FileLocInstallJson.Name = "radTextBox_FileLocInstallJson";
radTextBox_FileLocInstallJson.Size = new Size(294, 24);
radTextBox_FileLocInstallJson.TabIndex = 3;
//
// radTextBox_RepoBranche
//
radTextBox_RepoBranche.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_RepoBranche.Location = new Point(3, 205);
radTextBox_RepoBranche.Name = "radTextBox_RepoBranche";
radTextBox_RepoBranche.Size = new Size(294, 24);
radTextBox_RepoBranche.TabIndex = 2;
//
// radSpinEditor_RepoId
//
radSpinEditor_RepoId.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radSpinEditor_RepoId.Location = new Point(3, 147);
radSpinEditor_RepoId.Maximum = new decimal(new int[] { -1, int.MaxValue, 0, 0 });
radSpinEditor_RepoId.Name = "radSpinEditor_RepoId";
radSpinEditor_RepoId.Size = new Size(294, 24);
radSpinEditor_RepoId.TabIndex = 6;
//
// radTextBox_ApiToken
//
radTextBox_ApiToken.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_ApiToken.Location = new Point(3, 89);
radTextBox_ApiToken.Name = "radTextBox_ApiToken";
radTextBox_ApiToken.Size = new Size(294, 24);
radTextBox_ApiToken.TabIndex = 1;
//
// radTextBox_InstanceUrl
//
radTextBox_InstanceUrl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_InstanceUrl.Location = new Point(3, 31);
radTextBox_InstanceUrl.Name = "radTextBox_InstanceUrl";
radTextBox_InstanceUrl.Size = new Size(294, 24);
radTextBox_InstanceUrl.TabIndex = 0;
//
// radLabel1
//
radLabel1.Location = new Point(3, 3);
radLabel1.Name = "radLabel1";
radLabel1.Size = new Size(80, 22);
radLabel1.TabIndex = 7;
radLabel1.Text = "Instance url";
//
// radLabel2
//
radLabel2.Location = new Point(3, 61);
radLabel2.Name = "radLabel2";
radLabel2.Size = new Size(69, 22);
radLabel2.TabIndex = 8;
radLabel2.Text = "Api token";
//
// radLabel3
//
radLabel3.Location = new Point(3, 119);
radLabel3.Name = "radLabel3";
radLabel3.Size = new Size(91, 22);
radLabel3.TabIndex = 9;
radLabel3.Text = "Repository id";
//
// radLabel4
//
radLabel4.Location = new Point(3, 177);
radLabel4.Name = "radLabel4";
radLabel4.Size = new Size(130, 22);
radLabel4.TabIndex = 10;
radLabel4.Text = "Repository branche";
//
// radLabel5
//
radLabel5.Location = new Point(3, 235);
radLabel5.Name = "radLabel5";
radLabel5.Size = new Size(181, 22);
radLabel5.TabIndex = 11;
radLabel5.Text = "File location for install infos";
//
// radLabel6
//
radLabel6.Location = new Point(3, 293);
radLabel6.Name = "radLabel6";
radLabel6.Size = new Size(189, 22);
radLabel6.TabIndex = 12;
radLabel6.Text = "File location for updates info";
//
// radLabel7
//
radLabel7.Location = new Point(3, 351);
radLabel7.Name = "radLabel7";
radLabel7.Size = new Size(131, 22);
radLabel7.TabIndex = 13;
radLabel7.Text = "Modpack config url";
//
// radTextBox_ModpackConfigUrl
//
radTextBox_ModpackConfigUrl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_ModpackConfigUrl.Location = new Point(3, 379);
radTextBox_ModpackConfigUrl.Name = "radTextBox_ModpackConfigUrl";
radTextBox_ModpackConfigUrl.Size = new Size(294, 24);
radTextBox_ModpackConfigUrl.TabIndex = 14;
//
// GitLabRepoWorkspaceConfigEditor
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
BackColor = Color.Transparent;
Controls.Add(tableLayoutPanel1);
MinimumSize = new Size(300, 0);
Name = "GitLabRepoWorkspaceConfigEditor";
Size = new Size(300, 466);
Controls.SetChildIndex(tableLayoutPanel1, 0);
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocUpdateJson).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocInstallJson).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_RepoBranche).EndInit();
((System.ComponentModel.ISupportInitialize)radSpinEditor_RepoId).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ApiToken).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstanceUrl).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel2).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel3).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel4).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel5).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel6).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel7).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ModpackConfigUrl).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadTextBox radTextBox_InstanceUrl;
private Telerik.WinControls.UI.RadTextBox radTextBox_ApiToken;
private Telerik.WinControls.UI.RadTextBox radTextBox_RepoBranche;
private Telerik.WinControls.UI.RadTextBox radTextBox_FileLocInstallJson;
private Telerik.WinControls.UI.RadTextBox radTextBox_FileLocUpdateJson;
private Telerik.WinControls.UI.RadSpinEditor radSpinEditor_RepoId;
private Telerik.WinControls.UI.RadLabel radLabel1;
private Telerik.WinControls.UI.RadLabel radLabel2;
private Telerik.WinControls.UI.RadLabel radLabel3;
private Telerik.WinControls.UI.RadLabel radLabel4;
private Telerik.WinControls.UI.RadLabel radLabel5;
private Telerik.WinControls.UI.RadLabel radLabel6;
private Telerik.WinControls.UI.RadLabel radLabel7;
private Telerik.WinControls.UI.RadTextBox radTextBox_ModpackConfigUrl;
}

View File

@@ -0,0 +1,45 @@
using Pilz.UI;
using Pilz.UI.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal partial class GitLabRepoWorkspaceConfigEditor : RadFlyoutBase, ILoadContent
{
private readonly GitLabRepoWorkspaceConfig settings;
public GitLabRepoWorkspaceConfigEditor(GitLabRepoWorkspaceConfig settings)
{
this.settings = settings;
InitializeComponent();
var defaults = new GitLabRepoWorkspaceConfig();
radTextBox_InstanceUrl.NullText = defaults.InstanceUrl;
radTextBox_RepoBranche.NullText = defaults.RepoBranche;
radTextBox_FileLocInstallJson.NullText = defaults.InstanceUrl;
radTextBox_FileLocUpdateJson.NullText = defaults.FileLocationUpdateJson;
}
public void LoadContent()
{
radTextBox_InstanceUrl.Text = settings.InstanceUrl;
radTextBox_ApiToken.Text = settings.ApiToken;
radSpinEditor_RepoId.Value = settings.RepoId;
radTextBox_RepoBranche.Text = settings.RepoBranche;
radTextBox_FileLocInstallJson.Text = settings.FileLocationInstallJson;
radTextBox_FileLocUpdateJson.Text = settings.FileLocationUpdateJson;
radTextBox_ModpackConfigUrl.Text = settings.ModpackConfigUrl;
}
protected override bool ValidateOK()
{
settings.InstanceUrl = radTextBox_InstanceUrl.Text.Trim();
settings.ApiToken = radTextBox_ApiToken.Text.Trim();
settings.RepoId = (long)radSpinEditor_RepoId.Value;
settings.RepoBranche = radTextBox_RepoBranche.Text.Trim();
settings.FileLocationInstallJson = radTextBox_FileLocInstallJson.Text.Trim();
settings.FileLocationUpdateJson = radTextBox_FileLocUpdateJson.Text.Trim();
settings.ModpackConfigUrl = radTextBox_ModpackConfigUrl.Text.Trim();
return base.ValidateOK();
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,39 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced;
using Pilz.UI.Extensions;
using Pilz.UI.Symbols;
using Pilz.UI.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspaceFeature : WorkspaceFeature, IPluginFeatureProvider<GitLabRepoWorkspaceFeature>
{
public static GitLabRepoWorkspaceFeature Instance { get; } = new();
public GitLabRepoWorkspaceFeature() : base("origin.gitlab", FeatureNamesLangRes.GitLabWorkspace)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.gitlab, SymbolSize.Small);
}
protected override bool OnConfigure(ref IWorkspace? workspace)
{
var settings = workspace?.Config as GitLabRepoWorkspaceConfig ?? new();
if (RadDialogBase.ShowDialog(new GitLabRepoWorkspaceConfigEditor(settings), TitlesLangRes.GitLabRepoWorkspaceEditor, AppGlobals.Symbols.GetSvgImage(AppSymbols.gitlab, SymbolSize.Small)).Result.IsNotOk())
return false;
workspace = new GitLabRepoWorkspace(settings);
return true;
}
protected override void OnCreate(out IWorkspace workspace, WorkspaceConfig config)
{
if (config is not GitLabRepoWorkspaceConfig gitlabConfig)
throw new NotImplementedException($"Only configs of type {typeof(GitLabRepoWorkspaceConfig).Name} are allowed.");
workspace = new GitLabRepoWorkspace(gitlabConfig);
}
}

View File

@@ -0,0 +1,225 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ActionsListLangRes {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal ActionsListLangRes() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.ActionsListLangRes", typeof(ActionsListLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Destination path ähnelt.
/// </summary>
internal static string Col_DestPath {
get {
return ResourceManager.GetString("Col_DestPath", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Id ähnelt.
/// </summary>
internal static string Col_Id {
get {
return ResourceManager.GetString("Col_Id", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Inherit from ähnelt.
/// </summary>
internal static string Col_InheritFrom {
get {
return ResourceManager.GetString("Col_InheritFrom", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Is directory ähnelt.
/// </summary>
internal static string Col_IsDir {
get {
return ResourceManager.GetString("Col_IsDir", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Is Extra ähnelt.
/// </summary>
internal static string Col_IsExtra {
get {
return ResourceManager.GetString("Col_IsExtra", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Is ZIP ähnelt.
/// </summary>
internal static string Col_IsZip {
get {
return ResourceManager.GetString("Col_IsZip", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Name ähnelt.
/// </summary>
internal static string Col_Name {
get {
return ResourceManager.GetString("Col_Name", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Side ähnelt.
/// </summary>
internal static string Col_Side {
get {
return ResourceManager.GetString("Col_Side", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Source name ähnelt.
/// </summary>
internal static string Col_SrcName {
get {
return ResourceManager.GetString("Col_SrcName", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Source owner ähnelt.
/// </summary>
internal static string Col_SrcOwner {
get {
return ResourceManager.GetString("Col_SrcOwner", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Source path ähnelt.
/// </summary>
internal static string Col_SrcPath {
get {
return ResourceManager.GetString("Col_SrcPath", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Source RegEx ähnelt.
/// </summary>
internal static string Col_SrcRegEx {
get {
return ResourceManager.GetString("Col_SrcRegEx", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Source tag ähnelt.
/// </summary>
internal static string Col_SrcTag {
get {
return ResourceManager.GetString("Col_SrcTag", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Source type ähnelt.
/// </summary>
internal static string Col_SrcType {
get {
return ResourceManager.GetString("Col_SrcType", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Source URL ähnelt.
/// </summary>
internal static string Col_SrcUrl {
get {
return ResourceManager.GetString("Col_SrcUrl", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Update type ähnelt.
/// </summary>
internal static string Col_UpdateType {
get {
return ResourceManager.GetString("Col_UpdateType", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Website ähnelt.
/// </summary>
internal static string Col_Website {
get {
return ResourceManager.GetString("Col_Website", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ZIP archive path ähnelt.
/// </summary>
internal static string Col_ZipPath {
get {
return ResourceManager.GetString("Col_ZipPath", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Col_DestPath" xml:space="preserve">
<value>Destination path</value>
</data>
<data name="Col_Id" xml:space="preserve">
<value>Id</value>
</data>
<data name="Col_InheritFrom" xml:space="preserve">
<value>Inherit from</value>
</data>
<data name="Col_IsDir" xml:space="preserve">
<value>Is directory</value>
</data>
<data name="Col_IsExtra" xml:space="preserve">
<value>Is Extra</value>
</data>
<data name="Col_IsZip" xml:space="preserve">
<value>Is ZIP</value>
</data>
<data name="Col_Name" xml:space="preserve">
<value>Name</value>
</data>
<data name="Col_Side" xml:space="preserve">
<value>Side</value>
</data>
<data name="Col_SrcName" xml:space="preserve">
<value>Source name</value>
</data>
<data name="Col_SrcOwner" xml:space="preserve">
<value>Source owner</value>
</data>
<data name="Col_SrcPath" xml:space="preserve">
<value>Source path</value>
</data>
<data name="Col_SrcRegEx" xml:space="preserve">
<value>Source RegEx</value>
</data>
<data name="Col_SrcTag" xml:space="preserve">
<value>Source tag</value>
</data>
<data name="Col_SrcType" xml:space="preserve">
<value>Source type</value>
</data>
<data name="Col_SrcUrl" xml:space="preserve">
<value>Source URL</value>
</data>
<data name="Col_UpdateType" xml:space="preserve">
<value>Update type</value>
</data>
<data name="Col_Website" xml:space="preserve">
<value>Website</value>
</data>
<data name="Col_ZipPath" xml:space="preserve">
<value>ZIP archive path</value>
</data>
</root>

View File

@@ -0,0 +1,153 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class FeatureNamesLangRes {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal FeatureNamesLangRes() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.FeatureNamesLangRes", typeof(FeatureNamesLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Check healthy ähnelt.
/// </summary>
internal static string CheckAllActionsHealthy {
get {
return ResourceManager.GetString("CheckAllActionsHealthy", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Check healthy ähnelt.
/// </summary>
internal static string CheckSingleActionHealthy {
get {
return ResourceManager.GetString("CheckSingleActionHealthy", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Clear direct link ähnelt.
/// </summary>
internal static string ClearDirectLinkFeature {
get {
return ResourceManager.GetString("ClearDirectLinkFeature", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Clear direct links ähnelt.
/// </summary>
internal static string ClearDirectLinksFeature {
get {
return ResourceManager.GetString("ClearDirectLinksFeature", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Generate changelog ähnelt.
/// </summary>
internal static string GenerateChangelogFeature {
get {
return ResourceManager.GetString("GenerateChangelogFeature", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die GitLab workspace ähnelt.
/// </summary>
internal static string GitLabWorkspace {
get {
return ResourceManager.GetString("GitLabWorkspace", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Find update ähnelt.
/// </summary>
internal static string UpdateCollectorFeature {
get {
return ResourceManager.GetString("UpdateCollectorFeature", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Update direct link ähnelt.
/// </summary>
internal static string UpdateDirectLinkFeature {
get {
return ResourceManager.GetString("UpdateDirectLinkFeature", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Update direct links ähnelt.
/// </summary>
internal static string UpdateDirectLinksFeature {
get {
return ResourceManager.GetString("UpdateDirectLinksFeature", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Find updates ähnelt.
/// </summary>
internal static string UpdatesCollectorFeature {
get {
return ResourceManager.GetString("UpdatesCollectorFeature", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CheckAllActionsHealthy" xml:space="preserve">
<value>Check healthy</value>
</data>
<data name="CheckSingleActionHealthy" xml:space="preserve">
<value>Check healthy</value>
</data>
<data name="ClearDirectLinkFeature" xml:space="preserve">
<value>Clear direct link</value>
</data>
<data name="ClearDirectLinksFeature" xml:space="preserve">
<value>Clear direct links</value>
</data>
<data name="GenerateChangelogFeature" xml:space="preserve">
<value>Generate changelog</value>
</data>
<data name="GitLabWorkspace" xml:space="preserve">
<value>GitLab workspace</value>
</data>
<data name="UpdateCollectorFeature" xml:space="preserve">
<value>Find update</value>
</data>
<data name="UpdateDirectLinkFeature" xml:space="preserve">
<value>Update direct link</value>
</data>
<data name="UpdateDirectLinksFeature" xml:space="preserve">
<value>Update direct links</value>
</data>
<data name="UpdatesCollectorFeature" xml:space="preserve">
<value>Find updates</value>
</data>
</root>

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class GeneralLangRes {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal GeneralLangRes() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.GeneralLangRes", typeof(GeneralLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Installation: {0} ähnelt.
/// </summary>
internal static string Node_Install {
get {
return ResourceManager.GetString("Node_Install", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Update: {0} ähnelt.
/// </summary>
internal static string Node_Update {
get {
return ResourceManager.GetString("Node_Update", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Node_Install" xml:space="preserve">
<value>Installation: {0}</value>
</data>
<data name="Node_Update" xml:space="preserve">
<value>Update: {0}</value>
</data>
</root>

View File

@@ -0,0 +1,99 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class MsgBoxLangRes {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal MsgBoxLangRes() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.MsgBoxLangRes", typeof(MsgBoxLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The changelog for the selected version has been generated and copied to the clipboard. ähnelt.
/// </summary>
internal static string ChangelogCopiedToClipboard {
get {
return ResourceManager.GetString("ChangelogCopiedToClipboard", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Changelog generated successfully ähnelt.
/// </summary>
internal static string ChangelogCopiedToClipboard_Title {
get {
return ResourceManager.GetString("ChangelogCopiedToClipboard_Title", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Are you sure that you want to delete this update? ähnelt.
/// </summary>
internal static string RemoveUpdate {
get {
return ResourceManager.GetString("RemoveUpdate", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Remove update ähnelt.
/// </summary>
internal static string RemoveUpdate_Title {
get {
return ResourceManager.GetString("RemoveUpdate_Title", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ChangelogCopiedToClipboard" xml:space="preserve">
<value>The changelog for the selected version has been generated and copied to the clipboard.</value>
</data>
<data name="ChangelogCopiedToClipboard_Title" xml:space="preserve">
<value>Changelog generated successfully</value>
</data>
<data name="RemoveUpdate" xml:space="preserve">
<value>Are you sure that you want to delete this update?</value>
</data>
<data name="RemoveUpdate_Title" xml:space="preserve">
<value>Remove update</value>
</data>
</root>

View File

@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class TitlesLangRes {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal TitlesLangRes() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.TitlesLangRes", typeof(TitlesLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Create update ähnelt.
/// </summary>
internal static string CreateUpdate {
get {
return ResourceManager.GetString("CreateUpdate", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Edit update ähnelt.
/// </summary>
internal static string EditUpdate {
get {
return ResourceManager.GetString("EditUpdate", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Setup GitLab workspace ähnelt.
/// </summary>
internal static string GitLabRepoWorkspaceEditor {
get {
return ResourceManager.GetString("GitLabRepoWorkspaceEditor", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CreateUpdate" xml:space="preserve">
<value>Create update</value>
</data>
<data name="EditUpdate" xml:space="preserve">
<value>Edit update</value>
</data>
<data name="GitLabRepoWorkspaceEditor" xml:space="preserve">
<value>Setup GitLab workspace</value>
</data>
</root>

View File

@@ -0,0 +1,82 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>icons8_Windows_Update.ico</ApplicationIcon>
<AssemblyName>Minecraft Modpack Update Manager</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NGitLab" Version="6.59.0" />
<PackageReference Include="Pilz.Configuration" Version="3.2.0" />
<PackageReference Include="Pilz.Plugins.Advanced" Version="2.10.2" />
<PackageReference Include="Pilz.Plugins.Advanced.UI" Version="1.8.3" />
<PackageReference Include="Pilz.Plugins.Advanced.UI.Telerik" Version="1.7.2" />
<PackageReference Include="Pilz.UI" Version="2.3.14" />
<PackageReference Include="Pilz.UI.Telerik" Version="2.8.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2024.3.806" />
<PackageReference Include="UI.for.WinForms.GridView" Version="2024.3.806" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Apps\ModpackUpdater.Apps.csproj" />
<ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" />
<ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="LangRes\ActionsListLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ActionsListLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\FeatureNamesLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>FeatureNamesLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\GeneralLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>GeneralLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\MsgBoxLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>MsgBoxLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\TitlesLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>TitlesLangRes.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="LangRes\ActionsListLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ActionsListLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes\FeatureNamesLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>FeatureNamesLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes\GeneralLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>GeneralLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes\MsgBoxLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes\TitlesLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TitlesLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,45 @@
using Pilz;
using Pilz.Configuration;
using Pilz.Plugins.Advanced;
[assembly: AssemblyAppVersion("1.0.0.0")]
namespace ModpackUpdater.Apps.Manager;
public static class Program
{
private static readonly SettingsManager settingsManager;
public static ISettings Settings => settingsManager.Instance;
static Program()
{
settingsManager = new(GetSettingsPath(), true);
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
internal static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
AppGlobals.Initialize();
PluginFeatureController.Instance.RegisterAllOwn();
Application.Run(new Ui.MainForm());
}
private static string GetSettingsPath()
{
const string AppDataDirectoryName = "MinecraftModpackUpdateManager";
var SettingsFileName = $"Settings.json";
var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName);
Directory.CreateDirectory(settingsPath);
settingsPath = Path.Combine(settingsPath, SettingsFileName);
return settingsPath;
}
}

View File

@@ -0,0 +1,16 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using Pilz.Configuration;
namespace ModpackUpdater.Apps.Manager.Settings;
internal class WorkspaceSettings : IChildSettings, ISettingsIdentifier
{
public static string Identifier => "origin.workspaces";
public List<WorkspaceConfig> Workspaces { get; } = [];
public void Reset()
{
Workspaces.Clear();
}
}

View File

@@ -0,0 +1,353 @@
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 tableViewDefinition1 = 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();
radListControl_Updates = new Telerik.WinControls.UI.RadListControl();
splitPanel2 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel1 = new TableLayoutPanel();
radGridView_Actions = new Telerik.WinControls.UI.RadGridView();
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();
radMenuItem_OpenNewWorkspace = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_RecentWorkspaces = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_Tools = new Telerik.WinControls.UI.RadMenuItem();
radMenu1 = new Telerik.WinControls.UI.RadMenu();
radMenuItem_Updates = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_EditUpdate = new Telerik.WinControls.UI.RadMenuItem();
radMenuSeparatorItem2 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
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();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit();
radSplitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit();
splitPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radListControl_Updates).BeginInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).BeginInit();
splitPanel2.SuspendLayout();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).BeginInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).BeginInit();
((System.ComponentModel.ISupportInitialize)radMenu1).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).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.RootElement.MinSize = new Size(25, 25);
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.RootElement.MinSize = new Size(25, 25);
splitPanel1.Size = new Size(200, 422);
splitPanel1.SizeInfo.AutoSizeScale = new SizeF(-0.190954775F, 0F);
splitPanel1.SizeInfo.SizeMode = Telerik.WinControls.UI.Docking.SplitPanelSizeMode.Absolute;
splitPanel1.SizeInfo.SplitterCorrection = new Size(-152, 0);
splitPanel1.TabIndex = 0;
splitPanel1.TabStop = false;
//
// tableLayoutPanel2
//
tableLayoutPanel2.ColumnCount = 1;
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel2.Controls.Add(radListControl_Updates, 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(200, 422);
tableLayoutPanel2.TabIndex = 1;
//
// radListControl_Updates
//
radListControl_Updates.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radListControl_Updates.ItemHeight = 24;
radListControl_Updates.Location = new Point(3, 3);
radListControl_Updates.Name = "radListControl_Updates";
radListControl_Updates.Size = new Size(194, 416);
radListControl_Updates.TabIndex = 0;
radListControl_Updates.SelectedIndexChanged += RadListControl_Updates_SelectedIndexChanged;
//
// splitPanel2
//
splitPanel2.Controls.Add(tableLayoutPanel1);
splitPanel2.Location = new Point(204, 0);
splitPanel2.Name = "splitPanel2";
//
//
//
splitPanel2.RootElement.MinSize = new Size(25, 25);
splitPanel2.Size = new Size(596, 422);
splitPanel2.SizeInfo.AutoSizeScale = new SizeF(0.190954745F, 0F);
splitPanel2.SizeInfo.SplitterCorrection = new Size(152, 0);
splitPanel2.TabIndex = 1;
splitPanel2.TabStop = false;
//
// tableLayoutPanel1
//
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel1.Controls.Add(radGridView_Actions, 0, 0);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 0);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 1;
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
tableLayoutPanel1.Size = new Size(596, 422);
tableLayoutPanel1.TabIndex = 0;
//
// radGridView_Actions
//
radGridView_Actions.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radGridView_Actions.Location = new Point(3, 3);
//
//
//
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 = tableViewDefinition1;
radGridView_Actions.Name = "radGridView_Actions";
radGridView_Actions.Size = new Size(590, 416);
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;
//
// radMenuItem_Workspace
//
radMenuItem_Workspace.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_WorkspacePreferences, radMenuItem_SaveWorkspace, radMenuSeparatorItem1, radMenuItem_OpenNewWorkspace, radMenuItem_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;
//
// radMenuItem_OpenNewWorkspace
//
radMenuItem_OpenNewWorkspace.Name = "radMenuItem_OpenNewWorkspace";
radMenuItem_OpenNewWorkspace.Text = "Open new workspace";
//
// radMenuItem_RecentWorkspaces
//
radMenuItem_RecentWorkspaces.Name = "radMenuItem_RecentWorkspaces";
radMenuItem_RecentWorkspaces.Text = "Recent workspaces";
//
// radMenuItem_Tools
//
radMenuItem_Tools.Name = "radMenuItem_Tools";
radMenuItem_Tools.Text = "Tools";
//
// 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;
//
// radMenuItem_Updates
//
radMenuItem_Updates.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_EditUpdate, radMenuSeparatorItem2, radMenuItem_CreateUpdate, radMenuItem_RemoveUpdate });
radMenuItem_Updates.Name = "radMenuItem_Updates";
radMenuItem_Updates.Text = "Updates";
radMenuItem_Updates.DropDownOpening += RadMenuItem_Updates_DropDownOpening;
//
// radMenuItem_EditUpdate
//
radMenuItem_EditUpdate.Name = "radMenuItem_EditUpdate";
radMenuItem_EditUpdate.Text = "Edit";
radMenuItem_EditUpdate.Click += RadMenuItem_EditUpdate_Click;
//
// radMenuSeparatorItem2
//
radMenuSeparatorItem2.Name = "radMenuSeparatorItem2";
radMenuSeparatorItem2.Text = "radMenuSeparatorItem2";
radMenuSeparatorItem2.TextAlignment = ContentAlignment.MiddleLeft;
//
// 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 = radListControl_Updates;
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";
//
// 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)radListControl_Updates).EndInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).EndInit();
splitPanel2.ResumeLayout(false);
tableLayoutPanel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).EndInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).EndInit();
((System.ComponentModel.ISupportInitialize)radMenu1).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).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 tableLayoutPanel1;
private Telerik.WinControls.UI.RadGridView radGridView_Actions;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem1;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_OpenNewWorkspace;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_RecentWorkspaces;
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.RadListControl radListControl_Updates;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Updates;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_EditUpdate;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem2;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_CreateUpdate;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_RemoveUpdate;
}

View File

@@ -0,0 +1,599 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Settings;
using Pilz.Plugins.Advanced;
using Pilz.Plugins.Advanced.UI.Telerik;
using Pilz.UI.Extensions;
using Pilz.UI.Symbols;
using Pilz.UI.Telerik.Dialogs;
using Pilz.UI.Telerik.Extensions.Extensions;
using Telerik.WinControls;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class MainForm : RadForm, IMainApi
{
private WorkspaceTag? wsInfo;
Form IMainApi.MainWindow => this;
IWorkspace? IMainApi.CurWorkspace => wsInfo?.Workspace;
public IActionSetInfos? CurActionSet => radListControl_Updates.SelectedValue as IActionSetInfos;
private record RecentFilesItemTag(WorkspaceConfig Config, WorkspaceFeature Feature);
private record WorkspaceTag(IWorkspace Workspace, WorkspaceFeature Feature);
public MainForm()
{
InitializeComponent();
radMenuItem_Workspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.workspace, SymbolSize.Small);
radMenuItem_WorkspacePreferences.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.settings, SymbolSize.Small);
radMenuItem_SaveWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.save, SymbolSize.Small);
radMenuItem_OpenNewWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.new_window, SymbolSize.Small);
radMenuItem_RecentWorkspaces.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.time_machine, SymbolSize.Small);
radMenuItem_Updates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small);
radMenuItem_EditUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.edit, SymbolSize.Small);
radMenuItem_CreateUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.add, SymbolSize.Small);
radMenuItem_RemoveUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.remove, SymbolSize.Small);
radMenuItem_Tools.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.tools, SymbolSize.Small);
radMenuItem_SaveWorkspace.Shortcuts.Add(new(Keys.Control, Keys.S));
PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).InsertItemsTo(radMenuItem_OpenNewWorkspace.Items, customClickHandler: RadMenuItem_OpenNewWorkspace_Click);
PluginFeatureController.Instance.Functions.Get(FeatureTypes.Tools).InsertItemsTo(radMenuItem_Tools.Items, customClickHandler: RadMenuItem_ToolsItem_Click);
}
private void LoadRecentWorkspaces()
{
var settings = Program.Settings.Get<WorkspaceSettings>();
radMenuItem_RecentWorkspaces.Items.Clear();
foreach (var config in settings.Workspaces.ToArray())
{
if (PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).OfType<WorkspaceFeature>().FirstOrDefault(n => n.Identifier == config.ProviderId) is not WorkspaceFeature feature)
{
settings.Workspaces.Remove(config);
continue;
}
var item = new RadMenuItem
{
Text = config.DisplayText,
Tag = new RecentFilesItemTag(config, feature),
SvgImage = feature.Icon as RadSvgImage,
};
item.Click += RadMenuItem_OpenRecentWorkspace_Click;
radMenuItem_RecentWorkspaces.Items.Add(item);
}
if (radMenuItem_RecentWorkspaces.Items.Any())
radMenuItem_RecentWorkspaces.Visibility = ElementVisibility.Visible;
else
radMenuItem_RecentWorkspaces.Visibility = ElementVisibility.Collapsed;
}
private 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 async Task LoadNewWorkspace(IWorkspace? workspace, WorkspaceFeature feature)
{
if (workspace is null)
return;
if (workspace != wsInfo?.Workspace)
wsInfo = new(workspace, feature);
AddToRecentFiles(workspace);
Invoke(LoadRecentWorkspaces);
radWaitingBar_Updates.StartWaiting();
if (!await workspace.Load())
{
radWaitingBar_Updates.StopWaiting();
return;
}
Invoke(LoadWorkspace);
}
private void LoadWorkspace()
{
if (wsInfo?.Workspace.Config is null || wsInfo.Workspace.InstallInfos is null || wsInfo.Workspace.UpdateInfos is null)
return;
radWaitingBar_Updates.StartWaiting();
Text = wsInfo.Workspace.Config.DisplayText;
radListControl_Updates.BeginUpdate();
radListControl_Updates.Items.Clear();
AddUpdateItem(wsInfo.Workspace.InstallInfos);
wsInfo.Workspace.UpdateInfos.Updates.ForEach(n => AddUpdateItem(n));
radListControl_Updates.EndUpdate();
radWaitingBar_Updates.StopWaiting();
}
private RadListDataItem AddUpdateItem(IActionSetInfos infos)
{
var item = CreateUpdateItem(infos);
radListControl_Updates.Items.Add(item);
return item;
}
private RadListDataItem InsertUpdateItem(IActionSetInfos infos)
{
var item = CreateUpdateItem(infos);
radListControl_Updates.Items.Insert(Math.Min(1, radListControl_Updates.Items.Count), item);
return item;
}
private RadListDataItem CreateUpdateItem(IActionSetInfos infos)
{
var item = new RadListDataItem();
UpdateUpdateItem(item, infos);
return item;
}
private void UpdateUpdateItem(RadListDataItem item)
{
if (item.Value is IActionSetInfos infos)
UpdateUpdateItem(item, infos);
}
private void UpdateUpdateItem(RadListDataItem item, IActionSetInfos infos)
{
if (item.Value != infos)
item.Value = infos;
if (infos is UpdateInfo)
item.Text = string.Format(GeneralLangRes.Node_Update, infos.Version?.ToString() ?? "?");
else if (infos is InstallInfos)
item.Text = string.Format(GeneralLangRes.Node_Install, infos.Version?.ToString() ?? "?");
else
item.Text = infos.Version.ToString();
item.SvgImage = AppGlobals.Symbols.GetSvgImage(infos.IsPublic ? AppSymbols.eye : AppSymbols.invisible, SymbolSize.Small);
}
public void UpdateItem(IActionSetInfos actionSetInfos)
{
RadListDataItem? item = null;
foreach (var iitem in radListControl_Updates.Items)
{
if (item == null && iitem.Value == actionSetInfos)
item = iitem;
}
if (item == null)
InsertUpdateItem(actionSetInfos);
else if (wsInfo?.Workspace.UpdateInfos != null && !wsInfo.Workspace.UpdateInfos.Updates.Contains(actionSetInfos))
radListControl_Updates.Items.Remove(item);
else
UpdateUpdateItem(item);
}
public void UpdateItem(InstallAction action)
{
foreach (var row in radGridView_Actions.Rows)
{
if (row.Tag == action)
UpdateActionRow(row);
}
}
private void LoadActionSet(IActionSetInfos infos)
{
radGridView_Actions.BeginUpdate();
radGridView_Actions.Rows.Clear();
radGridView_Actions.Columns.Clear();
// Add columns
radGridView_Actions.Columns.AddRange([
new GridViewTextBoxColumn
{
Name = "id",
HeaderText = ActionsListLangRes.Col_Id,
Width = 150,
IsVisible = infos is not UpdateInfo,
IsPinned = true,
},
new GridViewTextBoxColumn
{
Name = "name",
HeaderText = ActionsListLangRes.Col_Name,
Width = 150,
IsVisible = infos is not UpdateInfo,
},
new GridViewTextBoxColumn
{
Name = "inherit",
HeaderText = ActionsListLangRes.Col_InheritFrom,
Width = 150,
IsVisible = infos is UpdateInfo,
IsPinned = true,
},
new GridViewComboBoxColumn
{
Name = "utype",
HeaderText = ActionsListLangRes.Col_UpdateType,
Width = 150,
DataSource = Enum.GetValues<UpdateActionType>(),
IsVisible = infos is UpdateInfo,
},
new GridViewComboBoxColumn
{
Name = "side",
HeaderText = ActionsListLangRes.Col_Side,
Width = 100,
DataSource = Enum.GetValues<Side>(),
},
new GridViewCheckBoxColumn
{
Name = "isextra",
HeaderText = ActionsListLangRes.Col_IsExtra,
Width = 50,
},
new GridViewCheckBoxColumn
{
Name = "iszip",
HeaderText = ActionsListLangRes.Col_IsZip,
Width = 50,
},
new GridViewCheckBoxColumn
{
Name = "isdir",
HeaderText = ActionsListLangRes.Col_IsDir,
Width = 50,
IsVisible = infos is UpdateInfo,
},
new GridViewComboBoxColumn
{
Name = "srctype",
HeaderText = ActionsListLangRes.Col_SrcType,
Width = 150,
DataSource = Enum.GetValues<SourceType>(),
},
new GridViewTextBoxColumn
{
Name = "srcowner",
HeaderText = ActionsListLangRes.Col_SrcOwner,
Width = 150,
},
new GridViewTextBoxColumn
{
Name = "srcname",
HeaderText = ActionsListLangRes.Col_SrcName,
Width = 150,
},
new GridViewTextBoxColumn
{
Name = "srcregex",
HeaderText = ActionsListLangRes.Col_SrcRegEx,
Width = 200,
},
new GridViewTextBoxColumn
{
Name = "srctag",
HeaderText = ActionsListLangRes.Col_SrcTag,
Width = 150,
},
new GridViewTextBoxColumn
{
Name = "srcurl",
HeaderText = ActionsListLangRes.Col_SrcUrl,
Width = 350,
},
new GridViewTextBoxColumn
{
Name = "zippath",
HeaderText = ActionsListLangRes.Col_ZipPath,
Width = 200,
},
new GridViewTextBoxColumn
{
Name = "srcpath",
HeaderText = ActionsListLangRes.Col_SrcPath,
Width = 250,
IsVisible = infos is UpdateInfo,
},
new GridViewTextBoxColumn
{
Name = "destpath",
HeaderText = ActionsListLangRes.Col_DestPath,
Width = 250,
},
new GridViewTextBoxColumn
{
Name = "website",
HeaderText = ActionsListLangRes.Col_Website,
Width = 350,
},
]);
// Add rows
foreach (var action in infos.Actions)
{
var row = radGridView_Actions.Rows.AddNew();
row.Tag = action;
UpdateActionRow(row);
}
radGridView_Actions.EndUpdate();
}
private void UpdateActionRow(GridViewRowInfo row)
{
if (row.Tag is not InstallAction action)
return;
row.Cells["id"].Value = action.Id;
row.Cells["name"].Value = action.Name;
row.Cells["iszip"].Value = action.IsZip;
row.Cells["zippath"].Value = action.ZipPath;
row.Cells["destpath"].Value = action.DestPath;
row.Cells["srcurl"].Value = action.SourceUrl;
row.Cells["srctype"].Value = action.SourceType;
row.Cells["srcowner"].Value = action.SourceOwner;
row.Cells["srcname"].Value = action.SourceName;
row.Cells["srcregex"].Value = action.SourceRegex;
row.Cells["srctag"].Value = action.SourceTag;
row.Cells["side"].Value = action.Side;
row.Cells["isextra"].Value = action.IsExtra;
row.Cells["website"].Value = action.Website;
if (action is not UpdateAction uaction)
return;
row.Cells["inherit"].Value = uaction.InheritFrom; // TODO: Find inherit action and put it in here!
row.Cells["utype"].Value = uaction.Type;
row.Cells["srcpath"].Value = uaction.SrcPath;
row.Cells["isdir"].Value = uaction.IsDirectory;
}
private void Form1_Load(object sender, EventArgs e)
{
LoadRecentWorkspaces();
}
private async void RadMenuItem_OpenNewWorkspace_Click(object? sender, EventArgs e)
{
if (sender is RadMenuItem item && item.Tag is WorkspaceFeature feature)
{
var ws = wsInfo?.Workspace;
if (feature.Configure(ref ws))
await LoadNewWorkspace(ws, feature);
}
}
private async void RadMenuItem_OpenRecentWorkspace_Click(object? sender, EventArgs e)
{
if (sender is RadMenuItem item && item.Tag is RecentFilesItemTag tag && tag.Feature.CreateFromConfig(tag.Config) is IWorkspace workspace)
await LoadNewWorkspace(workspace, tag.Feature);
}
private async void RadMenuItem_WorkspacePreferences_Click(object sender, EventArgs e)
{
if (wsInfo != null)
{
var ws = wsInfo.Workspace;
if (wsInfo.Feature.Configure(ref ws))
await LoadNewWorkspace(ws, wsInfo.Feature);
}
}
private void RadMenuItem_SaveWorkspace_Click(object sender, EventArgs e)
{
wsInfo?.Workspace.Save();
}
private void RadMenuItem_ToolsItem_Click(object? sender, EventArgs e)
{
if (sender is RadMenuItem item && item.Tag is PluginFunction func)
func.Execute(new MainApiParameters(this));
}
private void RadListControl_Updates_SelectedIndexChanged(object sender, Telerik.WinControls.UI.Data.PositionChangedEventArgs e)
{
if (radListControl_Updates.Items.ElementAtOrDefault(e.Position)?.Value is IActionSetInfos infos)
LoadActionSet(infos);
}
private void RadGridView_Actions_CellFormatting(object sender, CellFormattingEventArgs e)
{
//var cellElement = e.CellElement;
//var cellInfo = e.Row.Cells[e.Column.Name];
//if (e.Column.Name == "srctype" && cellInfo?.Value is string sourceTypeStr && Enum.Parse<SourceType>(sourceTypeStr) is SourceType sourceType)
//{
// cellElement.SvgImage = sourceType switch
// {
// SourceType.DirectLink => AppGlobals.Symbols.GetSvgImage(AppSymbols.link, SymbolSize.Small),
// SourceType.GitHub => AppGlobals.Symbols.GetSvgImage(AppSymbols.github, SymbolSize.Small),
// _ => null,
// };
// cellElement.DrawImage = cellElement.SvgImage != null;
// cellElement.TextImageRelation = TextImageRelation.ImageBeforeText;
// cellElement.ImageAlignment = ContentAlignment.MiddleLeft;
//}
//else
//{
// cellElement.ResetValue(LightVisualElement.SvgImageProperty, ValueResetFlags.Local);
// cellElement.ResetValue(LightVisualElement.DrawImageProperty, ValueResetFlags.Local);
// cellElement.ResetValue(LightVisualElement.TextImageRelationProperty, ValueResetFlags.Local);
// cellElement.ResetValue(LightVisualElement.ImageAlignmentProperty, ValueResetFlags.Local);
//}
}
private void RadGridView_Actions_CellValueChanged(object sender, GridViewCellEventArgs e)
{
if (e.Row?.Tag is not InstallAction action)
return;
var uaction = action as UpdateAction;
var newValue = e.Row.Cells[e.Column.Name].Value;
var colName = e.Column.Name;
if (newValue is bool valueBool)
{
switch (colName)
{
case "iszip":
action.IsZip = valueBool;
break;
case "isextra":
action.IsExtra = valueBool;
break;
case "isdir":
if (uaction is not null)
uaction.IsDirectory = valueBool;
break;
}
}
else
{
var valueStr = newValue as string ?? string.Empty;
var valueNullStr = valueStr.Nullify();
switch (colName)
{
case "id":
action.Id = valueNullStr;
break;
case "name":
action.Name = valueNullStr;
break;
case "zippath":
action.ZipPath = valueNullStr;
break;
case "destpath":
action.DestPath = valueNullStr;
break;
case "srcurl":
action.SourceUrl = valueNullStr;
break;
case "srctype":
action.SourceType = Enum.Parse<SourceType>(valueStr);
break;
case "srcowner":
action.SourceOwner = valueNullStr;
break;
case "srcname":
action.SourceName = valueNullStr;
break;
case "srcregex":
action.SourceRegex = valueNullStr;
break;
case "srctag":
action.SourceTag = valueNullStr;
break;
case "website":
action.Website = valueNullStr;
break;
case "side":
action.Side = Enum.Parse<Side>(valueStr);
break;
case "inherit":
if (uaction is not null)
uaction.InheritFrom = valueNullStr;
break;
case "utype":
if (uaction is not null)
uaction.Type = Enum.Parse<UpdateActionType>(valueStr);
break;
case "srcpath":
if (uaction is not null)
uaction.SrcPath = valueNullStr;
break;
}
}
}
private void RadMenuItem_Updates_DropDownOpening(object sender, System.ComponentModel.CancelEventArgs e)
{
radMenuItem_EditUpdate.Enabled = radListControl_Updates.SelectedItem?.Value is IActionSetInfos;
radMenuItem_RemoveUpdate.Enabled = radListControl_Updates.SelectedItem?.Value is UpdateInfo;
}
private void RadMenuItem_EditUpdate_Click(object sender, EventArgs e)
{
if (radListControl_Updates.SelectedItem?.Value is IActionSetInfos infos
&& RadDialogBase.ShowDialog(new UpdatePropertiesEditorFlyout(infos), TitlesLangRes.EditUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.edit, SymbolSize.Small)).IsValid())
UpdateUpdateItem(radListControl_Updates.SelectedItem);
}
private void RadMenuItem_CreateUpdate_Click(object sender, EventArgs e)
{
var infos = new UpdateInfo();
if (wsInfo?.Workspace.UpdateInfos is not null
&& RadDialogBase.ShowDialog(new UpdatePropertiesEditorFlyout(infos), TitlesLangRes.EditUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.edit, SymbolSize.Small)).IsValid())
{
wsInfo.Workspace.UpdateInfos.Updates.Insert(0, infos);
InsertUpdateItem(infos);
}
}
private void RadMenuItem_RemoveUpdate_Click(object sender, EventArgs e)
{
if (radListControl_Updates.SelectedItem?.Value is UpdateInfo infos && wsInfo?.Workspace.UpdateInfos is not null
&& RadMessageBox.Show(MsgBoxLangRes.RemoveUpdate, MsgBoxLangRes.RemoveUpdate_Title, MessageBoxButtons.YesNo, RadMessageIcon.Exclamation).IsYes())
{
wsInfo.Workspace.UpdateInfos.Updates.Remove(infos);
radListControl_Updates.Items.Remove(radListControl_Updates.SelectedItem);
}
}
private void RadGridView_Actions_UserAddedRow(object sender, GridViewRowEventArgs e)
{
foreach (var row in e.Rows)
{
if (CurActionSet is UpdateInfo uinfo)
{
var action = new UpdateAction();
// ...
uinfo.Actions.Add(action);
}
if (CurActionSet is InstallInfos iinfo)
{
var action = new InstallAction();
// ...
iinfo.Actions.Add(action);
}
}
}
private void RadGridView_Actions_UserDeletingRow(object sender, GridViewRowCancelEventArgs e)
{
foreach (var row in e.Rows)
{
if (row.Tag is UpdateAction uaction && CurActionSet is UpdateInfo uinfo)
uinfo.Actions.Remove(uaction);
else if (row.Tag is InstallAction iaction && CurActionSet is InstallInfos iinfo)
iinfo.Actions.Remove(iaction);
}
}
private void RadGridView_Actions_ContextMenuOpening(object sender, ContextMenuOpeningEventArgs e)
{
PluginFeatureController.Instance.Functions.Get(FeatureTypes.ActionsContextMenu).InsertItemsTo(e.ContextMenu.Items, customClickHandler: RadMenuItem_ToolsItem_Click);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
namespace ModpackUpdater.Apps.Manager.Ui;
partial class UpdatePropertiesEditorFlyout
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
tableLayoutPanel1 = new TableLayoutPanel();
radLabel1 = new Telerik.WinControls.UI.RadLabel();
radTextBox_Version = new Telerik.WinControls.UI.RadTextBox();
radCheckBox_IsPublic = new Telerik.WinControls.UI.RadCheckBox();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_Version).BeginInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).BeginInit();
SuspendLayout();
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(radLabel1, 0, 0);
tableLayoutPanel1.Controls.Add(radTextBox_Version, 0, 1);
tableLayoutPanel1.Controls.Add(radCheckBox_IsPublic, 0, 3);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 30);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 4;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel1.Size = new Size(300, 84);
tableLayoutPanel1.TabIndex = 4;
//
// radLabel1
//
radLabel1.Location = new Point(3, 3);
radLabel1.Name = "radLabel1";
radLabel1.Size = new Size(55, 22);
radLabel1.TabIndex = 0;
radLabel1.Text = "Version";
//
// radTextBox_Version
//
radTextBox_Version.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_Version.Location = new Point(3, 31);
radTextBox_Version.Name = "radTextBox_Version";
radTextBox_Version.NullText = "1.5.37.0";
radTextBox_Version.Size = new Size(294, 24);
radTextBox_Version.TabIndex = 1;
//
// radCheckBox_IsPublic
//
radCheckBox_IsPublic.Location = new Point(3, 61);
radCheckBox_IsPublic.Name = "radCheckBox_IsPublic";
radCheckBox_IsPublic.Size = new Size(76, 20);
radCheckBox_IsPublic.TabIndex = 3;
radCheckBox_IsPublic.Text = "Is public";
//
// UpdatePropertiesEditorFlyout
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
BackColor = Color.Transparent;
Controls.Add(tableLayoutPanel1);
MinimumSize = new Size(300, 0);
Name = "UpdatePropertiesEditorFlyout";
Size = new Size(300, 144);
Controls.SetChildIndex(tableLayoutPanel1, 0);
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_Version).EndInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadLabel radLabel1;
private Telerik.WinControls.UI.RadTextBox radTextBox_Version;
private Telerik.WinControls.UI.RadCheckBox radCheckBox_IsPublic;
}

View File

@@ -0,0 +1,32 @@
using Pilz.UI;
using Pilz.UI.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class UpdatePropertiesEditorFlyout : RadFlyoutBase, ILoadContent
{
private readonly IActionSetInfos infos;
public UpdatePropertiesEditorFlyout(IActionSetInfos infos)
{
this.infos = infos;
InitializeComponent();
}
public void LoadContent()
{
radTextBox_Version.Text = infos.Version?.ToString();
radCheckBox_IsPublic.Checked = infos.IsPublic;
}
protected override bool ValidateOK()
{
if (!Version.TryParse(radTextBox_Version.Text.Trim(), out Version? version))
return false;
infos.Version = version;
infos.IsPublic = radCheckBox_IsPublic.Checked;
return base.ValidateOK();
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,266 @@
namespace ModpackUpdater.Apps.Manager.Ui;
partial class UpdatesCollectorUi
{
/// <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 listViewDetailColumn1 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 0", "Name");
var listViewDetailColumn2 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 1", "Current version");
var listViewDetailColumn3 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 2", "New version");
var listViewDetailColumn4 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 0", "Release");
var listViewDetailColumn5 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 1", "Tag");
var resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdatesCollectorUi));
tableLayoutPanel1 = new TableLayoutPanel();
radButton_Continue = new Telerik.WinControls.UI.RadButton();
radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer();
splitPanel1 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel2 = new TableLayoutPanel();
radListView_Updates = new Telerik.WinControls.UI.RadListView();
splitPanel2 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel3 = new TableLayoutPanel();
radListView_VersionTags = new Telerik.WinControls.UI.RadListView();
radWaitingBar1 = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radButton_Continue).BeginInit();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit();
radSplitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit();
splitPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radListView_Updates).BeginInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).BeginInit();
splitPanel2.SuspendLayout();
tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radListView_VersionTags).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar1).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout();
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.ColumnCount = 2;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel1.Controls.Add(radButton_Continue, 1, 0);
tableLayoutPanel1.Dock = DockStyle.Bottom;
tableLayoutPanel1.Location = new Point(0, 420);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 1;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(800, 30);
tableLayoutPanel1.TabIndex = 0;
//
// radButton_Continue
//
radButton_Continue.Anchor = AnchorStyles.Top | AnchorStyles.Right;
radButton_Continue.DialogResult = DialogResult.OK;
radButton_Continue.ImageAlignment = ContentAlignment.MiddleRight;
radButton_Continue.Location = new Point(647, 3);
radButton_Continue.Name = "radButton_Continue";
radButton_Continue.Size = new Size(150, 24);
radButton_Continue.TabIndex = 0;
radButton_Continue.Text = "Continue";
radButton_Continue.TextAlignment = ContentAlignment.MiddleLeft;
radButton_Continue.TextImageRelation = TextImageRelation.ImageBeforeText;
//
// radSplitContainer1
//
radSplitContainer1.Controls.Add(splitPanel1);
radSplitContainer1.Controls.Add(splitPanel2);
radSplitContainer1.Dock = DockStyle.Fill;
radSplitContainer1.Location = new Point(0, 0);
radSplitContainer1.Name = "radSplitContainer1";
//
//
//
radSplitContainer1.RootElement.MinSize = new Size(25, 25);
radSplitContainer1.Size = new Size(800, 420);
radSplitContainer1.TabIndex = 1;
radSplitContainer1.TabStop = false;
//
// splitPanel1
//
splitPanel1.Controls.Add(tableLayoutPanel2);
splitPanel1.Location = new Point(0, 0);
splitPanel1.Name = "splitPanel1";
//
//
//
splitPanel1.RootElement.MinSize = new Size(25, 25);
splitPanel1.Size = new Size(516, 420);
splitPanel1.SizeInfo.AutoSizeScale = new SizeF(0.148241222F, 0F);
splitPanel1.SizeInfo.SplitterCorrection = new Size(118, 0);
splitPanel1.TabIndex = 0;
splitPanel1.TabStop = false;
splitPanel1.Text = "splitPanel1";
//
// tableLayoutPanel2
//
tableLayoutPanel2.ColumnCount = 1;
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tableLayoutPanel2.Controls.Add(radListView_Updates, 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, 100F));
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel2.Size = new Size(516, 420);
tableLayoutPanel2.TabIndex = 1;
//
// radListView_Updates
//
radListView_Updates.AllowEdit = false;
radListView_Updates.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
listViewDetailColumn1.HeaderText = "Name";
listViewDetailColumn2.HeaderText = "Current version";
listViewDetailColumn2.Width = 120F;
listViewDetailColumn3.HeaderText = "New version";
listViewDetailColumn3.Width = 120F;
radListView_Updates.Columns.AddRange(new Telerik.WinControls.UI.ListViewDetailColumn[] { listViewDetailColumn1, listViewDetailColumn2, listViewDetailColumn3 });
radListView_Updates.ItemSpacing = -1;
radListView_Updates.Location = new Point(3, 3);
radListView_Updates.Name = "radListView_Updates";
radListView_Updates.Size = new Size(510, 414);
radListView_Updates.TabIndex = 0;
radListView_Updates.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView;
radListView_Updates.SelectedItemChanged += RadListView_Updates_SelectedItemChanged;
radListView_Updates.ItemRemoved += RadListView_Updates_ItemRemoved;
//
// splitPanel2
//
splitPanel2.Controls.Add(tableLayoutPanel3);
splitPanel2.Location = new Point(520, 0);
splitPanel2.Name = "splitPanel2";
//
//
//
splitPanel2.RootElement.MinSize = new Size(25, 25);
splitPanel2.Size = new Size(280, 420);
splitPanel2.SizeInfo.AutoSizeScale = new SizeF(-0.148241192F, 0F);
splitPanel2.SizeInfo.SplitterCorrection = new Size(-118, 0);
splitPanel2.TabIndex = 1;
splitPanel2.TabStop = false;
splitPanel2.Text = "splitPanel2";
//
// tableLayoutPanel3
//
tableLayoutPanel3.ColumnCount = 1;
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tableLayoutPanel3.Controls.Add(radListView_VersionTags, 0, 0);
tableLayoutPanel3.Dock = DockStyle.Fill;
tableLayoutPanel3.Location = new Point(0, 0);
tableLayoutPanel3.Name = "tableLayoutPanel3";
tableLayoutPanel3.RowCount = 1;
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel3.Size = new Size(280, 420);
tableLayoutPanel3.TabIndex = 0;
//
// radListView_VersionTags
//
radListView_VersionTags.AllowEdit = false;
radListView_VersionTags.AllowRemove = false;
radListView_VersionTags.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
listViewDetailColumn4.HeaderText = "Release";
listViewDetailColumn5.HeaderText = "Tag";
radListView_VersionTags.Columns.AddRange(new Telerik.WinControls.UI.ListViewDetailColumn[] { listViewDetailColumn4, listViewDetailColumn5 });
radListView_VersionTags.ItemSpacing = -1;
radListView_VersionTags.Location = new Point(3, 3);
radListView_VersionTags.Name = "radListView_VersionTags";
radListView_VersionTags.Size = new Size(274, 414);
radListView_VersionTags.TabIndex = 0;
radListView_VersionTags.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView;
radListView_VersionTags.SelectedIndexChanged += RadListView_VersionTags_SelectedIndexChanged;
//
// radWaitingBar1
//
radWaitingBar1.AssociatedControl = radListView_Updates;
radWaitingBar1.Location = new Point(0, 0);
radWaitingBar1.Name = "radWaitingBar1";
radWaitingBar1.Size = new Size(70, 70);
radWaitingBar1.TabIndex = 2;
radWaitingBar1.Text = "radWaitingBar1";
radWaitingBar1.WaitingIndicators.Add(dotsRingWaitingBarIndicatorElement1);
radWaitingBar1.WaitingIndicatorSize = new Size(100, 14);
radWaitingBar1.WaitingSpeed = 50;
radWaitingBar1.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsRing;
//
// dotsRingWaitingBarIndicatorElement1
//
dotsRingWaitingBarIndicatorElement1.Name = "dotsRingWaitingBarIndicatorElement1";
//
// UpdatesCollectorUi
//
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(radWaitingBar1);
Controls.Add(radSplitContainer1);
Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "UpdatesCollectorUi";
StartPosition = FormStartPosition.CenterParent;
Text = "Find updates";
Shown += UpdatesCollectorUi_Shown;
tableLayoutPanel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radButton_Continue).EndInit();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).EndInit();
radSplitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit();
splitPanel1.ResumeLayout(false);
tableLayoutPanel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radListView_Updates).EndInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).EndInit();
splitPanel2.ResumeLayout(false);
tableLayoutPanel3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radListView_VersionTags).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar1).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadButton radButton_Continue;
private Telerik.WinControls.UI.RadSplitContainer radSplitContainer1;
private Telerik.WinControls.UI.SplitPanel splitPanel1;
private TableLayoutPanel tableLayoutPanel2;
private Telerik.WinControls.UI.SplitPanel splitPanel2;
private TableLayoutPanel tableLayoutPanel3;
private Telerik.WinControls.UI.RadListView radListView_Updates;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar1;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement1;
private Telerik.WinControls.UI.RadListView radListView_VersionTags;
}

View File

@@ -0,0 +1,126 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Manager;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class UpdatesCollectorUi : RadForm
{
public record ModUpdateInfo(KeyValuePair<string, string>[] AvailableVersions, InstallAction Origin)
{
public int NewVersion { get; set; } = 0;
}
public record ModUpdates(List<ModUpdateInfo> List);
private readonly IWorkspace workspace;
private readonly ModpackFactory factory = new();
private readonly InstallAction[] actions;
public ModUpdates? CurrentUpdates { get; private set; }
public ModUpdateInfo? SelectedUpdate => radListView_Updates.SelectedItem?.Value as ModUpdateInfo;
public int SelectedVersion => radListView_VersionTags.SelectedIndex;
public UpdatesCollectorUi(IWorkspace workspace, params InstallAction[] actions)
{
this.workspace = workspace;
this.actions = actions;
InitializeComponent();
radListView_Updates.AutoSizeColumnsMode = ListViewAutoSizeColumnsMode.Fill;
radListView_VersionTags.AutoSizeColumnsMode = ListViewAutoSizeColumnsMode.Fill;
}
private async Task<ModUpdates> FindUpdates()
{
var list = new List<ModUpdateInfo>();
foreach (var action in actions)
{
var updates = await factory.FindUpdates(action, workspace.ModpackConfig?.MinecraftVersion, workspace.ModpackConfig?.ModLoader ?? ModLoader.Any);
if (updates == null || updates.Length == 0 || updates[0].Value == action.SourceTag)
continue;
list.Add(new(updates, action));
}
return new ModUpdates(list);
}
private void LoadUpdates(ModUpdates updates)
{
radListView_Updates.BeginUpdate();
radListView_Updates.Items.Clear();
foreach (var update in updates.List)
{
var item = new ListViewDataItem(update);
UpdateUpdatesItem(item);
radListView_Updates.Items.Add(item);
}
radListView_Updates.EndUpdate();
}
private static void UpdateUpdatesItem(ListViewDataItem? item)
{
if (item?.Value is not ModUpdateInfo updates)
return;
item[0] = updates.Origin.Name;
item[1] = updates.Origin.SourceTag;
item[2] = updates.AvailableVersions[updates.NewVersion].Value;
}
private void LoadVersions(ModUpdateInfo updates)
{
radListView_VersionTags.BeginUpdate();
radListView_VersionTags.Items.Clear();
foreach (var kvp in updates.AvailableVersions)
{
var item = new ListViewDataItem();
item[0] = kvp.Key;
item[1] = kvp.Value;
radListView_VersionTags.Items.Add(item);
}
radListView_VersionTags.SelectedIndex = updates.NewVersion;
radListView_VersionTags.EndUpdate();
}
private async void UpdatesCollectorUi_Shown(object sender, EventArgs e)
{
radWaitingBar1.StartWaiting();
CurrentUpdates = await FindUpdates();
LoadUpdates(CurrentUpdates);
radWaitingBar1.StopWaiting();
}
private void RadListView_Updates_SelectedItemChanged(object sender, EventArgs e)
{
if (SelectedUpdate is ModUpdateInfo updates)
LoadVersions(updates);
}
private void RadListView_VersionTags_SelectedIndexChanged(object sender, EventArgs e)
{
var newIndex = SelectedVersion;
if (newIndex != -1 && SelectedUpdate is ModUpdateInfo updates)
{
updates.NewVersion = newIndex;
UpdateUpdatesItem(radListView_Updates.SelectedItem);
}
}
private void RadListView_Updates_ItemRemoved(object sender, ListViewItemEventArgs e)
{
if (e.Item?.Value is ModUpdateInfo update && CurrentUpdates is not null && CurrentUpdates.List.Contains(update))
CurrentUpdates.List.Remove(update);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="TelerikWinFormsThemeName" value="Windows11CompactDark" />
</appSettings>
</configuration>

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@@ -0,0 +1,22 @@
using Pilz.UI.Telerik.Dialogs;
using Pilz.UI.Telerik.Symbols;
using Pilz.UI.Telerik.Theming;
using Telerik.WinControls;
using Telerik.WinControls.Themes;
namespace ModpackUpdater.Apps;
public static class AppGlobals
{
public static IRadSymbolFactory<AppSymbols> Symbols { get; } = new AppSymbolFactory();
public static void Initialize()
{
ThemeHelper.ApplyApplicationTheme(ApplicationTheme.Auto,
() => new Windows11CompactTheme(),
() => new Windows11CompactDarkTheme());
RadFlyoutBase.ConfirmSvg = Symbols.GetSvgImage(AppSymbols.checkmark, Pilz.UI.Symbols.SymbolSize.Small);
RadFlyoutBase.CancelSvg = Symbols.GetSvgImage(AppSymbols.cancel, Pilz.UI.Symbols.SymbolSize.Small);
}
}

View File

@@ -0,0 +1,18 @@
using Pilz.UI.Telerik;
using Pilz.UI.Telerik.Symbols;
using System.Reflection;
namespace ModpackUpdater.Apps;
internal class AppSymbolFactory : RadSymbolFactory<AppSymbols>
{
public override Assembly GetImageResourceAssembly()
{
return Assembly.GetExecutingAssembly();
}
public override string GetImageRessourcePath(AppSymbols svgImage)
{
return $"{GetType().Namespace}.Symbols.{svgImage}.svg";
}
}

View File

@@ -0,0 +1,38 @@
namespace ModpackUpdater.Apps;
public enum AppSymbols
{
checkmark,
close,
delete,
done,
download_from_ftp,
general_warning_sign,
opened_folder,
paste,
refresh,
reload,
save,
services,
software_installer,
update_done,
wrench,
github,
gitlab,
cancel,
tools,
workspace,
new_window,
time_machine,
settings,
link,
add,
edit,
remove,
search,
eye,
invisible,
heart_with_pulse,
broom,
renew,
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Symbols\*.svg" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Pilz.UI" Version="2.3.14" />
<PackageReference Include="Pilz.UI.Telerik" Version="2.8.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2024.3.806" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2024.3.806" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="240" height="240">
<linearGradient id="YT1YFZGinBDJ1OgDZNBs_a" x1="9.858" x2="38.142" y1="9.858" y2="38.142" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#21ad64" />
<stop offset="1" stop-color="#088242" />
</linearGradient>
<path fill="url(#YT1YFZGinBDJ1OgDZNBs_a)" d="M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z" />
<path d="M34,21h-7v-7c0-1.105-0.895-2-2-2h-2c-1.105,0-2,0.895-2,2v7h-7c-1.105,0-2,0.895-2,2v2c0,1.105,0.895,2,2,2h7v7c0,1.105,0.895,2,2,2h2c1.105,0,2-0.895,2-2v-7h7c1.105,0,2-0.895,2-2v-2C36,21.895,35.105,21,34,21z" opacity=".05" />
<path d="M34,21.5h-7.5V14c0-0.828-0.672-1.5-1.5-1.5h-2c-0.828,0-1.5,0.672-1.5,1.5v7.5H14c-0.828,0-1.5,0.672-1.5,1.5v2c0,0.828,0.672,1.5,1.5,1.5h7.5V34c0,0.828,0.672,1.5,1.5,1.5h2c0.828,0,1.5-0.672,1.5-1.5v-7.5H34c0.828,0,1.5-0.672,1.5-1.5v-2C35.5,22.172,34.828,21.5,34,21.5z" opacity=".07" />
<path fill="#fff" d="M23,13h2c0.552,0,1,0.448,1,1v20c0,0.552-0.448,1-1,1h-2c-0.552,0-1-0.448-1-1V14C22,13.448,22.448,13,23,13z" />
<path fill="#fff" d="M35,23v2c0,0.552-0.448,1-1,1H14c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1h20C34.552,22,35,22.448,35,23z" />
</svg>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="240" height="240">
<linearGradient id="_mrS6zdlYNXjKXndQNmOka" x1="24" x2="24" y1="1.206" y2="19.206" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#eba600" />
<stop offset="1" stop-color="#c28200" />
</linearGradient>
<path fill="url(#_mrS6zdlYNXjKXndQNmOka)" d="M27,19h-6V4c0-1.657,1.343-3,3-3h0c1.657,0,3,1.343,3,3V19z" />
<rect width="6" height="5" x="21" y="13" fill="#16528c" />
<linearGradient id="_mrS6zdlYNXjKXndQNmOkb" x1="24" x2="24" y1="44.265" y2="23.765" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ffcf54" />
<stop offset=".261" stop-color="#fdcb4d" />
<stop offset=".639" stop-color="#f7c13a" />
<stop offset="1" stop-color="#f0b421" />
</linearGradient>
<path fill="url(#_mrS6zdlYNXjKXndQNmOkb)" d="M38,24H10C8.706,34.353,6,43,6,43s7.647,2,18,2s18-2,18-2S39.294,34.353,38,24z" />
<linearGradient id="_mrS6zdlYNXjKXndQNmOkc" x1="16.669" x2="16.669" y1="44.687" y2="34.602" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#eba600" />
<stop offset="1" stop-color="#c28200" />
</linearGradient>
<path fill="url(#_mrS6zdlYNXjKXndQNmOkc)" d="M18,44.778V34c-0.471,3.767-1.809,7.705-2.663,10.546C16.18,44.633,17.074,44.711,18,44.778z" />
<linearGradient id="_mrS6zdlYNXjKXndQNmOkd" x1="32.392" x2="32.392" y1="44.307" y2="29.756" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#eba600" />
<stop offset="1" stop-color="#c28200" />
</linearGradient>
<path fill="url(#_mrS6zdlYNXjKXndQNmOkd)" d="M33.784,44.42C32.922,41.117,31.747,34.974,31,29v15.701C31.982,44.619,32.907,44.523,33.784,44.42z" />
<linearGradient id="_mrS6zdlYNXjKXndQNmOke" x1="22.142" x2="25.491" y1="15.701" y2="27.791" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#0d61a9" />
<stop offset="1" stop-color="#16528c" />
</linearGradient>
<path fill="url(#_mrS6zdlYNXjKXndQNmOke)" d="M38,24H10v-2.77c0-1.369,0.919-2.57,2.247-2.905C14.551,17.744,18.565,17,24,17s9.449,0.744,11.753,1.325C37.081,18.659,38,19.861,38,21.23V24z" />
</svg>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="wRKXFJsqHCxLE9yyOYHkza" x1="9.858" x2="38.142" y1="9.858" y2="38.142" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f44f5a"/><stop offset=".443" stop-color="#ee3d4a"/><stop offset="1" stop-color="#e52030"/></linearGradient><path fill="url(#wRKXFJsqHCxLE9yyOYHkza)" d="M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z"/><path d="M33.192,28.95L28.243,24l4.95-4.95c0.781-0.781,0.781-2.047,0-2.828l-1.414-1.414c-0.781-0.781-2.047-0.781-2.828,0L24,19.757l-4.95-4.95c-0.781-0.781-2.047-0.781-2.828,0l-1.414,1.414c-0.781,0.781-0.781,2.047,0,2.828l4.95,4.95l-4.95,4.95c-0.781,0.781-0.781,2.047,0,2.828l1.414,1.414c0.781,0.781,2.047,0.781,2.828,0l4.95-4.95l4.95,4.95c0.781,0.781,2.047,0.781,2.828,0l1.414-1.414C33.973,30.997,33.973,29.731,33.192,28.95z" opacity=".05"/><path d="M32.839,29.303L27.536,24l5.303-5.303c0.586-0.586,0.586-1.536,0-2.121l-1.414-1.414c-0.586-0.586-1.536-0.586-2.121,0L24,20.464l-5.303-5.303c-0.586-0.586-1.536-0.586-2.121,0l-1.414,1.414c-0.586,0.586-0.586,1.536,0,2.121L20.464,24l-5.303,5.303c-0.586,0.586-0.586,1.536,0,2.121l1.414,1.414c0.586,0.586,1.536,0.586,2.121,0L24,27.536l5.303,5.303c0.586,0.586,1.536,0.586,2.121,0l1.414-1.414C33.425,30.839,33.425,29.889,32.839,29.303z" opacity=".07"/><path fill="#fff" d="M31.071,15.515l1.414,1.414c0.391,0.391,0.391,1.024,0,1.414L18.343,32.485c-0.391,0.391-1.024,0.391-1.414,0l-1.414-1.414c-0.391-0.391-0.391-1.024,0-1.414l14.142-14.142C30.047,15.124,30.681,15.124,31.071,15.515z"/><path fill="#fff" d="M32.485,31.071l-1.414,1.414c-0.391,0.391-1.024,0.391-1.414,0L15.515,18.343c-0.391-0.391-0.391-1.024,0-1.414l1.414-1.414c0.391-0.391,1.024-0.391,1.414,0l14.142,14.142C32.876,30.047,32.876,30.681,32.485,31.071z"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="IMoH7gpu5un5Dx2vID39Ra" x1="9.858" x2="38.142" y1="9.858" y2="38.142" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#9dffce"/><stop offset="1" stop-color="#50d18d"/></linearGradient><path fill="url(#IMoH7gpu5un5Dx2vID39Ra)" d="M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z"/><linearGradient id="IMoH7gpu5un5Dx2vID39Rb" x1="13" x2="36" y1="24.793" y2="24.793" gradientUnits="userSpaceOnUse"><stop offset=".824" stop-color="#135d36"/><stop offset=".931" stop-color="#125933"/><stop offset="1" stop-color="#11522f"/></linearGradient><path fill="url(#IMoH7gpu5un5Dx2vID39Rb)" d="M21.293,32.707l-8-8c-0.391-0.391-0.391-1.024,0-1.414l1.414-1.414c0.391-0.391,1.024-0.391,1.414,0L22,27.758l10.879-10.879c0.391-0.391,1.024-0.391,1.414,0l1.414,1.414c0.391,0.391,0.391,1.024,0,1.414l-13,13C22.317,33.098,21.683,33.098,21.293,32.707z"/></svg>

After

Width:  |  Height:  |  Size: 954 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="hbE9Evnj3wAjjA2RX0We2a" x1="7.534" x2="27.557" y1="7.534" y2="27.557" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f44f5a"/><stop offset=".443" stop-color="#ee3d4a"/><stop offset="1" stop-color="#e52030"/></linearGradient><path fill="url(#hbE9Evnj3wAjjA2RX0We2a)" d="M42.42,12.401c0.774-0.774,0.774-2.028,0-2.802L38.401,5.58c-0.774-0.774-2.028-0.774-2.802,0L24,17.179L12.401,5.58c-0.774-0.774-2.028-0.774-2.802,0L5.58,9.599c-0.774,0.774-0.774,2.028,0,2.802L17.179,24L5.58,35.599c-0.774,0.774-0.774,2.028,0,2.802l4.019,4.019c0.774,0.774,2.028,0.774,2.802,0L42.42,12.401z"/><linearGradient id="hbE9Evnj3wAjjA2RX0We2b" x1="27.373" x2="40.507" y1="27.373" y2="40.507" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a8142e"/><stop offset=".179" stop-color="#ba1632"/><stop offset=".243" stop-color="#c21734"/></linearGradient><path fill="url(#hbE9Evnj3wAjjA2RX0We2b)" d="M24,30.821L35.599,42.42c0.774,0.774,2.028,0.774,2.802,0l4.019-4.019c0.774-0.774,0.774-2.028,0-2.802L30.821,24L24,30.821z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="nyvBozV7VK1PdF3LtMmOna" x1="18.405" x2="33.814" y1="10.91" y2="43.484" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#nyvBozV7VK1PdF3LtMmOna)" d="M39,10l-2.835,31.181C36.072,42.211,35.208,43,34.174,43H13.826c-1.034,0-1.898-0.789-1.992-1.819L9,10H39z"/><path fill="#0176d0" d="M32,7c0-1.105-0.895-2-2-2H18c-1.105,0-2,0.895-2,2c0,0,0,0.634,0,1h16C32,7.634,32,7,32,7z"/><path fill="#007ad9" d="M7,9.886L7,9.886C7,9.363,7.358,8.912,7.868,8.8C10.173,8.293,16.763,7,24,7s13.827,1.293,16.132,1.8C40.642,8.912,41,9.363,41,9.886v0C41,10.501,40.501,11,39.886,11H8.114C7.499,11,7,10.501,7,9.886z"/></svg>

After

Width:  |  Height:  |  Size: 769 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="HoiJCu43QtshzIrYCxOfCa" x1="21.241" x2="3.541" y1="39.241" y2="21.541" gradientUnits="userSpaceOnUse"><stop offset=".108" stop-color="#0d7044"/><stop offset=".433" stop-color="#11945a"/></linearGradient><path fill="url(#HoiJCu43QtshzIrYCxOfCa)" d="M16.599,41.42L1.58,26.401c-0.774-0.774-0.774-2.028,0-2.802l4.019-4.019c0.774-0.774,2.028-0.774,2.802,0L23.42,34.599c0.774,0.774,0.774,2.028,0,2.802l-4.019,4.019C18.627,42.193,17.373,42.193,16.599,41.42z"/><linearGradient id="HoiJCu43QtshzIrYCxOfCb" x1="-15.77" x2="26.403" y1="43.228" y2="43.228" gradientTransform="rotate(134.999 21.287 38.873)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2ac782"/><stop offset="1" stop-color="#21b876"/></linearGradient><path fill="url(#HoiJCu43QtshzIrYCxOfCb)" d="M12.58,34.599L39.599,7.58c0.774-0.774,2.028-0.774,2.802,0l4.019,4.019c0.774,0.774,0.774,2.028,0,2.802L19.401,41.42c-0.774,0.774-2.028,0.774-2.802,0l-4.019-4.019C11.807,36.627,11.807,35.373,12.58,34.599z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="U9JenDUaYvGOzlbpKqZV2a" x1="23" x2="23" y1="548.505" y2="556.288" gradientTransform="translate(0 -541.78)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#eba600"/><stop offset="1" stop-color="#c28200"/></linearGradient><path fill="url(#U9JenDUaYvGOzlbpKqZV2a)" d="M22.414,10.414l-2.536-2.536C19.316,7.316,18.553,7,17.757,7H5C3.895,7,3,7.895,3,9v8l2,22h38V13l-18.569-2h-0.603C23.298,11,22.789,10.789,22.414,10.414z"/><linearGradient id="U9JenDUaYvGOzlbpKqZV2b" x1="24" x2="24" y1="552.634" y2="582.763" gradientTransform="translate(0 -541.78)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd869"/><stop offset="1" stop-color="#fec52b"/></linearGradient><path fill="url(#U9JenDUaYvGOzlbpKqZV2b)" d="M20.586,14.414l3.268-3.268C23.947,11.053,24.074,11,24.207,11H28l17,17v11c0,1.105-0.895,2-2,2H5c-1.105,0-2-0.895-2-2V15.5C3,15.224,3.224,15,3.5,15h15.672C19.702,15,20.211,14.789,20.586,14.414z"/><path d="M32.24,39.34L30.75,41h-13.5l-1.49-1.66c-0.54-0.6-0.67-1.42-0.34-2.15c0.32-0.74,1.02-1.19,1.83-1.19H20v-9c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2v9h2.75c0.81,0,1.51,0.45,1.83,1.19C32.91,37.92,32.78,38.74,32.24,39.34z" opacity=".05"/><path d="M31.87,39l-1.8,2H17.93l-1.8-2c-0.4-0.44-0.5-1.06-0.25-1.61c0.24-0.55,0.76-0.89,1.37-0.89h3.25V27c0-0.83,0.67-1.5,1.5-1.5h4c0.83,0,1.5,0.67,1.5,1.5v9.5h3.25c0.61,0,1.13,0.34,1.37,0.89C32.37,37.94,32.27,38.56,31.87,39z" opacity=".07"/><path d="M45,22.99v6.98C44.66,29.99,44.33,30,44,30c-4.78,0-9.3-1.88-12.72-5.28c-3.62-3.64-5.53-8.63-5.25-13.72h6.98v0.04c-0.11,3.03,0.99,6.03,3.02,8.23C38.2,21.64,41.29,23,44.5,23c0.16,0,0.3,0,0.44-0.01H45z" opacity=".05"/><path d="M45,23.49v5.98c-0.34,0.02-0.67,0.03-1,0.03c-4.65,0-9.04-1.82-12.36-5.14c-3.53-3.53-5.39-8.4-5.11-13.36h5.98v0.02c-0.12,3.16,1.03,6.29,3.15,8.59c2.27,2.47,5.49,3.89,8.84,3.89h0.03c0.14,0,0.29,0,0.44-0.01H45z" opacity=".07"/><linearGradient id="U9JenDUaYvGOzlbpKqZV2c" x1="27" x2="45" y1="27.89" y2="27.89" gradientTransform="matrix(1 0 0 -1 0 47.89)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#7819a2"/><stop offset="1" stop-color="#771aa9"/></linearGradient><path fill="url(#U9JenDUaYvGOzlbpKqZV2c)" d="M31.99,24.01c-3.298-3.309-5.254-7.936-4.961-13.01h4.981c-0.12,3.29,1.05,6.53,3.28,8.95C37.65,22.52,41.01,24,44.5,24c0.16,0,0.33,0,0.5-0.01v4.981C39.926,29.264,35.299,27.308,31.99,24.01z"/><path fill="#a238c2" d="M31,11.5c0-0.17,0-0.34,0.01-0.5h5.01c-0.13,2.3,0.67,4.56,2.21,6.25C39.84,19,42.12,20,44.5,20c0.17,0,0.33,0,0.5-0.02v5.01C44.84,25,44.67,25,44.5,25C37.06,25,31,18.94,31,11.5z"/><path fill="#ba54d9" d="M35,11.5c0-0.17,0-0.33,0.01-0.5h5.08c0.2,1.26,0.8,2.38,1.67,3.24c0.86,0.87,1.98,1.47,3.24,1.67v5.08C44.83,21,44.67,21,44.5,21C39.26,21,35,16.74,35,11.5z"/><path fill="#c767e5" d="M39.021,11.008c0.003-0.003,0.005-0.005,0.009-0.008H43c1.105,0,2,0.893,2,1.998v3.944c-0.004,0.036-0.004,0.036-0.008,0.037C41.565,17.276,38.724,14.436,39.021,11.008z"/><linearGradient id="U9JenDUaYvGOzlbpKqZV2d" x1="-101.914" x2="-91.369" y1="507.75" y2="488.785" gradientTransform="matrix(1 0 0 -1 120 533.89)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#007ad9"/><stop offset="1" stop-color="#2aa4f4"/></linearGradient><path fill="url(#U9JenDUaYvGOzlbpKqZV2d)" d="M30.755,37H27V27c0-0.552-0.448-1-1-1h-4c-0.552,0-1,0.448-1,1v10h-3.755c-0.866,0-1.322,1.025-0.743,1.669l6.011,6.679c0.794,0.883,2.179,0.883,2.973,0l6.011-6.679C32.077,38.025,31.62,37,30.755,37z"/></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="240" height="240">
<path fill="#c94f60" d="M42.583,9.067l-3.651-3.65c-0.555-0.556-1.459-0.556-2.015,0l-1.718,1.72l5.664,5.664l1.72-1.718C43.139,10.526,43.139,9.625,42.583,9.067" />
<path fill="#f0f0f0" d="M6.905,35.43L5,43l7.571-1.906l0.794-6.567L6.905,35.43z" />
<path fill="#edbe00" d="M36.032,17.632l-23.46,23.461l-5.665-5.665l23.46-23.461L36.032,17.632z" />
<linearGradient id="YoPixpDbHWOyk~b005eF1a" x1="35.612" x2="35.612" y1="7.494" y2="17.921" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#dedede" />
<stop offset="1" stop-color="#d6d6d6" />
</linearGradient>
<path fill="url(#YoPixpDbHWOyk~b005eF1a)" d="M30.363,11.968l4.832-4.834l5.668,5.664l-4.832,4.834L30.363,11.968z" />
<path fill="#787878" d="M5.965,39.172L5,43l3.827-0.965L5.965,39.172z" />
</svg>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><radialGradient id="q52hzhdzvMMZA5gZkbbYUa" cx="24.134" cy="19.042" r="21.223" gradientTransform="matrix(1.05 0 0 1.0625 -1.2 -1.563)" gradientUnits="userSpaceOnUse"><stop offset=".55" stop-color="#e4e4e6"/><stop offset=".73" stop-color="#e1e2e4"/><stop offset=".854" stop-color="#d8dadc"/><stop offset=".961" stop-color="#c9cdcf"/><stop offset="1" stop-color="#c1c6c9"/></radialGradient><ellipse cx="24" cy="24" fill="url(#q52hzhdzvMMZA5gZkbbYUa)" rx="21" ry="17"/><linearGradient id="q52hzhdzvMMZA5gZkbbYUb" x1="15.089" x2="33.163" y1="12.089" y2="30.163" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><circle cx="24" cy="21" r="14" fill="url(#q52hzhdzvMMZA5gZkbbYUb)"/><radialGradient id="q52hzhdzvMMZA5gZkbbYUc" cx="19.876" cy="10.758" r="18.169" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#4b4b4b"/><stop offset=".531" stop-color="#393939"/><stop offset="1" stop-color="#252525"/></radialGradient><circle cx="24" cy="21" r="7" fill="url(#q52hzhdzvMMZA5gZkbbYUc)"/><circle cx="19" cy="16" r="2" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" data-name="Слой 1" viewBox="0 0 48 48"><defs><linearGradient id="Oks0BVGeIiW4yZ9DYg69Ba" x1="10.531" x2="27.482" y1="4.992" y2="51.563" data-name="Безымянный градиент 138" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#6d6d6d"/><stop offset=".126" stop-color="#626262"/><stop offset=".987" stop-color="#464646"/><stop offset=".998" stop-color="#454545"/></linearGradient><linearGradient id="Oks0BVGeIiW4yZ9DYg69Bb" x1="18.357" x2="24.573" y1="-1872.995" y2="-1908.249" data-name="Безымянный градиент 134" gradientTransform="matrix(1 0 0 -1 0 -1864)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffda1c"/><stop offset="1" stop-color="#feb705"/></linearGradient><radialGradient id="Oks0BVGeIiW4yZ9DYg69Bc" cx="18.189" cy="-1948.781" r="22.363" data-name="Безымянный градиент 133" gradientTransform="matrix(1 0 0 -1 0 -1930)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#4b4b4b"/><stop offset=".531" stop-color="#393939"/><stop offset="1" stop-color="#252525"/></radialGradient></defs><path fill="url(#Oks0BVGeIiW4yZ9DYg69Ba)" d="M24.00043,4A1.96747,1.96747,0,0,0,22.2731,5.00878L1.82176,41.00568A2.00136,2.00136,0,0,0,3.54909,44H44.45078a2.001,2.001,0,0,0,1.72733-2.99432L25.72776,5.00878A1.96745,1.96745,0,0,0,24.00043,4Z"/><polygon fill="url(#Oks0BVGeIiW4yZ9DYg69Bb)" points="5 41 24.001 8 43 41 5 41"/><path fill="url(#Oks0BVGeIiW4yZ9DYg69Bc)" d="M24.014,39a2.55181,2.55181,0,0,1-1.812-.666,2.124,2.124,0,0,1-.714-1.613,2.055,2.055,0,0,1,.721-1.62,2.6383,2.6383,0,0,1,1.805-.631,2.56628,2.56628,0,0,1,1.798.638,2.08812,2.08812,0,0,1,.7,1.613,2.13406,2.13406,0,0,1-.693,1.633A2.54451,2.54451,0,0,1,24.014,39Zm2.222-19.279-.481,12.175a.69392.69392,0,0,1-.693.666H22.883a.6936.6936,0,0,1-.693-.668L21.735,19.72a.69384.69384,0,0,1,.693-.72h3.116A.69267.69267,0,0,1,26.236,19.721Z"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#e53935" d="M24 43L16 20 32 20z" />
<path fill="#ff7043" d="M24 43L42 20 32 20z" />
<path fill="#e53935" d="M37 5L42 20 32 20z" />
<path fill="#ffa726" d="M24 43L42 20 45 28z" />
<path fill="#ff7043" d="M24 43L6 20 16 20z" />
<path fill="#e53935" d="M11 5L6 20 16 20z" />
<path fill="#ffa726" d="M24 43L6 20 3 28z" />
</svg>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="240" height="240">
<linearGradient id="o5BohGJy0xHajxWpIzsAMa" x1="15.595" x2="35.333" y1="4.867" y2="35.264" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f44f5a" />
<stop offset=".443" stop-color="#ee3d4a" />
<stop offset="1" stop-color="#e52030" />
</linearGradient>
<path fill="url(#o5BohGJy0xHajxWpIzsAMa)" d="M24,12.25c0,0,4.701-5.25,10.5-5.25S45,11.765,45,17.5c0,9.869-15.466,21.138-19.853,24.135c-0.695,0.475-1.599,0.475-2.294,0C18.466,38.638,3,27.369,3,17.5C3,11.765,7.701,7,13.5,7S24,12.25,24,12.25z" />
<path fill="#ffebee" d="M26.67,28.236c0.111,0.362,0.419,0.63,0.793,0.691c0.369,0.058,0.751-0.095,0.973-0.401L30.261,26H34.5c0.553,0,1-0.448,1-1s-0.447-1-1-1h-4.75c-0.321,0-0.622,0.154-0.811,0.415l-0.951,1.316l-1.783-5.767c-0.126-0.41-0.5-0.693-0.929-0.704c-0.425-0.017-0.816,0.251-0.965,0.654l-3.192,8.659L19.24,15.483c-0.065-0.456-0.434-0.807-0.891-0.853c-0.466-0.049-0.888,0.227-1.042,0.66l-3.214,9.045l-2.641-3.896c-0.198-0.291-0.536-0.461-0.882-0.438c-0.351,0.019-0.665,0.22-0.829,0.529L7.898,24H4.903c0.365,0.671,0.772,1.338,1.216,2H8.5c0.37,0,0.71-0.204,0.883-0.531l1.347-2.534l2.817,4.158c0.211,0.312,0.571,0.481,0.955,0.431c0.374-0.047,0.689-0.302,0.815-0.657l2.519-7.09l1.865,12.99c0.065,0.453,0.43,0.804,0.885,0.853c0.036,0.003,0.071,0.005,0.106,0.005c0.414,0,0.791-0.258,0.938-0.654l3.537-9.595L26.67,28.236z" />
<path fill="#ffebee" d="M35,23c-1.105,0-2,0.895-2,2s0.895,2,2,2s2-0.895,2-2S36.105,23,35,23z" />
</svg>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><radialGradient id="tx8Zca041q9EWw3FdAYMda" cx="-7.914" cy="526.782" r="21.223" gradientTransform="matrix(1.05 0 0 -1.0625 32.45 578.375)" gradientUnits="userSpaceOnUse"><stop offset=".55" stop-color="#e4e4e6"/><stop offset=".73" stop-color="#e1e2e4"/><stop offset=".854" stop-color="#d8dadc"/><stop offset=".961" stop-color="#c9cdcf"/><stop offset="1" stop-color="#c1c6c9"/></radialGradient><ellipse cx="24" cy="24" fill="url(#tx8Zca041q9EWw3FdAYMda)" rx="21" ry="17"/><linearGradient id="tx8Zca041q9EWw3FdAYMdb" x1="15.089" x2="33.163" y1="513.911" y2="495.837" gradientTransform="matrix(1 0 0 -1 0 526)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><circle cx="24" cy="21" r="14" fill="url(#tx8Zca041q9EWw3FdAYMdb)"/><radialGradient id="tx8Zca041q9EWw3FdAYMdc" cx="19.876" cy="515.242" r="18.169" gradientTransform="matrix(1 0 0 -1 0 526)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#4b4b4b"/><stop offset=".531" stop-color="#393939"/><stop offset="1" stop-color="#252525"/></radialGradient><circle cx="24" cy="21" r="7" fill="url(#tx8Zca041q9EWw3FdAYMdc)"/><circle cx="19" cy="16" r="2" fill="#fff"/><path fill="#e52030" d="M44.888,42.734L5.266,3.112c-0.149-0.149-0.39-0.149-0.539,0L3.112,4.728c-0.149,0.149-0.149,0.39,0,0.539l39.622,39.622c0.149,0.149,0.39,0.149,0.539,0l1.616-1.616C45.037,43.124,45.037,42.882,44.888,42.734z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="240" height="240">
<path fill="#0078d4" d="M7.782,40.218c3.71,3.71,9.725,3.71,13.435,0c1.733-1.733,5.267-5.267,7-7c3.71-3.71,3.71-9.725,0-13.435c-3.71-3.71-9.725-3.71-13.435,0c-1.733,1.733-5.267,5.267-7,7C4.073,30.492,4.073,36.508,7.782,40.218z M11.318,30.318c1.02-1.02,6.237-6.237,7-7c1.757-1.757,4.607-1.757,6.364,0c1.757,1.757,1.757,4.607,0,6.364c-0.763,0.763-5.98,5.98-7,7c-1.757,1.757-4.607,1.757-6.364,0C9.561,34.925,9.561,32.075,11.318,30.318z" />
<path d="M23.609,22.509c0,0-0.609-1.509,0.77-3.131l1.369-1.37c-3.165-1.583-7.022-1.285-9.926,0.888C15,22,16.197,25.439,16.197,25.439c1.04-1.04,1.872-1.872,2.121-2.121C19.758,21.879,21.851,21.613,23.609,22.509z" opacity=".05" />
<path d="M22.827,22.193c-0.082-0.664-0.178-2.024,1.022-3.345c0.07-0.07,0.92-0.94,1.143-1.163c-2.642-1.109-5.689-0.896-8.192,0.57c-0.849,2.578-0.317,5.522,0,6.582c0.743-0.743,1.324-1.324,1.519-1.519C19.548,22.088,21.254,21.714,22.827,22.193z" opacity=".07" />
<path fill="#1b9de2" d="M40.218,7.782c-3.71-3.71-9.725-3.71-13.435,0c-1.733,1.733-5.267,5.267-7,7c-3.71,3.71-3.71,9.725,0,13.435c3.71,3.71,9.725,3.71,13.435,0c1.733-1.733,5.267-5.267,7-7C43.927,17.508,43.927,11.492,40.218,7.782z M36.682,17.682c-1.02,1.02-6.237,6.237-7,7c-1.757,1.757-4.607,1.757-6.364,0c-1.757-1.757-1.757-4.607,0-6.364c0.763-0.763,5.98-5.98,7-7c1.757-1.757,4.607-1.757,6.364,0C38.439,13.075,38.439,15.925,36.682,17.682z" />
<path d="M24.386,25.476c0,0,0.614,1.524-0.765,3.146l-1.369,1.37c3.165,1.583,7.022,1.285,9.926-0.888C33,26,31.803,22.561,31.803,22.561c-1.04,1.04-1.872,1.872-2.121,2.121C28.242,26.121,26.09,26.395,24.386,25.476z" opacity=".05" />
<path d="M25.188,25.806c0.082,0.664,0.163,2.025-1.037,3.346c-0.07,0.07-0.92,0.92-1.143,1.143c2.642,1.109,5.718,0.897,8.196-0.628c0.849-2.578,0.314-5.445-0.004-6.504c-0.743,0.743-1.324,1.324-1.519,1.519C28.452,25.912,26.673,26.271,25.188,25.806z" opacity=".07" />
<path fill="#0078d4" d="M24.682,23.318c1.757,1.757,1.757,4.607,0,6.364c-0.763,0.763-5.98,5.98-7,7l3.536,3.536c1.733-1.733,5.267-5.267,7-7c3.71-3.71,3.71-9.725,0-13.435L24.682,23.318z" />
</svg>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="ssYo2_G6_lrXAD6cTwfU1a" x1="4.614" x2="42.936" y1="110.259" y2="102.467" gradientTransform="matrix(1 0 0 -1 0 118)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0077d2"/><stop offset="1" stop-color="#0b59a2"/></linearGradient><path fill="url(#ssYo2_G6_lrXAD6cTwfU1a)" d="M44,10v5H4v-5c0-1.1,0.9-2,2-2h36C43.1,8,44,8.9,44,10z"/><linearGradient id="ssYo2_G6_lrXAD6cTwfU1b" x1="13.275" x2="31.78" y1="107.204" y2="80.436" gradientTransform="matrix(1 0 0 -1 0 118)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#7dd8f3"/><stop offset="1" stop-color="#45b0d0"/></linearGradient><path fill="url(#ssYo2_G6_lrXAD6cTwfU1b)" d="M4,38V14h40v24c0,1.1-0.9,2-2,2H6C4.9,40,4,39.1,4,38z"/><path d="M23,36c-1.103,0-2-0.897-2-2v-4h-4c-1.103,0-2-0.897-2-2v-2c0-1.103,0.897-2,2-2h4v-4c0-1.103,0.897-2,2-2h2c1.103,0,2,0.897,2,2v4h4c1.103,0,2,0.897,2,2v2c0,1.103-0.897,2-2,2h-4v4c0,1.103-0.897,2-2,2H23z" opacity=".05"/><path d="M23,35.5c-0.827,0-1.5-0.673-1.5-1.5v-4.5H17c-0.827,0-1.5-0.673-1.5-1.5v-2c0-0.827,0.673-1.5,1.5-1.5h4.5V20c0-0.827,0.673-1.5,1.5-1.5h2c0.827,0,1.5,0.673,1.5,1.5v4.5H31c0.827,0,1.5,0.673,1.5,1.5v2c0,0.827-0.673,1.5-1.5,1.5h-4.5V34c0,0.827-0.673,1.5-1.5,1.5H23z" opacity=".07"/><path fill="#fff" d="M31,25h-5v-5c0-0.552-0.448-1-1-1h-2c-0.552,0-1,0.448-1,1v5h-5c-0.552,0-1,0.448-1,1v2c0,0.552,0.448,1,1,1h5v5c0,0.552,0.448,1,1,1h2c0.552,0,1-0.448,1-1v-5h5c0.552,0,1-0.448,1-1v-2C32,25.448,31.552,25,31,25z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="xGIh33lbYX9pWIYWeZsuka" x1="24" x2="24" y1="6.955" y2="23.167" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#eba600"/><stop offset="1" stop-color="#c28200"/></linearGradient><path fill="url(#xGIh33lbYX9pWIYWeZsuka)" d="M24.414,10.414l-2.536-2.536C21.316,7.316,20.553,7,19.757,7H5C3.895,7,3,7.895,3,9v30c0,1.105,0.895,2,2,2h38c1.105,0,2-0.895,2-2V13c0-1.105-0.895-2-2-2H25.828C25.298,11,24.789,10.789,24.414,10.414z"/><linearGradient id="xGIh33lbYX9pWIYWeZsukb" x1="24.066" x2="24.066" y1="19.228" y2="33.821" gradientTransform="matrix(-1 0 0 1 48 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd869"/><stop offset="1" stop-color="#fec52b"/></linearGradient><path fill="url(#xGIh33lbYX9pWIYWeZsukb)" d="M24,23l3.854-3.854C27.947,19.053,28.074,19,28.207,19H44.81c1.176,0,2.098,1.01,1.992,2.181l-1.636,18C45.072,40.211,44.208,41,43.174,41H4.79c-1.019,0-1.875-0.766-1.988-1.779L1.062,23.555C1.029,23.259,1.261,23,1.559,23H24z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="I93pW93qJSUhtSDIz1RZKa" x1="-248" x2="-238" y1="-234" y2="-234" gradientTransform="rotate(180 -112 -112)" gradientUnits="userSpaceOnUse"><stop offset=".266" stop-color="#199ae0"/><stop offset=".582" stop-color="#1898de"/><stop offset=".745" stop-color="#1590d6"/><stop offset=".873" stop-color="#1083c9"/><stop offset=".982" stop-color="#0870b7"/><stop offset="1" stop-color="#076cb3"/></linearGradient><path fill="url(#I93pW93qJSUhtSDIz1RZKa)" d="M14,13h9c0.552,0,1-0.448,1-1V8c0-0.552-0.448-1-1-1h-9V13z"/><linearGradient id="I93pW93qJSUhtSDIz1RZKb" x1="3.924" x2="17.001" y1="8.199" y2="41.867" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#I93pW93qJSUhtSDIz1RZKb)" d="M18.19,32H14V7l-4.828,4.828C8.421,12.579,8,13.596,8,14.657V32H3.81c-0.72,0-1.08,0.87-0.571,1.379l6.701,6.701c0.586,0.586,1.536,0.586,2.121,0l6.701-6.701C19.271,32.87,18.91,32,18.19,32z"/><linearGradient id="I93pW93qJSUhtSDIz1RZKc" x1="-365" x2="-355" y1="-231.472" y2="-231.472" gradientTransform="translate(389 269.472)" gradientUnits="userSpaceOnUse"><stop offset=".266" stop-color="#199ae0"/><stop offset=".582" stop-color="#1898de"/><stop offset=".745" stop-color="#1590d6"/><stop offset=".873" stop-color="#1083c9"/><stop offset=".982" stop-color="#0870b7"/><stop offset="1" stop-color="#076cb3"/></linearGradient><path fill="url(#I93pW93qJSUhtSDIz1RZKc)" d="M34,35h-9c-0.552,0-1,0.448-1,1v4c0,0.552,0.448,1,1,1h9V35z"/><linearGradient id="I93pW93qJSUhtSDIz1RZKd" x1="32.313" x2="44" y1="7.663" y2="40.775" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#I93pW93qJSUhtSDIz1RZKd)" d="M29.81,16H34v25l4.828-4.828c0.75-0.75,1.172-1.768,1.172-2.828V16h4.19c0.72,0,1.08-0.87,0.571-1.379L38.061,7.92c-0.586-0.586-1.536-0.586-2.121,0l-6.701,6.701C28.729,15.13,29.09,16,29.81,16z"/></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="240" height="240">
<linearGradient id="WxWrlTsssL_WlnpfbClFCa" x1="24" x2="24" y1="592.908" y2="650.553" gradientTransform="matrix(1 0 0 -1 0 662)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f44f5a" />
<stop offset=".443" stop-color="#ee3d4a" />
<stop offset="1" stop-color="#e52030" />
</linearGradient>
<path fill="url(#WxWrlTsssL_WlnpfbClFCa)" d="M39,10v31c0,1.105-0.895,2-2,2H11c-1.105,0-2-0.895-2-2V10H39z" />
<linearGradient id="WxWrlTsssL_WlnpfbClFCb" x1="24" x2="24" y1="657.947" y2="648.199" gradientTransform="matrix(1 0 0 -1 0 662)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f44f5a" />
<stop offset=".443" stop-color="#ee3d4a" />
<stop offset="1" stop-color="#e52030" />
</linearGradient>
<path fill="url(#WxWrlTsssL_WlnpfbClFCb)" d="M28,4h-8c-1.105,0-2,0.895-2,2v2h12V6C30,4.895,29.105,4,28,4z" />
<path fill="#ffa8a8" d="M8,11v-1c0-1.657,1.343-3,3-3h26c1.657,0,3,1.343,3,3v1H8z" />
<path d="M32.395,30.153L28.243,26l4.191-4.191c0.781-0.781,0.781-2.047,0-2.828 l-1.414-1.414c-0.781-0.781-2.047-0.781-2.828,0L24,21.757l-4.191-4.191c-0.781-0.781-2.047-0.781-2.828,0l-1.414,1.414 c-0.781,0.781-0.781,2.047,0,2.828l4.191,4.191l-4.192,4.192c-0.781,0.781-0.781,2.047,0,2.828l1.414,1.414 c0.781,0.781,2.047,0.781,2.828,0L24,30.241l4.153,4.153c0.781,0.781,2.047,0.781,2.828,0l1.414-1.414 C33.176,32.2,33.176,30.934,32.395,30.153z" opacity=".05" />
<path d="M32.042,30.506L27.536,26l4.544-4.544c0.586-0.586,0.586-1.536,0-2.121 l-1.414-1.414c-0.586-0.586-1.536-0.586-2.121,0L24,22.464l-4.544-4.544c-0.586-0.586-1.536-0.586-2.121,0l-1.414,1.414 c-0.586,0.586-0.586,1.536,0,2.121L20.464,26l-4.545,4.545c-0.586,0.586-0.586,1.536,0,2.121l1.414,1.414 c0.586,0.586,1.536,0.586,2.121,0L24,29.536l4.506,4.506c0.586,0.586,1.536,0.586,2.121,0l1.414-1.414 C32.628,32.042,32.628,31.092,32.042,30.506z" opacity=".07" />
<path fill="#fff" d="M26.828,26l4.898-4.898c0.391-0.39,0.391-1.023,0-1.414l-1.414-1.414 c-0.39-0.391-1.024-0.391-1.414,0L24,23.172l-4.898-4.898c-0.39-0.391-1.023-0.391-1.414,0l-1.414,1.414 c-0.391,0.39-0.391,1.023,0,1.414L21.172,26l-4.899,4.899c-0.391,0.39-0.391,1.023,0,1.414l1.414,1.414 c0.39,0.391,1.023,0.391,1.414,0L24,28.828l4.86,4.86c0.39,0.391,1.023,0.391,1.414,0l1.414-1.414c0.391-0.39,0.391-1.024,0-1.414 L26.828,26z" />
</svg>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="240" height="240">
<linearGradient id="2oz8eBjuNR7A1ADmHf2vja" x1="41.018" x2="45.176" y1="228" y2="228" gradientTransform="matrix(1 0 0 -1 0 254)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#3537b0" />
<stop offset="1" stop-color="#4646cf" />
</linearGradient>
<path fill="url(#2oz8eBjuNR7A1ADmHf2vja)" d="M43,11h-3v30h3c1.105,0,2-0.895,2-2V13C45,11.895,44.105,11,43,11z" />
<path fill="#5286ff" d="M41,39V9c0-1.105-0.895-2-2-2H5C3.895,7,3,7.895,3,9v30c0,1.105,0.895,2,2,2h38C41.895,41,41,40.105,41,39z" />
<path fill="#fff" d="M37,17H7c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1h30c0.552,0,1,0.448,1,1v2C38,16.552,37.552,17,37,17z" />
<path fill="#fff" d="M19,36H7c-0.552,0-1-0.448-1-1V22c0-0.552,0.448-1,1-1h12c0.552,0,1,0.448,1,1v13C20,35.552,19.552,36,19,36z" />
<path fill="#fff" d="M38,24H24v-2c0-0.552,0.448-1,1-1h12c0.552,0,1,0.448,1,1V24z" />
<rect width="14" height="3" x="24" y="24" fill="#e6eeff" />
<rect width="14" height="3" x="24" y="27" fill="#ccdcff" />
<rect width="14" height="3" x="24" y="30" fill="#b3cbff" />
<path fill="#9abaff" d="M37,36H25c-0.552,0-1-0.448-1-1v-2h14v2C38,35.552,37.552,36,37,36z" />
<radialGradient id="2oz8eBjuNR7A1ADmHf2vjb" cx="37.925" cy="38.053" r="11.954" gradientUnits="userSpaceOnUse">
<stop offset="0" />
<stop offset="1" stop-opacity="0" />
</radialGradient>
<path fill="url(#2oz8eBjuNR7A1ADmHf2vjb)" d="M38,26c-6.617,0-12,5.383-12,12c0,1.037,0.146,2.039,0.395,3H43c1.105,0,2-0.895,2-2V28.273C43.027,26.849,40.614,26,38,26z" />
<linearGradient id="2oz8eBjuNR7A1ADmHf2vjc" x1="27.766" x2="43.124" y1="226.234" y2="210.876" gradientTransform="matrix(1 0 0 -1 0 254)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#05acb3" />
<stop offset="1" stop-color="#038387" />
</linearGradient>
<path fill="url(#2oz8eBjuNR7A1ADmHf2vjc)" d="M48,38c0,5.522-4.478,10-10,10s-10-4.478-10-10s4.478-10,10-10S48,32.478,48,38z" />
<path d="M38.01,44.537c-1.727,0-3.36-0.633-4.603-1.781c-2.416-2.237-2.83-5.982-1.026-8.709l-0.279-0.279c-0.385-0.385-0.498-0.958-0.29-1.46c0.207-0.502,0.692-0.826,1.236-0.826h3.034c0.816,0,1.481,0.665,1.481,1.481v3.034c0,0.739-0.602,1.34-1.342,1.34c-0.346,0-0.674-0.133-0.925-0.374c-0.123,0.401-0.157,0.827-0.098,1.245c0.114,0.8,0.556,1.496,1.244,1.958c0.457,0.308,0.998,0.47,1.564,0.47s1.107-0.162,1.564-0.47c0.696-0.468,1.143-1.172,1.257-1.982c0.114-0.803-0.117-1.618-0.634-2.234c-0.46-0.55-0.43-1.343,0.071-1.844l0.857-0.857c0.254-0.254,0.605-0.399,0.966-0.399c0.387,0,0.755,0.165,1.009,0.454c2.407,2.735,2.188,6.977-0.489,9.455C41.367,43.905,39.734,44.537,38.01,44.537z" opacity=".05" />
<path d="M38.009,44.037c-1.6,0-3.113-0.586-4.262-1.648c-2.363-2.188-2.644-5.861-0.715-8.396l-0.577-0.578c-0.241-0.241-0.313-0.6-0.182-0.915c0.13-0.314,0.434-0.518,0.774-0.518h3.034c0.541,0,0.981,0.44,0.981,0.981v3.034c0,0.463-0.378,0.84-0.842,0.84c-0.222,0-0.432-0.088-0.591-0.247l-0.495-0.495c-0.384,0.653-0.54,1.425-0.432,2.184c0.135,0.942,0.652,1.76,1.46,2.303c0.539,0.362,1.177,0.555,1.844,0.555s1.305-0.192,1.844-0.555c0.814-0.548,1.338-1.374,1.473-2.327c0.134-0.943-0.138-1.9-0.745-2.626c-0.293-0.35-0.275-0.853,0.041-1.169l0.857-0.857c0.161-0.161,0.384-0.253,0.612-0.253c0.243,0,0.475,0.104,0.634,0.284c2.229,2.534,2.025,6.462-0.454,8.758C41.121,43.452,39.608,44.037,38.009,44.037L38.009,44.037z" opacity=".07" />
<path fill="#fff" d="M42.35,33.964c-0.134-0.153-0.375-0.153-0.519-0.009l-0.857,0.857c-0.136,0.136-0.134,0.348-0.011,0.495c1.425,1.703,1.148,4.357-0.833,5.689c-1.268,0.853-2.978,0.853-4.246,0c-1.979-1.331-2.237-3.971-0.815-5.673l0.914,0.914c0.214,0.214,0.579,0.062,0.579-0.24v-3.034c0-0.266-0.216-0.482-0.482-0.482h-3.034c-0.302,0-0.453,0.365-0.24,0.579l0.898,0.898c-2.061,2.322-1.949,5.907,0.38,8.063c2.182,2.02,5.66,2.021,7.843,0.001C44.253,39.873,44.393,36.287,42.35,33.964z" />
</svg>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path fill="#0884db" d="M23.401,10.798L18.069,6.8c-0.533-0.4-0.533-1.2,0-1.599L23.4,1.202C24.06,0.707,25,1.178,25,2.001v7.997C25,10.822,24.06,11.293,23.401,10.798z"/><path fill="#0368ba" d="M25.105,43.97C13.609,44.597,4,35.366,4,24c0-4.358,1.462-8.63,4.146-12.099c0.346-0.447,1.008-0.494,1.435-0.124l1.479,1.282c0.411,0.356,0.447,0.964,0.113,1.393c-2.688,3.464-3.711,8.072-2.906,12.531c1.399,7.746,8.128,13.145,15.998,13.015c9.228-0.152,16.62-8.218,15.649-17.667l4.056,2.775C43.42,35.174,35.174,43.42,25.105,43.97z"/><path fill="#0884db" d="M24,44c0,0,16-3,16-20c0-8.8-7.2-16-16-16h-3.2V4H24c11,0,20,9,20,20S35,44,24,44z"/></svg>

After

Width:  |  Height:  |  Size: 689 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="RYATVpJlDntEW8LOcPQLra" x1="5.715" x2="40.857" y1="40.37" y2="5.229" gradientTransform="matrix(1 0 0 -1 0 48)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#RYATVpJlDntEW8LOcPQLra)" d="M36.2,6H8C6.9,6,6,6.9,6,8v32c0,1.1,0.9,2,2,2h32c1.1,0,2-0.9,2-2V11.8c0-0.5-0.2-1-0.6-1.4l-3.8-3.8C37.2,6.2,36.7,6,36.2,6z"/><path d="M36,6H14v10c0,1.7,1.3,3,3,3h16c1.7,0,3-1.3,3-3V6z" opacity=".05"/><path fill="#1fa4e6" d="M33,19H13c-1.1,0-2-0.9-2-2V6h24v11C35,18.1,34.1,19,33,19z"/><path d="M33,18.5H17c-1.4,0-2.5-1.1-2.5-2.5V6h21v10C35.5,17.4,34.4,18.5,33,18.5z" opacity=".07"/><radialGradient id="RYATVpJlDntEW8LOcPQLrb" cx="17.573" cy="45.392" r="23.87" gradientTransform="matrix(1 0 0 -1 0 48)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fafafb"/><stop offset=".523" stop-color="#e2e4e7"/><stop offset="1" stop-color="#c8cdd1"/></radialGradient><path fill="url(#RYATVpJlDntEW8LOcPQLrb)" d="M15,6v10c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6H15z"/><rect width="4" height="8" x="27" y="8" fill="#177cad"/><linearGradient id="RYATVpJlDntEW8LOcPQLrc" x1="38.003" x2="40.027" y1="9.997" y2="7.973" gradientTransform="matrix(1 0 0 -1 0 48)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0d61a9"/><stop offset="1" stop-color="#16528c"/></linearGradient><rect width="2" height="2" x="38" y="38" fill="url(#RYATVpJlDntEW8LOcPQLrc)"/><linearGradient id="RYATVpJlDntEW8LOcPQLrd" x1="8.003" x2="10.027" y1="9.997" y2="7.973" gradientTransform="matrix(1 0 0 -1 0 48)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0d61a9"/><stop offset="1" stop-color="#16528c"/></linearGradient><rect width="2" height="2" x="8" y="38" fill="url(#RYATVpJlDntEW8LOcPQLrd)"/><linearGradient id="RYATVpJlDntEW8LOcPQLre" x1="13.83" x2="34.965" y1="23.83" y2="44.965" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".242" stop-color="#f2f2f2"/><stop offset="1" stop-color="#ccc"/></linearGradient><path fill="url(#RYATVpJlDntEW8LOcPQLre)" d="M34,42H14c-1.1,0-2-0.9-2-2V28c0-1.1,0.9-2,2-2h20c1.1,0,2,0.9,2,2v12C36,41.1,35.1,42,34,42z"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path fill="#199be2" d="M35.983,32.448l-3.536,3.536l7.87,7.87c0.195,0.195,0.512,0.195,0.707,0l2.828-2.828c0.195-0.195,0.195-0.512,0-0.707L35.983,32.448z"/><radialGradient id="KGt2acGa95QyN2j07oBX6a" cx="20.024" cy="20.096" r="19.604" gradientUnits="userSpaceOnUse"><stop offset=".693" stop-color="#006185"/><stop offset=".921" stop-color="#35c1f1"/></radialGradient><polygon fill="url(#KGt2acGa95QyN2j07oBX6a)" points="31.601,28.065 28.065,31.601 32.448,35.983 35.983,32.448"/><linearGradient id="KGt2acGa95QyN2j07oBX6b" x1="8.911" x2="31.339" y1="8.911" y2="31.339" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a3ffff"/><stop offset=".223" stop-color="#9dfbff"/><stop offset=".53" stop-color="#8bf1ff"/><stop offset=".885" stop-color="#6ee0ff"/><stop offset="1" stop-color="#63daff"/></linearGradient><circle cx="20" cy="20" r="16" fill="url(#KGt2acGa95QyN2j07oBX6b)"/></svg>

After

Width:  |  Height:  |  Size: 952 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="L4rKfs~Qrm~k0Pk8MRsoza" x1="32.012" x2="15.881" y1="32.012" y2="15.881" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".242" stop-color="#f2f2f2"/><stop offset="1" stop-color="#ccc"/></linearGradient><circle cx="24" cy="24" r="11.5" fill="url(#L4rKfs~Qrm~k0Pk8MRsoza)"/><linearGradient id="L4rKfs~Qrm~k0Pk8MRsozb" x1="17.45" x2="28.94" y1="17.45" y2="28.94" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0d61a9"/><stop offset=".363" stop-color="#0e5fa4"/><stop offset=".78" stop-color="#135796"/><stop offset="1" stop-color="#16528c"/></linearGradient><circle cx="24" cy="24" r="7" fill="url(#L4rKfs~Qrm~k0Pk8MRsozb)"/><linearGradient id="L4rKfs~Qrm~k0Pk8MRsozc" x1="5.326" x2="38.082" y1="5.344" y2="38.099" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#889097"/><stop offset=".331" stop-color="#848c94"/><stop offset=".669" stop-color="#78828b"/><stop offset="1" stop-color="#64717c"/></linearGradient><path fill="url(#L4rKfs~Qrm~k0Pk8MRsozc)" d="M43.407,19.243c-2.389-0.029-4.702-1.274-5.983-3.493c-1.233-2.136-1.208-4.649-0.162-6.693 c-2.125-1.887-4.642-3.339-7.43-4.188C28.577,6.756,26.435,8,24,8s-4.577-1.244-5.831-3.131c-2.788,0.849-5.305,2.301-7.43,4.188 c1.046,2.044,1.071,4.557-0.162,6.693c-1.281,2.219-3.594,3.464-5.983,3.493C4.22,20.77,4,22.358,4,24 c0,1.284,0.133,2.535,0.364,3.752c2.469-0.051,4.891,1.208,6.213,3.498c1.368,2.37,1.187,5.204-0.22,7.345 c2.082,1.947,4.573,3.456,7.34,4.375C18.827,40.624,21.221,39,24,39s5.173,1.624,6.303,3.971c2.767-0.919,5.258-2.428,7.34-4.375 c-1.407-2.141-1.588-4.975-0.22-7.345c1.322-2.29,3.743-3.549,6.213-3.498C43.867,26.535,44,25.284,44,24 C44,22.358,43.78,20.77,43.407,19.243z M24,34.5c-5.799,0-10.5-4.701-10.5-10.5c0-5.799,4.701-10.5,10.5-10.5S34.5,18.201,34.5,24 C34.5,29.799,29.799,34.5,24,34.5z"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 48 48"><linearGradient id="SVGID_1_" x1="24" x2="24" y1="656" y2="630.201" gradientTransform="matrix(1 0 0 -1 0 662)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#737b80"/><stop offset="1" stop-color="#575c61"/></linearGradient><path fill="url(#SVGID_1_)" d="M10.8,6h26.5c1,0,1.9,0.8,2,1.8l2.8,22c0.1,1.2-0.8,2.2-2,2.2H8c-1.2,0-2.1-1-2-2.2l2.8-22C8.9,6.8,9.8,6,10.8,6z"/><linearGradient id="SVGID_2_" x1="24" x2="24" y1="631.917" y2="619.5" gradientTransform="matrix(1 0 0 -1 0 662)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#c3cdd9"/><stop offset="1" stop-color="#9fa7b0"/></linearGradient><path fill="url(#SVGID_2_)" d="M42,30H6v10c0,1.1,0.9,2,2,2h32c1.1,0,2-0.9,2-2V30z"/><path d="M35,35c1.1,0,2,0.9,2,2s-0.9,2-2,2s-2-0.9-2-2S33.9,35,35,35 M35,34c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S36.7,34,35,34L35,34z" opacity=".05"/><path d="M35,35c1.1,0,2,0.9,2,2s-0.9,2-2,2s-2-0.9-2-2S33.9,35,35,35 M35,34.5c-1.4,0-2.5,1.1-2.5,2.5s1.1,2.5,2.5,2.5s2.5-1.1,2.5-2.5S36.4,34.5,35,34.5L35,34.5z" opacity=".07"/><linearGradient id="SVGID_3_" x1="35" x2="35" y1="627.333" y2="622.993" gradientTransform="matrix(1 0 0 -1 0 662)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#75ff8a"/><stop offset="1" stop-color="#1ee446"/></linearGradient><circle cx="35" cy="37" r="2" fill="url(#SVGID_3_)"/><path d="M22.2,22.6c0.5,0.5,1.1,0.7,1.8,0.7c0.7,0,1.3-0.3,1.8-0.7l6.7-6.7c0.5-0.5,0.6-1.2,0.4-1.9C32.6,13.4,32,13,31.3,13H28V6h-8v7h-3.3c-0.7,0-1.3,0.4-1.6,1.1c-0.3,0.6-0.1,1.4,0.4,1.9L22.2,22.6z" opacity=".05"/><path d="M22.6,22.3c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6l6.7-6.7c0.3-0.3,0.5-0.9,0.3-1.3c-0.2-0.5-0.6-0.7-1.1-0.7h-3.8V6h-7v7.5h-3.8c-0.5,0-0.9,0.3-1.1,0.7c-0.2,0.5-0.1,1,0.3,1.3L22.6,22.3z" opacity=".07"/><path fill="#50e6ff" d="M31.8,15.2l-6.7,6.7c-0.6,0.6-1.5,0.6-2.1,0l-6.7-6.7c-0.4-0.4-0.1-1.2,0.5-1.2H21V1c0-0.6,0.4-1,1-1h4c0.6,0,1,0.4,1,1v13h4.3C31.9,14,32.2,14.8,31.8,15.2z"/></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path fill="#09914a" d="M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z"/><linearGradient id="wNnN53lrjZSLZlIPnrNqHa" x1="10.251" x2="15.3" y1="10.763" y2="30.307" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f2f2f2"/><stop offset=".148" stop-color="#eef1ef"/><stop offset=".282" stop-color="#e4ece8"/><stop offset=".409" stop-color="#d1e4da"/><stop offset=".533" stop-color="#b7dac8"/><stop offset=".654" stop-color="#96ccb0"/><stop offset=".773" stop-color="#6dbb92"/><stop offset=".889" stop-color="#3ea770"/><stop offset="1" stop-color="#09914a"/></linearGradient><path fill="url(#wNnN53lrjZSLZlIPnrNqHa)" d="M24,24L9.999,38.282C2.112,30.55,1.986,17.886,9.718,9.999L24,24z"/><circle cx="24" cy="24" r="17" fill="#f2f2f2"/><path fill="#d83b01" d="M24,36.75c-0.414,0-0.75-0.336-0.75-0.75V24c0-0.414,0.336-0.75,0.75-0.75s0.75,0.336,0.75,0.75v12C24.75,36.414,24.414,36.75,24,36.75z"/><path fill="#45494d" d="M24,24.75c-0.192,0-0.384-0.073-0.53-0.22c-0.293-0.293-0.293-0.768,0-1.061l8.485-8.485c0.293-0.293,0.768-0.293,1.061,0s0.293,0.768,0,1.061L24.53,24.53C24.384,24.677,24.192,24.75,24,24.75z"/><path fill="#45494d" d="M23.999,25.25c-0.181,0-0.365-0.039-0.54-0.123l-7.787-3.735c-0.623-0.299-0.885-1.045-0.586-1.668c0.298-0.622,1.044-0.887,1.667-0.586l7.787,3.735c0.623,0.299,0.885,1.045,0.586,1.668C24.912,24.988,24.465,25.25,23.999,25.25z"/><circle cx="24" cy="24" r="2" fill="#1e2021"/><path fill="#09914a" d="M17.287,12.963l-8.419,1.089c-0.534,0.069-0.989-0.386-0.92-0.92l1.089-8.419c0.087-0.676,0.913-0.958,1.395-0.475l7.33,7.33C18.244,12.05,17.963,12.875,17.287,12.963z"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><radialGradient id="ZvG93iL2s_aXWH0fFsunUa" cx="36.661" cy="12.462" r="13.235" gradientUnits="userSpaceOnUse"><stop offset=".706" stop-color="#787f85"/><stop offset=".713" stop-color="#7a8187"/><stop offset=".793" stop-color="#90989f"/><stop offset=".868" stop-color="#9da5ae"/><stop offset=".93" stop-color="#a1aab3"/></radialGradient><path fill="url(#ZvG93iL2s_aXWH0fFsunUa)" d="M27.318,15.318c-0.352,0.352-18.648,18.648-19,19c-1.757,1.757-1.757,4.607,0,6.364c1.757,1.757,4.607,1.757,6.364,0c0.352-0.352,18.648-18.648,19-19L27.318,15.318z"/><linearGradient id="ZvG93iL2s_aXWH0fFsunUb" x1="10.129" x2="13.411" y1="35.129" y2="38.411" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0d61a9"/><stop offset=".363" stop-color="#0e5fa4"/><stop offset=".78" stop-color="#135796"/><stop offset="1" stop-color="#16528c"/></linearGradient><circle cx="12" cy="37" r="2" fill="url(#ZvG93iL2s_aXWH0fFsunUb)"/><linearGradient id="ZvG93iL2s_aXWH0fFsunUc" x1="29.131" x2="41.661" y1="7.002" y2="19.532" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a1aab3"/><stop offset="1" stop-color="#8f979e"/></linearGradient><path fill="url(#ZvG93iL2s_aXWH0fFsunUc)" d="M40.425,13.838c-1.453,1.453-3.81,1.453-5.263,0c-1.453-1.453-1.453-3.81,0-5.263c0.355-0.355,1.784-1.784,3.24-3.24c0.349-0.349,0.194-0.959-0.285-1.077c-1.18-0.29-2.45-0.351-3.771-0.102c-3.874,0.73-6.895,3.972-7.297,7.893c-0.586,5.718,4.186,10.489,9.904,9.902c3.921-0.403,7.162-3.424,7.892-7.298c0.249-1.321,0.188-2.59-0.102-3.77c-0.118-0.48-0.728-0.635-1.077-0.285C42.209,12.054,40.78,13.484,40.425,13.838z"/><linearGradient id="ZvG93iL2s_aXWH0fFsunUd" x1="4" x2="37" y1="22.4" y2="22.4" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a1aab3"/><stop offset="1" stop-color="#8f979e"/></linearGradient><path fill="url(#ZvG93iL2s_aXWH0fFsunUd)" d="M37,36L12.5,11.7L10,8L5.4,6L4,7.4L6,12l3.7,2.5l24.5,24.3L37,36z"/><path fill="#af2031" d="M19.13,27.494c0.54,0.54,12.836,12.836,13.188,13.188c1.757,1.757,4.607,1.757,6.364,0c1.757-1.757,1.757-4.607,0-6.364C38.33,33.966,26.034,21.67,25.494,21.13L19.13,27.494z"/><path fill="#c94f60" d="M23.494,19.13l-6.364,6.364c0.085,0.085,0.865,0.865,2,2l6.364-6.364 C24.359,19.995,23.579,19.215,23.494,19.13z"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><radialGradient id="9Y8YaPFEzyGwEgYZ1l__na" cx="-219.911" cy="-33.889" r="25.29" gradientTransform="rotate(-134.999 -86.009 -55.502)" gradientUnits="userSpaceOnUse"><stop offset=".752" stop-color="#076cb3"/><stop offset=".825" stop-color="#138cd2"/><stop offset=".865" stop-color="#1898de"/><stop offset="1" stop-color="#199ae0"/></radialGradient><path fill="url(#9Y8YaPFEzyGwEgYZ1l__na)" d="M35.067,8.135L40,14.174v-9.54c0-0.528-0.639-0.792-1.013-0.419L35.067,8.135z"/><linearGradient id="9Y8YaPFEzyGwEgYZ1l__nb" x1="19.482" x2="26.572" y1="249.377" y2="209.164" gradientTransform="matrix(1 0 0 -1 0 254)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#9Y8YaPFEzyGwEgYZ1l__nb)" d="M24,4C12.972,4,4,12.972,4,24s8.972,20,20,20c3.648,0,7.065-0.992,10.012-2.708c0.469-0.273,0.615-0.886,0.343-1.357l-1.492-2.584c-0.271-0.469-0.874-0.652-1.342-0.379C29.309,38.261,26.74,39,24,39c-8.271,0-15-6.729-15-15S15.729,9,24,9c2.909,0,5.612,0.851,7.91,2.293l-2.695,2.695C28.842,14.361,29.106,15,29.635,15h9.573C39.645,15,40,14.645,40,14.208v-2.157C36.349,7.175,30.546,4,24,4z"/><radialGradient id="9Y8YaPFEzyGwEgYZ1l__nc" cx="36.693" cy="38.778" r="10.696" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop offset=".979" stop-opacity="0"/></radialGradient><path fill="url(#9Y8YaPFEzyGwEgYZ1l__nc)" d="M32.863,37.351c-0.271-0.469-0.874-0.652-1.342-0.379c-1.652,0.963-3.504,1.618-5.477,1.888c0.124,1.736,0.608,3.375,1.395,4.83c2.357-0.414,4.575-1.235,6.574-2.398c0.469-0.273,0.615-0.886,0.343-1.357L32.863,37.351z"/><linearGradient id="9Y8YaPFEzyGwEgYZ1l__nd" x1="30.929" x2="45.071" y1="223.071" y2="208.929" gradientTransform="matrix(1 0 0 -1 0 254)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#21ad64"/><stop offset="1" stop-color="#088242"/></linearGradient><path fill="url(#9Y8YaPFEzyGwEgYZ1l__nd)" d="M48,38c0,5.522-4.478,10-10,10s-10-4.478-10-10s4.478-10,10-10S48,32.478,48,38z"/><path fill="#fff" d="M36.646,42.354l-4-4c-0.195-0.195-0.195-0.512,0-0.707l0.707-0.707c0.195-0.195,0.512-0.195,0.707,0L37,39.879l5.439-5.439c0.195-0.195,0.512-0.195,0.707,0l0.707,0.707c0.195,0.195,0.195,0.512,0,0.707l-6.5,6.5C37.158,42.549,36.842,42.549,36.646,42.354z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><linearGradient id="jqRAop7tyWoUQ0CkVwCu6a" x1="8.663" x2="38.122" y1="8.059" y2="32.915" gradientTransform="matrix(-1 0 0 1 48 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a1aab3"/><stop offset="1" stop-color="#8f979e"/></linearGradient><path fill="url(#jqRAop7tyWoUQ0CkVwCu6a)" d="M7,35h34c1.105,0,2-0.895,2-2V9c0-1.105-0.895-2-2-2H7C5.895,7,5,7.895,5,9v24C5,34.105,5.895,35,7,35z"/><radialGradient id="jqRAop7tyWoUQ0CkVwCu6b" cx="72.516" cy="158.294" r="86.245" gradientTransform="matrix(.8095 0 0 .7188 -11.619 -54.844)" gradientUnits="userSpaceOnUse"><stop offset=".323" stop-color="#23d9d6"/><stop offset=".444" stop-color="#23d4d8"/><stop offset=".579" stop-color="#24c7de"/><stop offset=".721" stop-color="#26b0e8"/><stop offset=".867" stop-color="#2891f6"/><stop offset=".944" stop-color="#297eff"/></radialGradient><rect width="34" height="24" x="7" y="9" fill="url(#jqRAop7tyWoUQ0CkVwCu6b)"/><linearGradient id="jqRAop7tyWoUQ0CkVwCu6c" x1="16.462" x2="31.425" y1="33.571" y2="48.533" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#007ccf"/><stop offset=".317" stop-color="#0074c7"/><stop offset=".818" stop-color="#005eb0"/><stop offset="1" stop-color="#0055a6"/></linearGradient><path fill="url(#jqRAop7tyWoUQ0CkVwCu6c)" d="M24,32.857c-7.18,0-13,4.23-13,8.589v1.161C11,43.376,11.624,44,12.393,44h23.214C36.376,44,37,43.376,37,42.607v-1.161C37,37.087,31.18,32.857,24,32.857z"/><path fill="#d6a121" d="M28.179,34.086c0,1.585-2.365,2.343-4.179,2.343s-4.179-0.757-4.179-2.343c0-2.204,0-5.88,0-5.88h8.357C28.179,28.206,28.179,31.882,28.179,34.086z"/><linearGradient id="jqRAop7tyWoUQ0CkVwCu6d" x1="31.351" x2="32.59" y1="26.357" y2="26.357" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#c48f0c"/><stop offset=".251" stop-color="#d19b16"/><stop offset=".619" stop-color="#dca51f"/><stop offset="1" stop-color="#e0a922"/></linearGradient><path fill="url(#jqRAop7tyWoUQ0CkVwCu6d)" d="M31.351,24.5h-0.49v3.714h0.653c0.478,0,0.886-0.29,0.966-0.687l0.32-1.582C32.953,25.19,32.261,24.5,31.351,24.5z"/><linearGradient id="jqRAop7tyWoUQ0CkVwCu6e" x1="-72.649" x2="-71.41" y1="26.357" y2="26.357" gradientTransform="matrix(-1 0 0 1 -56 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#c48f0c"/><stop offset=".251" stop-color="#d19b16"/><stop offset=".619" stop-color="#dca51f"/><stop offset="1" stop-color="#e0a922"/></linearGradient><path fill="url(#jqRAop7tyWoUQ0CkVwCu6e)" d="M16.649,24.5h0.49v3.714h-0.653c-0.478,0-0.886-0.29-0.966-0.687l-0.32-1.582C15.047,25.19,15.739,24.5,16.649,24.5z"/><radialGradient id="jqRAop7tyWoUQ0CkVwCu6f" cx="-12.518" cy="78.093" r="10.09" gradientTransform="translate(35.037 -45.216) scale(.8816)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffcf54"/><stop offset=".261" stop-color="#fdcb4d"/><stop offset=".639" stop-color="#f7c13a"/><stop offset="1" stop-color="#f0b421"/></radialGradient><path fill="url(#jqRAop7tyWoUQ0CkVwCu6f)" d="M24,13.481c-3.666,0-7.429,0.557-7.429,8.481c0,0.634,0,4.851,0,5.528c0,2.829,4.457,6.295,7.429,6.295s7.429-3.467,7.429-6.295c0-0.677,0-4.894,0-5.528C31.429,14.038,27.666,13.481,24,13.481z"/><linearGradient id="jqRAop7tyWoUQ0CkVwCu6g" x1="20.15" x2="28.734" y1="12.866" y2="32.857" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#c26715"/><stop offset=".508" stop-color="#b85515"/><stop offset="1" stop-color="#ad3f16"/></linearGradient><path fill="url(#jqRAop7tyWoUQ0CkVwCu6g)" d="M24,12.429c2.786,0,4.643,1.857,4.643,1.857c1.479,0.218,3.714,0.929,3.714,4.643c0,1.382-0.929,5.929-0.929,8.5S27,33.823,24,33.823s-7.429-2.966-7.429-6.394s-0.929-7.292-0.929-8.5C15.643,16.062,18.811,12.429,24,12.429z"/><radialGradient id="jqRAop7tyWoUQ0CkVwCu6h" cx="-28.79" cy="68.49" r="28.922" gradientTransform="matrix(-.8431 0 0 .8816 1.265 -45.216)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#c26715"/><stop offset=".508" stop-color="#b85515"/><stop offset="1" stop-color="#ad3f16"/></radialGradient><path fill="url(#jqRAop7tyWoUQ0CkVwCu6h)" d="M23.706,12.429c4.008,0,4.937,1.857,4.937,1.857c0.034,0.942-1.122,1.688-1.122,1.688s-0.619,1.33-4.144,1.33c-2.129,0-5.18-1.328-5.18-4.875C18.196,12.429,18.882,12.429,23.706,12.429z"/></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

Some files were not shown because too many files have changed in this diff Show More