local folder workspace

This commit is contained in:
2025-11-17 16:35:02 +01:00
parent 5df8019cfb
commit e04e5f0b13
17 changed files with 347 additions and 151 deletions

View File

@@ -6,19 +6,14 @@ namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspace internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspace
{ {
private string? rawInstallInfos = null; private string? rawInstallInfos;
private string? rawUpdateInfos = null; private string? rawUpdateInfos;
public WorkspaceConfig Config => ConfigX; public WorkspaceConfig Config => ConfigX;
public GitLabRepoWorkspaceConfig ConfigX { get; } = config; public GitLabRepoWorkspaceConfig ConfigX { get; } = config;
public IGitLabClient Gitlab { get; } = new GitLabClient(config.InstanceUrl, config.ApiToken); public IGitLabClient Gitlab { get; } = new GitLabClient(config.InstanceUrl, config.ApiToken);
public ModpackConfig? ModpackConfig { get; private set; } public ModpackConfig? ModpackConfig { get; private set; }
public InstallInfos? InstallInfos { get; private set; } public InstallInfos? InstallInfos { get; private set; }
public UpdateInfos? UpdateInfos { get; private set; } public UpdateInfos? UpdateInfos { get; private set; }
public async Task<bool> Load() public async Task<bool> Load()
@@ -39,13 +34,17 @@ internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspac
public async Task<bool> Save() public async Task<bool> Save()
{ {
var failed = true;
if (InstallInfos != null) if (InstallInfos != null)
{ {
var newInstallInfos = InstallInfos.ToString(); var newInstallInfos = InstallInfos.ToString();
if (newInstallInfos != rawInstallInfos) if (newInstallInfos != rawInstallInfos)
{ {
await SaveContent(ConfigX.FileLocationInstallJson, newInstallInfos); if (await SaveContent(ConfigX.FileLocationInstallJson, newInstallInfos))
rawInstallInfos = newInstallInfos; rawInstallInfos = newInstallInfos;
else
failed = true;
} }
} }
@@ -54,12 +53,14 @@ internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspac
var newUpdateInfos = UpdateInfos.ToString(); var newUpdateInfos = UpdateInfos.ToString();
if (newUpdateInfos != rawUpdateInfos) if (newUpdateInfos != rawUpdateInfos)
{ {
await SaveContent(ConfigX.FileLocationUpdateJson, newUpdateInfos); if (await SaveContent(ConfigX.FileLocationUpdateJson, newUpdateInfos))
rawUpdateInfos = newUpdateInfos; rawUpdateInfos = newUpdateInfos;
else
failed = true;
} }
} }
return true; return failed;
} }
private async Task<string> GetContent(string path) private async Task<string> GetContent(string path)

View File

@@ -10,27 +10,28 @@
d:DesignWidth="800" d:DesignWidth="800"
d:DesignHeight="450" d:DesignHeight="450"
Width="300" Width="300"
x:Class="ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo.GitLabRepoWorkspaceConfigEditorView"> x:Class="ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo.GitLabRepoWorkspaceConfigEditorView"
x:DataType="gitLabRepo:GitLabRepoWorkspaceConfig">
<dialogs:AvaloniaFlyoutBase.MainContent> <dialogs:AvaloniaFlyoutBase.MainContent>
<StackPanel Spacing="6"> <StackPanel Spacing="6">
<TextBlock Text="{x:Static langRes:GeneralLangRes.GitLabInstanceUrl}"/> <Label Target="TextBoxInstanceUrl" Content="{x:Static langRes:GeneralLangRes.GitLabInstanceUrl}"/>
<TextBox Text="{Binding InstanceUrl, DataType=gitLabRepo:GitLabRepoWorkspaceConfig}"/> <TextBox Name="TextBoxInstanceUrl" Text="{Binding InstanceUrl}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.GitLabApiToken}"/> <Label Target="TextBoxApiToken" Content="{x:Static langRes:GeneralLangRes.GitLabApiToken}"/>
<TextBox Text="{Binding ApiToken, DataType=gitLabRepo:GitLabRepoWorkspaceConfig}"/> <TextBox Name="TextBoxApiToken" Text="{Binding ApiToken}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.RepositoryId}"/> <Label Target="NumericUpDownRepoId" Content="{x:Static langRes:GeneralLangRes.RepositoryId}"/>
<NumericUpDown Value="{Binding RepoId, DataType=gitLabRepo:GitLabRepoWorkspaceConfig}"/> <NumericUpDown Name="NumericUpDownRepoId" Value="{Binding RepoId}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.FileLocationOfInstallJson}"/> <Label Target="TextBoxInstallJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfInstallJson}"/>
<TextBox Text="{Binding FileLocationInstallJson, DataType=gitLabRepo:GitLabRepoWorkspaceConfig}"/> <TextBox Name="TextBoxInstallJson" Text="{Binding FileLocationInstallJson}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.FileLocationOfUpdateJson}"/> <Label Target="TextBoxUpdateJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfUpdateJson}"/>
<TextBox Text="{Binding FileLocationUpdateJson, DataType=gitLabRepo:GitLabRepoWorkspaceConfig}"/> <TextBox Name="TextBoxUpdateJson" Text="{Binding FileLocationUpdateJson}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.ModpackConfigUrl}"/> <Label Target="TextBoxModpackConfigUrl" Content="{x:Static langRes:GeneralLangRes.ModpackConfigUrl}"/>
<TextBox Text="{Binding ModpackConfigUrl, DataType=gitLabRepo:GitLabRepoWorkspaceConfig}"/> <TextBox Name="TextBoxModpackConfigUrl" Text="{Binding ModpackConfigUrl}"/>
</StackPanel> </StackPanel>
</dialogs:AvaloniaFlyoutBase.MainContent> </dialogs:AvaloniaFlyoutBase.MainContent>
</dialogs:AvaloniaFlyoutBase> </dialogs:AvaloniaFlyoutBase>

View File

@@ -31,7 +31,7 @@ internal class GitLabRepoWorkspaceFeature() : WorkspaceFeature("origin.gitlab",
protected override void OnCreate(out IWorkspace workspace, WorkspaceConfig config) protected override void OnCreate(out IWorkspace workspace, WorkspaceConfig config)
{ {
if (config is not GitLabRepoWorkspaceConfig gitlabConfig) if (config is not GitLabRepoWorkspaceConfig gitlabConfig)
throw new NotImplementedException($"Only configs of type {nameof(GitLabRepoWorkspaceConfig)} are allowed."); throw new NotSupportedException($"Only configs of type {nameof(GitLabRepoWorkspaceConfig)} are allowed.");
workspace = new GitLabRepoWorkspace(gitlabConfig); workspace = new GitLabRepoWorkspace(gitlabConfig);
} }
} }

View File

@@ -0,0 +1,84 @@
using ModpackUpdater.Apps.Manager.Api.Model;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
internal class LocalFolderWorkspace(LocalFolderWorkspaceConfig config) : IWorkspace
{
private string? rawInstallInfos;
private string? rawUpdateInfos;
public WorkspaceConfig Config => ConfigX;
public LocalFolderWorkspaceConfig ConfigX { get; } = config;
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.FolderName = Path.GetFileName(ConfigX.RootFolderPath);
return InstallInfos != null && UpdateInfos != null;
}
public async Task<bool> Save()
{
var failed = false;
if (InstallInfos != null)
{
var newInstallInfos = InstallInfos.ToString();
if (newInstallInfos != rawInstallInfos)
{
if (await SaveContent(ConfigX.FileLocationInstallJson, newInstallInfos))
rawInstallInfos = newInstallInfos;
else
failed = true;
}
}
if (UpdateInfos != null)
{
var newUpdateInfos = UpdateInfos.ToString();
if (newUpdateInfos != rawUpdateInfos)
{
if (await SaveContent(ConfigX.FileLocationUpdateJson, newUpdateInfos))
rawUpdateInfos = newUpdateInfos;
else
failed = true;
}
}
return !failed;
}
private async Task<string?> GetContent(string path)
{
if (ConfigX.RootFolderPath == null)
return null;
var filePath = Path.Combine(ConfigX.RootFolderPath!, path);
return File.Exists(filePath) ? await File.ReadAllTextAsync(filePath) : null;
}
private async Task<bool> SaveContent(string path, string content)
{
if (ConfigX.RootFolderPath == null)
return false;
var filePath = Path.Combine(ConfigX.RootFolderPath!, path);
if (!File.Exists(filePath))
return false;
await File.WriteAllTextAsync(filePath, content);
return true;
}
}

View File

@@ -0,0 +1,17 @@
using ModpackUpdater.Apps.Manager.Api.Model;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
public class LocalFolderWorkspaceConfig : WorkspaceConfig, ICloneable
{
public override string DisplayText => FolderName ?? string.Empty;
public string? FolderName { get; set; }
public string? RootFolderPath { get; set; }
public string FileLocationInstallJson { get; set; } = "install.json";
public string FileLocationUpdateJson { get; set; } = "updates.json";
public object Clone()
{
return MemberwiseClone();
}
}

View File

@@ -0,0 +1,43 @@
<dialogs:AvaloniaFlyoutBase
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dialogs="https://git.pilzinsel64.de/pilz-framework/pilz"
xmlns:langRes="clr-namespace:ModpackUpdater.Apps.Manager.LangRes"
xmlns:localFolder="clr-namespace:ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
Width="300"
x:Class="ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder.LocalFolderWorkspaceConfigEditorView"
x:DataType="localFolder:LocalFolderWorkspaceConfig">
<dialogs:AvaloniaFlyoutBase.MainContent>
<StackPanel Spacing="6">
<Label Target="TextBoxRootFolderPath" Content="{x:Static langRes:GeneralLangRes.RootFolderPath}"/>
<StackPanel
Orientation="Horizontal"
Spacing="6">
<TextBox x:Name="TextBoxRootFolderPath" Text="{Binding RootFolderPath}"/>
<dialogs:ImageButton
x:Name="ButtonSearch"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Text="{x:Static langRes:GeneralLangRes.Select}"
Click="ButtonSearch_OnClick"/>
</StackPanel>
<Label Target="TextBoxInstallJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfInstallJson}"/>
<TextBox Name="TextBoxInstallJson" Text="{Binding FileLocationInstallJson}"/>
<Label Target="TextBoxUpdateJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfUpdateJson}"/>
<TextBox Name="TextBoxUpdateJson" Text="{Binding FileLocationUpdateJson}"/>
<Label Target="TextBoxModpackConfigUrl" Content="{x:Static langRes:GeneralLangRes.ModpackConfigUrl}"/>
<TextBox Name="TextBoxModpackConfigUrl" Text="{Binding ModpackConfigUrl}"/>
</StackPanel>
</dialogs:AvaloniaFlyoutBase.MainContent>
</dialogs:AvaloniaFlyoutBase>

View File

@@ -0,0 +1,35 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.UI.AvaloniaUI.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
public partial class LocalFolderWorkspaceConfigEditorView : AvaloniaFlyoutBase
{
public LocalFolderWorkspaceConfig Settings { get; }
public LocalFolderWorkspaceConfigEditorView(LocalFolderWorkspaceConfig settings)
{
Settings = settings;
DataContext = settings;
InitializeComponent();
ButtonSearch.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.opened_folder);
}
private async void ButtonSearch_OnClick(object? sender, RoutedEventArgs e)
{
if (TopLevel.GetTopLevel(this) is not { } topLevel)
return;
var filePaths = await topLevel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = GeneralLangRes.SelectRootFolder,
AllowMultiple = false,
});
if (filePaths.Count >= 1)
TextBoxRootFolderPath.Text = filePaths[0].Path.AbsolutePath;
}
}

View File

@@ -0,0 +1,37 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features;
using Pilz.UI.AvaloniaUI.Dialogs;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
internal class LocalFolderWorkspaceFeature() : WorkspaceFeature("origin.localfolder", FeatureNamesLangRes.LocalFolderWorkspace), IPluginFeatureProvider<LocalFolderWorkspaceFeature>
{
public static LocalFolderWorkspaceFeature Instance { get; } = new();
public override object? Icon => AppGlobals.Symbols.GetImage(AppSymbols.opened_folder, SymbolSize.Small);
protected override async Task OnConfigure(WorkspaceContext context)
{
var settings = context.Workspace?.Config as LocalFolderWorkspaceConfig ?? new();
if ((await AvaloniaFlyoutBase.Show(
new LocalFolderWorkspaceConfigEditorView((LocalFolderWorkspaceConfig)settings.Clone()),
context.MainApi.MainWindow,
TitlesLangRes.LocalFolderWorkspaceEditor,
AppGlobals.Symbols.GetImageSource(AppSymbols.gitlab)))
.Result is LocalFolderWorkspaceConfig settingsNew)
context.Workspace = new LocalFolderWorkspace(settingsNew);
else
context.Canceled = true;
}
protected override void OnCreate(out IWorkspace workspace, WorkspaceConfig config)
{
if (config is not LocalFolderWorkspaceConfig gitlabConfig)
throw new NotSupportedException($"Only configs of type {nameof(LocalFolderWorkspaceConfig)} are allowed.");
workspace = new LocalFolderWorkspace(gitlabConfig);
}
}

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class FeatureNamesLangRes {
// -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 System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal FeatureNamesLangRes() { internal FeatureNamesLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.FeatureNamesLangRes", typeof(FeatureNamesLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.FeatureNamesLangRes", typeof(FeatureNamesLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// 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 { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,109 +45,79 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string CheckAllActionsHealthy {
/// Sucht eine lokalisierte Zeichenfolge, die Check healthy ähnelt.
/// </summary>
internal static string CheckAllActionsHealthy {
get { get {
return ResourceManager.GetString("CheckAllActionsHealthy", resourceCulture); return ResourceManager.GetString("CheckAllActionsHealthy", resourceCulture);
} }
} }
/// <summary> public static string CheckSingleActionHealthy {
/// Sucht eine lokalisierte Zeichenfolge, die Check healthy ähnelt.
/// </summary>
internal static string CheckSingleActionHealthy {
get { get {
return ResourceManager.GetString("CheckSingleActionHealthy", resourceCulture); return ResourceManager.GetString("CheckSingleActionHealthy", resourceCulture);
} }
} }
/// <summary> public static string ClearDirectLinkFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Clear direct link ähnelt.
/// </summary>
internal static string ClearDirectLinkFeature {
get { get {
return ResourceManager.GetString("ClearDirectLinkFeature", resourceCulture); return ResourceManager.GetString("ClearDirectLinkFeature", resourceCulture);
} }
} }
/// <summary> public static string ClearDirectLinksFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Clear direct links ähnelt.
/// </summary>
internal static string ClearDirectLinksFeature {
get { get {
return ResourceManager.GetString("ClearDirectLinksFeature", resourceCulture); return ResourceManager.GetString("ClearDirectLinksFeature", resourceCulture);
} }
} }
/// <summary> public static string GenerateChangelogFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Generate changelog ähnelt.
/// </summary>
internal static string GenerateChangelogFeature {
get { get {
return ResourceManager.GetString("GenerateChangelogFeature", resourceCulture); return ResourceManager.GetString("GenerateChangelogFeature", resourceCulture);
} }
} }
/// <summary> public static string GenerateModlistAsExcelFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Generate modlist excel file ähnelt.
/// </summary>
internal static string GenerateModlistAsExcelFeature {
get { get {
return ResourceManager.GetString("GenerateModlistAsExcelFeature", resourceCulture); return ResourceManager.GetString("GenerateModlistAsExcelFeature", resourceCulture);
} }
} }
/// <summary> public static string GenerateModlistAsMarkdownFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Generate modlist markdown table ähnelt.
/// </summary>
internal static string GenerateModlistAsMarkdownFeature {
get { get {
return ResourceManager.GetString("GenerateModlistAsMarkdownFeature", resourceCulture); return ResourceManager.GetString("GenerateModlistAsMarkdownFeature", resourceCulture);
} }
} }
/// <summary> public static string GitLabWorkspace {
/// Sucht eine lokalisierte Zeichenfolge, die GitLab workspace ähnelt.
/// </summary>
internal static string GitLabWorkspace {
get { get {
return ResourceManager.GetString("GitLabWorkspace", resourceCulture); return ResourceManager.GetString("GitLabWorkspace", resourceCulture);
} }
} }
/// <summary> public static string LocalFolderWorkspace {
/// Sucht eine lokalisierte Zeichenfolge, die Find update ähnelt. get {
/// </summary> return ResourceManager.GetString("LocalFolderWorkspace", resourceCulture);
internal static string UpdateCollectorFeature { }
}
public static string UpdateCollectorFeature {
get { get {
return ResourceManager.GetString("UpdateCollectorFeature", resourceCulture); return ResourceManager.GetString("UpdateCollectorFeature", resourceCulture);
} }
} }
/// <summary> public static string UpdateDirectLinkFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Update direct link ähnelt.
/// </summary>
internal static string UpdateDirectLinkFeature {
get { get {
return ResourceManager.GetString("UpdateDirectLinkFeature", resourceCulture); return ResourceManager.GetString("UpdateDirectLinkFeature", resourceCulture);
} }
} }
/// <summary> public static string UpdateDirectLinksFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Update direct links ähnelt.
/// </summary>
internal static string UpdateDirectLinksFeature {
get { get {
return ResourceManager.GetString("UpdateDirectLinksFeature", resourceCulture); return ResourceManager.GetString("UpdateDirectLinksFeature", resourceCulture);
} }
} }
/// <summary> public static string UpdatesCollectorFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Find updates ähnelt.
/// </summary>
internal static string UpdatesCollectorFeature {
get { get {
return ResourceManager.GetString("UpdatesCollectorFeature", resourceCulture); return ResourceManager.GetString("UpdatesCollectorFeature", resourceCulture);
} }

View File

@@ -141,6 +141,9 @@
<data name="GitLabWorkspace" xml:space="preserve"> <data name="GitLabWorkspace" xml:space="preserve">
<value>GitLab workspace</value> <value>GitLab workspace</value>
</data> </data>
<data name="LocalFolderWorkspace" xml:space="preserve">
<value>Local folder workspace</value>
</data>
<data name="UpdateCollectorFeature" xml:space="preserve"> <data name="UpdateCollectorFeature" xml:space="preserve">
<value>Find update</value> <value>Find update</value>
</data> </data>

View File

@@ -69,6 +69,12 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
public static string RootFolderPath {
get {
return ResourceManager.GetString("RootFolderPath", resourceCulture);
}
}
public static string FileLocationOfInstallJson { public static string FileLocationOfInstallJson {
get { get {
return ResourceManager.GetString("FileLocationOfInstallJson", resourceCulture); return ResourceManager.GetString("FileLocationOfInstallJson", resourceCulture);
@@ -296,5 +302,17 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
return ResourceManager.GetString("Website", resourceCulture); return ResourceManager.GetString("Website", resourceCulture);
} }
} }
public static string Select {
get {
return ResourceManager.GetString("Select", resourceCulture);
}
}
public static string SelectRootFolder {
get {
return ResourceManager.GetString("SelectRootFolder", resourceCulture);
}
}
} }
} }

View File

@@ -129,6 +129,9 @@
<data name="RepositoryId" xml:space="preserve"> <data name="RepositoryId" xml:space="preserve">
<value>Repository Id</value> <value>Repository Id</value>
</data> </data>
<data name="RootFolderPath" xml:space="preserve">
<value>Root folder path</value>
</data>
<data name="FileLocationOfInstallJson" xml:space="preserve"> <data name="FileLocationOfInstallJson" xml:space="preserve">
<value>File location of "install.json"</value> <value>File location of "install.json"</value>
</data> </data>
@@ -243,4 +246,10 @@
<data name="Website" xml:space="preserve"> <data name="Website" xml:space="preserve">
<value>Website</value> <value>Website</value>
</data> </data>
<data name="Select" xml:space="preserve">
<value>Select</value>
</data>
<data name="SelectRootFolder" xml:space="preserve">
<value>Select root folder</value>
</data>
</root> </root>

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class TitlesLangRes {
// -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 System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal TitlesLangRes() { internal TitlesLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.TitlesLangRes", typeof(TitlesLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.TitlesLangRes", typeof(TitlesLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// 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 { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,31 +45,28 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string CreateUpdate {
/// Sucht eine lokalisierte Zeichenfolge, die Create update ähnelt.
/// </summary>
internal static string CreateUpdate {
get { get {
return ResourceManager.GetString("CreateUpdate", resourceCulture); return ResourceManager.GetString("CreateUpdate", resourceCulture);
} }
} }
/// <summary> public static string EditUpdate {
/// Sucht eine lokalisierte Zeichenfolge, die Edit update ähnelt.
/// </summary>
internal static string EditUpdate {
get { get {
return ResourceManager.GetString("EditUpdate", resourceCulture); return ResourceManager.GetString("EditUpdate", resourceCulture);
} }
} }
/// <summary> public static string GitLabRepoWorkspaceEditor {
/// Sucht eine lokalisierte Zeichenfolge, die Setup GitLab workspace ähnelt.
/// </summary>
internal static string GitLabRepoWorkspaceEditor {
get { get {
return ResourceManager.GetString("GitLabRepoWorkspaceEditor", resourceCulture); return ResourceManager.GetString("GitLabRepoWorkspaceEditor", resourceCulture);
} }
} }
public static string LocalFolderWorkspaceEditor {
get {
return ResourceManager.GetString("LocalFolderWorkspaceEditor", resourceCulture);
}
}
} }
} }

View File

@@ -126,4 +126,7 @@
<data name="GitLabRepoWorkspaceEditor" xml:space="preserve"> <data name="GitLabRepoWorkspaceEditor" xml:space="preserve">
<value>Setup GitLab workspace</value> <value>Setup GitLab workspace</value>
</data> </data>
<data name="LocalFolderWorkspaceEditor" xml:space="preserve">
<value>Setup local folder workspace</value>
</data>
</root> </root>

View File

@@ -26,6 +26,10 @@
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>SourceTypeLangRes.resx</DependentUpon> <DependentUpon>SourceTypeLangRes.resx</DependentUpon>
</Compile> </Compile>
<Compile Update="Features\Workspaces\LocalFolder\LocalFolderWorkspaceConfigEditorView.axaml.cs">
<DependentUpon>GitLabRepoWorkspaceConfigEditorView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -6,7 +6,7 @@ namespace ModpackUpdater;
public class InstallInfos : IActionSetInfos public class InstallInfos : IActionSetInfos
{ {
[JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))] [JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))]
public Version Version { get; set; } public Version Version { get; set; } = new();
[DefaultValue(true)] [DefaultValue(true)]
public bool IsPublic { get; set; } = true; public bool IsPublic { get; set; } = true;
@@ -17,8 +17,10 @@ public class InstallInfos : IActionSetInfos
IEnumerable<InstallAction> IActionSet.Actions => Actions; IEnumerable<InstallAction> IActionSet.Actions => Actions;
public static InstallInfos Parse(string content) public static InstallInfos? Parse(string? content)
{ {
if (string.IsNullOrWhiteSpace(content))
return null;
return JsonConvert.DeserializeObject<InstallInfos>(content); return JsonConvert.DeserializeObject<InstallInfos>(content);
} }

View File

@@ -6,8 +6,10 @@ public class UpdateInfos
{ {
public List<UpdateInfo> Updates { get; private set; } = []; public List<UpdateInfo> Updates { get; private set; } = [];
public static UpdateInfos Parse(string content) public static UpdateInfos? Parse(string? content)
{ {
if (string.IsNullOrWhiteSpace(content))
return null;
return JsonConvert.DeserializeObject<UpdateInfos>(content); return JsonConvert.DeserializeObject<UpdateInfos>(content);
} }