diff --git a/.editorconfig b/.editorconfig
index a513f1f..644396b 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,3 +1,5 @@
+root = true
+
[*]
charset = utf-8
end_of_line = lf
@@ -7,24 +9,16 @@ indent_style = space
indent_size = 4 # A property with the same name was updated with a value 2 in a section [{*.yaml,*.yml}]
[{*.yaml,*.yml}]
-indent_style = space
indent_size = 2 # A property with the same name was updated with a value 4 in a section [*]; with a value 4 in a section [*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,hlsl,hlsli,hlslinc,master,nuspec,paml,razor,resw,resx,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
-dotnet_diagnostic.CA1047.severity = error
[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,hlsl,hlsli,hlslinc,master,nuspec,paml,razor,resw,resx,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
-indent_style = space
-indent_size = 4 # A property with the same name was updated with a value 2 in a section [{*.yaml,*.yml}]
tab_width = 4
-dotnet_style_operator_placement_when_wrapping = beginning_of_line
+
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
-dotnet_style_prefer_is_null_check_over_reference_equality_method = true:error
-dotnet_style_prefer_auto_properties = true:warning
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
-dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
-dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
@@ -35,13 +29,8 @@ dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_readonly_field = true:warning
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
-dotnet_style_require_accessibility_modifiers = always:error
dotnet_style_allow_multiple_blank_lines_experimental = false:silent
dotnet_style_allow_statement_immediately_after_block_experimental = false:silent
-dotnet_code_quality_unused_parameters = all:warning
-dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
-dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
-dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
@@ -68,7 +57,7 @@ dotnet_diagnostic.CA1832.severity = warning
dotnet_diagnostic.CA1833.severity = warning
dotnet_diagnostic.CA1842.severity = warning
dotnet_diagnostic.CA1843.severity = warning
-dotnet_diagnostic.CA1836.severity = none
+dotnet_diagnostic.CA1836.severity = warning
dotnet_diagnostic.CA1839.severity = warning
dotnet_diagnostic.CA1840.severity = warning
dotnet_diagnostic.CA1846.severity = warning
@@ -77,6 +66,8 @@ dotnet_diagnostic.CA1852.severity = suggestion
dotnet_diagnostic.CA2012.severity = warning
dotnet_diagnostic.CA2019.severity = warning
dotnet_diagnostic.CA2211.severity = warning
+dotnet_diagnostic.CA1822.severity = suggestion
+dotnet_diagnostic.CA1725.severity = suggestion
[*.cs]
@@ -712,14 +703,16 @@ resharper_blank_lines_inside_region = 1
resharper_blank_lines_inside_type = 0
resharper_blank_line_after_pi = true
resharper_braces_for_dowhile = required
-resharper_braces_for_fixed = required
+resharper_braces_for_fixed = required_for_multiline
resharper_braces_for_for = required_for_multiline
resharper_braces_for_foreach = required_for_multiline
resharper_braces_for_ifelse = required_for_multiline
-resharper_braces_for_lock = required
-resharper_braces_for_using = required
+resharper_braces_for_lock = required_for_multiline
+resharper_braces_for_using = required_for_multiline
resharper_braces_for_while = required_for_multiline
resharper_braces_redundant = true
+resharper_builtin_type_apply_to_native_integer = true
+resharper_csharp_empty_block_style = together_same_line
resharper_break_template_declaration = line_break
resharper_can_use_global_alias = false
resharper_configure_await_analysis_mode = disabled
@@ -817,7 +810,7 @@ resharper_indent_typearg_angles = inside
resharper_indent_typeparam_angles = inside
resharper_indent_type_constraints = true
resharper_indent_wrapped_function_names = false
-resharper_instance_members_qualify_declared_in = base_class
+resharper_instance_members_qualify_declared_in =
resharper_int_align_assignments = false
resharper_int_align_binary_expressions = false
resharper_int_align_declaration_names = false
@@ -918,7 +911,7 @@ resharper_place_simple_switch_expression_on_single_line = false
resharper_place_type_attribute_on_same_line = false
resharper_place_type_constraints_on_same_line = true
resharper_prefer_explicit_discard_declaration = false
-resharper_prefer_separate_deconstructed_variables_declaration = true
+resharper_prefer_separate_deconstructed_variables_declaration = false
resharper_preserve_spaces_inside_tags = pre,textarea
resharper_qualified_using_at_nested_scope = false
resharper_quote_style = doublequoted
@@ -1069,6 +1062,7 @@ resharper_space_within_typeof_parentheses = false
resharper_space_within_type_argument_angles = false
resharper_space_within_type_parameter_angles = false
resharper_space_within_type_parameter_parentheses = false
+resharper_csharp_allow_alias = false
resharper_special_else_if_treatment = true
resharper_static_members_qualify_members = none
resharper_static_members_qualify_with = declared_type
@@ -1289,7 +1283,7 @@ resharper_convert_to_using_declaration_highlighting = suggestion
resharper_convert_to_vb_auto_property_highlighting = suggestion
resharper_convert_to_vb_auto_property_when_possible_highlighting = hint
resharper_convert_to_vb_auto_property_with_private_setter_highlighting = hint
-resharper_convert_type_check_pattern_to_null_check_highlighting = warning
+resharper_convert_type_check_pattern_to_null_check_highlighting = none
resharper_convert_type_check_to_null_check_highlighting = warning
resharper_co_variant_array_conversion_highlighting = warning
resharper_c_declaration_with_implicit_int_type_highlighting = warning
@@ -1408,8 +1402,8 @@ resharper_meaningless_default_parameter_value_highlighting = warning
resharper_member_can_be_internal_highlighting = none
resharper_member_can_be_made_static_global_highlighting = hint
resharper_member_can_be_made_static_local_highlighting = hint
-resharper_member_can_be_private_global_highlighting = suggestion
-resharper_member_can_be_private_local_highlighting = suggestion
+resharper_member_can_be_private_global_highlighting = hint
+resharper_member_can_be_private_local_highlighting = hint
resharper_member_can_be_protected_global_highlighting = suggestion
resharper_member_can_be_protected_local_highlighting = suggestion
resharper_member_hides_interface_member_with_default_implementation_highlighting = warning
@@ -1537,7 +1531,7 @@ resharper_redundant_assignment_highlighting = warning
resharper_redundant_attribute_parentheses_highlighting = hint
resharper_redundant_attribute_usage_property_highlighting = suggestion
resharper_redundant_base_constructor_call_highlighting = warning
-resharper_redundant_base_qualifier_highlighting = warning
+resharper_redundant_base_qualifier_highlighting = none
resharper_redundant_blank_lines_highlighting = none
resharper_redundant_bool_compare_highlighting = warning
resharper_redundant_case_label_highlighting = warning
@@ -1547,7 +1541,7 @@ resharper_redundant_check_before_assignment_highlighting = warning
resharper_redundant_collection_initializer_element_braces_highlighting = hint
resharper_redundant_configure_await_highlighting = suggestion
resharper_redundant_declaration_semicolon_highlighting = hint
-resharper_redundant_default_member_initializer_highlighting = warning
+resharper_redundant_default_member_initializer_highlighting = hint
resharper_redundant_delegate_creation_highlighting = warning
resharper_redundant_disable_warning_comment_highlighting = warning
resharper_redundant_discard_designation_highlighting = suggestion
@@ -1872,4 +1866,18 @@ resharper_virtual_member_never_overridden_local_highlighting = suggestion
resharper_void_method_with_must_use_return_value_attribute_highlighting = warning
resharper_with_expression_instead_of_initializer_highlighting = suggestion
resharper_wrong_indent_size_highlighting = none
-resharper_xunit_xunit_test_with_console_output_highlighting = warning
\ No newline at end of file
+resharper_xunit_xunit_test_with_console_output_highlighting = warning
+resharper_arrange_constructor_or_destructor_body_highlighting = hint
+resharper_arrange_local_function_body_highlighting = hint
+resharper_arrange_method_or_operator_body_highlighting = hint
+resharper_arrange_null_checking_pattern_highlighting = suggestion
+resharper_enforce_do_while_statement_braces_highlighting = warning
+resharper_enforce_fixed_statement_braces_highlighting = warning
+resharper_enforce_foreach_statement_braces_highlighting = suggestion
+resharper_enforce_for_statement_braces_highlighting = suggestion
+resharper_enforce_if_statement_braces_highlighting = suggestion
+resharper_enforce_lock_statement_braces_highlighting = warning
+resharper_enforce_while_statement_braces_highlighting = suggestion
+resharper_remove_redundant_braces_highlighting = hint
+resharper_suggest_discard_declaration_var_style_highlighting = warning
+resharper_prefer_concrete_value_over_default_highlighting = hint
\ No newline at end of file
diff --git a/EllieHub/App.axaml.cs b/EllieHub/App.axaml.cs
index d535943..9a6e0b1 100644
--- a/EllieHub/App.axaml.cs
+++ b/EllieHub/App.axaml.cs
@@ -20,7 +20,7 @@ public partial class App : Application
///
public IServiceProvider Services { get; } = new ServiceCollection()
.RegisterViewsAndViewModels(Assembly.GetExecutingAssembly())
- .RegisterServices()
+ .RegisterAppServices()
.BuildServiceProvider(true);
///
diff --git a/EllieHub/Avalonia/DesignData/Controls/DesignBotConfigViewModel.cs b/EllieHub/Avalonia/DesignData/Controls/DesignBotConfigViewModel.cs
index 6d7a88b..73b43d6 100644
--- a/EllieHub/Avalonia/DesignData/Controls/DesignBotConfigViewModel.cs
+++ b/EllieHub/Avalonia/DesignData/Controls/DesignBotConfigViewModel.cs
@@ -6,7 +6,7 @@ using EllieHub.Features.AppWindow.Views.Windows;
using EllieHub.Features.BotConfig.Services.Abstractions;
using EllieHub.Features.BotConfig.Services.Mocks;
using EllieHub.Features.BotConfig.ViewModels;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
namespace EllieHub.Avalonia.DesignData.Controls;
diff --git a/EllieHub/Avalonia/DesignData/Controls/DesignConfigViewModel.cs b/EllieHub/Avalonia/DesignData/Controls/DesignConfigViewModel.cs
index 670e539..d4c0507 100644
--- a/EllieHub/Avalonia/DesignData/Controls/DesignConfigViewModel.cs
+++ b/EllieHub/Avalonia/DesignData/Controls/DesignConfigViewModel.cs
@@ -4,7 +4,7 @@ using EllieHub.Features.AppConfig.Services.Abstractions;
using EllieHub.Features.AppConfig.Services.Mocks;
using EllieHub.Features.AppConfig.ViewModels;
using EllieHub.Features.AppWindow.Views.Windows;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
namespace EllieHub.Avalonia.DesignData.Controls;
diff --git a/EllieHub/Avalonia/DesignData/Controls/DesignDependencyButtonViewModel.cs b/EllieHub/Avalonia/DesignData/Controls/DesignDependencyButtonViewModel.cs
index ff1399f..245f8d7 100644
--- a/EllieHub/Avalonia/DesignData/Controls/DesignDependencyButtonViewModel.cs
+++ b/EllieHub/Avalonia/DesignData/Controls/DesignDependencyButtonViewModel.cs
@@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using EllieHub.Avalonia.DesignData.Common;
using EllieHub.Features.AppWindow.Views.Windows;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
namespace EllieHub.Avalonia.DesignData.Controls;
diff --git a/EllieHub/Avalonia/DesignData/Controls/DesignFakeConsoleViewModel.cs b/EllieHub/Avalonia/DesignData/Controls/DesignFakeConsoleViewModel.cs
index 9836508..3d87c0d 100644
--- a/EllieHub/Avalonia/DesignData/Controls/DesignFakeConsoleViewModel.cs
+++ b/EllieHub/Avalonia/DesignData/Controls/DesignFakeConsoleViewModel.cs
@@ -10,6 +10,6 @@ public sealed class DesignFakeConsoleViewModel : FakeConsoleViewModel
///
/// Creates a mock to be used at design-time.
///
- public DesignFakeConsoleViewModel() : base()
+ public DesignFakeConsoleViewModel()
=> Watermark = "Sample watermark.";
}
\ No newline at end of file
diff --git a/EllieHub/Avalonia/DesignData/Controls/DesignUriInputBarViewModel.cs b/EllieHub/Avalonia/DesignData/Controls/DesignUriInputBarViewModel.cs
index a70d2de..4dd32b4 100644
--- a/EllieHub/Avalonia/DesignData/Controls/DesignUriInputBarViewModel.cs
+++ b/EllieHub/Avalonia/DesignData/Controls/DesignUriInputBarViewModel.cs
@@ -1,7 +1,7 @@
using Avalonia.Platform.Storage;
using Microsoft.Extensions.DependencyInjection;
using EllieHub.Avalonia.DesignData.Common;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
namespace EllieHub.Avalonia.DesignData.Controls;
diff --git a/EllieHub/Avalonia/Resources/Fonts.axaml b/EllieHub/Avalonia/Resources/Fonts.axaml
index 7b6d0a9..902d474 100644
--- a/EllieHub/Avalonia/Resources/Fonts.axaml
+++ b/EllieHub/Avalonia/Resources/Fonts.axaml
@@ -1,5 +1,9 @@
+
+ avares://EllieHub/Assets/Fonts/NotoSans-Regular.ttf
+ avares://EllieHub/Assets/Fonts/NotoSans-Bold.ttf
+
@@ -13,7 +17,4 @@
-
- avares://EllieHub/Assets/Fonts/NotoSans-Regular.ttf
- avares://EllieHub/Assets/Fonts/NotoSans-Bold.ttf
\ No newline at end of file
diff --git a/EllieHub/Avalonia/Resources/Images.axaml b/EllieHub/Avalonia/Resources/Images.axaml
index 403d07a..0acf6b0 100644
--- a/EllieHub/Avalonia/Resources/Images.axaml
+++ b/EllieHub/Avalonia/Resources/Images.axaml
@@ -50,7 +50,7 @@
avares://EllieHub/Assets/Light/icon-link.png
avares://EllieHub/Assets/Light/icon-suggest.png
avares://EllieHub/Assets/Light/icon-support.png
- avares://EllieHub/Assets/Light/ellieupdatericon.ico
+
avares://EllieHub/Assets/Light/ellieupdatericon.ico
avares://EllieHub/Assets/Light/terminal.png
@@ -65,7 +65,7 @@
avares://EllieHub/Assets/Dark/icon-link.png
avares://EllieHub/Assets/Dark/icon-suggest.png
avares://EllieHub/Assets/Dark/icon-support.png
- avares://EllieHub/Assets/Dark/ellieupdatericon.ico
+
avares://EllieHub/Assets/Dark/ellieupdatericon.ico
avares://EllieHub/Assets/Dark/terminal.png
diff --git a/EllieHub/Common/Utilities.cs b/EllieHub/Common/Utilities.cs
index 7533d5c..eb2bc3c 100644
--- a/EllieHub/Common/Utilities.cs
+++ b/EllieHub/Common/Utilities.cs
@@ -1,8 +1,5 @@
using Avalonia.Platform;
using SkiaSharp;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
namespace EllieHub.Common;
@@ -11,205 +8,30 @@ namespace EllieHub.Common;
///
internal static class Utilities
{
- private static readonly string _programVerifier = (Environment.OSVersion.Platform is PlatformID.Win32NT) ? "where" : "which";
- private static readonly string _envPathSeparator = (Environment.OSVersion.Platform is PlatformID.Win32NT) ? ";" : ":";
- private static readonly EnvironmentVariableTarget _envTarget = (Environment.OSVersion.Platform is PlatformID.Win32NT)
- ? EnvironmentVariableTarget.User
- : EnvironmentVariableTarget.Process;
-
///
- /// Loads an image embeded with this application.
+ /// Loads an image embedded with this application.
///
/// An uri that starts with "avares://"
/// Valid uris must start with "avares://".
- /// The embeded image or the default bot avatar placeholder.
- /// Occurs when the embeded resource does not exist.
- public static SKBitmap LoadEmbededImage(string? uri = default)
+ /// The embedded image or the default bot avatar placeholder.
+ /// Occurs when the embedded resource does not exist.
+ public static SKBitmap LoadEmbeddedImage(string? uri = default)
{
return (string.IsNullOrWhiteSpace(uri) || !uri.StartsWith("avares://", StringComparison.Ordinal))
- ? SKBitmap.Decode(AssetLoader.Open(new Uri(AppConstants.BotAvatarUri)))
- : SKBitmap.Decode(AssetLoader.Open(new Uri(uri)));
+ ? SKBitmap.Decode(AssetLoader.Open(new(AppConstants.BotAvatarUri)))
+ : SKBitmap.Decode(AssetLoader.Open(new(uri)));
}
///
/// Loads the image at the specified location or the bot avatar placeholder if it was not found.
///
- /// The absolute path to the image file or to get the avatar placeholder.
- /// This fallsback to if doesn't point to a valid image file.
+ /// The absolute path to the image file or to get the avatar placeholder.
+ /// This fallsback to if doesn't point to a valid image file.
/// The requested image or the default bot avatar placeholder.
- public static SKBitmap LoadLocalImage(string? uri = default)
+ public static SKBitmap LoadLocalImage(string? imagePath)
{
- return (File.Exists(uri))
- ? SKBitmap.Decode(uri)
- : LoadEmbededImage(uri);
- }
-
- ///
- /// Safely casts an to a .
- ///
- /// The type to cast to.
- /// The object to be cast.
- /// The cast object, or is casting failed.
- /// if the object was successfully cast, otherwise.
- public static bool TryCastTo(object? obj, [MaybeNullWhen(false)] out T castObject)
- {
- if (obj is T result)
- {
- castObject = result;
- return true;
- }
-
- castObject = default;
- return false;
- }
-
- ///
- /// Starts the specified program in the background.
- ///
- ///
- /// The name of the program in the PATH environment variable,
- /// or the absolute path to its executable.
- ///
- /// The arguments to the program.
- /// The process of the specified program.
- ///
- ///
- /// Occurs when does not exist.
- /// Occurs when the process fails to execute.
- public static Process StartProcess(string program, string arguments = "")
- {
- ArgumentException.ThrowIfNullOrEmpty(program, nameof(program));
- ArgumentNullException.ThrowIfNull(arguments, nameof(arguments));
-
- return Process.Start(new ProcessStartInfo()
- {
- FileName = program,
- Arguments = arguments,
- UseShellExecute = false,
- CreateNoWindow = true,
- RedirectStandardOutput = true,
- }) ?? throw new InvalidOperationException($"Failed spawing process for: {program} {arguments}");
- }
-
- ///
- /// Checks if a program exists.
- ///
- /// The name of the program.
- /// The cancellation token.
- /// if the program exists, otherwise.
- ///
- ///
- public static async ValueTask ProgramExistsAsync(string programName, CancellationToken cToken = default)
- {
- ArgumentException.ThrowIfNullOrEmpty(programName, nameof(programName));
-
- using var process = StartProcess(_programVerifier, programName);
- return !string.IsNullOrWhiteSpace(await process.StandardOutput.ReadToEndAsync(cToken));
- }
-
- ///
- /// Safely deletes a file.
- ///
- /// The absolute path to the file.
- /// if the file was deleted, otherwise.
- ///
- ///
- ///
- ///
- ///
- ///
- public static bool TryDeleteFile(string fileUri)
- {
- ArgumentException.ThrowIfNullOrEmpty(fileUri, nameof(fileUri));
-
- if (!File.Exists(fileUri))
- return false;
-
- File.Delete(fileUri);
- return true;
- }
-
- ///
- /// Safely deletes a directory.
- ///
- /// The absolute path to the directory.
- /// if the directory was deleted, otherwise.
- ///
- ///
- ///
- ///
- ///
- ///
- public static bool TryDeleteDirectory(string directoryUri)
- {
- ArgumentException.ThrowIfNullOrEmpty(directoryUri, nameof(directoryUri));
-
- if (!Directory.Exists(directoryUri))
- return false;
-
- Directory.Delete(directoryUri, true);
- return true;
- }
-
- ///
- /// Checks if this application can write to .
- ///
- /// The absolute path to a directory.
- /// if writing is allowed, otherwise.
- ///
- ///
- public static bool CanWriteTo(string directoryUri)
- {
- var tempFileUri = Path.Combine(directoryUri, $"{Guid.NewGuid()}.tmp");
-
- try
- {
- using var fileStream = File.Create(tempFileUri);
- return true;
- }
- catch (UnauthorizedAccessException)
- {
- return false;
- }
- finally
- {
- TryDeleteFile(tempFileUri);
- }
- }
-
- ///
- /// Adds a directory path to the PATH environment variable.
- ///
- /// The absolute path to a directory.
- ///
- /// On Windows, this needs to be called once and the dependencies will be available for the user forever.
- /// On Unix systems, we can only add to the PATH on a process basis, so this needs to be called at least once everytime the application is opened.
- ///
- /// if got successfully added to the PATH envar, otherwise.
- ///
- ///
- public static bool AddPathToPATHEnvar(string directoryUri)
- {
- ArgumentException.ThrowIfNullOrEmpty(directoryUri, nameof(directoryUri));
-
- if (File.Exists(directoryUri))
- throw new ArgumentException("Parameter must point to a directory, not a file.", nameof(directoryUri));
-
- var envPathValue = Environment.GetEnvironmentVariable("PATH", _envTarget) ?? string.Empty;
-
- // If directoryPath is already in the PATH envar, don't add it again.
- if (envPathValue.Contains(directoryUri, StringComparison.Ordinal))
- return false;
-
- var newPathEnvValue = envPathValue + _envPathSeparator + directoryUri;
-
- // Add path to Windows' user envar, so it persists across reboots.
- if (Environment.OSVersion.Platform is PlatformID.Win32NT)
- Environment.SetEnvironmentVariable("PATH", newPathEnvValue, EnvironmentVariableTarget.User);
-
- // Add path to the current process' envar, so the updater can see the dependencies.
- Environment.SetEnvironmentVariable("PATH", newPathEnvValue, EnvironmentVariableTarget.Process);
-
- return true;
+ return (File.Exists(imagePath))
+ ? SKBitmap.Decode(imagePath)
+ : LoadEmbeddedImage(imagePath);
}
}
\ No newline at end of file
diff --git a/EllieHub/EllieHub.csproj b/EllieHub/EllieHub.csproj
index fd51eff..1104402 100644
--- a/EllieHub/EllieHub.csproj
+++ b/EllieHub/EllieHub.csproj
@@ -2,7 +2,7 @@
WinExe
- net8.0
+ net9.0
latest
latest
enable
@@ -20,7 +20,7 @@
embedded
- 1.0.3.4
+ 1.0.4.0
app.manifest
@@ -46,21 +46,23 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
+
+
diff --git a/EllieHub/Extensions/IServiceCollectionExt.cs b/EllieHub/Extensions/IServiceCollectionExt.cs
index e224b91..2af9b0f 100644
--- a/EllieHub/Extensions/IServiceCollectionExt.cs
+++ b/EllieHub/Extensions/IServiceCollectionExt.cs
@@ -10,7 +10,6 @@ using EllieHub.Features.BotConfig.Services.Abstractions;
using EllieHub.Features.BotConfig.Services.Mocks;
using EllieHub.Features.Home.Services;
using EllieHub.Features.Home.Services.Abstractions;
-using EllieHub.Services;
using ReactiveUI;
using System.Reflection;
using System.Text.Json;
@@ -48,7 +47,7 @@ public static class IServiceCollectionExt
///
/// This service collection.
/// This service collection with the services added.
- public static IServiceCollection RegisterServices(this IServiceCollection serviceCollection)
+ public static IServiceCollection RegisterAppServices(this IServiceCollection serviceCollection)
{
// Design-time
if (Design.IsDesignMode)
@@ -66,18 +65,18 @@ public static class IServiceCollectionExt
// Web requests
serviceCollection.AddHttpClient();
- serviceCollection.AddHttpClient(AppConstants.NoRedirectClient) // Client that doesn't allow automatic reditections
+ serviceCollection.AddHttpClient(AppConstants.NoRedirectClient) // Client that doesn't allow automatic redirections
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { AllowAutoRedirect = false });
serviceCollection.AddHttpClient(AppConstants.ToastielabClient)
.ConfigureHttpClient(x =>
{
x.DefaultRequestHeaders.Add("Accept", "application/vnd.toastielab+json");
x.DefaultRequestHeaders.Add("X-Toastielab-Api-Version", "2022-11-28");
- #if DEBUG
+#if DEBUG
x.DefaultRequestHeaders.UserAgent.TryParseAdd($"EllieHub v{AppStatics.AppVersion}-Debug");
- #else
+#else
x.DefaultRequestHeaders.UserAgent.TryParseAdd($"EllieHub v{AppStatics.AppVersion}");
- #endif
+#endif
});
// App settings
diff --git a/EllieHub/Extensions/IServiceProviderExt.cs b/EllieHub/Extensions/IServiceProviderExt.cs
deleted file mode 100644
index f488bd5..0000000
--- a/EllieHub/Extensions/IServiceProviderExt.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-
-namespace EllieHub.Extensions;
-
-///
-/// Defines extension methods for .
-///
-public static class IServiceProviderExt
-{
- ///
- /// Gets service of type from the .
- ///
- /// The type of service object to get.
- /// The to retrieve the service object from.
- ///
- /// Do not use abstract types in the type argument!
- /// A service object of type .
- /// Occurs when or are .
- /// Occurs when there is no concrete service of type or when the arguments are wrong.
- public static T GetParameterizedService(this IServiceProvider serviceProvider, params object[] arguments)
- {
- ArgumentNullException.ThrowIfNull(serviceProvider, nameof(serviceProvider));
- ArgumentNullException.ThrowIfNull(arguments, nameof(arguments));
-
- var result = ActivatorUtilities.CreateInstance(serviceProvider, arguments);
-
- return (result is null)
- ? throw new InvalidOperationException($"There is no service of type {nameof(T)} or the arguments were incorrect.")
- : result;
- }
-}
\ No newline at end of file
diff --git a/EllieHub/Extensions/WindowExt.cs b/EllieHub/Extensions/WindowExt.cs
index 71bbe95..f54dd3e 100644
--- a/EllieHub/Extensions/WindowExt.cs
+++ b/EllieHub/Extensions/WindowExt.cs
@@ -85,6 +85,6 @@ public static class WindowExt
? throw new InvalidOperationException($"Resource '{resourceName}' was not found.")
: (resource is T castResource)
? castResource
- : throw new InvalidCastException($"Could not convert resource of type '{resource?.GetType()?.FullName}' to '{nameof(T)}'.");
+ : throw new InvalidCastException($"Could not convert resource of type '{resource?.GetType().FullName}' to '{nameof(T)}'.");
}
}
\ No newline at end of file
diff --git a/EllieHub/Features/AppConfig/Services/Abstractions/IFfmpegResolver.cs b/EllieHub/Features/AppConfig/Services/Abstractions/IFfmpegResolver.cs
index 26f39c2..5cabfa8 100644
--- a/EllieHub/Features/AppConfig/Services/Abstractions/IFfmpegResolver.cs
+++ b/EllieHub/Features/AppConfig/Services/Abstractions/IFfmpegResolver.cs
@@ -1,4 +1,4 @@
-using EllieHub.Features.Shared.Services.Abstractions;
+using EllieHub.Features.Common.Services.Abstractions;
namespace EllieHub.Features.AppConfig.Services.Abstractions;
diff --git a/EllieHub/Features/AppConfig/Services/Abstractions/IYtdlpResolver.cs b/EllieHub/Features/AppConfig/Services/Abstractions/IYtdlpResolver.cs
index 5a85453..d83d5f6 100644
--- a/EllieHub/Features/AppConfig/Services/Abstractions/IYtdlpResolver.cs
+++ b/EllieHub/Features/AppConfig/Services/Abstractions/IYtdlpResolver.cs
@@ -1,4 +1,4 @@
-using EllieHub.Features.Shared.Services.Abstractions;
+using EllieHub.Features.Common.Services.Abstractions;
namespace EllieHub.Features.AppConfig.Services.Abstractions;
diff --git a/EllieHub/Features/AppConfig/Services/FfmpegLinuxResolver.cs b/EllieHub/Features/AppConfig/Services/FfmpegLinuxResolver.cs
index 852f1a2..4c6774e 100644
--- a/EllieHub/Features/AppConfig/Services/FfmpegLinuxResolver.cs
+++ b/EllieHub/Features/AppConfig/Services/FfmpegLinuxResolver.cs
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
-namespace EllieHub.Services;
+namespace EllieHub.Features.AppConfig.Services;
///
/// Service that checks, downloads, installs, and updates ffmpeg on Linux.
@@ -14,7 +14,7 @@ public sealed partial class FfmpegLinuxResolver : FfmpegResolver
{
private readonly Regex _ffmpegLatestVersionRegex = FfmpegLatestVersionRegexGenerator();
private readonly string _tempDirectory = Path.GetTempPath();
- private bool _isUpdating = false;
+ private bool _isUpdating;
private readonly IHttpClientFactory _httpClientFactory;
///
@@ -48,7 +48,7 @@ public sealed partial class FfmpegLinuxResolver : FfmpegResolver
}
///
- public override async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string dependenciesUri, CancellationToken cToken = default)
+ public override async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string installationUri, CancellationToken cToken = default)
{
if (_isUpdating)
return (null, null);
@@ -64,22 +64,22 @@ public sealed partial class FfmpegLinuxResolver : FfmpegResolver
if (currentVersion == newVersion)
return (currentVersion, null);
- Utilities.TryDeleteFile(Path.Combine(dependenciesUri, FileName));
- Utilities.TryDeleteFile(Path.Combine(dependenciesUri, "ffprobe"));
+ Utilities.TryDeleteFile(Path.Combine(installationUri, FileName));
+ Utilities.TryDeleteFile(Path.Combine(installationUri, "ffprobe"));
}
// Install
- Directory.CreateDirectory(dependenciesUri);
+ Directory.CreateDirectory(installationUri);
var architecture = (RuntimeInformation.OSArchitecture is Architecture.X64) ? "amd" : "arm";
var tarFileName = $"ffmpeg-release-{architecture}64-static.tar.xz";
var http = _httpClientFactory.CreateClient();
- using var downloadStream = await http.GetStreamAsync($"https://johnvansickle.com/ffmpeg/releases/{tarFileName}", cToken);
+ await using var downloadStream = await http.GetStreamAsync($"https://johnvansickle.com/ffmpeg/releases/{tarFileName}", cToken);
// Save tar file to the temporary directory.
var tarFilePath = Path.Combine(_tempDirectory, tarFileName);
var tarExtractDir = Path.Combine(_tempDirectory, $"ffmpeg-{newVersion}-{architecture}64-static");
- using (var fileStream = new FileStream(tarFilePath, FileMode.Create))
+ await using (var fileStream = new FileStream(tarFilePath, FileMode.Create))
await downloadStream.CopyToAsync(fileStream, cToken);
// Extract the tar file.
@@ -87,11 +87,11 @@ public sealed partial class FfmpegLinuxResolver : FfmpegResolver
await extractProcess.WaitForExitAsync(cToken);
// Move ffmpeg to the dependencies directory.
- File.Move(Path.Combine(tarExtractDir, FileName), Path.Combine(dependenciesUri, FileName), true);
- File.Move(Path.Combine(tarExtractDir, "ffprobe"), Path.Combine(dependenciesUri, "ffprobe"), true);
+ File.Move(Path.Combine(tarExtractDir, FileName), Path.Combine(installationUri, FileName), true);
+ File.Move(Path.Combine(tarExtractDir, "ffprobe"), Path.Combine(installationUri, "ffprobe"), true);
// Mark the files as executable.
- using var chmod = Utilities.StartProcess("chmod", $"+x \"{Path.Combine(dependenciesUri, FileName)}\" \"{Path.Combine(dependenciesUri, "ffprobe")}\"");
+ using var chmod = Utilities.StartProcess("chmod", $"+x \"{Path.Combine(installationUri, FileName)}\" \"{Path.Combine(installationUri, "ffprobe")}\"");
await chmod.WaitForExitAsync(cToken);
// Cleanup
@@ -99,7 +99,7 @@ public sealed partial class FfmpegLinuxResolver : FfmpegResolver
Directory.Delete(tarExtractDir, true);
// Update environment variable
- Utilities.AddPathToPATHEnvar(dependenciesUri);
+ Utilities.AddPathToPathEnvar(installationUri);
_isUpdating = false;
return (currentVersion, newVersion);
diff --git a/EllieHub/Features/AppConfig/Services/FfmpegMacResolver.cs b/EllieHub/Features/AppConfig/Services/FfmpegMacResolver.cs
index 8557ec0..7d04e2f 100644
--- a/EllieHub/Features/AppConfig/Services/FfmpegMacResolver.cs
+++ b/EllieHub/Features/AppConfig/Services/FfmpegMacResolver.cs
@@ -38,7 +38,7 @@ public sealed class FfmpegMacResolver : FfmpegResolver
}
///
- public override async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string dependenciesUri, CancellationToken cToken = default)
+ public override async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string installationUri, CancellationToken cToken = default)
{
if (_isUpdating)
return (null, null);
@@ -57,24 +57,24 @@ public sealed class FfmpegMacResolver : FfmpegResolver
return (currentVersion, null);
}
- Utilities.TryDeleteFile(Path.Combine(dependenciesUri, FileName));
- Utilities.TryDeleteFile(Path.Combine(dependenciesUri, "ffprobe"));
+ Utilities.TryDeleteFile(Path.Combine(installationUri, FileName));
+ Utilities.TryDeleteFile(Path.Combine(installationUri, "ffprobe"));
}
// Install
- Directory.CreateDirectory(dependenciesUri);
+ Directory.CreateDirectory(installationUri);
var http = _httpClientFactory.CreateClient();
var ffmpegResponse = await http.CallApiAsync(_apiFfmpegInfoEndpoint, cToken);
var ffprobeResponse = await http.CallApiAsync(_apiFfprobeInfoEndpoint, cToken);
await Task.WhenAll(
- InstallDependencyAsync(ffmpegResponse, dependenciesUri, cToken),
- InstallDependencyAsync(ffprobeResponse, dependenciesUri, cToken)
+ InstallDependencyAsync(ffmpegResponse, installationUri, cToken),
+ InstallDependencyAsync(ffprobeResponse, installationUri, cToken)
);
// Update environment variable
- Utilities.AddPathToPATHEnvar(dependenciesUri);
+ Utilities.AddPathToPathEnvar(installationUri);
_isUpdating = false;
return (currentVersion, newVersion);
diff --git a/EllieHub/Features/AppConfig/Services/FfmpegWindowsResolver.cs b/EllieHub/Features/AppConfig/Services/FfmpegWindowsResolver.cs
index c99f49b..40a5f1c 100644
--- a/EllieHub/Features/AppConfig/Services/FfmpegWindowsResolver.cs
+++ b/EllieHub/Features/AppConfig/Services/FfmpegWindowsResolver.cs
@@ -49,7 +49,7 @@ public sealed class FfmpegWindowsResolver : FfmpegResolver
}
///
- public override async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string dependenciesUri, CancellationToken cToken = default)
+ public override async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string installationUri, CancellationToken cToken = default)
{
if (_isUpdating)
return (null, null);
@@ -68,13 +68,13 @@ public sealed class FfmpegWindowsResolver : FfmpegResolver
return (currentVersion, null);
}
- Utilities.TryDeleteFile(Path.Combine(dependenciesUri, FileName));
- Utilities.TryDeleteFile(Path.Combine(dependenciesUri, "ffprobe.exe"));
+ Utilities.TryDeleteFile(Path.Combine(installationUri, FileName));
+ Utilities.TryDeleteFile(Path.Combine(installationUri, "ffprobe.exe"));
//Utilities.TryDeleteFile(Path.Combine(dependenciesUri, "ffplay.exe"));
}
// Install
- Directory.CreateDirectory(dependenciesUri);
+ Directory.CreateDirectory(installationUri);
var zipFileName = $"ffmpeg-{newVersion}-full_build.zip";
var http = _httpClientFactory.CreateClient();
@@ -94,8 +94,8 @@ public sealed class FfmpegWindowsResolver : FfmpegResolver
ZipFile.ExtractToDirectory(zipFilePath, _tempDirectory);
// Move ffmpeg to the dependencies directory.
- File.Move(Path.Combine(zipExtractDir, "bin", FileName), Path.Combine(dependenciesUri, FileName), true);
- File.Move(Path.Combine(zipExtractDir, "bin", "ffprobe.exe"), Path.Combine(dependenciesUri, "ffprobe.exe"), true);
+ File.Move(Path.Combine(zipExtractDir, "bin", FileName), Path.Combine(installationUri, FileName), true);
+ File.Move(Path.Combine(zipExtractDir, "bin", "ffprobe.exe"), Path.Combine(installationUri, "ffprobe.exe"), true);
//File.Move(Path.Combine(zipExtractDir, "bin", "ffplay.exe"), Path.Combine(dependenciesUri, "ffplay.exe"));
// Cleanup
@@ -104,7 +104,7 @@ public sealed class FfmpegWindowsResolver : FfmpegResolver
}, cToken);
// Update environment variable
- Utilities.AddPathToPATHEnvar(dependenciesUri);
+ Utilities.AddPathToPathEnvar(installationUri);
_isUpdating = false;
return (currentVersion, newVersion);
diff --git a/EllieHub/Features/AppConfig/Services/YtdlpResolver.cs b/EllieHub/Features/AppConfig/Services/YtdlpResolver.cs
index 259dcc5..dc30dae 100644
--- a/EllieHub/Features/AppConfig/Services/YtdlpResolver.cs
+++ b/EllieHub/Features/AppConfig/Services/YtdlpResolver.cs
@@ -65,7 +65,7 @@ public sealed class YtdlpResolver : IYtdlpResolver
// Else, add the dependencies directory to the PATH envar,
// then try again.
- Utilities.AddPathToPATHEnvar(AppStatics.AppDepsUri);
+ Utilities.AddPathToPathEnvar(AppStatics.AppDepsUri);
return await GetCurrentVersionAsync(cToken);
}
@@ -95,7 +95,7 @@ public sealed class YtdlpResolver : IYtdlpResolver
}
///
- public async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string dependenciesUri, CancellationToken cToken = default)
+ public async ValueTask<(string? OldVersion, string? NewVersion)> InstallOrUpdateAsync(string installationUri, CancellationToken cToken = default)
{
if (_isUpdating)
return (null, null);
@@ -124,16 +124,16 @@ public sealed class YtdlpResolver : IYtdlpResolver
}
// Install
- Directory.CreateDirectory(dependenciesUri);
+ Directory.CreateDirectory(installationUri);
- var finalFilePath = Path.Combine(dependenciesUri, FileName);
+ var finalFilePath = Path.Combine(installationUri, FileName);
var http = _httpClientFactory.CreateClient();
using var downloadStream = await http.GetStreamAsync($"https://github.com/yt-dlp/yt-dlp/releases/download/{newVersion}/{_downloadedFileName}", cToken);
using (var fileStream = new FileStream(finalFilePath, FileMode.Create))
await downloadStream.CopyToAsync(fileStream, cToken);
// Update environment variable
- Utilities.AddPathToPATHEnvar(dependenciesUri);
+ Utilities.AddPathToPathEnvar(installationUri);
// On Linux and MacOS, we need to mark the file as executable.
if (Environment.OSVersion.Platform is PlatformID.Unix)
diff --git a/EllieHub/Features/AppConfig/ViewModels/ConfigViewModel.cs b/EllieHub/Features/AppConfig/ViewModels/ConfigViewModel.cs
index 54861b0..0f59d52 100644
--- a/EllieHub/Features/AppConfig/ViewModels/ConfigViewModel.cs
+++ b/EllieHub/Features/AppConfig/ViewModels/ConfigViewModel.cs
@@ -8,8 +8,8 @@ using EllieHub.Features.AppConfig.Views.Controls;
using EllieHub.Features.AppConfig.Views.Windows;
using EllieHub.Features.AppWindow.ViewModels;
using EllieHub.Features.AppWindow.Views.Windows;
-using EllieHub.Features.Shared.Services.Abstractions;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.Services.Abstractions;
+using EllieHub.Features.Common.ViewModels;
using ReactiveUI;
using System.Diagnostics;
diff --git a/EllieHub/Features/AppConfig/Views/Controls/ConfigView.axaml b/EllieHub/Features/AppConfig/Views/Controls/ConfigView.axaml
index 3249969..f794e2d 100644
--- a/EllieHub/Features/AppConfig/Views/Controls/ConfigView.axaml
+++ b/EllieHub/Features/AppConfig/Views/Controls/ConfigView.axaml
@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:EllieHub.Features.AppConfig.ViewModels"
- xmlns:views="using:EllieHub.Features.Shared.Views.Controls"
+ xmlns:views="using:EllieHub.Features.Common.Views.Controls"
xmlns:const="using:EllieHub.Common"
xmlns:dd="using:EllieHub.Avalonia.DesignData.Controls"
mc:Ignorable="d"
@@ -23,7 +23,6 @@
Fill="{DynamicResource HeavyBackground}" />
@@ -87,9 +86,10 @@
+ ToolTip.Tip="Defines the directory the updater is going to store the backups of the bot instances."/>
diff --git a/EllieHub/Features/AppConfig/Views/Windows/AboutMeView.axaml b/EllieHub/Features/AppConfig/Views/Windows/AboutMeView.axaml
index 9c964b7..5345aad 100644
--- a/EllieHub/Features/AppConfig/Views/Windows/AboutMeView.axaml
+++ b/EllieHub/Features/AppConfig/Views/Windows/AboutMeView.axaml
@@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:EllieHub.Features.AppConfig.ViewModels"
- xmlns:const="using:EllieHub.Common"
xmlns:dd="using:EllieHub.Avalonia.DesignData.Windows"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="305"
Width="400" Height="305"
diff --git a/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml b/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml
index 19e6fb9..63bcbe6 100644
--- a/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml
+++ b/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml
@@ -5,7 +5,6 @@
xmlns:siv="https://github.com/kekyo/SkiaImageView"
xmlns:vm="using:EllieHub.Features.AppWindow.ViewModels"
xmlns:dd="using:EllieHub.Avalonia.DesignData.Controls"
- xmlns:const="using:EllieHub.Common"
mc:Ignorable="d" d:DesignWidth="70" d:DesignHeight="450"
x:Class="EllieHub.Features.AppWindow.Views.Controls.LateralBarView"
x:DataType="vm:LateralBarViewModel">
diff --git a/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml.cs b/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml.cs
index 1885fc6..232c194 100644
--- a/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml.cs
+++ b/EllieHub/Features/AppWindow/Views/Controls/LateralBarView.axaml.cs
@@ -20,8 +20,6 @@ namespace EllieHub.Features.AppWindow.Views.Controls;
///
public partial class LateralBarView : ReactiveUserControl
{
- private static readonly Cursor _pointingHandCursor = new(StandardCursorType.Hand);
- private static readonly Cursor _arrow = new(StandardCursorType.Arrow);
private readonly ReadOnlyAppSettings _appConfig;
///
diff --git a/EllieHub/Features/AppWindow/Views/Windows/AppView.axaml.cs b/EllieHub/Features/AppWindow/Views/Windows/AppView.axaml.cs
index 70205f8..f021f89 100644
--- a/EllieHub/Features/AppWindow/Views/Windows/AppView.axaml.cs
+++ b/EllieHub/Features/AppWindow/Views/Windows/AppView.axaml.cs
@@ -1,6 +1,8 @@
using Avalonia.Controls;
using Avalonia.ReactiveUI;
using Avalonia.Styling;
+using Toastie.DependencyInjection.Extensions;
+using Toastie.Utilities;
using Microsoft.Extensions.DependencyInjection;
using EllieHub.Avalonia.DesignData.Common;
using EllieHub.Enums;
@@ -15,7 +17,7 @@ using EllieHub.Features.BotConfig.ViewModels;
using EllieHub.Features.Home.Services.Abstractions;
using EllieHub.Features.Home.ViewModels;
using EllieHub.Features.Home.Views.Windows;
-using EllieHub.Services;
+using EllieHub.Features.BotConfig.Services;
using ReactiveUI;
using System.Diagnostics;
using System.Runtime.Versioning;
@@ -117,7 +119,7 @@ public partial class AppView : ReactiveWindow
{
// Ensure that bots on Unix system have access to the dependencies.
if (Environment.OSVersion.Platform is PlatformID.Unix)
- Utilities.AddPathToPATHEnvar(AppStatics.AppDepsUri);
+ ToastieUtilities.AddPathToPATHEnvar(AppStatics.AppDepsUri);
// Set the window size from the last session
base.Height = _appConfigManager.AppConfig.WindowSize.Height;
@@ -156,11 +158,11 @@ public partial class AppView : ReactiveWindow
}
///
- protected override async void OnClosed(EventArgs eventArgs)
+ protected override void OnClosed(EventArgs eventArgs)
{
// When the updater is closed, kill all bots and write their logs.
- _botOrchestrator.StopAll();
- await _logWriter.FlushAllAsync(true);
+ _botOrchestrator.StopAllBots();
+ _logWriter.FlushAllAsync(true).Wait();
base.OnClosed(eventArgs);
}
diff --git a/EllieHub/Features/BotConfig/Services/Abstractions/IBotOrchestrator.cs b/EllieHub/Features/BotConfig/Services/Abstractions/IBotOrchestrator.cs
index cb9a21c..91b9fbb 100644
--- a/EllieHub/Features/BotConfig/Services/Abstractions/IBotOrchestrator.cs
+++ b/EllieHub/Features/BotConfig/Services/Abstractions/IBotOrchestrator.cs
@@ -34,18 +34,18 @@ public interface IBotOrchestrator
///
/// The bot's Id.
/// if the bot successfully started, otherwise.
- bool Start(Guid botId);
+ bool StartBot(Guid botId);
///
/// Stops the bot with the specified .
///
/// The bot's Id.
/// if the bot successfully stopped, otherwise.
- bool Stop(Guid botId);
+ bool StopBot(Guid botId);
///
/// Stops all bot instances.
///
/// if at least one bot instance was stopped, otherwise.
- bool StopAll();
+ bool StopAllBots();
}
\ No newline at end of file
diff --git a/EllieHub/Features/BotConfig/Services/Abstractions/IBotResolver.cs b/EllieHub/Features/BotConfig/Services/Abstractions/IBotResolver.cs
index 7d33ad0..e555a19 100644
--- a/EllieHub/Features/BotConfig/Services/Abstractions/IBotResolver.cs
+++ b/EllieHub/Features/BotConfig/Services/Abstractions/IBotResolver.cs
@@ -1,4 +1,4 @@
-using EllieHub.Features.Shared.Services.Abstractions;
+using EllieHub.Features.Common.Services.Abstractions;
namespace EllieHub.Features.BotConfig.Services.Abstractions;
diff --git a/EllieHub/Features/BotConfig/Services/EllieOrchestrator.cs b/EllieHub/Features/BotConfig/Services/EllieOrchestrator.cs
index fefc4f2..a03ce9f 100644
--- a/EllieHub/Features/BotConfig/Services/EllieOrchestrator.cs
+++ b/EllieHub/Features/BotConfig/Services/EllieOrchestrator.cs
@@ -35,7 +35,7 @@ public sealed class EllieOrchestrator : IBotOrchestrator
=> _runningBots.ContainsKey(botId);
///
- public bool Start(Guid botId)
+ public bool StartBot(Guid botId)
{
if (_runningBots.ContainsKey(botId)
|| !_appConfig.BotEntries.TryGetValue(botId, out var botEntry)
@@ -66,7 +66,7 @@ public sealed class EllieOrchestrator : IBotOrchestrator
}
///
- public bool Stop(Guid botId)
+ public bool StopBot(Guid botId)
{
if (!_runningBots.TryGetValue(botId, out var botProcess))
return false;
@@ -76,7 +76,7 @@ public sealed class EllieOrchestrator : IBotOrchestrator
}
///
- public bool StopAll()
+ public bool StopAllBots()
{
var amount = _runningBots.Count;
diff --git a/EllieHub/Features/BotConfig/Services/EllieResolver.cs b/EllieHub/Features/BotConfig/Services/EllieResolver.cs
index bb8ce25..7c92fbd 100644
--- a/EllieHub/Features/BotConfig/Services/EllieResolver.cs
+++ b/EllieHub/Features/BotConfig/Services/EllieResolver.cs
@@ -1,3 +1,4 @@
+using Toastie.Utilities;
using Microsoft.Extensions.Caching.Memory;
using EllieHub.Features.AppConfig.Services.Abstractions;
using EllieHub.Features.BotConfig.Models.Api.Toastielab;
@@ -10,7 +11,7 @@ using System.Runtime.InteropServices;
using System.Text.Json;
using System.Text.RegularExpressions;
-namespace EllieHub.Services;
+namespace EllieHub.Features.BotConfig.Services;
///
/// Service that checks, downloads, installs, and updates a EllieBot instance.
@@ -23,7 +24,7 @@ public sealed partial class EllieResolver : IBotResolver
private const string _toastielabReleasesRepoUrl = "https://toastielab.dev/EllieBotDevs/elliebot/releases/latest";
private static readonly HashSet _updateIdOngoing = [];
private static readonly string _tempDirectory = Path.GetTempPath();
- private static readonly Regex _unzipedDirRegex = GenerateUnzipedDirRegex();
+ private static readonly Regex _unzippedDirRegex = GenerateUnzipedDirRegex();
private readonly IHttpClientFactory _httpClientFactory;
private readonly IMemoryCache _memoryCache;
private readonly IAppConfigManager _appConfigManager;
@@ -94,7 +95,7 @@ public sealed partial class EllieResolver : IBotResolver
var now = DateTimeOffset.Now;
var date = new DateOnly(now.Year, now.Month, now.Day).ToShortDateString().Replace('/', '-');
var backupZipName = $"{botInstance.Name}_v{botInstance.Version}_{date}-{now.ToUnixTimeMilliseconds()}.zip";
- var destinationUri = Path.Combine(_appConfigManager.AppConfig.BotsBackupDirectoryUri, backupZipName);
+ var destinationUri = Path.Join(_appConfigManager.AppConfig.BotsBackupDirectoryUri, backupZipName);
// ZipFile does not provide asynchronous implementations, so we have to schedule its
// execution to be run in the thread-pool due to how long it takes to finish execution.
@@ -107,7 +108,7 @@ public sealed partial class EllieResolver : IBotResolver
public async ValueTask GetCurrentVersionAsync(CancellationToken cToken = default)
{
var botEntry = _appConfigManager.AppConfig.BotEntries[Id];
- var executableUri = Path.Combine(botEntry.InstanceDirectoryUri, FileName);
+ var executableUri = Path.Join(botEntry.InstanceDirectoryUri, FileName);
if (!File.Exists(executableUri))
{
@@ -161,8 +162,8 @@ public sealed partial class EllieResolver : IBotResolver
var http = _httpClientFactory.CreateClient();
var downloadFileName = GetDownloadFileName(latestVersion);
- var botTempLocation = Path.Combine(_tempDirectory, "elliebot-" + _unzipedDirRegex.Match(downloadFileName).Groups[1].Value);
- var zipTempLocation = Path.Combine(_tempDirectory, downloadFileName);
+ var botTempLocation = Path.Join(_tempDirectory, "elliebot-" + _unzippedDirRegex.Match(downloadFileName).Groups[1].Value);
+ var zipTempLocation = Path.Join(_tempDirectory, downloadFileName);
try
{
@@ -185,10 +186,10 @@ public sealed partial class EllieResolver : IBotResolver
await _appConfigManager.UpdateBotEntryAsync(Id, x => x with { Version = latestVersion }, cToken);
// Create creds.yml
- var credsUri = Path.Combine(installationUri, "creds.yml");
+ var credsUri = Path.Join(installationUri, "creds.yml");
if (!File.Exists(credsUri))
- File.Copy(Path.Combine(installationUri, "creds_example.yml"), credsUri);
+ File.Copy(Path.Join(installationUri, "creds_example.yml"), credsUri);
return (currentVersion, latestVersion);
}
@@ -197,8 +198,8 @@ public sealed partial class EllieResolver : IBotResolver
_updateIdOngoing.Remove(Id);
// Cleanup
- Utilities.TryDeleteFile(zipTempLocation);
- Utilities.TryDeleteDirectory(botTempLocation);
+ ToastieUtilities.TryDeleteFile(zipTempLocation);
+ ToastieUtilities.TryDeleteDirectory(botTempLocation);
}
}
@@ -214,12 +215,10 @@ public sealed partial class EllieResolver : IBotResolver
// Extract the tar ball
await TarFile.ExtractToDirectoryAsync(downloadStream, _tempDirectory, true, cToken);
- // Move the bot root directory with "mv" to circumvent this issue on Unix systems: https://github.com/dotnet/runtime/issues/31149
- using var moveProcess = Utilities.StartProcess("mv", $"\"{botTempLocation}\" \"{installationUri}\"");
- await moveProcess.WaitForExitAsync(cToken);
+ ToastieUtilities.TryMoveDirectory(botTempLocation, installationUri);
// Set executable permission
- using var chmod = Utilities.StartProcess("chmod", $"+x \"{Path.Combine(installationUri, FileName)}\"");
+ using var chmod = ToastieUtilities.StartProcess("chmod", ["+x", Path.Join(installationUri, FileName)]);
await chmod.WaitForExitAsync(cToken);
}
@@ -231,10 +230,10 @@ public sealed partial class EllieResolver : IBotResolver
/// The absolute path to the zip file the bot is initially on.
/// The absolute path to the temporary directory the bot is extracted to.
/// The cancellation token.
- private async static ValueTask InstallToWindowsAsync(Stream downloadStream, string installationUri, string zipTempLocation, string botTempLocation, CancellationToken cToken = default)
+ private static async ValueTask InstallToWindowsAsync(Stream downloadStream, string installationUri, string zipTempLocation, string botTempLocation, CancellationToken cToken = default)
{
// Save the zip file
- using (var fileStream = new FileStream(zipTempLocation, FileMode.Create))
+ await using (var fileStream = new FileStream(zipTempLocation, FileMode.Create))
await downloadStream.CopyToAsync(fileStream, cToken);
// Extract the zip file
@@ -250,7 +249,7 @@ public sealed partial class EllieResolver : IBotResolver
/// The absolute path to the directory the bot got installed to.
/// The absolute path to the backup zip file.
/// The cancellation token.
- private async static ValueTask ReaplyBotSettingsAsync(string installationUri, string backupFileUri, CancellationToken cToken = default)
+ private static async ValueTask ReaplyBotSettingsAsync(string installationUri, string backupFileUri, CancellationToken cToken = default)
{
using var zipFile = ZipFile.OpenRead(backupFileUri);
var zippedFiles = zipFile.Entries
@@ -265,7 +264,7 @@ public sealed partial class EllieResolver : IBotResolver
.Prepend(Directory.GetParent(installationUri)?.FullName ?? string.Empty)
.ToArray();
- await RestoreFileAsync(zippedFile, Path.Combine(fileDestinationPath), cToken);
+ await RestoreFileAsync(zippedFile, Path.Join(fileDestinationPath), cToken);
}
}
@@ -275,10 +274,10 @@ public sealed partial class EllieResolver : IBotResolver
/// The file to be extracted.
/// The final location of the extracted file.
/// The cancellation token.
- private async static ValueTask RestoreFileAsync(ZipArchiveEntry zippedFile, string destinationPath, CancellationToken cToken = default)
+ private static async ValueTask RestoreFileAsync(ZipArchiveEntry zippedFile, string destinationPath, CancellationToken cToken = default)
{
- using var zipStream = zippedFile.Open();
- using var fileStream = new FileStream(destinationPath, FileMode.Create);
+ await using var zipStream = zippedFile.Open();
+ await using var fileStream = new FileStream(destinationPath, FileMode.Create);
await zipStream.CopyToAsync(fileStream, cToken);
}
@@ -414,7 +413,7 @@ public sealed partial class EllieResolver : IBotResolver
finally
{
if (isSingleFile)
- Utilities.TryDeleteDirectory(directoryUri);
+ ToastieUtilities.TryDeleteDirectory(directoryUri);
}
}
diff --git a/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs b/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs
index 26566ca..0ffbbe0 100644
--- a/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs
+++ b/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs
@@ -1,15 +1,15 @@
using Avalonia.Controls;
+using Toastie.Utilities;
using MsBox.Avalonia.Enums;
using EllieHub.Enums;
using EllieHub.Features.Abstractions;
using EllieHub.Features.AppConfig.Services.Abstractions;
using EllieHub.Features.AppWindow.ViewModels;
-using EllieHub.Features.AppWindow.Views.Controls;
using EllieHub.Features.AppWindow.Views.Windows;
using EllieHub.Features.BotConfig.Models;
using EllieHub.Features.BotConfig.Services.Abstractions;
using EllieHub.Features.BotConfig.Views.Controls;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
using ReactiveUI;
using SkiaSharp;
using System.Diagnostics;
@@ -216,14 +216,12 @@ public class BotConfigViewModel : ViewModelBase, IDisposable
Directory.Delete(BotDirectoryUriBar.CurrentUri);
}
- if (Environment.OSVersion.Platform is not PlatformID.Unix)
- Directory.Move(oldUri, BotDirectoryUriBar.CurrentUri);
- else
- {
- // Move the bot root directory with "mv" to circumvent this issue on Unix systems: https://github.com/dotnet/runtime/issues/31149
- using var moveProcess = Utilities.StartProcess("mv", $"\"{oldUri}\" \"{BotDirectoryUriBar.CurrentUri}\"");
- await moveProcess.WaitForExitAsync();
- }
+ if (!ToastieUtilities.TryMoveDirectory(oldUri, BotDirectoryUriBar.CurrentUri))
+ throw new InvalidOperationException(
+ $"Could not move \"{oldUri}\" to \"{BotDirectoryUriBar.CurrentUri}\"." +
+ Environment.NewLine + Environment.NewLine +
+ "Make sure you have permission to write to the target directory."
+ );
BotDirectoryUriBar.RecheckCurrentUri();
}
@@ -330,7 +328,7 @@ public class BotConfigViewModel : ViewModelBase, IDisposable
ButtonDefinitions = ButtonEnum.OkCancel,
ContentTitle = "Are you sure?",
ContentMessage = $"Are you sure you want to delete {ActualBotName}?{Environment.NewLine}This action cannot be reversed.",
- MaxWidth = int.Parse(WindowConstants.DefaultWindowWidth) / 2.0,
+ MaxWidth = WindowConstants.DefaultWindowWidth / 2.0,
SizeToContent = SizeToContent.WidthAndHeight,
ShowInCenter = true,
WindowIcon = _mainWindow.GetResource(AppResources.EllieHubIcon),
@@ -343,7 +341,7 @@ public class BotConfigViewModel : ViewModelBase, IDisposable
EnableButtons(true, false);
// Stop the bot instance
- _botOrchestrator.Stop(Resolver.Id);
+ _botOrchestrator.StopBot(Resolver.Id);
// Cleanup
FakeConsole.Content = string.Empty;
@@ -410,7 +408,7 @@ public class BotConfigViewModel : ViewModelBase, IDisposable
///
public void StartBot()
{
- IsBotRunning = _botOrchestrator.Start(Id);
+ IsBotRunning = _botOrchestrator.StartBot(Id);
if (IsBotRunning)
EnableButtons(true, false);
@@ -420,7 +418,7 @@ public class BotConfigViewModel : ViewModelBase, IDisposable
/// Stops the bot instance associated with this view-model.
///
public void StopBot()
- => _botOrchestrator.Stop(Id);
+ => _botOrchestrator.StopBot(Id);
///
/// Loads the bot update bar.
@@ -508,7 +506,7 @@ public class BotConfigViewModel : ViewModelBase, IDisposable
///
public void Dispose()
{
- BotAvatar?.Dispose();
+ BotAvatar.Dispose();
GC.SuppressFinalize(this);
}
}
\ No newline at end of file
diff --git a/EllieHub/Features/BotConfig/ViewModels/FakeConsoleViewModel.cs b/EllieHub/Features/BotConfig/ViewModels/FakeConsoleViewModel.cs
index a008aaa..981ce07 100644
--- a/EllieHub/Features/BotConfig/ViewModels/FakeConsoleViewModel.cs
+++ b/EllieHub/Features/BotConfig/ViewModels/FakeConsoleViewModel.cs
@@ -1,5 +1,5 @@
using EllieHub.Features.Abstractions;
-using EllieHub.Features.AppConfig.Views.Controls;
+using EllieHub.Features.BotConfig.Views.Controls;
using ReactiveUI;
namespace EllieHub.Features.BotConfig.ViewModels;
diff --git a/EllieHub/Features/BotConfig/Views/Controls/BotConfigView.axaml b/EllieHub/Features/BotConfig/Views/Controls/BotConfigView.axaml
index d5d59f1..a4f4a3b 100644
--- a/EllieHub/Features/BotConfig/Views/Controls/BotConfigView.axaml
+++ b/EllieHub/Features/BotConfig/Views/Controls/BotConfigView.axaml
@@ -22,7 +22,7 @@
Fill="{DynamicResource HeavyBackground}"/>
diff --git a/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml b/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml
index e78ff89..c6174b3 100644
--- a/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml
+++ b/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml
@@ -5,7 +5,7 @@
xmlns:vm="using:EllieHub.Features.BotConfig.ViewModels"
xmlns:dd="using:EllieHub.Avalonia.DesignData.Controls"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="250"
- x:Class="EllieHub.Features.AppConfig.Views.Controls.FakeConsole"
+ x:Class="EllieHub.Features.BotConfig.Views.Controls.FakeConsole"
x:DataType="vm:FakeConsoleViewModel">
diff --git a/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml.cs b/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml.cs
index edc6873..2039ee4 100644
--- a/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml.cs
+++ b/EllieHub/Features/BotConfig/Views/Controls/FakeConsole.axaml.cs
@@ -1,7 +1,7 @@
using Avalonia.ReactiveUI;
using EllieHub.Features.BotConfig.ViewModels;
-namespace EllieHub.Features.AppConfig.Views.Controls;
+namespace EllieHub.Features.BotConfig.Views.Controls;
///
/// Represents a control that mimics the appearance of a terminal emulator.
diff --git a/EllieHub/Features/Shared/Models/UriInputBarEventArgs.cs b/EllieHub/Features/Common/Models/UriInputBarEventArgs.cs
similarity index 89%
rename from EllieHub/Features/Shared/Models/UriInputBarEventArgs.cs
rename to EllieHub/Features/Common/Models/UriInputBarEventArgs.cs
index 768c1c9..5b66614 100644
--- a/EllieHub/Features/Shared/Models/UriInputBarEventArgs.cs
+++ b/EllieHub/Features/Common/Models/UriInputBarEventArgs.cs
@@ -1,6 +1,6 @@
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
-namespace EllieHub.Features.Shared.Models;
+namespace EllieHub.Features.Common.Models;
///
/// Defines the event arguments for when a valid uri is set to a .
diff --git a/EllieHub/Features/Shared/Services/Abstractions/IDependencyResolver.cs b/EllieHub/Features/Common/Services/Abstractions/IDependencyResolver.cs
similarity index 97%
rename from EllieHub/Features/Shared/Services/Abstractions/IDependencyResolver.cs
rename to EllieHub/Features/Common/Services/Abstractions/IDependencyResolver.cs
index 6a80f42..d2e1861 100644
--- a/EllieHub/Features/Shared/Services/Abstractions/IDependencyResolver.cs
+++ b/EllieHub/Features/Common/Services/Abstractions/IDependencyResolver.cs
@@ -1,4 +1,4 @@
-namespace EllieHub.Features.Shared.Services.Abstractions;
+namespace EllieHub.Features.Common.Services.Abstractions;
///
/// Represents a service that checks, downloads, installs, and updates a dependency.
diff --git a/EllieHub/Features/Shared/ViewModels/DependencyButtonViewModel.cs b/EllieHub/Features/Common/ViewModels/DependencyButtonViewModel.cs
similarity index 97%
rename from EllieHub/Features/Shared/ViewModels/DependencyButtonViewModel.cs
rename to EllieHub/Features/Common/ViewModels/DependencyButtonViewModel.cs
index ede11ec..34df368 100644
--- a/EllieHub/Features/Shared/ViewModels/DependencyButtonViewModel.cs
+++ b/EllieHub/Features/Common/ViewModels/DependencyButtonViewModel.cs
@@ -2,11 +2,11 @@ using Avalonia.Media.Immutable;
using EllieHub.Enums;
using EllieHub.Features.Abstractions;
using EllieHub.Features.AppWindow.Views.Windows;
-using EllieHub.Features.Shared.Views.Controls;
+using EllieHub.Features.Common.Views.Controls;
using ReactiveUI;
using System.Diagnostics;
-namespace EllieHub.Features.Shared.ViewModels;
+namespace EllieHub.Features.Common.ViewModels;
///
/// Defines the view-model for a button that installs a dependency for Ellie.
diff --git a/EllieHub/Features/Shared/ViewModels/UriInputBarViewModel.cs b/EllieHub/Features/Common/ViewModels/UriInputBarViewModel.cs
similarity index 96%
rename from EllieHub/Features/Shared/ViewModels/UriInputBarViewModel.cs
rename to EllieHub/Features/Common/ViewModels/UriInputBarViewModel.cs
index d3c7b5a..a08cc5f 100644
--- a/EllieHub/Features/Shared/ViewModels/UriInputBarViewModel.cs
+++ b/EllieHub/Features/Common/ViewModels/UriInputBarViewModel.cs
@@ -1,11 +1,11 @@
using Avalonia.Platform.Storage;
using EllieHub.Features.Abstractions;
-using EllieHub.Features.Shared.Models;
-using EllieHub.Features.Shared.Views.Controls;
+using EllieHub.Features.Common.Models;
+using EllieHub.Features.Common.Views.Controls;
using ReactiveUI;
using System.Diagnostics;
-namespace EllieHub.Features.Shared.ViewModels;
+namespace EllieHub.Features.Common.ViewModels;
///
/// Represents a text box for inputting the absolute path of a directory.
diff --git a/EllieHub/Features/Shared/Views/Controls/DependencyButton.axaml b/EllieHub/Features/Common/Views/Controls/DependencyButton.axaml
similarity index 92%
rename from EllieHub/Features/Shared/Views/Controls/DependencyButton.axaml
rename to EllieHub/Features/Common/Views/Controls/DependencyButton.axaml
index 683943c..1c7fefa 100644
--- a/EllieHub/Features/Shared/Views/Controls/DependencyButton.axaml
+++ b/EllieHub/Features/Common/Views/Controls/DependencyButton.axaml
@@ -2,10 +2,10 @@
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:vm="using:EllieHub.Features.Shared.ViewModels"
+ xmlns:vm="using:EllieHub.Features.Common.ViewModels"
xmlns:dd="using:EllieHub.Avalonia.DesignData.Controls"
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="50"
- x:Class="EllieHub.Features.Shared.Views.Controls.DependencyButton"
+ x:Class="EllieHub.Features.Common.Views.Controls.DependencyButton"
x:DataType="vm:DependencyButtonViewModel">
diff --git a/EllieHub/Features/Shared/Views/Controls/DependencyButton.axaml.cs b/EllieHub/Features/Common/Views/Controls/DependencyButton.axaml.cs
similarity index 79%
rename from EllieHub/Features/Shared/Views/Controls/DependencyButton.axaml.cs
rename to EllieHub/Features/Common/Views/Controls/DependencyButton.axaml.cs
index 1b72be6..2bec229 100644
--- a/EllieHub/Features/Shared/Views/Controls/DependencyButton.axaml.cs
+++ b/EllieHub/Features/Common/Views/Controls/DependencyButton.axaml.cs
@@ -1,7 +1,7 @@
using Avalonia.ReactiveUI;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
-namespace EllieHub.Features.Shared.Views.Controls;
+namespace EllieHub.Features.Common.Views.Controls;
///
/// Represents a button that installs a dependency for Ellie.
diff --git a/EllieHub/Features/Shared/Views/Controls/UriInputBar.axaml b/EllieHub/Features/Common/Views/Controls/UriInputBar.axaml
similarity index 91%
rename from EllieHub/Features/Shared/Views/Controls/UriInputBar.axaml
rename to EllieHub/Features/Common/Views/Controls/UriInputBar.axaml
index 38ea3fc..4ed0890 100644
--- a/EllieHub/Features/Shared/Views/Controls/UriInputBar.axaml
+++ b/EllieHub/Features/Common/Views/Controls/UriInputBar.axaml
@@ -2,10 +2,10 @@
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:vm="using:EllieHub.Features.Shared.ViewModels"
+ xmlns:vm="using:EllieHub.Features.Common.ViewModels"
xmlns:dd="using:EllieHub.Avalonia.DesignData.Controls"
mc:Ignorable="d" d:DesignWidth="700" d:DesignHeight="33"
- x:Class="EllieHub.Features.Shared.Views.Controls.UriInputBar"
+ x:Class="EllieHub.Features.Common.Views.Controls.UriInputBar"
x:DataType="vm:UriInputBarViewModel">
diff --git a/EllieHub/Features/Shared/Views/Controls/UriInputBar.axaml.cs b/EllieHub/Features/Common/Views/Controls/UriInputBar.axaml.cs
similarity index 80%
rename from EllieHub/Features/Shared/Views/Controls/UriInputBar.axaml.cs
rename to EllieHub/Features/Common/Views/Controls/UriInputBar.axaml.cs
index beae307..42dc5a2 100644
--- a/EllieHub/Features/Shared/Views/Controls/UriInputBar.axaml.cs
+++ b/EllieHub/Features/Common/Views/Controls/UriInputBar.axaml.cs
@@ -1,7 +1,7 @@
using Avalonia.ReactiveUI;
-using EllieHub.Features.Shared.ViewModels;
+using EllieHub.Features.Common.ViewModels;
-namespace EllieHub.Features.Shared.Views.Controls;
+namespace EllieHub.Features.Common.Views.Controls;
///
/// Represents a text box that receives the absolute path to a directory.
diff --git a/EllieHub/Features/Home/Services/Abstractions/IAppResolver.cs b/EllieHub/Features/Home/Services/Abstractions/IAppResolver.cs
index fb17d89..4f32b76 100644
--- a/EllieHub/Features/Home/Services/Abstractions/IAppResolver.cs
+++ b/EllieHub/Features/Home/Services/Abstractions/IAppResolver.cs
@@ -1,4 +1,4 @@
-using EllieHub.Features.Shared.Services.Abstractions;
+using EllieHub.Features.Common.Services.Abstractions;
namespace EllieHub.Features.Home.Services.Abstractions;
diff --git a/EllieHub/Features/Home/Services/AppResolver.cs b/EllieHub/Features/Home/Services/AppResolver.cs
index de05f50..20a46bb 100644
--- a/EllieHub/Features/Home/Services/AppResolver.cs
+++ b/EllieHub/Features/Home/Services/AppResolver.cs
@@ -1,3 +1,4 @@
+using Toastie.Utilities;
using Microsoft.Extensions.Caching.Memory;
using EllieHub.Features.Home.Models.Api.Toastielab;
using EllieHub.Features.Home.Services.Abstractions;
@@ -51,7 +52,7 @@ public sealed class AppResolver : IAppResolver
///
public void LaunchNewVersion()
- => Utilities.StartProcess(BinaryUri);
+ => ToastieUtilities.StartProcess(BinaryUri);
///
/// if the updater can be updated,
@@ -61,7 +62,7 @@ public sealed class AppResolver : IAppResolver
///
public async ValueTask CanUpdateAsync(CancellationToken cToken = default)
{
- if (!Utilities.CanWriteTo(AppContext.BaseDirectory))
+ if (!ToastieUtilities.HasWritePermissionAt(AppContext.BaseDirectory))
return null;
var currentVersion = await GetCurrentVersionAsync(cToken);
@@ -88,7 +89,7 @@ public sealed class AppResolver : IAppResolver
var result = false;
foreach (var file in Directory.GetFiles(AppContext.BaseDirectory).Where(x => x.EndsWith(OldFileSuffix, StringComparison.Ordinal)))
- result |= Utilities.TryDeleteFile(file);
+ result |= ToastieUtilities.TryDeleteFile(file);
return result;
}
@@ -144,21 +145,13 @@ public sealed class AppResolver : IAppResolver
if (File.Exists(destinationUri))
File.Move(destinationUri, destinationUri + OldFileSuffix, true);
- // Move the new file to the application's directory.
- if (Environment.OSVersion.Platform is not PlatformID.Unix)
- File.Move(newFileUri, destinationUri, true);
- else
- {
- // Circumvent this issue on Unix systems: https://github.com/dotnet/runtime/issues/31149
- using var moveProcess = Utilities.StartProcess("mv", $"\"{newFileUri}\" \"{destinationUri}\"");
- await moveProcess.WaitForExitAsync(cToken);
- }
+ ToastieUtilities.TryMoveFile(newFileUri, destinationUri, true);
}
// Mark the new binary file as executable.
if (Environment.OSVersion.Platform is PlatformID.Unix)
{
- using var chmod = Utilities.StartProcess("chmod", $"+x \"{BinaryUri}\"");
+ using var chmod = ToastieUtilities.StartProcess("chmod", $"+x \"{BinaryUri}\"");
await chmod.WaitForExitAsync(cToken);
}
@@ -167,8 +160,8 @@ public sealed class AppResolver : IAppResolver
finally
{
// Cleanup
- Utilities.TryDeleteFile(zipTempLocation);
- Utilities.TryDeleteDirectory(appTempLocation);
+ ToastieUtilities.TryDeleteFile(zipTempLocation);
+ ToastieUtilities.TryDeleteDirectory(appTempLocation);
}
}
diff --git a/EllieHub/Features/Home/Views/Controls/HomeView.axaml b/EllieHub/Features/Home/Views/Controls/HomeView.axaml
index 91aaf0f..6d30451 100644
--- a/EllieHub/Features/Home/Views/Controls/HomeView.axaml
+++ b/EllieHub/Features/Home/Views/Controls/HomeView.axaml
@@ -28,15 +28,15 @@
Grid.ColumnSpan="5"
Fill="{DynamicResource HeavyBackground}"/>
-
-
-
@@ -147,7 +147,7 @@
VerticalAlignment="Top"/>
-
-
-
-
-