diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5cb08dec2..cc5dcd3f4 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -49,12 +49,12 @@ jobs:
# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
- android: true
+ android: false
dotnet: false
haskell: true
- large-packages: true
- docker-images: true
- swap-storage: true
+ large-packages: false
+ docker-images: false
+ swap-storage: false
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
diff --git a/Directory.Build.props b/Directory.Build.props
index c1837c2fc..1ca9981b5 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -25,6 +25,29 @@
false
true
+
+
+
+ <_Parameter1>$(InternalsVisibleToFriends)
+
+
+
+
+
+
+
+
+
+ <_Parameter1>%(InternalsVisibleTo.Identity)
+
+
+
+
+
+ <_Parameter1>$(AssemblyName)%(InternalsVisibleToSuffix.Identity)
+
+
+
true
diff --git a/README.md b/README.md
index 8c93e66c5..733820fdf 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@
- Keeps compatibility with the custom uploader configuration format (.sxcu)
- As a user, you do **NOT** need to have .NET installed. Whether you're on Linux, Windows, or macOS.
-What does this all mean? It means you'll be able to have a more **performant**, **reliable**, and **stylish** application.
+What does this all mean? You'll have an app that **flies**, is **reliable**, and looks **sleek**.
You will *not* receive any support from the ShareX project for this software. \
If you have any issues with this project, please **open an issue** in this repository.
diff --git a/SnapX.Avalonia/App.axaml.cs b/SnapX.Avalonia/App.axaml.cs
index e5c14717e..41a9f0c63 100644
--- a/SnapX.Avalonia/App.axaml.cs
+++ b/SnapX.Avalonia/App.axaml.cs
@@ -5,28 +5,21 @@
using Avalonia.Layout;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
-using Avalonia.Media.Imaging;
-using Avalonia.Platform;
using Avalonia.Styling;
using CommunityToolkit.Mvvm.DependencyInjection;
-using CommunityToolkit.Mvvm.Input;
-using CommunityToolkit.Mvvm.Messaging;
using FluentAvalonia.UI.Windowing;
-using Microsoft.Extensions.DependencyInjection;
-using Serilog;
using SnapX.Avalonia.ViewModels;
using SnapX.Avalonia.Views;
+using SnapX.Avalonia.Views.About;
using SnapX.Avalonia.Views.Settings;
-using SnapX.Avalonia.Views.Settings.Views;
using SnapX.Core;
-using SnapX.Core.Capture;
-using SnapX.Core.Job;
+using SnapX.Core.Interfaces;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Native;
namespace SnapX.Avalonia;
-public partial class App : Application
+public class App : Application
{
public App()
{
@@ -35,28 +28,18 @@ public App()
public static SnapXAvalonia SnapX { get; private set; } = null!;
public static MainWindow? MyMainWindow { get; private set; }
- public static string TrayTitle => $"SnapX v{SimpleVersion()}";
-
- private static string SimpleVersion()
- {
- var version = Version.Parse(Helpers.GetApplicationVersion());
- var versionString = $"{version.Major}.{version.Minor}.{version.Revision}";
- if (version.Build > 0)
- versionString += $".{version.Build}";
- return versionString;
- }
public override void Initialize()
{
SnapX = new SnapXAvalonia();
// SnapX.setQualifier(" UI");
AvaloniaXamlLoader.Load(this);
- AppDomain.CurrentDomain.UnhandledException += (Sender, Args) =>
+ AppDomain.CurrentDomain.UnhandledException += (_, Args) =>
{
- ShowErrorDialog(Lang.UnhandledException, Args.ExceptionObject as Exception);
+ ShowErrorDialog(Lang.UnhandledException, (Args.ExceptionObject as Exception)!);
};
#if DEBUG
- Current.AttachDevTools();
+ Current?.AttachDevTools();
#endif
// Default logic doesn't auto-detect windows theme anymore in designer
@@ -109,7 +92,7 @@ private void ShowErrorDialog(string? title, Exception ex)
// Padding = new Thickness(10),
});
}
- var version = Assembly.GetExecutingAssembly().GetName().Version;
+ var version = Assembly.GetExecutingAssembly().GetName().Version!;
var semver = version.Major + "." + version.Minor + "." + version.Revision;
stackPanel.Children.Add(new SelectableTextBlock
{
@@ -134,7 +117,7 @@ private void ShowErrorDialog(string? title, Exception ex)
FontWeight = FontWeight.Bold,
CornerRadius = new CornerRadius(5)
};
- reportButton.Click += (sender, e) => OnReportErrorClicked();
+ reportButton.Click += (_, _) => OnReportErrorClicked();
var githubButton = new Button
{
@@ -150,7 +133,7 @@ private void ShowErrorDialog(string? title, Exception ex)
FontWeight = FontWeight.Bold,
CornerRadius = new CornerRadius(5)
};
- githubButton.Click += (sender, e) => OnGitHubButtonClicked(ex);
+ githubButton.Click += (_, _) => OnGitHubButtonClicked(ex);
var copyButton = new Button
@@ -169,7 +152,7 @@ private void ShowErrorDialog(string? title, Exception ex)
};
// Copy error to clipboard when clicked
- copyButton.Click += (sender, e) => CopyErrorToClipboard(ex.ToString());
+ copyButton.Click += (_, _) => CopyErrorToClipboard(ex.ToString());
buttonPanel.Children.Add(reportButton);
@@ -212,14 +195,14 @@ private void OnReportErrorClicked()
{
// For now, do nothing when the button is clicked
// This is where Sentry comes in
- Console.WriteLine("Report Error button clicked. No action yet. If you have telemetry enabled, (it is by default) it will have already been sent to Sentry.");
+ DebugHelper.WriteLine("Report Error button clicked. No action yet. If you have telemetry enabled, (it is by default) it will have already been sent to Sentry.");
}
- private void Shutdown()
+ public static void Shutdown()
{
try
{
- SnapX?.shutdown();
+ SnapX.shutdown();
}
catch (Exception e)
{
@@ -233,13 +216,7 @@ public override void OnFrameworkInitializationCompleted()
{
var locator = new ViewLocator();
DataTemplates.Add(locator);
- var services = new ServiceCollection();
- ConfigureServices(services);
- var provider = services.BuildServiceProvider();
-
- Ioc.Default.ConfigureServices(provider);
- Ioc.Default.AddStaticLogging();
var vm = Ioc.Default.GetRequiredService();
switch (ApplicationLifetime)
@@ -253,7 +230,7 @@ public override void OnFrameworkInitializationCompleted()
DebugHelper.WriteLine("Received Shutdown from Avalonia");
if (sigintReceived) return;
sigintReceived = true;
- SnapX.shutdown();
+ Shutdown();
// desktop.Shutdown();
};
@@ -264,22 +241,9 @@ public override void OnFrameworkInitializationCompleted()
if (sigintReceived) return;
ea.Cancel = true;
sigintReceived = true;
- SnapX.shutdown();
+ Shutdown();
desktop.Shutdown();
};
- // AppDomain.CurrentDomain.ProcessExit += (o, _) =>
- // {
- // if (!sigintReceived)
- // {
- // sigintReceived = true;
- // DebugHelper.WriteLine("Received SIGTERM");
- // SnapX.shutdown();
- // }
- // else
- // {
- // DebugHelper.WriteLine("Received SIGTERM, ignoring it because already processed SIGINT");
- // }
- // };
var errorStarting = false;
// DebugHelper.Logger.Debug($"Avalonia Args: {desktop.Args}");
try
@@ -299,97 +263,6 @@ public override void OnFrameworkInitializationCompleted()
if (errorStarting) return;
DebugHelper.WriteLine("Internal Startup time: {0} ms", SnapX.getStartupTime());
- var logoBitmap = new Bitmap(AssetLoader.Open(new Uri("avares://snapx-ui/SnapX_Logo.png")));
- var trayIcon = new TrayIcon
- {
- Icon = new WindowIcon(logoBitmap),
- ToolTipText = Core.SnapX.AppName,
- Command = OpenSnapXCommand
- };
-
- var menu = new NativeMenu();
- menu.Opening += NativeMenu_OnOpening;
- menu.NeedsUpdate += NativeMenu_OnNeedsUpdate;
-
- var about = new NativeMenuItem(TrayTitle)
- {
- Icon = logoBitmap,
- ToolTip = Lang.AboutSnapX
- };
- about.Click += NativeMenuItem_SnapX_OnClick;
- menu.Items.Add(about);
- menu.Items.Add(new NativeMenuItemSeparator());
-
- var capture = new NativeMenuItem("Capture") { Menu = new NativeMenu() };
- var full = new NativeMenuItem(Lang.UI_Capture_Fullscreen);
- full.Click += NativeMenuItem_Capture_Fullscreen_OnClick;
- capture.Menu.Items.Add(full);
-
- var windowPicker = new NativeMenuItem(Lang.UI_Dropdown_Window)
- {
- Menu = new NativeMenu
- {
- new NativeMenuItem("SnapX UI") { Icon = logoBitmap },
- new NativeMenuItem("Marvel Rivals") { Icon = logoBitmap },
- new NativeMenuItem("Man of Steel (2013)") { Icon = logoBitmap }
- }
- };
- capture.Menu.Items.Add(windowPicker);
-
- var monitorPicker = new NativeMenuItem(Lang.UI_Dropdown_Monitor) { Menu = [] };
- monitorPicker.Menu.NeedsUpdate += NativeMenu_OnNeedsUpdate;
- capture.Menu.Items.Add(monitorPicker);
-
- capture.Menu.Items.Add(new NativeMenuItem("Region"));
- capture.Menu.Items.Add(new NativeMenuItem("Region (Light)"));
- capture.Menu.Items.Add(new NativeMenuItem("Region (Transparent)"));
- menu.Items.Add(capture);
-
- menu.Items.Add(new NativeMenuItem("Upload")
- {
- Menu = new NativeMenu
- {
- new NativeMenuItem("Upload File..."),
- new NativeMenuItem("Upload Folder..."),
- new NativeMenuItem("Upload from clipboard..."),
- new NativeMenuItem("Upload text..."),
- new NativeMenuItem("Drag and drop upload..."),
- new NativeMenuItem("Shorten URL..."),
- new NativeMenuItem("Tweet message...")
- }
- });
- var captureFullscreenMenuItem = new NativeMenuItem("Capture entire screen");
- captureFullscreenMenuItem.Click += NativeMenuItem_Capture_Fullscreen_OnClick;
- var captureActiveWindowMenuItem = new NativeMenuItem("Capture active window");
- captureActiveWindowMenuItem.Click += NativeMenuItem_Workflows_CaptureActiveWindow_OnClick;
- var captureActiveScreenMenuItem = new NativeMenuItem("Capture active screen");
- captureActiveScreenMenuItem.Click += NativeMenuItem_Workflows_CaptureActiveScreen_OnClick;
- var workflows = new NativeMenuItem("Workflows")
- {
- Menu =
- [
- captureFullscreenMenuItem,
- captureActiveScreenMenuItem,
- captureActiveWindowMenuItem,
- ]
- };
-
- menu.Items.Add(workflows);
-
- menu.Items.Add(new NativeMenuItemSeparator());
-
- var open = new NativeMenuItem("Open");
- open.Command = OpenSnapXCommand;
- menu.Items.Add(open);
-
- var quit = new NativeMenuItem("Quit");
- quit.Click += NativeMenuItem_Quit_OnClick;
- menu.Items.Add(quit);
-
- trayIcon.Menu = menu;
-
- TrayIcon.SetIcons(Current, [trayIcon]);
-
if (SnapX.isSilent()) return;
if (SnapX.GetCLIManager().IsCommandExist("video"))
{
@@ -402,9 +275,11 @@ public override void OnFrameworkInitializationCompleted()
MyMainWindow = Window;
desktop.MainWindow = Window;
+ var tray = new OSTray(this, Ioc.Default.GetRequiredService());
+ tray.display();
break;
}
- case ISingleViewApplicationLifetime singleView when SnapX.isSilent():
+ case ISingleViewApplicationLifetime when SnapX.isSilent():
return;
case ISingleViewApplicationLifetime singleView:
{
@@ -452,6 +327,10 @@ public static void CreateAboutWindowStatic()
aboutWindow.Show();
}
}
+ public void NativeMenuAboutSnapXClick(object? _, EventArgs E)
+ {
+ CreateAboutWindowStatic();
+ }
public static void CreateSettingsWindowStatic()
{
var settingsWindow = Design.IsDesignMode
@@ -470,87 +349,4 @@ public static void CreateSettingsWindowStatic()
settingsWindow.Show();
}
}
-
-
- private void NativeMenuAboutSnapXClick(object? Sender, EventArgs E)
- {
- CreateAboutWindowStatic();
- }
-
- public static void ConfigureServices(IServiceCollection services)
- {
- services.AddLogging(loggingBuilder =>
- loggingBuilder.AddSerilog(dispose: true));
-
-
- services.AddTransient();
- services.AddSingleton();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
-
- services.AddTransient();
- services.AddSingleton();
-
- services.AddTransient();
- services.AddSingleton();
-
- services.AddSingleton(WeakReferenceMessenger.Default);
- }
-
- private void NativeMenuItem_Quit_OnClick(object? Sender, EventArgs E)
- {
- Shutdown();
- }
-
- private void NativeMenuItem_SnapX_OnClick(object? Sender, EventArgs E)
- {
- NativeMenuAboutSnapXClick(Sender, E);
- }
-
- private void NativeMenuItem_Capture_Fullscreen_OnClick(object? Sender, EventArgs E)
- {
- TaskHelpers.GetScreenshot().CaptureFullscreen();
- }
-
- private void NativeMenuItem_Workflows_CaptureActiveScreen_OnClick(object? Sender, EventArgs E)
- {
- new CaptureActiveMonitor().Capture(TaskSettings.GetDefaultTaskSettings());
- }
-
- private void NativeMenuItem_Workflows_CaptureActiveWindow_OnClick(object? Sender, EventArgs E)
- {
- new CaptureActiveWindow().Capture(TaskSettings.GetDefaultTaskSettings());
- }
-
- private void NativeMenuItem_Open_OnClick(object? Sender, EventArgs E)
- {
- if (!MyMainWindow?.IsLoaded ?? false)
- {
- var vm = Ioc.Default.GetRequiredService();
- MyMainWindow = new MainWindow(vm);
- MyMainWindow.Show();
- }
-
- if (!MyMainWindow?.IsVisible ?? true) MyMainWindow?.Show();
- MyMainWindow?.Focus();
- MyMainWindow?.Activate();
- }
-
- [RelayCommand]
- private void OpenSnapX()
- {
- NativeMenuItem_Open_OnClick(this, EventArgs.Empty);
- }
- private void NativeMenu_OnNeedsUpdate(object? Sender, EventArgs E)
- {
- DebugHelper.WriteLine("NativeMenu_OnNeedsUpdate");
- }
-
- private void NativeMenu_OnOpening(object? Sender, EventArgs E)
- {
- DebugHelper.WriteLine("NativeMenu_OnOpening");
- }
}
diff --git a/SnapX.Avalonia/Extensions/AvaloniaListExtensions.cs b/SnapX.Avalonia/Extensions/AvaloniaListExtensions.cs
new file mode 100644
index 000000000..8ae9ff1b7
--- /dev/null
+++ b/SnapX.Avalonia/Extensions/AvaloniaListExtensions.cs
@@ -0,0 +1,20 @@
+using Avalonia.Collections;
+
+namespace SnapX.Avalonia.Extensions;
+
+public static class AvaloniaListExtensions
+{
+ public static int FindIndex(this AvaloniaList list, Predicate match)
+ {
+ if (match == null)
+ throw new ArgumentNullException(nameof(match));
+
+ for (int i = 0; i < list.Count; i++)
+ {
+ if (match(list[i]))
+ return i;
+ }
+
+ return -1;
+ }
+}
diff --git a/SnapX.Avalonia/OSTray.cs b/SnapX.Avalonia/OSTray.cs
new file mode 100644
index 000000000..0a3e2f36a
--- /dev/null
+++ b/SnapX.Avalonia/OSTray.cs
@@ -0,0 +1,177 @@
+using Avalonia.Controls;
+using Avalonia.Media.Imaging;
+using Avalonia.Platform;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using CommunityToolkit.Mvvm.Input;
+using SnapX.Avalonia.ViewModels;
+using SnapX.Avalonia.Views;
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture;
+using SnapX.Core.Utils;
+
+namespace SnapX.Avalonia;
+
+public partial class OSTray(App Current, ILoggerService Logger)
+{
+ private static string TrayTitle => $"{Core.SnapX.AppName} v{SimpleVersion()}";
+
+ private static string SimpleVersion()
+ {
+ var version = Version.Parse(Helpers.GetApplicationVersion());
+ var versionString = $"{version.Major}.{version.Minor}.{version.Revision}";
+ if (version.Build > 0)
+ versionString += $".{version.Build}";
+ return versionString;
+ }
+ public void display()
+ {
+ var logoBitmap = new Bitmap(AssetLoader.Open(new Uri("avares://snapx-ui/SnapX_Logo.png")));
+ var trayIcon = new TrayIcon
+ {
+ Icon = new WindowIcon(logoBitmap),
+ ToolTipText = Core.SnapX.AppName,
+ Command = OpenSnapXCommand
+ };
+
+ var menu = new NativeMenu();
+ menu.Opening += NativeMenu_OnOpening;
+ menu.NeedsUpdate += NativeMenu_OnNeedsUpdate;
+
+ var about = new NativeMenuItem(TrayTitle)
+ {
+ Icon = logoBitmap,
+ ToolTip = Lang.AboutSnapX
+ };
+ about.Click += NativeMenuItem_SnapX_OnClick;
+ menu.Items.Add(about);
+ menu.Items.Add(new NativeMenuItemSeparator());
+
+ var capture = new NativeMenuItem("Capture") { Menu = new NativeMenu() };
+ var full = new NativeMenuItem(Lang.UI_Capture_Fullscreen);
+ full.Click += NativeMenuItem_Capture_Fullscreen_OnClick;
+ capture.Menu.Items.Add(full);
+
+ var windowPicker = new NativeMenuItem(Lang.UI_Dropdown_Window)
+ {
+ Menu =
+ [
+ new NativeMenuItem("SnapX UI") { Icon = logoBitmap },
+ new NativeMenuItem("Marvel Rivals") { Icon = logoBitmap },
+ new NativeMenuItem("Man of Steel (2013)") { Icon = logoBitmap }
+ ]
+ };
+ capture.Menu.Items.Add(windowPicker);
+
+ var monitorPicker = new NativeMenuItem(Lang.UI_Dropdown_Monitor) { Menu = [] };
+ monitorPicker.Menu.NeedsUpdate += NativeMenu_OnNeedsUpdate;
+ capture.Menu.Items.Add(monitorPicker);
+
+ capture.Menu.Items.Add(new NativeMenuItem("Region"));
+ capture.Menu.Items.Add(new NativeMenuItem("Region (Light)"));
+ capture.Menu.Items.Add(new NativeMenuItem("Region (Transparent)"));
+ menu.Items.Add(capture);
+
+ menu.Items.Add(new NativeMenuItem("Upload")
+ {
+ Menu =
+ [
+ new NativeMenuItem("Upload File..."),
+ new NativeMenuItem("Upload Folder..."),
+ new NativeMenuItem("Upload from clipboard..."),
+ new NativeMenuItem("Upload text..."),
+ new NativeMenuItem("Drag and drop upload..."),
+ new NativeMenuItem("Shorten URL..."),
+ new NativeMenuItem("Tweet message...")
+ ]
+ });
+ var captureFullscreenMenuItem = new NativeMenuItem("Capture entire screen");
+ captureFullscreenMenuItem.Click += NativeMenuItem_Capture_Fullscreen_OnClick;
+ var captureActiveWindowMenuItem = new NativeMenuItem("Capture active window");
+ captureActiveWindowMenuItem.Click += NativeMenuItem_Workflows_CaptureActiveWindow_OnClick;
+ var captureActiveScreenMenuItem = new NativeMenuItem("Capture active screen");
+ captureActiveScreenMenuItem.Click += NativeMenuItem_Workflows_CaptureActiveScreen_OnClick;
+ var workflows = new NativeMenuItem("Workflows")
+ {
+ Menu =
+ [
+ captureFullscreenMenuItem,
+ captureActiveScreenMenuItem,
+ captureActiveWindowMenuItem,
+ ]
+ };
+
+ menu.Items.Add(workflows);
+
+ menu.Items.Add(new NativeMenuItemSeparator());
+
+ var open = new NativeMenuItem("Open")
+ {
+ Command = OpenSnapXCommand
+ };
+ menu.Items.Add(open);
+
+ var quit = new NativeMenuItem("Quit");
+ quit.Click += NativeMenuItem_Quit_OnClick;
+ menu.Items.Add(quit);
+
+ trayIcon.Menu = menu;
+
+ TrayIcon.SetIcons(Current, [trayIcon]);
+ }
+ private void NativeMenuItem_Quit_OnClick(object? Sender, EventArgs E)
+ {
+ App.Shutdown();
+ }
+ private void NativeMenuItem_SnapX_OnClick(object? Sender, EventArgs E)
+ {
+ Current.NativeMenuAboutSnapXClick(Sender, E);
+ }
+
+ private void NativeMenuItem_Capture_Fullscreen_OnClick(object? Sender, EventArgs E)
+ {
+ TaskHelpers.GetScreenshot().CaptureFullscreen();
+ }
+
+ private void NativeMenuItem_Workflows_CaptureActiveScreen_OnClick(object? Sender, EventArgs E)
+ {
+ var capture = Ioc.Default.GetRequiredService();
+ capture.CaptureAsync(TaskSettings.GetDefaultTaskSettings());
+ }
+
+ private void NativeMenuItem_Workflows_CaptureActiveWindow_OnClick(object? Sender, EventArgs E)
+ {
+ var capture = Ioc.Default.GetRequiredService();
+ capture.CaptureAsync(TaskSettings.GetDefaultTaskSettings());
+ }
+
+ private void NativeMenuItem_Open_OnClick(object? _, EventArgs _2)
+ {
+ var MyMainWindow = App.MyMainWindow;
+ if (!MyMainWindow?.IsLoaded ?? false)
+ {
+ var vm = Ioc.Default.GetRequiredService();
+ MyMainWindow = new MainWindow(vm);
+ MyMainWindow.Show();
+ }
+
+ if (!MyMainWindow?.IsVisible ?? true) MyMainWindow?.Show();
+ MyMainWindow?.Focus();
+ MyMainWindow?.Activate();
+ }
+
+ [RelayCommand]
+ private void OpenSnapX()
+ {
+ NativeMenuItem_Open_OnClick(this, EventArgs.Empty);
+ }
+ private void NativeMenu_OnNeedsUpdate(object? Sender, EventArgs E)
+ {
+ Logger.Information("NativeMenu_OnNeedsUpdate");
+ }
+
+ private void NativeMenu_OnOpening(object? Sender, EventArgs E)
+ {
+ Logger.Information("NativeMenu_OnOpening");
+ }
+}
diff --git a/SnapX.Avalonia/Program.cs b/SnapX.Avalonia/Program.cs
index 47789765e..4ca698d11 100644
--- a/SnapX.Avalonia/Program.cs
+++ b/SnapX.Avalonia/Program.cs
@@ -5,10 +5,14 @@
using Avalonia.Media;
using SnapX.Avalonia;
+var snapx = new SnapXAvalonia();
+
+snapx.loadApplicationSettingsPartial();
+
BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
-static AppBuilder BuildAvaloniaApp()
+AppBuilder BuildAvaloniaApp()
{
var builder = AppBuilder.Configure()
.WithInterFont();
@@ -19,11 +23,11 @@ static AppBuilder BuildAvaloniaApp()
builder = builder.With(new FontManagerOptions
{
DefaultFamilyName = "fonts:Inter#Inter",
- FontFallbacks = new List
- {
+ FontFallbacks =
+ [
new()
{
- FontFamily = "Inter"
+ FontFamily = "fonts:Inter#Inter"
},
new()
{
@@ -41,12 +45,13 @@ static AppBuilder BuildAvaloniaApp()
{
FontFamily = "Adwaita Sans"
}
- }
+ ]
});
}
builder = builder.LogToTrace();
+ var useGPU = snapx.GetConfiguration().HardwareAccelerated;
var x11Options = new X11PlatformOptions
{
// Fixes poor performance on my NVIDIA RTX 3060 Laptop GPU using Region Selector on Fedora KDE Wayland
@@ -54,6 +59,21 @@ static AppBuilder BuildAvaloniaApp()
UseRetainedFramebuffer = true,
OverlayPopups = true
};
+ if (!useGPU) x11Options.RenderingMode = [X11RenderingMode.Software];
+
+ var macOSOptions = new AvaloniaNativePlatformOptions
+ {
+ RenderingMode = [AvaloniaNativeRenderingMode.Metal, AvaloniaNativeRenderingMode.OpenGl, AvaloniaNativeRenderingMode.Software],
+ OverlayPopups = true
+ };
+ if (!useGPU) macOSOptions.RenderingMode = [AvaloniaNativeRenderingMode.Software];
+
+ var win32Options = new Win32PlatformOptions
+ {
+ // RenderingMode = [Win32RenderingMode.Vulkan, Win32RenderingMode.AngleEgl, Win32RenderingMode.Wgl, Win32RenderingMode.Software],
+ OverlayPopups = true
+ };
+ if (!useGPU) win32Options.RenderingMode = [Win32RenderingMode.Software];
if (OperatingSystem.IsFreeBSD())
{
@@ -68,8 +88,8 @@ static AppBuilder BuildAvaloniaApp()
.UsePlatformDetect()
.UseManagedSystemDialogs()
.With(x11Options)
- .With(new AvaloniaNativePlatformOptions { OverlayPopups = true })
- .With(new Win32PlatformOptions { OverlayPopups = true });
+ .With(macOSOptions)
+ .With(win32Options);
}
return builder;
diff --git a/SnapX.Avalonia/SnapX.Avalonia.csproj b/SnapX.Avalonia/SnapX.Avalonia.csproj
index d830e24a0..643c0a94f 100644
--- a/SnapX.Avalonia/SnapX.Avalonia.csproj
+++ b/SnapX.Avalonia/SnapX.Avalonia.csproj
@@ -11,6 +11,7 @@
snapx-ui
SnapX UI
Assets\SnapX_Icon.ico
+ SnapX.Avalonia.Tests
false
true
@@ -48,7 +49,6 @@
-
diff --git a/SnapX.Avalonia/SnapXAvalonia.cs b/SnapX.Avalonia/SnapXAvalonia.cs
index edd10612f..0acb7beb3 100644
--- a/SnapX.Avalonia/SnapXAvalonia.cs
+++ b/SnapX.Avalonia/SnapXAvalonia.cs
@@ -1,3 +1,53 @@
+using CommunityToolkit.Mvvm.DependencyInjection;
+using CommunityToolkit.Mvvm.Messaging;
+using Microsoft.Extensions.DependencyInjection;
+using Serilog;
+using SnapX.Avalonia.ViewModels;
+using SnapX.Avalonia.Views;
+using SnapX.Avalonia.Views.About;
+using SnapX.Avalonia.Views.Settings;
+using SnapX.Avalonia.Views.Settings.Views;
+using SnapX.CommonUI.ViewModels;
+
namespace SnapX.Avalonia;
-public class SnapXAvalonia : Core.SnapX;
+public class SnapXAvalonia() : SnapX.Core.SnapX(BuildServices())
+{
+ private static IServiceProvider BuildServices()
+ {
+ var services = new ServiceCollection();
+ Core.SnapX.ConfigureServices(services);
+ ConfigureServices(services);
+ var provider = services.BuildServiceProvider();
+
+ try
+ {
+ Ioc.Default.ConfigureServices(provider);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Failed to configure services");
+ }
+ Ioc.Default.AddStaticLogging();
+
+ return services.BuildServiceProvider();
+ }
+ public static void ConfigureServices(IServiceCollection services)
+ {
+ services.AddTransient();
+ services.AddSingleton();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+
+ services.AddTransient();
+ services.AddSingleton();
+
+ services.AddTransient();
+ services.AddSingleton();
+
+ services.AddSingleton(WeakReferenceMessenger.Default);
+ }
+}
diff --git a/SnapX.Avalonia/ViewLocator.cs b/SnapX.Avalonia/ViewLocator.cs
index 0bb7eb282..77cd51482 100644
--- a/SnapX.Avalonia/ViewLocator.cs
+++ b/SnapX.Avalonia/ViewLocator.cs
@@ -7,6 +7,7 @@
using SnapX.Avalonia.Views;
using SnapX.Avalonia.Views.Settings;
using SnapX.Avalonia.Views.Settings.Views;
+using SnapX.CommonUI.ViewModels;
namespace SnapX.Avalonia;
diff --git a/SnapX.Avalonia/ViewModels/HomePageViewModel.cs b/SnapX.Avalonia/ViewModels/HomePageViewModel.cs
index bb7cada92..6081980c8 100644
--- a/SnapX.Avalonia/ViewModels/HomePageViewModel.cs
+++ b/SnapX.Avalonia/ViewModels/HomePageViewModel.cs
@@ -4,8 +4,10 @@
using Avalonia.Input;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.Input;
-using SnapX.Avalonia.Models;
+using SnapX.Avalonia.Extensions;
using SnapX.Avalonia.Views;
+using SnapX.CommonUI.Models;
+using SnapX.CommonUI.ViewModels;
using SnapX.Core;
using SnapX.Core.Job;
using SnapX.Core.Upload;
@@ -16,78 +18,75 @@ namespace SnapX.Avalonia.ViewModels;
public partial class HomePageViewModel : ViewModelBase
{
public AvaloniaList SelectedTasks { get; set; } = [];
- public AvaloniaList recentTasks { get; set; } =
- [];
- private System.Timers.Timer _refreshTimer;
- private bool _isRefreshing; // Guard flag to prevent concurrent refreshes
+ public AvaloniaList recentTasks { get; set; } = [];
+ private readonly System.Timers.Timer _refreshTimer = new(5000); // Refresh every 5 seconds
+ private bool _isRefreshing;
private int _failedRefreshTasks;
- private DateTime _lastCacheTime = DateTime.MinValue;
- private List _cachedTasks;
- private readonly TimeSpan _cacheDuration = TimeSpan.FromSeconds(4);
-
public void InvalidateCache()
{
- _lastCacheTime = DateTime.MinValue;
- _cachedTasks = [];
- }
- public HomePageViewModel()
- {
- // ShowContextMenuCommand = new RelayCommand(ShowContextMenu);
- _refreshTimer = new System.Timers.Timer(5000); // Refresh every 5 seconds
}
+ // ShowContextMenuCommand = new RelayCommand(ShowContextMenu);
- public async Task Initialize()
+ public Task Initialize()
{
TaskManager.InitHistoryManager();
_refreshTimer.Elapsed += OnRefreshTimerElapsed;
_refreshTimer.AutoReset = true;
_refreshTimer.Start();
- RefreshTasks();
+ _ = RefreshTasks();
+ return Task.CompletedTask;
}
public void StopTimer() => _refreshTimer.Stop();
public void StartTimer() => _refreshTimer.Start();
private async void OnRefreshTimerElapsed(object sender, ElapsedEventArgs e)
{
- if (_isRefreshing)
- {
- DebugHelper.WriteLine("Previous timer run already in progress. Skipping this timer tick.");
- // Apply more conservative _refreshTimer interval when we know that there's a bunch of tasks.
- if (recentTasks.Count > 3000) _refreshTimer.Interval = 10_000;
- if (_failedRefreshTasks > 15) _refreshTimer.Interval = 30_000;
- if (_failedRefreshTasks > 10) _refreshTimer.Interval = 20_000;
- if (_failedRefreshTasks > 5) _refreshTimer.Interval = 10_000;
- if (_failedRefreshTasks > 19) _refreshTimer.Interval = 60_000;
- // Fuck it, give up.
- if (_failedRefreshTasks > 20) _refreshTimer.Stop();
- _failedRefreshTasks++;
- return;
- }
-
- _isRefreshing = true;
try
{
- // ConfigureAwait(false) is good practice here as it's background work.
- await RefreshTasks().ConfigureAwait(false);
+ if (_isRefreshing)
+ {
+ DebugHelper.WriteLine("Previous timer run already in progress. Skipping this timer tick.");
+ // Apply more conservative _refreshTimer interval when we know that there's a bunch of tasks.
+ if (recentTasks.Count > 3000) _refreshTimer.Interval = 10_000;
+ if (_failedRefreshTasks > 15) _refreshTimer.Interval = 30_000;
+ if (_failedRefreshTasks > 10) _refreshTimer.Interval = 20_000;
+ if (_failedRefreshTasks > 5) _refreshTimer.Interval = 10_000;
+ if (_failedRefreshTasks > 19) _refreshTimer.Interval = 60_000;
+ // Fuck it, give up.
+ if (_failedRefreshTasks > 20) _refreshTimer.Stop();
+ _failedRefreshTasks++;
+ return;
+ }
+
+ _isRefreshing = true;
+ try
+ {
+ await RefreshTasks().ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ DebugHelper.WriteException(ex);
+ }
+ finally
+ {
+ _isRefreshing = false;
+ }
}
catch (Exception ex)
{
- DebugHelper.WriteException(ex);
- }
- finally
- {
- _isRefreshing = false; // Reset the flag when the refresh is complete (or fails)
+ DebugHelper.WriteException(ex, "Error while refreshing tasks");
}
}
[RelayCommand]
public void ContextMenuSelection(object Sender)
{
- SelectedTasks.Add(Sender as ListTaskTemplate);
+ if (Sender is not ListTaskTemplate Template) return;
+ SelectedTasks.Add(Template);
}
[RelayCommand]
public void DeleteHistoryItemLocally(object Sender)
{
- var ltt = Sender as ListTaskTemplate;
+ if (Sender is not ListTaskTemplate ltt) return;
var task = ltt.task;
if (string.IsNullOrWhiteSpace(task.FilePath))
{
@@ -113,7 +112,7 @@ public void RemoveHistoryItem(object Sender)
if (Sender is not ListTaskTemplate ltt) return;
var task = ltt.task;
DebugHelper.WriteLine($"Removing {task.FilePath ?? task.FileName} (Id: {task.Id}) from history");
- var success = TaskManager.History.RemoveHistoryItem(task);
+ var success = TaskManager.History.RemoveHistoryItems([task]);
var status = success ? "Success" : "Failure";
DebugHelper.WriteLine($"{status} removing history item {task.FilePath ?? task.FileName}");
}
@@ -148,7 +147,7 @@ private void OnPointerPress(object sender, PointerPressedEventArgs e)
if (e.GetCurrentPoint(button).Properties.IsRightButtonPressed)
{
- // Right-click: Show context menu on the toggle button itself
+ // Right-click: Show a context menu on the toggle button itself
vm.ContextMenuSelectionCommand.Execute(button);
}
else if (e.GetCurrentPoint(button).Properties.IsLeftButtonPressed)
@@ -205,66 +204,61 @@ public async Task RefreshTasks()
{
var typeofVM = typeof(HomePageViewModel);
- List newDesiredTasks;
+ var historyItems = await TaskManager.History.GetHistoryItemsAsync().ConfigureAwait(false);
- // Check cache first
- if (DateTime.Now - _lastCacheTime < _cacheDuration && _cachedTasks != null)
- {
- newDesiredTasks = _cachedTasks;
- }
- else
- {
- var historyItems = await TaskManager.History.GetHistoryItemsAsync(30_000).ConfigureAwait(false);
+ var tasks = historyItems
+ .Select(task => new ListTaskTemplate(typeofVM, task))
+ .OrderByDescending(item => item.task.Id)
+ .ToList();
- var tasks = historyItems.Select(task => new ListTaskTemplate(typeofVM, task));
+ List toAdd = [];
+ List toUpdate = [];
+ List toRemove;
- newDesiredTasks = tasks
- .OrderByDescending(item => item.task.Id)
+ {
+ var currentTasksById = recentTasks.ToDictionary(t => t.task.Id);
+ var newTaskIds = tasks.Select(t => t.task.Id).ToHashSet();
+
+ toRemove = recentTasks
+ .Where(t => !newTaskIds.Contains(t.task.Id))
+ .Select(t => t.task.Id)
.ToList();
- _cachedTasks = newDesiredTasks;
- _lastCacheTime = DateTime.Now;
+ foreach (var newItem in tasks)
+ {
+ if (currentTasksById.TryGetValue(newItem.task.Id, out var existing))
+ {
+ if (!existing.Equals(newItem))
+ toUpdate.Add(newItem);
+ }
+ else
+ {
+ toAdd.Add(newItem);
+ }
+ }
}
-
+ // Warning: Computations on the UIThread are precious.
await Dispatcher.UIThread.InvokeAsync(() =>
{
- if (newDesiredTasks.Count > 50_000)
- {
- recentTasks.ResetBehavior = ResetBehavior.Remove;
- recentTasks.Clear();
- recentTasks.AddRange(newDesiredTasks);
- return;
- }
- var currentTasksById = recentTasks.ToDictionary(template => template.task.Id);
-
- var newDesiredTaskIds = newDesiredTasks.Select(template => template.task.Id).ToHashSet();
for (var i = recentTasks.Count - 1; i >= 0; i--)
{
- if (!newDesiredTaskIds.Contains(recentTasks[i].task.Id))
- {
+ if (toRemove.Contains(recentTasks[i].task.Id))
recentTasks.RemoveAt(i);
- }
}
- foreach (var newItem in newDesiredTasks)
+ foreach (var item in toUpdate)
{
- if (currentTasksById.TryGetValue(newItem.task.Id, out var existingItem))
- {
- if (existingItem.Equals(newItem))
- {
- continue;
- }
- var index = recentTasks.IndexOf(existingItem);
- if (index == -1) continue;
- recentTasks.RemoveAt(index);
- recentTasks.Insert(index, newItem);
- }
- else
- {
- recentTasks.Insert(0, newItem);
- }
+ var index = recentTasks.FindIndex(t => t.task.Id == item.task.Id);
+ if (index == -1) continue;
+ recentTasks.RemoveAt(index);
+ recentTasks.Insert(index, item);
+ }
+
+ foreach (var item in toAdd)
+ {
+ recentTasks.Insert(0, item);
}
- });
+ }).GetTask().ConfigureAwait(false);
}
}
diff --git a/SnapX.Avalonia/ViewModels/MainViewModel.cs b/SnapX.Avalonia/ViewModels/MainViewModel.cs
index 65f571d07..5a06bbd52 100644
--- a/SnapX.Avalonia/ViewModels/MainViewModel.cs
+++ b/SnapX.Avalonia/ViewModels/MainViewModel.cs
@@ -4,7 +4,8 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
-using SnapX.Avalonia.Models;
+using SnapX.CommonUI.Models;
+using SnapX.CommonUI.ViewModels;
namespace SnapX.Avalonia.ViewModels;
@@ -37,11 +38,9 @@ public MainViewModel() : this(new WeakReferenceMessenger()) { }
partial void OnSelectedListItemChanged(ListItemTemplate? value)
{
if (value is null) return;
-#pragma warning disable IL2072 // The code works, leave me alone
var vm = Design.IsDesignMode
? Activator.CreateInstance(value.ModelType)
: Ioc.Default.GetService(value.ModelType);
-#pragma warning restore IL2072
if (vm is not ViewModelBase vmb) return;
diff --git a/SnapX.Avalonia/Views/About/AboutWindow.axaml b/SnapX.Avalonia/Views/About/AboutWindow.axaml
index 142b5deae..66c648d5d 100644
--- a/SnapX.Avalonia/Views/About/AboutWindow.axaml
+++ b/SnapX.Avalonia/Views/About/AboutWindow.axaml
@@ -8,18 +8,18 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d"
- x:Class="SnapX.Avalonia.AboutWindow"
- x:DataType="viewModels:AboutWindowViewModel"
+ x:Class="SnapX.Avalonia.Views.About.AboutWindow"
+ x:DataType="viewModels1:AboutWindowViewModel"
xmlns="https://github.com/avaloniaui"
xmlns:avalonia="clr-namespace:FluentIcons.Avalonia;assembly=FluentIcons.Avalonia"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
- xmlns:viewModels="clr-namespace:SnapX.Avalonia.ViewModels"
+ xmlns:viewModels1="clr-namespace:SnapX.CommonUI.ViewModels;assembly=SnapX.CommonUI"
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
+
diff --git a/SnapX.Avalonia/Views/About/AboutWindow.axaml.cs b/SnapX.Avalonia/Views/About/AboutWindow.axaml.cs
index 6b88537e2..565a1ab4f 100644
--- a/SnapX.Avalonia/Views/About/AboutWindow.axaml.cs
+++ b/SnapX.Avalonia/Views/About/AboutWindow.axaml.cs
@@ -8,11 +8,11 @@
using FluentAvalonia.Styling;
using FluentAvalonia.UI.Media;
using FluentAvalonia.UI.Windowing;
-using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.ViewModels;
using SnapX.Core;
using SnapX.Core.Utils;
-namespace SnapX.Avalonia;
+namespace SnapX.Avalonia.Views.About;
public partial class AboutWindow : AppWindow
{
diff --git a/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml b/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml
index b4cd64994..7902f1f07 100644
--- a/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml
+++ b/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml
@@ -4,17 +4,16 @@
d:DesignWidth="800"
mc:Ignorable="d"
x:Class="SnapX.Avalonia.Views.Controls.ChangelogControl"
- x:DataType="viewModels:ChangelogViewModel"
+ x:DataType="viewModels1:ChangelogViewModel"
xmlns="https://github.com/avaloniaui"
xmlns:commonUi="clr-namespace:SnapX.CommonUI;assembly=SnapX.CommonUI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:fa="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:markdown="clr-namespace:Markdown.Avalonia;assembly=Markdown.Avalonia"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:viewModels="clr-namespace:SnapX.Avalonia.ViewModels"
+ xmlns:viewModels1="clr-namespace:SnapX.CommonUI.ViewModels;assembly=SnapX.CommonUI"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
+
diff --git a/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml.cs b/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml.cs
index 14c482f8d..0b77b4bea 100644
--- a/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml.cs
+++ b/SnapX.Avalonia/Views/Controls/ChangelogControl.axaml.cs
@@ -1,6 +1,6 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
-using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.ViewModels;
namespace SnapX.Avalonia.Views.Controls;
diff --git a/SnapX.Avalonia/Views/HomePageView.axaml b/SnapX.Avalonia/Views/HomePageView.axaml
index 6e1b0a87f..fa55ff047 100644
--- a/SnapX.Avalonia/Views/HomePageView.axaml
+++ b/SnapX.Avalonia/Views/HomePageView.axaml
@@ -15,7 +15,7 @@
xmlns:extensions="clr-namespace:SnapX.Avalonia.Extensions"
xmlns:fluent1="clr-namespace:FluentIcons.Avalonia.Fluent;assembly=FluentIcons.Avalonia.Fluent"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:models="clr-namespace:SnapX.Avalonia.Models"
+ xmlns:models="clr-namespace:SnapX.CommonUI.Models;assembly=SnapX.CommonUI"
xmlns:viewModels1="clr-namespace:SnapX.Avalonia.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
diff --git a/SnapX.Avalonia/Views/HomePageView.axaml.cs b/SnapX.Avalonia/Views/HomePageView.axaml.cs
index 75d2e1b14..2bd406392 100644
--- a/SnapX.Avalonia/Views/HomePageView.axaml.cs
+++ b/SnapX.Avalonia/Views/HomePageView.axaml.cs
@@ -2,8 +2,8 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using FluentAvalonia.UI.Controls;
-using SnapX.Avalonia.Models;
using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.Models;
using SnapX.Core;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Miscellaneous;
diff --git a/SnapX.Avalonia/Views/LogViewer.axaml b/SnapX.Avalonia/Views/LogViewer.axaml
index 70bcf458d..af946522e 100644
--- a/SnapX.Avalonia/Views/LogViewer.axaml
+++ b/SnapX.Avalonia/Views/LogViewer.axaml
@@ -1,7 +1,7 @@
RefreshLogs();
}
- private void AppWindow_OnLoaded(object? sender, RoutedEventArgs e)
+ private void AppWindow_OnLoaded(object? sender, EventArgs e)
{
- _scrollViewer = this.FindControl("ScrollViewer");
- _logTextBlock = this.FindControl("LogTextBlock");
- _lastDisplayedLogCount = 0;
- _refreshTimer.Start();
+ RefreshLogs();
+ DebugHelper.observableSink.LogMessageReceived += (_, _) => RefreshLogs();
}
private void AppWindow_OnClosed(object? sender, EventArgs e)
{
_lastDisplayedLogCount = 0;
- _refreshTimer.Stop();
}
private void Close_Click(object? sender, RoutedEventArgs e) => Close();
private void RefreshLogs()
{
- if (DebugHelper.LogEvents.Count() <= _lastDisplayedLogCount) return;
- for (var i = _lastDisplayedLogCount; i < DebugHelper.LogEvents.Count(); i++)
+ _scrollViewer = this.FindControl("ScrollViewer");
+ _logTextBlock = this.FindControl("LogTextBlock");
+ var bufferedEvents = DebugHelper.observableSink.GetBufferedEvents();
+ for (var i = _lastDisplayedLogCount; i < bufferedEvents.Count; i++)
{
- var logEvent = DebugHelper.LogEvents.ElementAt(i);
+ var logEvent = DebugHelper.observableSink.GetBufferedEvents().ElementAt(i);
var timestamp = logEvent.Timestamp.ToString("hh:mm:ss");
var level = logEvent.Level.ToString().ToUpper();
if (level == "INFORMATION") level = "INFO";
@@ -64,7 +56,7 @@ private void RefreshLogs()
_logTextBlock.Inlines!.Add(new Run($"{timestamp} ")
{
- Foreground = Brushes.DimGray // Use DimGray for a softer grey that works well on dark backgrounds
+ Foreground = Brushes.DimGray
});
_logTextBlock.Inlines.Add(new Run($"[{level}] ")
@@ -81,7 +73,7 @@ private void RefreshLogs()
Foreground = Brushes.DarkRed
});
}
- _lastDisplayedLogCount = DebugHelper.LogEvents.Count();
+ _lastDisplayedLogCount = bufferedEvents.Count;
}
}
private IBrush GetBrushForLevel(LogEventLevel level)
@@ -92,66 +84,66 @@ private IBrush GetBrushForLevel(LogEventLevel level)
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
- GradientStops = new GradientStops
- {
- new GradientStop(Color.FromRgb(60, 60, 60), 0),
- new GradientStop(Color.FromRgb(40, 40, 40), 1)
- }
+ GradientStops =
+ [
+ new GradientStop(Color.FromRgb(60, 60, 60), 0),
+ new GradientStop(Color.FromRgb(40, 40, 40), 1)
+ ]
},
LogEventLevel.Debug => new LinearGradientBrush
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
- GradientStops = new GradientStops
- {
- new GradientStop(Color.FromRgb(50, 100, 150), 0),
- new GradientStop(Color.FromRgb(30, 70, 120), 1)
- }
+ GradientStops =
+ [
+ new GradientStop(Color.FromRgb(50, 100, 150), 0),
+ new GradientStop(Color.FromRgb(30, 70, 120), 1)
+ ]
},
LogEventLevel.Information => new LinearGradientBrush
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
- GradientStops = new GradientStops
- {
- new GradientStop(Color.FromRgb(70, 130, 70), 0),
- new GradientStop(Color.FromRgb(40, 90, 40), 1)
- }
+ GradientStops =
+ [
+ new GradientStop(Color.FromRgb(70, 130, 70), 0),
+ new GradientStop(Color.FromRgb(40, 90, 40), 1)
+ ]
},
LogEventLevel.Warning => new LinearGradientBrush
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
- GradientStops = new GradientStops
- {
- new GradientStop(Color.FromRgb(200, 160, 0), 0),
- new GradientStop(Color.FromRgb(150, 110, 0), 1)
- }
+ GradientStops =
+ [
+ new GradientStop(Color.FromRgb(200, 160, 0), 0),
+ new GradientStop(Color.FromRgb(150, 110, 0), 1)
+ ]
},
LogEventLevel.Error => new LinearGradientBrush
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
- GradientStops = new GradientStops
- {
- new GradientStop(Color.FromRgb(180, 50, 50), 0),
- new GradientStop(Color.FromRgb(130, 30, 30), 1)
- }
+ GradientStops =
+ [
+ new GradientStop(Color.FromRgb(180, 50, 50), 0),
+ new GradientStop(Color.FromRgb(130, 30, 30), 1)
+ ]
},
LogEventLevel.Fatal => new LinearGradientBrush
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
- GradientStops = new GradientStops
- {
- new GradientStop(Color.FromRgb(100, 0, 0), 0),
- new GradientStop(Color.FromRgb(30, 0, 0), 1)
- }
+ GradientStops =
+ [
+ new GradientStop(Color.FromRgb(100, 0, 0), 0),
+ new GradientStop(Color.FromRgb(30, 0, 0), 1)
+ ]
},
_ => new SolidColorBrush(Colors.DimGray)
@@ -170,13 +162,13 @@ private void OpenLogFolderButton_OnClick(object? Sender, RoutedEventArgs E)
private void UploadLogButton_OnClick(object? Sender, RoutedEventArgs E)
{
- UploadManager.UploadText(_logTextBlock.Inlines?.OfType()
+ UploadManager.UploadText(_logTextBlock?.Inlines?.OfType()
.Aggregate("", (current, run) => current + run.Text)!);
}
private void CopyButton_OnClick(object? Sender, RoutedEventArgs E)
{
- Clipboard?.SetTextAsync(_logTextBlock.Inlines?.OfType().Aggregate("", (current, run) => current + run.Text)!);
+ Clipboard?.SetTextAsync(_logTextBlock?.Inlines?.OfType().Aggregate("", (current, run) => current + run.Text)!);
}
private void LogTextBlock_OnSizeChanged(object? Sender, SizeChangedEventArgs e)
diff --git a/SnapX.Avalonia/Views/MainView.axaml.cs b/SnapX.Avalonia/Views/MainView.axaml.cs
index df5806ca7..ebf22deeb 100644
--- a/SnapX.Avalonia/Views/MainView.axaml.cs
+++ b/SnapX.Avalonia/Views/MainView.axaml.cs
@@ -3,7 +3,7 @@
using Avalonia.LogicalTree;
using CommunityToolkit.Mvvm.Input;
using FluentAvalonia.UI.Controls;
-using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.ViewModels;
using SnapX.Core;
using SnapX.Core.Job;
using SnapX.Core.Upload;
diff --git a/SnapX.Avalonia/Views/MainWindow.axaml.cs b/SnapX.Avalonia/Views/MainWindow.axaml.cs
index 2c3c11ee0..d9a9e67c0 100644
--- a/SnapX.Avalonia/Views/MainWindow.axaml.cs
+++ b/SnapX.Avalonia/Views/MainWindow.axaml.cs
@@ -1,9 +1,7 @@
using Avalonia;
using Avalonia.Controls;
-using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Media.Immutable;
-using Avalonia.Platform.Storage;
using Avalonia.Styling;
using FluentAvalonia.Styling;
using FluentAvalonia.UI.Media;
@@ -13,7 +11,6 @@
using SnapX.Avalonia.Views.Controls;
using SnapX.Core;
using SnapX.Core.Job;
-using SnapX.Core.Upload;
using SnapX.Core.Utils;
using Color = Avalonia.Media.Color;
@@ -53,48 +50,9 @@ public MainWindow(MainViewModel vm)
Position = new PixelPoint(config.MainFormPosition.X, config.MainFormPosition.Y);
}
InitializeComponent();
- ListenForEvents();
}
public MainWindow() : this(new MainViewModel()) { }
- public void ListenForEvents()
- {
- Core.SnapX.EventAggregator.Subscribe(HandleFileSelectionRequested);
- }
- private async void HandleFileSelectionRequested(NeedFileOpenerEvent @event)
- {
- var topLevel = TopLevel.GetTopLevel(this);
- var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- Title = @event.Title,
- AllowMultiple = @event.Multiselect,
- SuggestedFileName = @event.FileName,
- SuggestedStartLocation = await StorageProvider.TryGetFolderFromPathAsync(@event.Directory)
- });
-
- if (files.Count > 0)
- {
- string?[] filePaths = files.Select(f => f.Path.ToString()).ToArray();
- UploadManager.UploadFile(filePaths, @event.TaskSettings);
- }
- }
-
- // Event handler for the button click
- private void OnDemoTestButtonClick(object sender, RoutedEventArgs e)
- {
- DebugHelper.WriteLine("Upload Demo Image triggered");
-
- // try
- // {
- // var imageUrl = ImageURLTextBox.Text ?? ImageURLTextBox.Watermark;
- // UploadManager.DownloadAndUploadFile(imageUrl!);
- // }
- // catch (Exception ex)
- // {
- // DebugHelper.Logger.Error(ex.ToString());
- // }
- }
-
private void ApplicationActualThemeVariantChanged(object? sender, EventArgs e)
{
if (!OperatingSystem.IsWindows()) return;
diff --git a/SnapX.Avalonia/Views/OCR.axaml b/SnapX.Avalonia/Views/OCR.axaml
index 52faf3554..a5e676217 100644
--- a/SnapX.Avalonia/Views/OCR.axaml
+++ b/SnapX.Avalonia/Views/OCR.axaml
@@ -6,7 +6,7 @@
x:Class="SnapX.Avalonia.Views.OCR"
x:DataType="viewModels:OCRViewModel"
xmlns="https://github.com/avaloniaui"
- xmlns:viewModels="clr-namespace:SnapX.Avalonia.ViewModels"
+ xmlns:viewModels="clr-namespace:SnapX.CommonUI.ViewModels;assembly=SnapX.CommonUI"
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
diff --git a/SnapX.Avalonia/Views/OCR.axaml.cs b/SnapX.Avalonia/Views/OCR.axaml.cs
index 3cd0d93ef..2ae007f6a 100644
--- a/SnapX.Avalonia/Views/OCR.axaml.cs
+++ b/SnapX.Avalonia/Views/OCR.axaml.cs
@@ -1,7 +1,7 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using FluentAvalonia.UI.Windowing;
-using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.ViewModels;
using SnapX.Core;
using SnapX.Core.History;
using SnapX.Core.Utils;
diff --git a/SnapX.Avalonia/Views/RegionSelectorWindow.axaml b/SnapX.Avalonia/Views/RegionSelectorWindow.axaml
index ea4390048..f00e9b865 100644
--- a/SnapX.Avalonia/Views/RegionSelectorWindow.axaml
+++ b/SnapX.Avalonia/Views/RegionSelectorWindow.axaml
@@ -24,7 +24,7 @@
xmlns="https://github.com/avaloniaui"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:viewModels="clr-namespace:SnapX.Avalonia.ViewModels"
+ xmlns:viewModels="clr-namespace:SnapX.CommonUI.ViewModels;assembly=SnapX.CommonUI"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
diff --git a/SnapX.Avalonia/Views/RegionSelectorWindow.axaml.cs b/SnapX.Avalonia/Views/RegionSelectorWindow.axaml.cs
index 7f08ec7ce..33d301613 100644
--- a/SnapX.Avalonia/Views/RegionSelectorWindow.axaml.cs
+++ b/SnapX.Avalonia/Views/RegionSelectorWindow.axaml.cs
@@ -8,7 +8,7 @@
using Avalonia.Threading;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
-using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.ViewModels;
using SnapX.Core;
using SnapX.Core.Job;
using SnapX.Core.Upload;
diff --git a/SnapX.Avalonia/Views/Settings/SettingsWindow.axaml.cs b/SnapX.Avalonia/Views/Settings/SettingsWindow.axaml.cs
index cf275b9c8..984136645 100644
--- a/SnapX.Avalonia/Views/Settings/SettingsWindow.axaml.cs
+++ b/SnapX.Avalonia/Views/Settings/SettingsWindow.axaml.cs
@@ -1,5 +1,5 @@
using FluentAvalonia.UI.Windowing;
-using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.ViewModels;
namespace SnapX.Avalonia.Views.Settings;
diff --git a/SnapX.Avalonia/Views/Settings/Views/SettingsHomePageView.axaml.cs b/SnapX.Avalonia/Views/Settings/Views/SettingsHomePageView.axaml.cs
index dec3c44b0..5a231e25d 100644
--- a/SnapX.Avalonia/Views/Settings/Views/SettingsHomePageView.axaml.cs
+++ b/SnapX.Avalonia/Views/Settings/Views/SettingsHomePageView.axaml.cs
@@ -1,18 +1,16 @@
using Avalonia.Controls;
using Avalonia.Media;
-using SnapX.Avalonia.ViewModels;
+using SnapX.CommonUI.ViewModels;
using SnapX.Core;
namespace SnapX.Avalonia.Views.Settings.Views;
public partial class SettingsHomePageView : UserControl
{
- private SettingsHomePageViewVM ViewModel;
public SettingsHomePageView(SettingsHomePageViewVM vm)
{
DataContext = vm;
- ViewModel = vm;
InitializeComponent();
var itemsAsList = FontManager.Current.SystemFonts
.OrderBy(font => font.Name)
diff --git a/SnapX.Avalonia/Views/Settings/Views/SettingsMainView.axaml b/SnapX.Avalonia/Views/Settings/Views/SettingsMainView.axaml
index 4958c2476..4292005c5 100644
--- a/SnapX.Avalonia/Views/Settings/Views/SettingsMainView.axaml
+++ b/SnapX.Avalonia/Views/Settings/Views/SettingsMainView.axaml
@@ -3,18 +3,18 @@
d:DesignWidth="800"
mc:Ignorable="d"
x:Class="SnapX.Avalonia.Views.Settings.Views.SettingsMainView"
- x:DataType="viewModels1:SettingsMainViewVM"
+ x:DataType="viewModels:SettingsMainViewVM"
xmlns="https://github.com/avaloniaui"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:core="clr-namespace:SnapX.Core;assembly=SnapX.Core"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fluent="clr-namespace:FluentIcons.Avalonia.Fluent;assembly=FluentIcons.Avalonia.Fluent"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:viewModels1="clr-namespace:SnapX.Avalonia.ViewModels"
xmlns:views="clr-namespace:SnapX.Avalonia.Views.Settings.Views"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:viewModels="clr-namespace:SnapX.CommonUI.ViewModels;assembly=SnapX.CommonUI">
-
+
true
snapx
SnapX CLI
+ SnapX.CLI.Tests
diff --git a/SnapX.CommonUI/Changelog.cs b/SnapX.CommonUI/Changelog.cs
index 3e39940f0..a7f7fcbad 100644
--- a/SnapX.CommonUI/Changelog.cs
+++ b/SnapX.CommonUI/Changelog.cs
@@ -21,17 +21,18 @@ internal partial class ChangelogContext : JsonSerializerContext;
public abstract class Changelog
{
private static readonly HttpClient Client = HttpClientFactory.Get();
- public string Version { get; init; }
- public Version versionSemver;
- public int major;
- public int minor;
- public int patch;
+ protected string Version { get; init; }
+ private readonly Version versionSemver;
+ private readonly int major;
+ private readonly int minor;
+ private readonly int patch;
- public JsonSerializerOptions Options = new()
+ private readonly JsonSerializerOptions Options = new()
{
TypeInfoResolver = ChangelogContext.Default
};
- public Changelog(string version)
+
+ protected Changelog(string version)
{
Version = version;
versionSemver = new Version(version);
@@ -42,8 +43,8 @@ public Changelog(string version)
public record ChangelogVersion
{
- public string Version { get; set; }
- public string Content { get; set; }
+ public string Version { get; set; } = "0.0.0";
+ public string Content { get; set; } = "";
}
public virtual async Task GetChangeSummary()
{
@@ -78,7 +79,7 @@ private bool IsValidChangelog(string changelog)
return false;
}
#if DEBUG
- DebugHelper.WriteLine($"Validating changelog: {changelog?.Substring(0, Math.Min(100, changelog.Length))}...");
+ DebugHelper.WriteLine($"Validating changelog: {changelog[..Math.Min(100, changelog.Length)]}...");
#endif
return changelog!.Length > 4;
}
@@ -158,7 +159,7 @@ private async Task GetTagsSinceVersion()
})
.Select(tag =>
{
- var firstLineOfMessage = tag.Commit?.Message?.Split('\n').FirstOrDefault()?.Trim();
+ var firstLineOfMessage = tag.Commit?.Message.Split('\n').FirstOrDefault()?.Trim();
return $"Tag: {tag.Name} - {firstLineOfMessage}";
})
.ToList();
@@ -180,7 +181,7 @@ private async Task GetBuildSummaryFromActions()
return string.Empty;
var buildSummaries = actions.WorkflowRuns
- .Where(run => (run?.RunNumber > patch) && (run.Name.Contains("build", StringComparison.OrdinalIgnoreCase)) && run.Status.Contains("success", StringComparison.InvariantCultureIgnoreCase))
+ .Where(run => run.RunNumber > patch && (run.Name.Contains("build", StringComparison.OrdinalIgnoreCase)) && run.Status.Contains("success", StringComparison.InvariantCultureIgnoreCase))
.Select(run => $"{run.Name} #{run.RunNumber}: {run.DisplayTitle} - {run.Actor.Login}")
.ToList();
@@ -234,13 +235,12 @@ private async Task GetRecentCommits()
/// Defaults to splitting on two or more consecutive newline sequences.
///
/// An enumerable of individual changelog entries.
- /// Thrown if changelogs is null.
+ /// Thrown if changelogs are null.
public static IEnumerable SeparateChangelogEntries(
IEnumerable changelogs,
string? pattern = null)
{
- if (changelogs == null)
- throw new ArgumentNullException(nameof(changelogs));
+ ArgumentNullException.ThrowIfNull(changelogs);
// Default pattern for separating traditional multi-line changelog entries
pattern ??= @"(?:\r?\n){2,}";
diff --git a/SnapX.Avalonia/Models/ListItemTemplate.cs b/SnapX.CommonUI/Models/ListItemTemplate.cs
similarity index 68%
rename from SnapX.Avalonia/Models/ListItemTemplate.cs
rename to SnapX.CommonUI/Models/ListItemTemplate.cs
index e5052b228..886b05d28 100644
--- a/SnapX.Avalonia/Models/ListItemTemplate.cs
+++ b/SnapX.CommonUI/Models/ListItemTemplate.cs
@@ -1,3 +1,3 @@
-namespace SnapX.Avalonia.Models;
+namespace SnapX.CommonUI.Models;
public record ListItemTemplate(Type ModelType, string IconKey, string Label);
diff --git a/SnapX.Avalonia/Models/ListTaskTemplate.cs b/SnapX.CommonUI/Models/ListTaskTemplate.cs
similarity index 74%
rename from SnapX.Avalonia/Models/ListTaskTemplate.cs
rename to SnapX.CommonUI/Models/ListTaskTemplate.cs
index e1c2fd307..73b2f7eff 100644
--- a/SnapX.Avalonia/Models/ListTaskTemplate.cs
+++ b/SnapX.CommonUI/Models/ListTaskTemplate.cs
@@ -1,5 +1,5 @@
using SnapX.Core.History;
-namespace SnapX.Avalonia.Models;
+namespace SnapX.CommonUI.Models;
public record ListTaskTemplate(Type ModelType, HistoryItem task);
diff --git a/SnapX.CommonUI/SnapX.CommonUI.csproj b/SnapX.CommonUI/SnapX.CommonUI.csproj
index 9f2367792..4e84d305d 100644
--- a/SnapX.CommonUI/SnapX.CommonUI.csproj
+++ b/SnapX.CommonUI/SnapX.CommonUI.csproj
@@ -9,5 +9,6 @@
+
diff --git a/SnapX.CommonUI/TaskThumbnailView.cs b/SnapX.CommonUI/TaskThumbnailView.cs
index 2696445c1..af5bdc35d 100644
--- a/SnapX.CommonUI/TaskThumbnailView.cs
+++ b/SnapX.CommonUI/TaskThumbnailView.cs
@@ -57,7 +57,7 @@ private Image CreateThumbnail(string? filePath = null, Image? img = null)
if (img != null) return ImageHelpers.ResizeImage(img, ThumbnailSize, false);
if (string.IsNullOrWhiteSpace(filePath)) filePath = Task.Info.FileName;
else if (File.Exists(filePath)) return ImageHelpers.ResizeImage(Image.Load(filePath), ThumbnailSize, true);
- if (string.IsNullOrEmpty(filePath)) return null; // TODO: Embed error image
+ if (string.IsNullOrEmpty(filePath)) return Image.Load([]); // TODO: Embed error image
var icon = Methods.GetJumboFileIcon(filePath, false);
return ImageHelpers.ResizeImage(icon, ThumbnailSize, false, true);
}
diff --git a/SnapX.CommonUI/Types/CommitTypes.cs b/SnapX.CommonUI/Types/CommitTypes.cs
index 7a6375af0..988643902 100644
--- a/SnapX.CommonUI/Types/CommitTypes.cs
+++ b/SnapX.CommonUI/Types/CommitTypes.cs
@@ -32,13 +32,13 @@ public record Author(
);
public record Commit(
- [property: JsonPropertyName("author")] Author Author,
- [property: JsonPropertyName("committer")] Committer Committer,
+ [property: JsonPropertyName("author")] Author? Author,
+ [property: JsonPropertyName("committer")] Committer? Committer,
[property: JsonPropertyName("message")] string Message,
- [property: JsonPropertyName("tree")] Tree Tree,
+ [property: JsonPropertyName("tree")] Tree? Tree,
[property: JsonPropertyName("html_url")] string Url,
[property: JsonPropertyName("comment_count")] int? CommentCount,
- [property: JsonPropertyName("verification")] Verification Verification
+ [property: JsonPropertyName("verification")] Verification? Verification
);
public record Committer(
@@ -75,13 +75,13 @@ public record Parent(
public record Root(
[property: JsonPropertyName("sha")] string Sha,
[property: JsonPropertyName("node_id")] string NodeId,
- [property: JsonPropertyName("commit")] Commit Commit,
+ [property: JsonPropertyName("commit")] Commit? Commit,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("html_url")] string HtmlUrl,
[property: JsonPropertyName("comments_url")] string CommentsUrl,
- [property: JsonPropertyName("author")] Author Author,
- [property: JsonPropertyName("committer")] Committer Committer,
- [property: JsonPropertyName("parents")] IReadOnlyList Parents
+ [property: JsonPropertyName("author")] Author? Author,
+ [property: JsonPropertyName("committer")] Committer? Committer,
+ [property: JsonPropertyName("parents")] IReadOnlyList? Parents
);
diff --git a/SnapX.CommonUI/Types/TagTypes.cs b/SnapX.CommonUI/Types/TagTypes.cs
index f14e3b71b..b28547f72 100644
--- a/SnapX.CommonUI/Types/TagTypes.cs
+++ b/SnapX.CommonUI/Types/TagTypes.cs
@@ -8,6 +8,6 @@ public record Tag(
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("zipball_url")] string ZipballUrl,
[property: JsonPropertyName("tarball_url")] string TarballUrl,
- [property: JsonPropertyName("commit")] Commit Commit,
+ [property: JsonPropertyName("commit")] Commit? Commit,
[property: JsonPropertyName("node_id")] string NodeId
);
diff --git a/SnapX.Avalonia/ViewModels/AboutWindowViewModel.cs b/SnapX.CommonUI/ViewModels/AboutWindowViewModel.cs
similarity index 71%
rename from SnapX.Avalonia/ViewModels/AboutWindowViewModel.cs
rename to SnapX.CommonUI/ViewModels/AboutWindowViewModel.cs
index aa1e9c0d7..0382d98a9 100644
--- a/SnapX.Avalonia/ViewModels/AboutWindowViewModel.cs
+++ b/SnapX.CommonUI/ViewModels/AboutWindowViewModel.cs
@@ -1,16 +1,15 @@
using System.Diagnostics.CodeAnalysis;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
-using SnapX.CommonUI;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Miscellaneous;
-namespace SnapX.Avalonia.ViewModels;
+namespace SnapX.CommonUI.ViewModels;
public partial class AboutWindowViewModel : ViewModelBase
{
// Internal instance of the base class (SnapX.CommonUI.AboutDialog)
- private AboutDialog _commonAboutDialog = new();
+ private readonly AboutDialog _commonAboutDialog = new();
[UnconditionalSuppressMessage("Trimming",
"IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code",
@@ -18,12 +17,11 @@ public partial class AboutWindowViewModel : ViewModelBase
RelayCommand]
private Task InitDataAsync()
{
- var combinedLoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies()
- .Concat(App.SnapX.GetAssemblies())
- .Distinct();
+ var combinedLoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
LoadedAssemblies = string.Join(Environment.NewLine, combinedLoadedAssemblies
.Where(a => a.GetName().Name != null)
.Where(a =>
+#pragma warning disable CS8602 // Dereference of a possibly null reference.
!a.GetName().Name.StartsWith("System") &&
!a.GetName().Name.StartsWith("SnapX", StringComparison.OrdinalIgnoreCase) &&
!a.GetName().Name.StartsWith("Anonymous", StringComparison.OrdinalIgnoreCase) &&
@@ -40,8 +38,10 @@ private Task InitDataAsync()
.Select(g => g.Count() > 1
? $"{g.Key} {g.First().Version.Major}.{g.First().Version.Minor}.{g.First().Version.Build}"
: $"{g.First().Name} {g.First().Version.Major}.{g.First().Version.Minor}.{g.First().Version.Build}")
- .Append($"SQLite {Core.SnapX.DbConnection.ServerVersion}")
+ .Append($"SQLite {Core.SnapX.DbConnection?.ServerVersion}")
.OrderBy(name => name));
+#pragma warning restore CS8602 // Dereference of a possibly null reference.
+
Description = _commonAboutDialog.GetDescription();
Version = _commonAboutDialog.GetVersion();
Copyright = _commonAboutDialog.GetCopyright();
@@ -59,48 +59,21 @@ private Task InitDataAsync()
SystemInformationText = $"{SystemInfo} ({OsArchitecture}, {OsPlatform}) powered by {Runtime}!";
return Task.CompletedTask;
}
- [ObservableProperty]
- public string dialogTitle = Lang.AboutSnapX;
- [ObservableProperty]
- private string? description;
- [ObservableProperty]
- public string? buildInformation;
- [ObservableProperty]
-
- public string? version;
- [ObservableProperty]
- public string? copyright;
- [ObservableProperty]
-
- public string? license;
- [ObservableProperty]
-
- public string? website;
- [ObservableProperty]
-
- public string? systemInfo;
- [ObservableProperty]
-
- public string? osArchitecture;
- [ObservableProperty]
-
- public string? runtime;
- [ObservableProperty]
-
- public string? osPlatform;
- [ObservableProperty]
-
- public string? documentation;
- [ObservableProperty]
-
- public string? issues;
- [ObservableProperty]
- public string? discord;
- [ObservableProperty]
- public string? donate;
- [ObservableProperty]
- public string? loadedAssemblies;
-
- [ObservableProperty]
- public string? systemInformationText;
+ [ObservableProperty] private string dialogTitle = Lang.AboutSnapX;
+ [ObservableProperty] private string? description;
+ [ObservableProperty] private string? buildInformation;
+ [ObservableProperty] private string? version;
+ [ObservableProperty] private string? copyright;
+ [ObservableProperty] private string? license;
+ [ObservableProperty] private string? website;
+ [ObservableProperty] private string? systemInfo;
+ [ObservableProperty] private string? osArchitecture;
+ [ObservableProperty] private string? runtime;
+ [ObservableProperty] private string? osPlatform;
+ [ObservableProperty] private string? documentation;
+ [ObservableProperty] private string? issues;
+ [ObservableProperty] private string? discord;
+ [ObservableProperty] private string? donate;
+ [ObservableProperty] private string? loadedAssemblies;
+ [ObservableProperty] private string? systemInformationText;
}
diff --git a/SnapX.Avalonia/ViewModels/AvaloniaChangelog.cs b/SnapX.CommonUI/ViewModels/AvaloniaChangelog.cs
similarity index 89%
rename from SnapX.Avalonia/ViewModels/AvaloniaChangelog.cs
rename to SnapX.CommonUI/ViewModels/AvaloniaChangelog.cs
index 19360251d..92c32c2c5 100644
--- a/SnapX.Avalonia/ViewModels/AvaloniaChangelog.cs
+++ b/SnapX.CommonUI/ViewModels/AvaloniaChangelog.cs
@@ -1,4 +1,4 @@
-namespace SnapX.Avalonia;
+namespace SnapX.CommonUI.ViewModels;
public class AvaloniaChangelog : SnapX.CommonUI.Changelog
{
diff --git a/SnapX.Avalonia/ViewModels/ChangelogViewModel.cs b/SnapX.CommonUI/ViewModels/ChangelogViewModel.cs
similarity index 85%
rename from SnapX.Avalonia/ViewModels/ChangelogViewModel.cs
rename to SnapX.CommonUI/ViewModels/ChangelogViewModel.cs
index 633d13885..0526cab1e 100644
--- a/SnapX.Avalonia/ViewModels/ChangelogViewModel.cs
+++ b/SnapX.CommonUI/ViewModels/ChangelogViewModel.cs
@@ -1,14 +1,13 @@
-using Avalonia.Collections;
+using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
-using SnapX.CommonUI;
using SnapX.Core.Utils;
-namespace SnapX.Avalonia.ViewModels;
+namespace SnapX.CommonUI.ViewModels;
public partial class ChangelogViewModel : ViewModelBase
{
- public AvaloniaList Versions { get; } = [];
+ public ObservableCollection Versions { get; } = [];
[ObservableProperty]
public Changelog.ChangelogVersion selectedChangelogVersion = new();
diff --git a/SnapX.Avalonia/ViewModels/OCRViewModel.cs b/SnapX.CommonUI/ViewModels/OCRViewModel.cs
similarity index 98%
rename from SnapX.Avalonia/ViewModels/OCRViewModel.cs
rename to SnapX.CommonUI/ViewModels/OCRViewModel.cs
index de9742e19..f014cd0de 100644
--- a/SnapX.Avalonia/ViewModels/OCRViewModel.cs
+++ b/SnapX.CommonUI/ViewModels/OCRViewModel.cs
@@ -5,7 +5,7 @@
using SnapX.Core.Utils;
using Image = SixLabors.ImageSharp.Image;
-namespace SnapX.Avalonia.ViewModels;
+namespace SnapX.CommonUI.ViewModels;
public partial class OCRViewModel : ViewModelBase
{
diff --git a/SnapX.Avalonia/ViewModels/RegionSelectorViewModel.cs b/SnapX.CommonUI/ViewModels/RegionSelectorViewModel.cs
similarity index 81%
rename from SnapX.Avalonia/ViewModels/RegionSelectorViewModel.cs
rename to SnapX.CommonUI/ViewModels/RegionSelectorViewModel.cs
index cc8ec1f88..a2b91578b 100644
--- a/SnapX.Avalonia/ViewModels/RegionSelectorViewModel.cs
+++ b/SnapX.CommonUI/ViewModels/RegionSelectorViewModel.cs
@@ -1,4 +1,4 @@
-namespace SnapX.Avalonia.ViewModels;
+namespace SnapX.CommonUI.ViewModels;
public partial class RegionSelectorViewModel : ViewModelBase
{
private int Width;
diff --git a/SnapX.Avalonia/ViewModels/SettingsHomePageViewVM.cs b/SnapX.CommonUI/ViewModels/SettingsHomePageViewVM.cs
similarity index 61%
rename from SnapX.Avalonia/ViewModels/SettingsHomePageViewVM.cs
rename to SnapX.CommonUI/ViewModels/SettingsHomePageViewVM.cs
index e6823e461..2b22bc0e2 100644
--- a/SnapX.Avalonia/ViewModels/SettingsHomePageViewVM.cs
+++ b/SnapX.CommonUI/ViewModels/SettingsHomePageViewVM.cs
@@ -1,4 +1,4 @@
-namespace SnapX.Avalonia.ViewModels;
+namespace SnapX.CommonUI.ViewModels;
public class SettingsHomePageViewVM : ViewModelBase
{
diff --git a/SnapX.Avalonia/ViewModels/SettingsMainViewVM.cs b/SnapX.CommonUI/ViewModels/SettingsMainViewVM.cs
similarity index 65%
rename from SnapX.Avalonia/ViewModels/SettingsMainViewVM.cs
rename to SnapX.CommonUI/ViewModels/SettingsMainViewVM.cs
index 9745f5492..d1b82b018 100644
--- a/SnapX.Avalonia/ViewModels/SettingsMainViewVM.cs
+++ b/SnapX.CommonUI/ViewModels/SettingsMainViewVM.cs
@@ -1,10 +1,9 @@
-using Avalonia.Collections;
-using Avalonia.Controls;
+using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
-using SnapX.Avalonia.Models;
+using SnapX.CommonUI.Models;
-namespace SnapX.Avalonia.ViewModels;
+namespace SnapX.CommonUI.ViewModels;
public partial class SettingsMainViewVM : ViewModelBase
{
@@ -15,23 +14,19 @@ public partial class SettingsMainViewVM : ViewModelBase
private ViewModelBase _currentPage = new SettingsHomePageViewVM();
[ObservableProperty]
private ListItemTemplate? _selectedListItem;
- public AvaloniaList Items { get; }
+ public ObservableCollection Items { get; }
public SettingsMainViewVM()
{
_currentPage = new SettingsHomePageViewVM();
- Items = new AvaloniaList(_templates);
+ Items = new ObservableCollection(_templates);
SelectedListItem = Items.First(vm => vm.ModelType == typeof(SettingsHomePageViewVM));
}
partial void OnSelectedListItemChanged(ListItemTemplate? value)
{
if (value is null) return;
-#pragma warning disable IL2072 // The code works, leave me alone
- var vm = Design.IsDesignMode
- ? Activator.CreateInstance(value.ModelType)
- : Ioc.Default.GetService(value.ModelType);
-#pragma warning restore IL2072
+ var vm = Ioc.Default.GetService(value.ModelType);
if (vm is not ViewModelBase vmb) return;
diff --git a/SnapX.Avalonia/ViewModels/ViewModelBase.cs b/SnapX.CommonUI/ViewModels/ViewModelBase.cs
similarity index 72%
rename from SnapX.Avalonia/ViewModels/ViewModelBase.cs
rename to SnapX.CommonUI/ViewModels/ViewModelBase.cs
index eafcb5e39..2790b058c 100644
--- a/SnapX.Avalonia/ViewModels/ViewModelBase.cs
+++ b/SnapX.CommonUI/ViewModels/ViewModelBase.cs
@@ -1,5 +1,5 @@
using CommunityToolkit.Mvvm.ComponentModel;
-namespace SnapX.Avalonia.ViewModels;
+namespace SnapX.CommonUI.ViewModels;
public class ViewModelBase : ObservableObject;
diff --git a/SnapX.Core/ApplicationConfig.cs b/SnapX.Core/ApplicationConfig.cs
index f61473933..741e93c4a 100644
--- a/SnapX.Core/ApplicationConfig.cs
+++ b/SnapX.Core/ApplicationConfig.cs
@@ -1,179 +1,21 @@
using System.ComponentModel;
using SixLabors.ImageSharp;
using SnapX.Core.History;
+using SnapX.Core.ImageEffects;
using SnapX.Core.Job;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Miscellaneous;
namespace SnapX.Core;
-public class GradientColor
+public class ApplicationConfig
{
- public string Color { get; set; }
- public double Location { get; set; }
-}
-
-public class PinToScreenOptions
-{
- public int InitialScale { get; set; }
- public int ScaleStep { get; set; }
- public bool HighQualityScale { get; set; }
- public int InitialOpacity { get; set; }
- public int OpacityStep { get; set; }
- public string Placement { get; set; }
- public int PlacementOffset { get; set; }
- public bool TopMost { get; set; }
- public bool KeepCenterLocation { get; set; }
- public string BackgroundColor { get; set; }
- public bool Shadow { get; set; }
- public bool Border { get; set; }
- public int BorderSize { get; set; }
- public string BorderColor { get; set; }
- public string MinimizeSize { get; set; }
-}
-
-public class ImageBeautifierOptions
-{
- public int Margin { get; set; }
- public int Padding { get; set; }
- public bool SmartPadding { get; set; }
- public int RoundedCorner { get; set; }
- public int ShadowRadius { get; set; }
- public int ShadowOpacity { get; set; }
- public int ShadowDistance { get; set; }
- public int ShadowAngle { get; set; }
- public string ShadowColor { get; set; }
- public string BackgroundType { get; set; }
- public BackgroundGradient BackgroundGradient { get; set; }
- public string BackgroundColor { get; set; }
- public string BackgroundImageFilePath { get; set; }
-}
-
-public class BackgroundGradient
-{
- public string Type { get; set; }
- public List Colors { get; set; }
-}
-
-public class ImageCombinerOptions
-{
- public string Orientation { get; set; }
- public string Alignment { get; set; }
- public int Space { get; set; }
- public int WrapAfter { get; set; }
- public bool AutoFillBackground { get; set; }
-}
-
-public class VideoConverterOptions
-{
- public string InputFilePath { get; set; }
- public string OutputFolderPath { get; set; }
- public string OutputFileName { get; set; }
- public string VideoCodec { get; set; }
- public int VideoQuality { get; set; }
- public bool VideoQualityUseBitrate { get; set; }
- public int VideoQualityBitrate { get; set; }
- public bool UseCustomArguments { get; set; }
- public string CustomArguments { get; set; }
- public bool AutoOpenFolder { get; set; }
-}
-
-public class VideoThumbnailOptions
-{
- public string DefaultOutputDirectory { get; set; }
- public string LastVideoPath { get; set; }
- public string OutputLocation { get; set; }
- public string CustomOutputDirectory { get; set; }
- public string ImageFormat { get; set; }
- public int ThumbnailCount { get; set; }
- public string FilenameSuffix { get; set; }
- public bool RandomFrame { get; set; }
- public bool UploadThumbnails { get; set; }
- public bool KeepScreenshots { get; set; }
- public bool OpenDirectory { get; set; }
- public int MaxThumbnailWidth { get; set; }
- public bool CombineScreenshots { get; set; }
- public int Padding { get; set; }
- public int Spacing { get; set; }
- public int ColumnCount { get; set; }
- public bool AddVideoInfo { get; set; }
- public bool AddTimestamp { get; set; }
- public bool DrawShadow { get; set; }
- public bool DrawBorder { get; set; }
-}
-
-public class BorderlessWindowSettings
-{
- public bool RememberWindowTitle { get; set; }
- public string WindowTitle { get; set; }
- public bool AutoCloseWindow { get; set; }
- public bool ExcludeTaskbarArea { get; set; }
-}
-
-public class QuickTaskPreset
-{
- public string Name { get; set; }
- public List AfterCaptureTasks { get; set; }
- public List AfterUploadTasks { get; set; }
-}
-
-public class Theme
-{
- public string Name { get; set; }
- public string BackgroundColor { get; set; }
- public string LightBackgroundColor { get; set; }
- public string DarkBackgroundColor { get; set; }
- public string TextColor { get; set; }
- public string BorderColor { get; set; }
- public string CheckerColor { get; set; }
- public string CheckerColor2 { get; set; }
- public int CheckerSize { get; set; }
- public string LinkColor { get; set; }
- public string MenuHighlightColor { get; set; }
- public string MenuHighlightBorderColor { get; set; }
- public string MenuBorderColor { get; set; }
- public string MenuCheckBackgroundColor { get; set; }
- public string MenuFont { get; set; }
- public string ContextMenuFont { get; set; }
- public int ContextMenuOpacity { get; set; }
- public string SeparatorLightColor { get; set; }
- public string SeparatorDarkColor { get; set; }
-}
-
-public class ProxySettings
-{
- public string ProxyMethod { get; set; }
- public string Host { get; set; }
- public int Port { get; set; }
- public string Username { get; set; }
- public string Password { get; set; }
-}
-
-public class WindowState
-{
- public string Location { get; set; }
- public string Size { get; set; }
- public bool IsMaximized { get; set; }
-}
-
-public class ImageHistorySettings
-{
- public bool RememberWindowState { get; set; }
- public WindowState WindowState { get; set; }
- public string ThumbnailSize { get; set; }
- public int MaxItemCount { get; set; }
- public bool FilterMissingFiles { get; set; }
- public bool RememberSearchText { get; set; }
- public string SearchText { get; set; }
-}
-
-public class RootConfiguration
-{
- public TaskSettings DefaultTaskSettings = TaskSettings.GetDefaultTaskSettings();
+ public TaskSettings? DefaultTaskSettings = TaskSettings.GetDefaultTaskSettings();
public DateTime FirstTimeRunDate = DateTime.Now;
public string FileUploadDefaultDirectory = "";
public int NameParserAutoIncrementNumber = 0;
- public List QuickTaskPresets = [];
+
+ public List QuickTaskPresets = QuickTaskInfo.DefaultPresets;
// Main window
public bool FirstTimeMinimizeToTray = true;
public List TaskListViewColumnWidths = [];
@@ -196,8 +38,8 @@ public class RootConfiguration
// TEMP: For backward compatibility
public bool CheckPreReleaseUpdates = false;
public bool UseCustomTheme { get; set; }
- public List Themes { get; set; }
- public int SelectedTheme { get; set; }
+ public List Themes { get; set; } = Theme.GetDefaultThemes();
+ public int SelectedTheme { get; set; } = 0;
public bool UseCustomScreenshotsPath = false;
public string? CustomScreenshotsPath = "";
public string? SaveImageSubFolderPattern = "%y-%mo";
@@ -224,7 +66,6 @@ public class RootConfiguration
public List SecondaryFileUploaders = [];
public bool HistorySaveTasks = true;
public bool HistoryCheckURL = false;
- public List RecentTasks { get; set; }
public bool RecentTasksSave = false;
public int RecentTasksMaxCount = 10;
public bool RecentTasksShowInMainWindow = true;
@@ -306,14 +147,8 @@ public bool DevMode
[Category("Hotkey"), DefaultValue(500), Description("If you hold hotkeys then it will only trigger every this milliseconds.")]
public int HotkeyRepeatLimit
{
- get
- {
- return hotkeyRepeatLimit;
- }
- set
- {
- hotkeyRepeatLimit = Math.Max(value, 200);
- }
+ get => hotkeyRepeatLimit;
+ set => hotkeyRepeatLimit = Math.Max(value, 200);
}
[Category("Clipboard"), DefaultValue(true), Description("Show clipboard content viewer when using clipboard upload in main window.")]
public bool ShowClipboardContentViewer { get; set; }
@@ -362,10 +197,9 @@ public int HotkeyRepeatLimit
[Category("Drag and drop window"), DefaultValue(255), Description("When you drag file to drop window then opacity will change to this.")]
public int DropHoverOpacity { get; set; }
- // [Category("Drag and drop window"), DefaultValue(ContentAlignment.BottomRight), Description("Where drop window will open.")]
- // public ContentAlignment DropAlignment { get; set; }
+ [Category("Drag and drop window"), DefaultValue(ContentAlignment.BottomRight), Description("Where drop window will open.")]
+ public ContentAlignment DropAlignment { get; set; }
public string ApplicationVersion { get; set; } = Helpers.GetApplicationVersion();
-
public string? SQLitePath { get; set; }
}
diff --git a/SnapX.Core/CLI/CLICommand.cs b/SnapX.Core/CLI/CLICommand.cs
index 38034bbe3..515f0c381 100644
--- a/SnapX.Core/CLI/CLICommand.cs
+++ b/SnapX.Core/CLI/CLICommand.cs
@@ -1,20 +1,13 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
namespace SnapX.Core.CLI;
-public class CLICommand
+public record CLICommand(string? Command = null, string? Parameter = null)
{
- public string? Command { get; set; }
- public string? Parameter { get; set; }
+ public string? Command { get; set; } = Command;
+ public string? Parameter { get; set; } = Parameter;
public bool IsCommand { get; set; } // Starts with hyphen?
- public CLICommand(string? command = null, string? parameter = null)
- {
- Command = command;
- Parameter = parameter;
- }
-
public bool CheckCommand(string command, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase)
{
return !string.IsNullOrEmpty(Command) && Command.Equals(command, comparisonType);
@@ -22,7 +15,7 @@ public bool CheckCommand(string command, StringComparison comparisonType = Strin
public override string? ToString()
{
- string? text = "";
+ var text = "";
if (IsCommand)
{
diff --git a/SnapX.Core/CLI/CLICommandAction.cs b/SnapX.Core/CLI/CLICommandAction.cs
index f2812bf04..154ef8b7b 100644
--- a/SnapX.Core/CLI/CLICommandAction.cs
+++ b/SnapX.Core/CLI/CLICommandAction.cs
@@ -1,20 +1,14 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
namespace SnapX.Core.CLI;
-public class CLICommandAction
+public record CLICommandAction(params string[] Commands)
{
- public string[] Commands;
+ public string[] Commands = Commands;
public Action DefaultAction;
public Action TextAction;
public Action NumberAction;
- public CLICommandAction(params string[] commands)
- {
- Commands = commands;
- }
-
public bool CheckCommands(List commands)
{
foreach (CLICommand command in commands)
diff --git a/SnapX.Core/CLI/CLIManager.cs b/SnapX.Core/CLI/CLIManager.cs
index 43af96297..d25ae4a5f 100644
--- a/SnapX.Core/CLI/CLIManager.cs
+++ b/SnapX.Core/CLI/CLIManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/CLI/ExternalCLIManager.cs b/SnapX.Core/CLI/ExternalCLIManager.cs
index 862c1402c..ed66914c4 100644
--- a/SnapX.Core/CLI/ExternalCLIManager.cs
+++ b/SnapX.Core/CLI/ExternalCLIManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -13,54 +12,51 @@ public abstract class ExternalCLIManager : IDisposable
public bool IsProcessRunning { get; private set; }
- protected Process process;
+ protected Process? process;
- public virtual int Open(string? path, string args = null)
+ public virtual int Open(string? path, string? args = null)
{
- if (System.IO.File.Exists(path))
+ if (!File.Exists(path)) return -1;
+ using (process = new Process())
{
- using (process = new Process())
+ var psi = new ProcessStartInfo
+ {
+ FileName = path,
+ WorkingDirectory = Path.GetDirectoryName(path),
+ Arguments = args,
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ RedirectStandardInput = true,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ StandardOutputEncoding = Encoding.UTF8,
+ StandardErrorEncoding = Encoding.UTF8
+ };
+
+ process.EnableRaisingEvents = true;
+ if (psi.RedirectStandardOutput) process.OutputDataReceived += cli_OutputDataReceived;
+ if (psi.RedirectStandardError) process.ErrorDataReceived += cli_ErrorDataReceived;
+ process.StartInfo = psi;
+
+ Console.WriteLine($"CLI: \"{psi.FileName}\" {psi.Arguments}");
+ process.Start();
+
+ if (psi.RedirectStandardOutput) process.BeginOutputReadLine();
+ if (psi.RedirectStandardError) process.BeginErrorReadLine();
+
+ try
+ {
+ IsProcessRunning = true;
+ process.WaitForExit();
+ }
+ finally
{
- ProcessStartInfo psi = new ProcessStartInfo()
- {
- FileName = path,
- WorkingDirectory = Path.GetDirectoryName(path),
- Arguments = args,
- UseShellExecute = false,
- CreateNoWindow = true,
- RedirectStandardInput = true,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- StandardOutputEncoding = Encoding.UTF8,
- StandardErrorEncoding = Encoding.UTF8
- };
-
- process.EnableRaisingEvents = true;
- if (psi.RedirectStandardOutput) process.OutputDataReceived += cli_OutputDataReceived;
- if (psi.RedirectStandardError) process.ErrorDataReceived += cli_ErrorDataReceived;
- process.StartInfo = psi;
-
- Console.WriteLine($"CLI: \"{psi.FileName}\" {psi.Arguments}");
- process.Start();
-
- if (psi.RedirectStandardOutput) process.BeginOutputReadLine();
- if (psi.RedirectStandardError) process.BeginErrorReadLine();
-
- try
- {
- IsProcessRunning = true;
- process.WaitForExit();
- }
- finally
- {
- IsProcessRunning = false;
- }
-
- return process.ExitCode;
+ IsProcessRunning = false;
}
+
+ return process.ExitCode;
}
- return -1;
}
private void cli_OutputDataReceived(object sender, DataReceivedEventArgs e)
@@ -81,7 +77,7 @@ private void cli_ErrorDataReceived(object sender, DataReceivedEventArgs e)
public void WriteInput(string input)
{
- if (IsProcessRunning && process != null && process.StartInfo != null && process.StartInfo.RedirectStandardInput)
+ if (IsProcessRunning && process is { StartInfo.RedirectStandardInput: true })
{
process.StandardInput.WriteLine(input);
}
@@ -97,10 +93,8 @@ public virtual void Close()
public void Dispose()
{
- if (process != null)
- {
- process.Dispose();
- }
+ process?.Dispose();
+ GC.SuppressFinalize(this);
}
}
diff --git a/SnapX.Core/CLI/NativeMessageInput.cs b/SnapX.Core/CLI/NativeMessageInput.cs
index e9254179f..d4d366ada 100644
--- a/SnapX.Core/CLI/NativeMessageInput.cs
+++ b/SnapX.Core/CLI/NativeMessageInput.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
namespace SnapX.Core.CLI;
-public class NativeMessagingInput
+public record NativeMessagingInput
{
public NativeMessagingAction Action { get; set; }
public string? URL { get; set; }
diff --git a/SnapX.Core/CLI/NativeMessagingHost.cs b/SnapX.Core/CLI/NativeMessagingHost.cs
index bec8e1094..4625f630b 100644
--- a/SnapX.Core/CLI/NativeMessagingHost.cs
+++ b/SnapX.Core/CLI/NativeMessagingHost.cs
@@ -1,38 +1,35 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Text;
namespace SnapX.Core.CLI;
-public class NativeMessagingHost
+public record NativeMessagingHost
{
public string Read()
{
- string input = null;
+ var input = "";
- Stream inputStream = Console.OpenStandardInput();
+ var inputStream = Console.OpenStandardInput();
- byte[] bytesLength = new byte[4];
+ var bytesLength = new byte[4];
inputStream.ReadExactly(bytesLength);
- int inputLength = BitConverter.ToInt32(bytesLength, 0);
+ var inputLength = BitConverter.ToInt32(bytesLength, 0);
- if (inputLength > 0)
- {
- byte[] bytesInput = new byte[inputLength];
- inputStream.ReadExactly(bytesInput);
- input = Encoding.UTF8.GetString(bytesInput);
- }
+ if (inputLength <= 0) return input;
+ var bytesInput = new byte[inputLength];
+ inputStream.ReadExactly(bytesInput);
+ input = Encoding.UTF8.GetString(bytesInput);
return input;
}
public void Write(string data)
{
- Stream outputStream = Console.OpenStandardOutput();
+ var outputStream = Console.OpenStandardOutput();
- byte[] bytesData = Encoding.UTF8.GetBytes(data);
- byte[] bytesLength = BitConverter.GetBytes(bytesData.Length);
+ var bytesData = Encoding.UTF8.GetBytes(data);
+ var bytesLength = BitConverter.GetBytes(bytesData.Length);
outputStream.Write(bytesLength, 0, bytesLength.Length);
diff --git a/SnapX.Core/CLI/SnapXCLIManager.cs b/SnapX.Core/CLI/SnapXCLIManager.cs
index f0d9ef269..5820fe9c9 100644
--- a/SnapX.Core/CLI/SnapXCLIManager.cs
+++ b/SnapX.Core/CLI/SnapXCLIManager.cs
@@ -5,21 +5,17 @@
namespace SnapX.Core.CLI;
-public class SnapXCLIManager : CLIManager
+public class SnapXCLIManager(string?[] Arguments) : CLIManager(Arguments)
{
- public SnapXCLIManager(string?[] arguments) : base(arguments)
- {
- }
-
public async Task UseCommandLineArgs() => UseCommandLineArgs(Commands);
public async Task UseCommandLineArgs(List commands)
{
- if (commands != null && commands.Count > 0)
+ if (commands is { Count: > 0 })
{
- TaskSettings taskSettings = FindCLITask(commands);
+ var taskSettings = FindCLITask(commands);
- foreach (CLICommand command in commands)
+ foreach (var command in commands)
{
if (command.IsCommand)
@@ -45,25 +41,12 @@ await CheckNativeMessagingInput(command))
}
}
- private TaskSettings FindCLITask(List commands)
+ private TaskSettings? FindCLITask(List commands)
{
- if (SnapX.HotkeysConfig != null)
- {
- CLICommand command = commands.FirstOrDefault(x => x.CheckCommand("task") && !string.IsNullOrEmpty(x.Parameter));
-
- if (command != null)
- {
- foreach (HotkeySettings hotkeySetting in SnapX.HotkeysConfig.Hotkeys)
- {
- if (command.Parameter == hotkeySetting.TaskSettings.ToString())
- {
- return TaskSettings.GetSafeTaskSettings(hotkeySetting.TaskSettings);
- }
- }
- }
- }
+ if (SnapX.HotkeysConfig == null) return null;
+ var command = commands.FirstOrDefault(x => x.CheckCommand("task") && !string.IsNullOrEmpty(x.Parameter));
- return null;
+ return command == null ? null : (from hotkeySetting in SnapX.HotkeysConfig.Hotkeys where command.Parameter == hotkeySetting.TaskSettings.ToString() select TaskSettings.GetSafeTaskSettings(hotkeySetting.TaskSettings)).FirstOrDefault();
}
private bool CheckCustomUploader(CLICommand command)
diff --git a/SnapX.Core/Capture/CaptureActiveMonitor.cs b/SnapX.Core/Capture/CaptureActiveMonitor.cs
deleted file mode 100644
index 5048d21b1..000000000
--- a/SnapX.Core/Capture/CaptureActiveMonitor.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SnapX.Core.Job;
-
-namespace SnapX.Core.Capture;
-
-public class CaptureActiveMonitor : CaptureBase
-{
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- DebugHelper.WriteLine("CaptureActiveMonitor started");
- var promise = TaskHelpers.GetScreenshot(taskSettings).CaptureActiveMonitor();
- promise.Wait();
- var img = promise.Result;
- var metadata = CreateMetadata(img.Bounds);
- metadata.Image = img;
- return metadata;
- }
-}
-
diff --git a/SnapX.Core/Capture/CaptureActiveWindow.cs b/SnapX.Core/Capture/CaptureActiveWindow.cs
deleted file mode 100644
index 92dd8d7a8..000000000
--- a/SnapX.Core/Capture/CaptureActiveWindow.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SnapX.Core.Job;
-
-namespace SnapX.Core.Capture;
-public class CaptureActiveWindow : CaptureBase
-{
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- var metadata = CreateMetadata();
-
- if (taskSettings.CaptureSettings.CaptureTransparent && !taskSettings.CaptureSettings.CaptureClientArea)
- {
- metadata.Image = TaskHelpers.GetScreenshot(taskSettings).CaptureActiveWindowTransparent();
- }
- else
- {
- metadata.Image = TaskHelpers.GetScreenshot(taskSettings).CaptureActiveWindow();
- }
-
- return metadata;
- }
-}
diff --git a/SnapX.Core/Capture/CaptureBase.cs b/SnapX.Core/Capture/CaptureBase.cs
deleted file mode 100644
index ceb1dca8c..000000000
--- a/SnapX.Core/Capture/CaptureBase.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SixLabors.ImageSharp;
-using SnapX.Core.Job;
-using SnapX.Core.Upload;
-using SnapX.Core.Utils.Extensions;
-using SnapX.Core.Utils.Native;
-
-namespace SnapX.Core.Capture;
-public abstract class CaptureBase
-{
- public bool AllowAutoHideForm { get; set; } = true;
- public bool AllowAnnotation { get; set; } = true;
-
- public void Capture(bool autoHideForm)
- {
- Capture(null, autoHideForm);
- }
-
- public void Capture(TaskSettings taskSettings = null, bool autoHideForm = false)
- {
- if (taskSettings == null) taskSettings = TaskSettings.GetDefaultTaskSettings();
-
- // TODO: Reimplement taskSettings.GeneralSettings.ToastWindowAutoHide
- // if (taskSettings.GeneralSettings.ToastWindowAutoHide)
- // {
- // NotificationForm.CloseActiveForm();
- // }
-
- if (taskSettings.CaptureSettings.ScreenshotDelay > 0)
- {
- int delay = (int)(taskSettings.CaptureSettings.ScreenshotDelay * 1000);
-
- Task.Delay(delay).ContinueInCurrentContext(() =>
- {
- CaptureInternal(taskSettings, autoHideForm);
- });
- }
- else
- {
- CaptureInternal(taskSettings, autoHideForm);
- }
- }
-
- protected abstract TaskMetadata Execute(TaskSettings taskSettings);
-
- private void CaptureInternal(TaskSettings taskSettings, bool autoHideForm)
- {
- if (autoHideForm && AllowAutoHideForm)
- {
- // SnapX.MainWindow.Hide();
- // Thread.Sleep(250);
- }
-
- TaskMetadata metadata = null;
-
- try
- {
- AllowAnnotation = true;
- metadata = Execute(taskSettings);
- }
- catch (Exception ex)
- {
- DebugHelper.WriteException(ex);
- }
- finally
- {
- if (autoHideForm && AllowAutoHideForm)
- {
- // SnapX.MainWindow.ForceActivate();
- }
-
- AfterCapture(metadata, taskSettings);
- }
- }
-
- private void AfterCapture(TaskMetadata metadata, TaskSettings taskSettings)
- {
- if (metadata != null && metadata.Image != null)
- {
- TaskHelpers.PlayNotificationSoundAsync(NotificationSound.Capture, taskSettings);
-
- if (taskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.AnnotateImage) && !AllowAnnotation)
- {
- taskSettings.AfterCaptureJob = taskSettings.AfterCaptureJob.Remove(AfterCaptureTasks.AnnotateImage);
- }
-
- if (taskSettings.ImageSettings.ImageEffectOnlyRegionCapture &&
- GetType() != typeof(CaptureRegion) && GetType() != typeof(CaptureLastRegion))
- {
- taskSettings.AfterCaptureJob = taskSettings.AfterCaptureJob.Remove(AfterCaptureTasks.AddImageEffects);
- }
-
- UploadManager.RunImageTask(metadata, taskSettings);
- }
- }
-
- protected TaskMetadata CreateMetadata()
- {
- return CreateMetadata(Rectangle.Empty, null);
- }
-
- protected TaskMetadata CreateMetadata(Rectangle insideRect)
- {
- return CreateMetadata(insideRect, "explorer");
- }
-
- protected TaskMetadata CreateMetadata(Rectangle insideRect, string ignoreProcess)
- {
- var metadata = new TaskMetadata();
-
- var windowInfo = Methods.GetForegroundWindow();
- if ((ignoreProcess == null || !windowInfo.ProcessName.Equals(ignoreProcess, StringComparison.OrdinalIgnoreCase)) &&
- (insideRect.IsEmpty || windowInfo.Rectangle.Contains(insideRect)))
- {
- metadata.UpdateInfo(windowInfo);
- }
-
- return metadata;
- }
-}
-
diff --git a/SnapX.Core/Capture/CaptureCustomRegion.cs b/SnapX.Core/Capture/CaptureCustomRegion.cs
deleted file mode 100644
index 712481ca4..000000000
--- a/SnapX.Core/Capture/CaptureCustomRegion.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SnapX.Core.Job;
-
-namespace SnapX.Core.Capture;
-
-public class CaptureCustomRegion : CaptureBase
-{
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- var rect = taskSettings.CaptureSettings.CaptureCustomRegion;
- var metadata = CreateMetadata(rect);
- metadata.Image = TaskHelpers.GetScreenshot(taskSettings).CaptureRectangle(rect);
- return metadata;
- }
-}
-
diff --git a/SnapX.Core/Capture/CaptureCustomWindow.cs b/SnapX.Core/Capture/CaptureCustomWindow.cs
deleted file mode 100644
index 6cafe2558..000000000
--- a/SnapX.Core/Capture/CaptureCustomWindow.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SnapX.Core.Job;
-
-namespace SnapX.Core.Capture;
-public class CaptureCustomWindow : CaptureWindow
-{
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- string windowTitle = taskSettings.CaptureSettings.CaptureCustomWindow;
-
- if (!string.IsNullOrEmpty(windowTitle))
- {
- // TODO: Reimplement w/ Windows support & Linux (X11, and KDE Plasma Wayland)
- // IntPtr hWnd = NativeMethods.SearchWindow(windowTitle);
- //
- // if (hWnd == IntPtr.Zero)
- // {
- // MessageBox.Show(Resources.UnableToFindAWindowWithSpecifiedWindowTitle, "SnapX", MessageBoxButtons.OK, MessageBoxIcon.Information);
- // }
- // else
- // {
- // WindowHandle = hWnd;
- //
- // return base.Execute(taskSettings);
- // }
- }
-
- return null;
- }
-}
-
diff --git a/SnapX.Core/Capture/CaptureFullscreen.cs b/SnapX.Core/Capture/CaptureFullscreen.cs
deleted file mode 100644
index 9e1e5f8a8..000000000
--- a/SnapX.Core/Capture/CaptureFullscreen.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SnapX.Core.Job;
-
-namespace SnapX.Core.Capture;
-
-public class CaptureFullscreen : CaptureBase
-{
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- DebugHelper.WriteLine("CaptureFullscreen");
- var img = TaskHelpers.GetScreenshot(taskSettings).CaptureFullscreen();
- var metadata = CreateMetadata(img.Bounds);
- metadata.Image = img;
-
- return metadata;
- }
-}
-
diff --git a/SnapX.Core/Capture/CaptureLastRegion.cs b/SnapX.Core/Capture/CaptureLastRegion.cs
deleted file mode 100644
index b99455790..000000000
--- a/SnapX.Core/Capture/CaptureLastRegion.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SnapX.Core.Job;
-
-namespace SnapX.Core.Capture;
-public class CaptureLastRegion : CaptureRegion
-{
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- switch (lastRegionCaptureType)
- {
- default:
- case RegionCaptureType.Default: return ExecuteRegionCapture(taskSettings);
- case RegionCaptureType.Light: return ExecuteRegionCaptureLight(taskSettings);
- case RegionCaptureType.Transparent: return ExecuteRegionCaptureTransparent(taskSettings);
- }
- }
-}
-
diff --git a/SnapX.Core/Capture/CaptureMonitor.cs b/SnapX.Core/Capture/CaptureMonitor.cs
deleted file mode 100644
index 25ebb0fc4..000000000
--- a/SnapX.Core/Capture/CaptureMonitor.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SixLabors.ImageSharp;
-using SnapX.Core.Job;
-
-namespace SnapX.Core.Capture;
-public class CaptureMonitor : CaptureBase
-{
- public Rectangle MonitorRectangle { get; private set; }
-
- public CaptureMonitor(Rectangle monitorRectangle)
- {
- MonitorRectangle = monitorRectangle;
- }
-
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- DebugHelper.WriteLine("CaptureMonitor Start");
- var metadata = CreateMetadata(MonitorRectangle);
- metadata.Image = TaskHelpers.GetScreenshot().CaptureRectangle(MonitorRectangle);
- return metadata;
- }
-}
-
diff --git a/SnapX.Core/Capture/CaptureWindow.cs b/SnapX.Core/Capture/CaptureWindow.cs
deleted file mode 100644
index b6f0927f6..000000000
--- a/SnapX.Core/Capture/CaptureWindow.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using SnapX.Core.Job;
-using SnapX.Core.Media;
-
-namespace SnapX.Core.Capture;
-public class CaptureWindow : CaptureBase
-{
- public IntPtr WindowHandle { get; protected set; }
-
- public CaptureWindow()
- {
- }
-
- public CaptureWindow(IntPtr windowHandle)
- {
- WindowHandle = windowHandle;
- }
-
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- WindowInfo windowInfo = new(WindowHandle);
-
- if (windowInfo.IsMinimized)
- {
- windowInfo.Restore();
- Thread.Sleep(250);
- }
-
- if (!windowInfo.IsActive)
- {
- windowInfo.Activate();
- Thread.Sleep(100);
- }
-
- var metadata = new TaskMetadata();
- metadata.UpdateInfo(windowInfo);
-
- if (taskSettings.CaptureSettings.CaptureTransparent && !taskSettings.CaptureSettings.CaptureClientArea)
- {
- metadata.Image = TaskHelpers.GetScreenshot(taskSettings).CaptureWindowTransparent(WindowHandle);
- }
- else
- {
- metadata.Image = TaskHelpers.GetScreenshot(taskSettings).CaptureWindow(WindowHandle);
- }
-
- return metadata;
- }
-}
-
diff --git a/SnapX.Core/DebugHelper.cs b/SnapX.Core/DebugHelper.cs
index 7bdf634bf..6a6a1e222 100644
--- a/SnapX.Core/DebugHelper.cs
+++ b/SnapX.Core/DebugHelper.cs
@@ -2,8 +2,6 @@
using Serilog;
-using Serilog.Events;
-using Serilog.Sinks.InMemory;
using Serilog.Sinks.SystemConsole.Themes;
namespace SnapX.Core;
@@ -12,8 +10,7 @@ public static class DebugHelper
{
public static ILogger? Logger { get; private set; }
private static List messageBuffer = new();
- private static InMemorySink inMemorySink = new();
- public static IEnumerable LogEvents => inMemorySink.LogEvents;
+ public static ObservableSink observableSink { get; private set; } = new();
public static void Init(string logFilePath)
{
if (string.IsNullOrEmpty(logFilePath)) return;
@@ -21,7 +18,7 @@ public static void Init(string logFilePath)
#if DEBUG
.MinimumLevel.Debug()
#endif
- .WriteTo.Sink(inMemorySink)
+ .WriteTo.Sink(observableSink)
// If you run multiple SnapX instances, this will be the first to break. :)
.WriteTo.Async(a => a.File(logFilePath, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}]: {Message:lj}{NewLine}{Exception}", rollingInterval: RollingInterval.Day, buffered: true));
if (SnapX.LogToConsole)
diff --git a/SnapX.Core/Enums.cs b/SnapX.Core/Enums.cs
index e796758da..47cc8780b 100644
--- a/SnapX.Core/Enums.cs
+++ b/SnapX.Core/Enums.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Events.cs b/SnapX.Core/Events.cs
deleted file mode 100644
index a330154bb..000000000
--- a/SnapX.Core/Events.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using SnapX.Core.Job;
-using Xdg.Directories;
-
-namespace SnapX.Core;
-
-public class NeedFileOpenerEvent
-{
- public string Directory { get; set; } = UserDirectory.PicturesDir;
- public string? FileName { get; set; }
- public List? AcceptedExtensions { get; set; }
- public string? Title { get; set; } = SnapX.AppName;
- public bool Multiselect { get; set; } = false;
- public TaskSettings TaskSettings { get; set; }
-}
-
-public class NeedRegionCaptureEvent
-{
-
-}
-public class EventAggregator
-{
- private readonly List>> _subscriptions = [];
-
- public void Subscribe(Action action)
- {
- _subscriptions.Add(Tuple.Create>(typeof(TEvent), (o) => action((TEvent)o)));
- }
-
- public void Publish(TEvent @event)
- {
- foreach (var subscription in _subscriptions.Where(s => s.Item1 == typeof(TEvent)))
- {
- subscription.Item2(@event);
- }
- }
-}
diff --git a/SnapX.Core/History/HistoryFilter.cs b/SnapX.Core/History/HistoryFilter.cs
index af1440246..b9f5ea2f3 100644
--- a/SnapX.Core/History/HistoryFilter.cs
+++ b/SnapX.Core/History/HistoryFilter.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -42,7 +41,7 @@ public IEnumerable ApplyFilter(IEnumerable historyItem
string pattern = Regex.Escape(Filename).Replace("\\?", ".").Replace("\\*", ".*");
Regex regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
historyItems = historyItems.Where(x => (x.FileName != null && regex.IsMatch(x.FileName)) ||
- (SearchInTags && x.Tags != null && x.Tags.Any(tag => regex.IsMatch(tag.Text))));
+ (SearchInTags && x.Tags != null && x.Tags.Any(tag => regex.IsMatch(tag.Name))));
}
if (!string.IsNullOrEmpty(URL))
diff --git a/SnapX.Core/History/HistoryItem.cs b/SnapX.Core/History/HistoryItem.cs
index 8e17d9da8..9a2c28391 100644
--- a/SnapX.Core/History/HistoryItem.cs
+++ b/SnapX.Core/History/HistoryItem.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -15,7 +14,7 @@ namespace SnapX.Core.History;
internal partial class HistoryContext : JsonSerializerContext;
[Table("HistoryItems")]
-public class HistoryItem
+public record HistoryItem
{
[Key]
public int Id { get; set; }
@@ -33,14 +32,27 @@ public class HistoryItem
public record Tag
{
public int Id { get; set; }
- public string? Text { get; set; }
- public string? WindowTitle { get; set; }
- public string? ProcessName { get; set; }
+ public required string Name { get; set; }
+ public string Value { get; set; } = "";
+
+ public virtual bool Equals(Tag? other)
+ {
+ if (other is null) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Id == other.Id &&
+ Name == other.Name &&
+ Value == other.Value;
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(Id, Name, Value);
+ }
}
- public List? Tags { get; set; } = [];
+ public List? Tags = [];
public override string ToString()
{
- string text = "";
+ var text = "";
if (!string.IsNullOrEmpty(ShortenedURL))
{
@@ -57,6 +69,7 @@ public override string ToString()
return text;
}
+ [JsonIgnore]
public string TrayMenuText
{
get
@@ -66,43 +79,49 @@ public string TrayMenuText
return $"[{DateTime:HH:mm:ss}] {text}";
}
}
+ [JsonIgnore]
public string? BestImageSource =>
!string.IsNullOrWhiteSpace(FilePath) && File.Exists(FilePath)
? FilePath
: URL ?? ThumbnailURL;
-
- public override bool Equals(object? obj)
+ public virtual bool Equals(HistoryItem? other)
{
- if (obj is not HistoryItem other)
- {
- return false;
- }
+ if (other is null) return false;
+ if (ReferenceEquals(this, other)) return true;
- return Id == other.Id &&
- FileName == other.FileName &&
+ return FileName == other.FileName &&
FilePath == other.FilePath &&
DateTime == other.DateTime &&
Type == other.Type &&
+ Id == other.Id &&
Hidden == other.Hidden &&
Host == other.Host &&
URL == other.URL &&
ThumbnailURL == other.ThumbnailURL &&
DeletionURL == other.DeletionURL &&
ShortenedURL == other.ShortenedURL &&
- // Deep equality for Tags might be needed if you care about changes within the list
- // This gets complex. Often, for lists, you might compare counts and then item-by-item,
- // or just rely on a "LastModified" timestamp on the parent object.
- (Tags?.SequenceEqual(other.Tags ?? Enumerable.Empty()) ?? (other.Tags == null));
+ TagsEqual(Tags, other.Tags);
+ }
+
+ private static bool TagsEqual(List? a, List? b)
+ {
+ if (a is null && b is null) return true;
+ if (a is null || b is null) return false;
+ if (a.Count != b.Count) return false;
+
+ var orderedA = a.OrderBy(t => t.Id).ThenBy(t => t.Name).ThenBy(t => t.Value);
+ var orderedB = b.OrderBy(t => t.Id).ThenBy(t => t.Name).ThenBy(t => t.Value);
+ return orderedA.SequenceEqual(orderedB);
}
+
public override int GetHashCode()
{
var hash = new HashCode();
-
- hash.Add(Id);
hash.Add(FileName);
hash.Add(FilePath);
hash.Add(DateTime);
hash.Add(Type);
+ hash.Add(Id);
hash.Add(Hidden);
hash.Add(Host);
hash.Add(URL);
@@ -112,7 +131,7 @@ public override int GetHashCode()
if (Tags != null)
{
- foreach (var tag in Tags)
+ foreach (var tag in Tags.OrderBy(t => t.Id).ThenBy(t => t.Name).ThenBy(t => t.Value))
{
hash.Add(tag);
}
diff --git a/SnapX.Core/History/HistoryItemManager.cs b/SnapX.Core/History/HistoryItemManager.cs
index 74e4c1476..d35e0eadc 100644
--- a/SnapX.Core/History/HistoryItemManager.cs
+++ b/SnapX.Core/History/HistoryItemManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/History/HistoryManager.cs b/SnapX.Core/History/HistoryManager.cs
index ca45207ec..300a683c8 100644
--- a/SnapX.Core/History/HistoryManager.cs
+++ b/SnapX.Core/History/HistoryManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -62,6 +61,18 @@ public virtual bool RemoveHistoryItem(HistoryItem historyItem)
return Save(FilePath, allHistoryItems);
}
+ public virtual bool RemoveHistoryItems(HistoryItem[] historyItems)
+ {
+ var allHistoryItems = Load();
+ foreach (var historyItem in historyItems)
+ {
+ var index = allHistoryItems.FindIndex(h => h.Id == historyItem.Id);
+ if (index == -1)
+ throw new InvalidOperationException($"History item with ID {historyItem.Id} was not found.");
+ allHistoryItems.RemoveAt(index);
+ }
+ return Save(FilePath, allHistoryItems);
+ }
public virtual async Task> GetHistoryItemsAsync(int Items = int.MaxValue)
diff --git a/SnapX.Core/History/HistoryManagerSQLite.cs b/SnapX.Core/History/HistoryManagerSQLite.cs
index feb4ede7e..816021f0f 100644
--- a/SnapX.Core/History/HistoryManagerSQLite.cs
+++ b/SnapX.Core/History/HistoryManagerSQLite.cs
@@ -71,6 +71,30 @@ public override bool RemoveHistoryItem(HistoryItem historyItem)
new { historyItem.Id });
return rowsAffected > 0;
}
+ [DapperAot]
+ public override bool RemoveHistoryItems(HistoryItem[] items)
+ {
+ if (items.Length == 0)
+ return false;
+
+ var allIds = items.Select(x => x.Id).ToArray();
+ var deleted = 0;
+
+ using var transaction = _connection.BeginTransaction();
+
+ for (var i = 0; i < allIds.Length; i += 999)
+ {
+ var batch = allIds.Skip(i).Take(999).ToArray();
+ var parameters = batch.Select((id, index) => new { Name = $"@id{index}", Value = id }).ToList();
+ var sql = $"DELETE FROM HistoryItems WHERE Id IN ({string.Join(", ", parameters.Select(p => p.Name))})";
+ var paramDict = parameters.ToDictionary(p => p.Name, p => (object)p.Value);
+ deleted += _connection.Execute(sql, paramDict, transaction);
+ }
+
+ transaction.Commit();
+
+ return deleted > 0;
+ }
[DapperAot]
public override HistoryItem UpdateHistoryItem(HistoryItem historyItem)
@@ -159,9 +183,8 @@ INSERT INTO HistoryItems
(h, t) => new
{
HistoryItemId = h.Id,
- t.Text,
- t.WindowTitle,
- t.ProcessName
+ t.Name,
+ t.Value,
});
if (allTags.Any())
diff --git a/SnapX.Core/History/HistorySettings.cs b/SnapX.Core/History/HistorySettings.cs
index d1a3e6e7a..bfec22095 100644
--- a/SnapX.Core/History/HistorySettings.cs
+++ b/SnapX.Core/History/HistorySettings.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
namespace SnapX.Core.History;
-public class HistorySettings
+public record HistorySettings
{
public bool RememberWindowState { get; set; } = true;
public int SplitterDistance { get; set; } = 550;
diff --git a/SnapX.Core/History/ImageHistorySettings.cs b/SnapX.Core/History/ImageHistorySettings.cs
new file mode 100644
index 000000000..7cfe58a07
--- /dev/null
+++ b/SnapX.Core/History/ImageHistorySettings.cs
@@ -0,0 +1,21 @@
+using SixLabors.ImageSharp;
+
+namespace SnapX.Core.History;
+
+
+public class WindowState
+{
+ public Point Location { get; set; }
+ public Size Size { get; set; }
+ public bool IsMaximized { get; set; }
+}
+public class ImageHistorySettings
+{
+ public bool RememberWindowState { get; set; } = true;
+ public WindowState WindowState { get; set; } = new();
+ public Size ThumbnailSize { get; set; } = new(150, 150);
+ public int MaxItemCount { get; set; } = 250;
+ public bool FilterMissingFiles { get; set; } = false;
+ public bool RememberSearchText { get; set; } = false;
+ public string SearchText { get; set; } = "";
+}
diff --git a/SnapX.Core/Hotkey/HotkeyInfo.cs b/SnapX.Core/Hotkey/HotkeyInfo.cs
index 592c1f0d0..7f10557bb 100644
--- a/SnapX.Core/Hotkey/HotkeyInfo.cs
+++ b/SnapX.Core/Hotkey/HotkeyInfo.cs
@@ -3,7 +3,7 @@
namespace SnapX.Core.Hotkey;
-public class HotkeyInfo
+public record HotkeyInfo()
{
public Keys Hotkey { get; set; }
@@ -11,7 +11,7 @@ public class HotkeyInfo
public ushort ID { get; set; }
[JsonIgnore]
- public HotkeyStatus Status { get; set; }
+ public HotkeyStatus Status { get; set; } = HotkeyStatus.NotConfigured;
public Keys KeyCode => Hotkey & Keys.KeyCode;
@@ -29,7 +29,7 @@ public Modifiers ModifiersEnum
{
get
{
- Modifiers modifiers = Modifiers.None;
+ var modifiers = Modifiers.None;
if (Alt) modifiers |= Modifiers.Alt;
if (Control) modifiers |= Modifiers.Control;
@@ -44,11 +44,6 @@ public Modifiers ModifiersEnum
public bool IsValidHotkey => KeyCode != Keys.None && !IsOnlyModifiers;
- public HotkeyInfo()
- {
- Status = HotkeyStatus.NotConfigured;
- }
-
public HotkeyInfo(Keys hotkey) : this()
{
Hotkey = hotkey;
@@ -61,7 +56,7 @@ public HotkeyInfo(Keys hotkey, ushort id) : this(hotkey)
public override string ToString()
{
- string text = "";
+ var text = "";
if (Control)
{
@@ -107,13 +102,13 @@ public override string ToString()
{
text += "Scroll Lock";
}
- else if (KeyCode >= Keys.D0 && KeyCode <= Keys.D9)
+ else if (KeyCode is >= Keys.D0 and <= Keys.D9)
{
text += (KeyCode - Keys.D0).ToString();
}
- else if (KeyCode >= Keys.NumPad0 && KeyCode <= Keys.NumPad9)
+ else if (KeyCode is >= Keys.NumPad0 and <= Keys.NumPad9)
{
- text += "Numpad " + (KeyCode - Keys.NumPad0).ToString();
+ text += "Numpad " + (KeyCode - Keys.NumPad0);
}
else
{
@@ -125,11 +120,11 @@ public override string ToString()
private string ToStringWithSpaces(Keys key)
{
- string name = key.ToString();
+ var name = key.ToString();
var result = new StringBuilder();
- for (int i = 0; i < name.Length; i++)
+ for (var i = 0; i < name.Length; i++)
{
if (i > 0 && char.IsUpper(name[i]))
{
diff --git a/SnapX.Core/Hotkey/HotkeyManager.cs b/SnapX.Core/Hotkey/HotkeyManager.cs
index 0826ed7b8..9780ec539 100644
--- a/SnapX.Core/Hotkey/HotkeyManager.cs
+++ b/SnapX.Core/Hotkey/HotkeyManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Hotkey/HotkeySettings.cs b/SnapX.Core/Hotkey/HotkeySettings.cs
index f34c189ba..2a88926e4 100644
--- a/SnapX.Core/Hotkey/HotkeySettings.cs
+++ b/SnapX.Core/Hotkey/HotkeySettings.cs
@@ -1,20 +1,14 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using SnapX.Core.Job;
namespace SnapX.Core.Hotkey;
-public class HotkeySettings
+public record HotkeySettings()
{
- public HotkeyInfo HotkeyInfo { get; set; }
-
- public TaskSettings TaskSettings { get; set; }
+ public HotkeyInfo? HotkeyInfo { get; set; } = new();
- public HotkeySettings()
- {
- HotkeyInfo = new HotkeyInfo();
- }
+ public TaskSettings? TaskSettings { get; set; }
public HotkeySettings(HotkeyType job, Keys hotkey = Keys.None) : this()
{
@@ -27,7 +21,7 @@ public override string ToString()
{
if (HotkeyInfo != null && TaskSettings != null)
{
- return string.Format("Hotkey: {0}, Description: {1}, Job: {2}", HotkeyInfo, TaskSettings, TaskSettings.Job);
+ return $"Hotkey: {HotkeyInfo}, Description: {TaskSettings}, Job: {TaskSettings.Job}";
}
return "";
diff --git a/SnapX.Core/Hotkey/HotkeysConfig.cs b/SnapX.Core/Hotkey/HotkeysConfig.cs
index 72edba478..8baf56e7f 100644
--- a/SnapX.Core/Hotkey/HotkeysConfig.cs
+++ b/SnapX.Core/Hotkey/HotkeysConfig.cs
@@ -2,7 +2,7 @@
namespace SnapX.Core.Hotkey;
-public class HotkeysConfig
+public record HotkeysConfig
{
public List Hotkeys = HotkeyManager.GetDefaultHotkeyList();
}
diff --git a/SnapX.Core/Hotkey/Keys.cs b/SnapX.Core/Hotkey/Keys.cs
index 18bbe0252..b027c12c9 100644
--- a/SnapX.Core/Hotkey/Keys.cs
+++ b/SnapX.Core/Hotkey/Keys.cs
@@ -1,5 +1,5 @@
namespace SnapX.Core.Hotkey;
-
+[Flags]
public enum Keys
{
None = 0,
@@ -158,6 +158,7 @@ public enum Keys
}
+[Flags]
public enum Modifiers
{
None = 0,
diff --git a/SnapX.Core/ImageEffects/Adjustments/Alpha.cs b/SnapX.Core/ImageEffects/Adjustments/Alpha.cs
index 55698c753..c77943e85 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Alpha.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Alpha.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/BlackWhite.cs b/SnapX.Core/ImageEffects/Adjustments/BlackWhite.cs
index 409dea6f9..e17ccd86d 100644
--- a/SnapX.Core/ImageEffects/Adjustments/BlackWhite.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/BlackWhite.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Brightness.cs b/SnapX.Core/ImageEffects/Adjustments/Brightness.cs
index cdcee5f62..c9ae78d88 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Brightness.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Brightness.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Colorize.cs b/SnapX.Core/ImageEffects/Adjustments/Colorize.cs
index 1d3fac252..f4d82558d 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Colorize.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Colorize.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Contrast.cs b/SnapX.Core/ImageEffects/Adjustments/Contrast.cs
index 82ef6164a..d7b19ba90 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Contrast.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Contrast.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Gamma.cs b/SnapX.Core/ImageEffects/Adjustments/Gamma.cs
index 82920e931..c72f97cd6 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Gamma.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Gamma.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Grayscale.cs b/SnapX.Core/ImageEffects/Adjustments/Grayscale.cs
index 650dab33e..041659e0f 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Grayscale.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Grayscale.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Hue.cs b/SnapX.Core/ImageEffects/Adjustments/Hue.cs
index dddb5d6a0..8a110ab2f 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Hue.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Hue.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/MatrixColor.cs b/SnapX.Core/ImageEffects/Adjustments/MatrixColor.cs
index 7a6c50911..177bff51f 100644
--- a/SnapX.Core/ImageEffects/Adjustments/MatrixColor.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/MatrixColor.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/ReplaceColor.cs b/SnapX.Core/ImageEffects/Adjustments/ReplaceColor.cs
index 568aa47c2..a034b8b09 100644
--- a/SnapX.Core/ImageEffects/Adjustments/ReplaceColor.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/ReplaceColor.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Saturation.cs b/SnapX.Core/ImageEffects/Adjustments/Saturation.cs
index 727a48604..a62dff0f9 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Saturation.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Saturation.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/SelectiveColor.cs b/SnapX.Core/ImageEffects/Adjustments/SelectiveColor.cs
index 01c398cfc..274b4f423 100644
--- a/SnapX.Core/ImageEffects/Adjustments/SelectiveColor.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/SelectiveColor.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Adjustments/Sepia.cs b/SnapX.Core/ImageEffects/Adjustments/Sepia.cs
index 0a347fd2d..ccf01e698 100644
--- a/SnapX.Core/ImageEffects/Adjustments/Sepia.cs
+++ b/SnapX.Core/ImageEffects/Adjustments/Sepia.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawBackground.cs b/SnapX.Core/ImageEffects/Drawings/DrawBackground.cs
index f1fbf980a..4740afff4 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawBackground.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawBackground.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawBackgroundImage.cs b/SnapX.Core/ImageEffects/Drawings/DrawBackgroundImage.cs
index db82694f6..3bad927a9 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawBackgroundImage.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawBackgroundImage.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawBorder.cs b/SnapX.Core/ImageEffects/Drawings/DrawBorder.cs
index 88eef2fa7..887c880c6 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawBorder.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawBorder.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawCheckerboard.cs b/SnapX.Core/ImageEffects/Drawings/DrawCheckerboard.cs
index f6e6681af..6c7ed65ce 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawCheckerboard.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawCheckerboard.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawImage.cs b/SnapX.Core/ImageEffects/Drawings/DrawImage.cs
index 87db843cc..29d9a67ff 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawImage.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawImage.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawParticles.cs b/SnapX.Core/ImageEffects/Drawings/DrawParticles.cs
index 7fc391bc0..7187140e7 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawParticles.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawParticles.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawText.cs b/SnapX.Core/ImageEffects/Drawings/DrawText.cs
index 5d9e56e5c..e14038102 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawText.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawText.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Drawings/DrawTextEx.cs b/SnapX.Core/ImageEffects/Drawings/DrawTextEx.cs
index b0acd2b4f..460b9a94e 100644
--- a/SnapX.Core/ImageEffects/Drawings/DrawTextEx.cs
+++ b/SnapX.Core/ImageEffects/Drawings/DrawTextEx.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Enums.cs b/SnapX.Core/ImageEffects/Enums.cs
index 758e38883..6dc5595e7 100644
--- a/SnapX.Core/ImageEffects/Enums.cs
+++ b/SnapX.Core/ImageEffects/Enums.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/Blur.cs b/SnapX.Core/ImageEffects/Filters/Blur.cs
index 95488c96a..c87aecf1d 100644
--- a/SnapX.Core/ImageEffects/Filters/Blur.cs
+++ b/SnapX.Core/ImageEffects/Filters/Blur.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/EdgeDetect.cs b/SnapX.Core/ImageEffects/Filters/EdgeDetect.cs
index 1cc2652eb..803f08a78 100644
--- a/SnapX.Core/ImageEffects/Filters/EdgeDetect.cs
+++ b/SnapX.Core/ImageEffects/Filters/EdgeDetect.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/Emboss.cs b/SnapX.Core/ImageEffects/Filters/Emboss.cs
index 58b66c69c..b1b17cb1a 100644
--- a/SnapX.Core/ImageEffects/Filters/Emboss.cs
+++ b/SnapX.Core/ImageEffects/Filters/Emboss.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Numerics;
diff --git a/SnapX.Core/ImageEffects/Filters/GaussianBlur.cs b/SnapX.Core/ImageEffects/Filters/GaussianBlur.cs
index a82b31934..19a008c97 100644
--- a/SnapX.Core/ImageEffects/Filters/GaussianBlur.cs
+++ b/SnapX.Core/ImageEffects/Filters/GaussianBlur.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.ComponentModel;
diff --git a/SnapX.Core/ImageEffects/Filters/Glow.cs b/SnapX.Core/ImageEffects/Filters/Glow.cs
index 2887b8cd5..f15eeba63 100644
--- a/SnapX.Core/ImageEffects/Filters/Glow.cs
+++ b/SnapX.Core/ImageEffects/Filters/Glow.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/MatrixConvolution.cs b/SnapX.Core/ImageEffects/Filters/MatrixConvolution.cs
index fb3864983..0fdafce45 100644
--- a/SnapX.Core/ImageEffects/Filters/MatrixConvolution.cs
+++ b/SnapX.Core/ImageEffects/Filters/MatrixConvolution.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/MeanRemoval.cs b/SnapX.Core/ImageEffects/Filters/MeanRemoval.cs
index 20170729b..74d8291a0 100644
--- a/SnapX.Core/ImageEffects/Filters/MeanRemoval.cs
+++ b/SnapX.Core/ImageEffects/Filters/MeanRemoval.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/Outline.cs b/SnapX.Core/ImageEffects/Filters/Outline.cs
index d65ae6b63..865ee9a00 100644
--- a/SnapX.Core/ImageEffects/Filters/Outline.cs
+++ b/SnapX.Core/ImageEffects/Filters/Outline.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/Pixelate.cs b/SnapX.Core/ImageEffects/Filters/Pixelate.cs
index 0bf7280dd..c0f10578a 100644
--- a/SnapX.Core/ImageEffects/Filters/Pixelate.cs
+++ b/SnapX.Core/ImageEffects/Filters/Pixelate.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/RGBSplit.cs b/SnapX.Core/ImageEffects/Filters/RGBSplit.cs
index 3bbf133d4..5be9366ab 100644
--- a/SnapX.Core/ImageEffects/Filters/RGBSplit.cs
+++ b/SnapX.Core/ImageEffects/Filters/RGBSplit.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/Reflection.cs b/SnapX.Core/ImageEffects/Filters/Reflection.cs
index 32a833a01..bfb9fb3a8 100644
--- a/SnapX.Core/ImageEffects/Filters/Reflection.cs
+++ b/SnapX.Core/ImageEffects/Filters/Reflection.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/Shadow.cs b/SnapX.Core/ImageEffects/Filters/Shadow.cs
index e376c25d9..da3690395 100644
--- a/SnapX.Core/ImageEffects/Filters/Shadow.cs
+++ b/SnapX.Core/ImageEffects/Filters/Shadow.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/Slice.cs b/SnapX.Core/ImageEffects/Filters/Slice.cs
index 552c540e3..26ec405a7 100644
--- a/SnapX.Core/ImageEffects/Filters/Slice.cs
+++ b/SnapX.Core/ImageEffects/Filters/Slice.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/TornEdge.cs b/SnapX.Core/ImageEffects/Filters/TornEdge.cs
index e129205ef..e6470b9e2 100644
--- a/SnapX.Core/ImageEffects/Filters/TornEdge.cs
+++ b/SnapX.Core/ImageEffects/Filters/TornEdge.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Filters/WaveEdge.cs b/SnapX.Core/ImageEffects/Filters/WaveEdge.cs
index c940e1b00..6336e604c 100644
--- a/SnapX.Core/ImageEffects/Filters/WaveEdge.cs
+++ b/SnapX.Core/ImageEffects/Filters/WaveEdge.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/ImageEffect.cs b/SnapX.Core/ImageEffects/ImageEffect.cs
index ae833b876..07c733244 100644
--- a/SnapX.Core/ImageEffects/ImageEffect.cs
+++ b/SnapX.Core/ImageEffects/ImageEffect.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/ImageEffectPackager.cs b/SnapX.Core/ImageEffects/ImageEffectPackager.cs
index 7a69aeac5..67b9a256a 100644
--- a/SnapX.Core/ImageEffects/ImageEffectPackager.cs
+++ b/SnapX.Core/ImageEffects/ImageEffectPackager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/ImageEffectPreset.cs b/SnapX.Core/ImageEffects/ImageEffectPreset.cs
index 1e2e7028e..62bae19d0 100644
--- a/SnapX.Core/ImageEffects/ImageEffectPreset.cs
+++ b/SnapX.Core/ImageEffects/ImageEffectPreset.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/AutoCrop.cs b/SnapX.Core/ImageEffects/Manipulations/AutoCrop.cs
index 1b4e3e1eb..bdb5c8712 100644
--- a/SnapX.Core/ImageEffects/Manipulations/AutoCrop.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/AutoCrop.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/Canvas.cs b/SnapX.Core/ImageEffects/Manipulations/Canvas.cs
index be0102ef6..259e2db05 100644
--- a/SnapX.Core/ImageEffects/Manipulations/Canvas.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/Canvas.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/Crop.cs b/SnapX.Core/ImageEffects/Manipulations/Crop.cs
index becc2a8db..47beb3c51 100644
--- a/SnapX.Core/ImageEffects/Manipulations/Crop.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/Crop.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/Flip.cs b/SnapX.Core/ImageEffects/Manipulations/Flip.cs
index 36e8e718d..43b51050e 100644
--- a/SnapX.Core/ImageEffects/Manipulations/Flip.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/Flip.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/ForceProportions.cs b/SnapX.Core/ImageEffects/Manipulations/ForceProportions.cs
index 44094f211..0059b2b12 100644
--- a/SnapX.Core/ImageEffects/Manipulations/ForceProportions.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/ForceProportions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/Resize.cs b/SnapX.Core/ImageEffects/Manipulations/Resize.cs
index 804cf00ce..9cd4ab7e3 100644
--- a/SnapX.Core/ImageEffects/Manipulations/Resize.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/Resize.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/Rotate.cs b/SnapX.Core/ImageEffects/Manipulations/Rotate.cs
index b5c66df1d..07da43dae 100644
--- a/SnapX.Core/ImageEffects/Manipulations/Rotate.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/Rotate.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/RoundedCorners.cs b/SnapX.Core/ImageEffects/Manipulations/RoundedCorners.cs
index 6f79c32f0..71fabcb97 100644
--- a/SnapX.Core/ImageEffects/Manipulations/RoundedCorners.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/RoundedCorners.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/Scale.cs b/SnapX.Core/ImageEffects/Manipulations/Scale.cs
index e5136c876..72e642e5d 100644
--- a/SnapX.Core/ImageEffects/Manipulations/Scale.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/Scale.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/Manipulations/Skew.cs b/SnapX.Core/ImageEffects/Manipulations/Skew.cs
index 20e385e48..3eec948e3 100644
--- a/SnapX.Core/ImageEffects/Manipulations/Skew.cs
+++ b/SnapX.Core/ImageEffects/Manipulations/Skew.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/ImageEffects/WatermarkConfig.cs b/SnapX.Core/ImageEffects/WatermarkConfig.cs
index 9064f9914..8d1f6e861 100644
--- a/SnapX.Core/ImageEffects/WatermarkConfig.cs
+++ b/SnapX.Core/ImageEffects/WatermarkConfig.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Indexer/Enums.cs b/SnapX.Core/Indexer/Enums.cs
index b4223d0d1..1cb3d89eb 100644
--- a/SnapX.Core/Indexer/Enums.cs
+++ b/SnapX.Core/Indexer/Enums.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Indexer/FolderInfo.cs b/SnapX.Core/Indexer/FolderInfo.cs
index 7108b6e32..6f2ab5153 100644
--- a/SnapX.Core/Indexer/FolderInfo.cs
+++ b/SnapX.Core/Indexer/FolderInfo.cs
@@ -1,34 +1,28 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
+using static System.String;
+
namespace SnapX.Core.Indexer;
-public class FolderInfo
+public record FolderInfo(string FolderPath)
{
- public string FolderPath { get; set; }
- public List Files { get; set; }
- public List Folders { get; set; }
+ public string FolderPath { get; set; } = FolderPath;
+ public List Files { get; set; } = [];
+ public List Folders { get; set; } = [];
public long Size { get; private set; }
public int TotalFileCount { get; private set; }
public int TotalFolderCount { get; private set; }
- public FolderInfo Parent { get; set; }
+ public FolderInfo? Parent { get; set; }
public string FolderName => Path.GetFileName(FolderPath);
public bool IsEmpty => TotalFileCount == 0 && TotalFolderCount == 0;
- public FolderInfo(string folderPath)
- {
- FolderPath = folderPath;
- Files = [];
- Folders = [];
- }
-
public void Update()
{
Folders.ForEach(x => x.Update());
- Folders.Sort((x, y) => x.FolderName.CompareTo(y.FolderName));
+ Folders.Sort((x, y) => Compare(x.FolderName, y.FolderName, StringComparison.Ordinal));
Size = Folders.Sum(x => x.Size) + Files.Sum(x => x.Length);
TotalFileCount = Files.Count + Folders.Sum(x => x.TotalFileCount);
TotalFolderCount = Folders.Count + Folders.Sum(x => x.TotalFolderCount);
diff --git a/SnapX.Core/Indexer/HtmlHelper.cs b/SnapX.Core/Indexer/HtmlHelper.cs
index 20bcddf10..5d53acc34 100644
--- a/SnapX.Core/Indexer/HtmlHelper.cs
+++ b/SnapX.Core/Indexer/HtmlHelper.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -10,14 +9,14 @@ public static class HtmlHelper
{
public static string StartTag(string tag, string style = "", string otherFields = "")
{
- string css = "";
+ var css = "";
if (!string.IsNullOrEmpty(style))
{
css = $" style=\"{style}\"";
}
- string fields = "";
+ var fields = "";
if (!string.IsNullOrEmpty(otherFields))
{
diff --git a/SnapX.Core/Indexer/Indexer.cs b/SnapX.Core/Indexer/Indexer.cs
index b6cdd5aba..56a287f61 100644
--- a/SnapX.Core/Indexer/Indexer.cs
+++ b/SnapX.Core/Indexer/Indexer.cs
@@ -1,16 +1,14 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
+using static System.String;
+
namespace SnapX.Core.Indexer;
-public abstract class Indexer
+public abstract class Indexer(IndexerSettings IndexerSettings)
{
- protected IndexerSettings settings = null;
- protected Indexer(IndexerSettings indexerSettings)
- {
- settings = indexerSettings;
- }
+ protected IndexerSettings? settings = IndexerSettings;
+
public string? Index(string? folderPath)
{
Indexer indexer = null;
@@ -60,27 +58,27 @@ protected Indexer(IndexerSettings indexerSettings)
protected FolderInfo GetFolderInfo(string folderPath, int level = 0)
{
- FolderInfo folderInfo = new FolderInfo(folderPath);
+ var folderInfo = new FolderInfo(folderPath);
if (settings.MaxDepthLevel == 0 || level < settings.MaxDepthLevel)
{
try
{
- DirectoryInfo currentDirectoryInfo = new DirectoryInfo(folderPath);
+ var currentDirectoryInfo = new DirectoryInfo(folderPath);
- foreach (DirectoryInfo directoryInfo in currentDirectoryInfo.EnumerateDirectories())
+ foreach (var directoryInfo in currentDirectoryInfo.EnumerateDirectories())
{
if (settings.SkipHiddenFolders && directoryInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
continue;
}
- FolderInfo subFolderInfo = GetFolderInfo(directoryInfo.FullName, level + 1);
+ var subFolderInfo = GetFolderInfo(directoryInfo.FullName, level + 1);
folderInfo.Folders.Add(subFolderInfo);
subFolderInfo.Parent = folderInfo;
}
- foreach (FileInfo fileInfo in currentDirectoryInfo.EnumerateFiles())
+ foreach (var fileInfo in currentDirectoryInfo.EnumerateFiles())
{
if (settings.SkipHiddenFiles && fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
@@ -90,7 +88,7 @@ protected FolderInfo GetFolderInfo(string folderPath, int level = 0)
folderInfo.Files.Add(fileInfo);
}
- folderInfo.Files.Sort((x, y) => x.Name.CompareTo(y.Name));
+ folderInfo.Files.Sort((x, y) => Compare(x.Name, y.Name, StringComparison.Ordinal));
}
catch (UnauthorizedAccessException)
{
diff --git a/SnapX.Core/Indexer/IndexerHtml.cs b/SnapX.Core/Indexer/IndexerHtml.cs
index 977a1532b..ef20c5475 100644
--- a/SnapX.Core/Indexer/IndexerHtml.cs
+++ b/SnapX.Core/Indexer/IndexerHtml.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Indexer/IndexerJson.cs b/SnapX.Core/Indexer/IndexerJson.cs
index b2be409a5..9272a4488 100644
--- a/SnapX.Core/Indexer/IndexerJson.cs
+++ b/SnapX.Core/Indexer/IndexerJson.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Indexer/IndexerText.cs b/SnapX.Core/Indexer/IndexerText.cs
index 8a0f830fc..6369aa25c 100644
--- a/SnapX.Core/Indexer/IndexerText.cs
+++ b/SnapX.Core/Indexer/IndexerText.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Indexer/IndexerXml.cs b/SnapX.Core/Indexer/IndexerXml.cs
index 0b4e1258d..69c241cb4 100644
--- a/SnapX.Core/Indexer/IndexerXml.cs
+++ b/SnapX.Core/Indexer/IndexerXml.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -15,26 +14,24 @@ public IndexerXml(IndexerSettings indexerSettings) : base(indexerSettings)
public string Index(string folderPath)
{
- FolderInfo folderInfo = new FolderInfo(folderPath);
+ var folderInfo = new FolderInfo(folderPath);
folderInfo.Update();
- XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
+ var xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Encoding = new UTF8Encoding(false);
xmlWriterSettings.ConformanceLevel = ConformanceLevel.Document;
xmlWriterSettings.Indent = true;
- using (MemoryStream ms = new MemoryStream())
+ using var ms = new MemoryStream();
+ using (xmlWriter = XmlWriter.Create(ms, xmlWriterSettings))
{
- using (xmlWriter = XmlWriter.Create(ms, xmlWriterSettings))
- {
- xmlWriter.WriteStartDocument();
- IndexFolder(folderInfo);
- xmlWriter.WriteEndDocument();
- xmlWriter.Flush();
- }
-
- return Encoding.UTF8.GetString(ms.ToArray());
+ xmlWriter.WriteStartDocument();
+ IndexFolder(folderInfo);
+ xmlWriter.WriteEndDocument();
+ xmlWriter.Flush();
}
+
+ return Encoding.UTF8.GetString(ms.ToArray());
}
protected override void IndexFolder(FolderInfo dir, int level = 0)
@@ -45,7 +42,7 @@ protected override void IndexFolder(FolderInfo dir, int level = 0)
{
xmlWriter.WriteStartElement("Files");
- foreach (FileInfo fi in dir.Files)
+ foreach (var _ in dir.Files)
{
xmlWriter.WriteStartElement("File");
@@ -59,9 +56,9 @@ protected override void IndexFolder(FolderInfo dir, int level = 0)
{
xmlWriter.WriteStartElement("Folders");
- foreach (FolderInfo subdir in dir.Folders)
+ foreach (var subDir in dir.Folders)
{
- IndexFolder(subdir);
+ IndexFolder(subDir);
}
xmlWriter.WriteEndElement();
diff --git a/SnapX.Core/Interfaces/IDelayService.cs b/SnapX.Core/Interfaces/IDelayService.cs
new file mode 100644
index 000000000..722a1738e
--- /dev/null
+++ b/SnapX.Core/Interfaces/IDelayService.cs
@@ -0,0 +1,6 @@
+namespace SnapX.Core.Interfaces;
+
+public interface IDelayService
+{
+ Task DelayAsync(int milliseconds);
+}
diff --git a/SnapX.Core/Interfaces/IFilePicker.cs b/SnapX.Core/Interfaces/IFilePicker.cs
new file mode 100644
index 000000000..0b642c349
--- /dev/null
+++ b/SnapX.Core/Interfaces/IFilePicker.cs
@@ -0,0 +1,13 @@
+namespace SnapX.Core.Interfaces;
+
+public interface IFilePicker
+{
+ ///
+ /// Prompts the user to select one or more files.
+ ///
+ /// Dialog title.
+ /// Optional initial directory.
+ /// Allow selecting multiple files.
+ /// Array of selected file paths, or empty array if cancelled.
+ Task PickFilesAsync(string title, string initialDirectory, bool allowMultiple);
+}
diff --git a/SnapX.Core/Interfaces/ILoggerService.cs b/SnapX.Core/Interfaces/ILoggerService.cs
new file mode 100644
index 000000000..875cc83de
--- /dev/null
+++ b/SnapX.Core/Interfaces/ILoggerService.cs
@@ -0,0 +1,20 @@
+using Serilog.Core;
+
+namespace SnapX.Core.Interfaces;
+
+public interface ILoggerService
+{
+ ILogScope BeginScope(string name);
+ [MessageTemplateFormatMethod("messageTemplate")]
+ void Debug(string messageTemplate, params object[] propertyValues);
+ [MessageTemplateFormatMethod("messageTemplate")]
+ void Information(string messageTemplate, params object[] propertyValues);
+ [MessageTemplateFormatMethod("messageTemplate")]
+ void Warning(string messageTemplate, params object[] propertyValues);
+ [MessageTemplateFormatMethod("messageTemplate")]
+ void Error(string messageTemplate, params object[] propertyValues);
+ [MessageTemplateFormatMethod("messageTemplate")]
+ void Error(Exception exception, string messageTemplate, params object[] propertyValues);
+}
+
+public interface ILogScope : IDisposable;
diff --git a/SnapX.Core/Interfaces/IMainWindowService.cs b/SnapX.Core/Interfaces/IMainWindowService.cs
new file mode 100644
index 000000000..cf1231ae5
--- /dev/null
+++ b/SnapX.Core/Interfaces/IMainWindowService.cs
@@ -0,0 +1,7 @@
+namespace SnapX.Core.SharpCapture.Interfaces;
+
+public interface IMainWindowService
+{
+ Task HideAsync();
+ Task ForceActivateAsync();
+}
diff --git a/SnapX.Core/Interfaces/INotificationService.cs b/SnapX.Core/Interfaces/INotificationService.cs
new file mode 100644
index 000000000..54873aebc
--- /dev/null
+++ b/SnapX.Core/Interfaces/INotificationService.cs
@@ -0,0 +1,9 @@
+using SnapX.Core.Job;
+
+namespace SnapX.Core.Interfaces;
+
+public interface INotificationService
+{
+ Task CloseActiveFormAsync();
+ Task PlayNotificationSoundAsync(NotificationSound sound, TaskSettings settings);
+}
diff --git a/SnapX.Core/Interfaces/IUploadManager.cs b/SnapX.Core/Interfaces/IUploadManager.cs
new file mode 100644
index 000000000..a15df2c1d
--- /dev/null
+++ b/SnapX.Core/Interfaces/IUploadManager.cs
@@ -0,0 +1,8 @@
+using SnapX.Core.Job;
+
+namespace SnapX.Core.Interfaces;
+
+public interface IUploadManager
+{
+ Task RunImageTaskAsync(TaskMetadata metadata, TaskSettings taskSettings);
+}
diff --git a/SnapX.Core/Job/QuickTaskInfo.cs b/SnapX.Core/Job/QuickTaskInfo.cs
index c57601a16..bd61edcb3 100644
--- a/SnapX.Core/Job/QuickTaskInfo.cs
+++ b/SnapX.Core/Job/QuickTaskInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Job/TaskEx.cs b/SnapX.Core/Job/TaskEx.cs
index 18eea9f7b..12a486a19 100644
--- a/SnapX.Core/Job/TaskEx.cs
+++ b/SnapX.Core/Job/TaskEx.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Job/TaskHelpers.cs b/SnapX.Core/Job/TaskHelpers.cs
index ce0051772..b8161f3a7 100644
--- a/SnapX.Core/Job/TaskHelpers.cs
+++ b/SnapX.Core/Job/TaskHelpers.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -22,11 +21,10 @@
using SixLabors.ImageSharp.Formats.Tiff;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
-using SnapX.Core.Capture;
using SnapX.Core.CLI;
using SnapX.Core.ImageEffects;
using SnapX.Core.Media;
-using SnapX.Core.ScreenCapture;
+using SnapX.Core.SharpCapture;
using SnapX.Core.Upload;
using SnapX.Core.Upload.Custom;
using SnapX.Core.Upload.SharingServices;
@@ -47,12 +45,12 @@ public static async Task ExecuteJob(HotkeyType job, CLICommand command = null)
await ExecuteJob(SnapX.DefaultTaskSettings, job, command);
}
- public static async Task ExecuteJob(TaskSettings taskSettings)
+ public static async Task ExecuteJob(TaskSettings? taskSettings)
{
await ExecuteJob(taskSettings, taskSettings.Job);
}
- public static async Task ExecuteJob(TaskSettings taskSettings, HotkeyType job, CLICommand command = null)
+ public static async Task ExecuteJob(TaskSettings? taskSettings, HotkeyType job, CLICommand command = null)
{
if (job == HotkeyType.None) return;
@@ -100,31 +98,31 @@ public static async Task ExecuteJob(TaskSettings taskSettings, HotkeyType job, C
break;
// Screen capture
case HotkeyType.PrintScreen:
- new CaptureFullscreen().Capture(safeTaskSettings);
+ // new CaptureFullscreen().CaptureAsync(safeTaskSettings);
break;
case HotkeyType.ActiveWindow:
- new CaptureActiveWindow().Capture(safeTaskSettings);
+ // new CaptureActiveWindow().CaptureAsync(safeTaskSettings);
break;
case HotkeyType.ActiveMonitor:
- new CaptureActiveMonitor().Capture(safeTaskSettings);
+ // new CaptureActiveMonitor().CaptureAsync(safeTaskSettings);
break;
case HotkeyType.RectangleRegion:
- new CaptureRegion().Capture(safeTaskSettings);
+ // new CaptureRegion().CaptureAsync(safeTaskSettings);
break;
case HotkeyType.RectangleLight:
- new CaptureRegion(RegionCaptureType.Light).Capture(safeTaskSettings);
+ // new CaptureRegion(RegionCaptureType.Light).Capture(safeTaskSettings);
break;
case HotkeyType.RectangleTransparent:
- new CaptureRegion(RegionCaptureType.Transparent).Capture(safeTaskSettings);
+ // new CaptureRegion(RegionCaptureType.Transparent).Capture(safeTaskSettings);
break;
case HotkeyType.CustomRegion:
- new CaptureCustomRegion().Capture(safeTaskSettings);
+ // new CaptureCustomRegion().Capture(safeTaskSettings);
break;
case HotkeyType.CustomWindow:
- new CaptureCustomWindow().Capture(safeTaskSettings);
+ // new CaptureCustomWindow().Capture(safeTaskSettings);
break;
case HotkeyType.LastRegion:
- new CaptureLastRegion().Capture(safeTaskSettings);
+ // new CaptureLastRegion().Capture(safeTaskSettings);
break;
case HotkeyType.ScrollingCapture:
DebugHelper.WriteException("HotkeyType.ScrollingCapture is NOT implemented.");
@@ -321,7 +319,7 @@ public static async Task ExecuteJob(TaskSettings taskSettings, HotkeyType job, C
}
}
- public static ImageData PrepareImage(Image img, TaskSettings taskSettings)
+ public static ImageData PrepareImage(Image img, TaskSettings? taskSettings)
{
var imageData = new ImageData();
imageData.ImageStream = SaveImageAsStream(img, taskSettings.ImageSettings.ImageFormat, taskSettings);
@@ -371,7 +369,7 @@ public static ImageData PrepareImage(Image img, TaskSettings taskSettings)
// return null;
// }
- public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat, TaskSettings taskSettings)
+ public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat, TaskSettings? taskSettings)
{
return SaveImageAsStream(img, imageFormat, taskSettings.ImageSettings.ImagePNGBitDepth,
taskSettings.ImageSettings.ImageJPEGQuality, taskSettings.ImageSettings.ImageGIFQuality);
@@ -417,7 +415,7 @@ public static MemoryStream SaveImageAsStream(Image image, EImageFormat imageForm
return ms;
}
- public static void SaveImageAsFile(Image img, TaskSettings taskSettings, bool overwriteFile = false)
+ public static void SaveImageAsFile(Image img, TaskSettings? taskSettings, bool overwriteFile = false)
{
using (ImageData imageData = PrepareImage(img, taskSettings))
{
@@ -437,7 +435,7 @@ public static void SaveImageAsFile(Image img, TaskSettings taskSettings, bool ov
}
}
}
- public static string? HandleExistsFile(string? filePath, TaskSettings taskSettings)
+ public static string? HandleExistsFile(string? filePath, TaskSettings? taskSettings)
{
if (File.Exists(filePath))
{
@@ -457,18 +455,18 @@ public static void SaveImageAsFile(Image img, TaskSettings taskSettings, bool ov
return filePath;
}
- public static string? HandleExistsFile(string? folderPath, string? fileName, TaskSettings taskSettings)
+ public static string? HandleExistsFile(string? folderPath, string? fileName, TaskSettings? taskSettings)
{
var filePath = Path.Combine(folderPath, fileName);
return HandleExistsFile(filePath, taskSettings);
}
- public static string? GetFileName(TaskSettings taskSettings, string extension, Image bmp)
+ public static string? GetFileName(TaskSettings? taskSettings, string extension, Image bmp)
{
var metadata = new TaskMetadata(bmp);
return GetFileName(taskSettings, extension, metadata);
}
- public static string? GetFileName(TaskSettings taskSettings, string extension = null, TaskMetadata metadata = null)
+ public static string? GetFileName(TaskSettings? taskSettings, string extension = null, TaskMetadata metadata = null)
{
string? fileName;
@@ -511,7 +509,7 @@ public static void SaveImageAsFile(Image img, TaskSettings taskSettings, bool ov
return fileName;
}
- public static string? GetScreenshotsFolder(TaskSettings taskSettings = null, TaskMetadata metadata = null, DateTime? date = null)
+ public static string? GetScreenshotsFolder(TaskSettings? taskSettings = null, TaskMetadata metadata = null, DateTime? date = null)
{
date ??= DateTime.Now;
var dt = date.Value;
@@ -753,7 +751,7 @@ public static async Task OCRImage(Image? image = null, string? filePath
return result.Text;
}
- public static void PinToScreen(TaskSettings taskSettings = null)
+ public static void PinToScreen(TaskSettings? taskSettings = null)
{
throw new NotImplementedException("PinToScreen is not implemented");
}
@@ -763,7 +761,7 @@ public static void TweetMessage()
throw new NotImplementedException("TweetMessage is not implemented");
}
- public static EDataType FindDataType(string? filePath, TaskSettings taskSettings)
+ public static EDataType FindDataType(string? filePath, TaskSettings? taskSettings)
{
if (FileHelpers.CheckExtension(filePath, taskSettings.AdvancedSettings.ImageExtensions))
{
@@ -796,7 +794,7 @@ public static bool CheckFFmpeg(TaskSettings taskSettings)
return true;
}
- public static Screenshot GetScreenshot(TaskSettings taskSettings = null)
+ public static Screenshot GetScreenshot(TaskSettings? taskSettings = null)
{
if (taskSettings == null) taskSettings = TaskSettings.GetDefaultTaskSettings();
@@ -909,7 +907,7 @@ public static void ImportImageEffect(string? json)
}
}
- public static async Task HandleNativeMessagingInput(string? filePath, TaskSettings taskSettings = null)
+ public static async Task HandleNativeMessagingInput(string? filePath, TaskSettings? taskSettings = null)
{
if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
{
diff --git a/SnapX.Core/Job/TaskInfo.cs b/SnapX.Core/Job/TaskInfo.cs
index 7faf072a2..9d62270f6 100644
--- a/SnapX.Core/Job/TaskInfo.cs
+++ b/SnapX.Core/Job/TaskInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -10,9 +9,9 @@
using SnapX.Core.Utils.Extensions;
namespace SnapX.Core.Job;
-public class TaskInfo
+public record TaskInfo
{
- public TaskSettings TaskSettings { get; set; }
+ public TaskSettings? TaskSettings { get; set; }
public string Status { get; set; }
public TaskJob Job { get; set; }
@@ -126,14 +125,11 @@ public string UploaderHost
public Stopwatch UploadDuration { get; set; }
- public UploadResult Result { get; set; }
+ public UploadResult? Result { get; set; }
- public TaskInfo(TaskSettings taskSettings)
+ public TaskInfo(TaskSettings? taskSettings = null)
{
- if (taskSettings == null)
- {
- taskSettings = TaskSettings.GetDefaultTaskSettings();
- }
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
TaskSettings = taskSettings;
Metadata = new TaskMetadata();
@@ -149,16 +145,15 @@ public TaskInfo(TaskSettings taskSettings)
if (!string.IsNullOrEmpty(Metadata.WindowTitle))
{
- tags.Add(new HistoryItem.Tag { Text = Metadata.WindowTitle });
+ tags.Add(new HistoryItem.Tag { Name = "WindowTitle", Value = Metadata.WindowTitle });
}
- // Add ProcessName tag if present
if (!string.IsNullOrEmpty(Metadata.ProcessName))
{
- tags.Add(new HistoryItem.Tag { Text = Metadata.ProcessName });
+ tags.Add(new HistoryItem.Tag { Name = "ProcessName", Value = Metadata.ProcessName });
}
- return tags.Count != 0 ? tags : null;
+ return tags.Count != 0 ? tags : [];
}
diff --git a/SnapX.Core/Job/TaskManager.cs b/SnapX.Core/Job/TaskManager.cs
index 940f13c0b..00684ec67 100644
--- a/SnapX.Core/Job/TaskManager.cs
+++ b/SnapX.Core/Job/TaskManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Job/TaskMetadata.cs b/SnapX.Core/Job/TaskMetadata.cs
index 9570e031f..27ac79699 100644
--- a/SnapX.Core/Job/TaskMetadata.cs
+++ b/SnapX.Core/Job/TaskMetadata.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -11,7 +10,7 @@ public class TaskMetadata : IDisposable
{
private const int WindowInfoMaxLength = 255;
- public Image Image { get; set; }
+ public Image? Image { get; set; }
private string? windowTitle;
diff --git a/SnapX.Core/Job/TaskSettings.cs b/SnapX.Core/Job/TaskSettings.cs
index 4ff4caf29..529a1d47e 100644
--- a/SnapX.Core/Job/TaskSettings.cs
+++ b/SnapX.Core/Job/TaskSettings.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -7,7 +6,8 @@
using System.Text.Json.Serialization;
using SixLabors.ImageSharp;
using SnapX.Core.Indexer;
-using SnapX.Core.ScreenCapture;
+using SnapX.Core.Media;
+using SnapX.Core.SharpCapture;
using SnapX.Core.Upload;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Extensions;
@@ -18,7 +18,7 @@ namespace SnapX.Core.Job;
public class TaskSettings
{
[JsonIgnore]
- public TaskSettings TaskSettingsReference { get; private set; }
+ public TaskSettings? TaskSettingsReference { get; private set; }
[JsonIgnore]
public bool IsSafeTaskSettings => TaskSettingsReference != null;
@@ -132,17 +132,17 @@ public bool IsUsingDefaultSettings
}
}
- public static TaskSettings GetDefaultTaskSettings()
+ public static TaskSettings? GetDefaultTaskSettings()
{
- TaskSettings taskSettings = new TaskSettings();
+ var taskSettings = new TaskSettings();
taskSettings.SetDefaultSettings();
taskSettings.TaskSettingsReference = SnapX.DefaultTaskSettings;
return taskSettings;
}
- public static TaskSettings GetSafeTaskSettings(TaskSettings taskSettings)
+ public static TaskSettings? GetSafeTaskSettings(TaskSettings? taskSettings)
{
- TaskSettings safeTaskSettings;
+ TaskSettings? safeTaskSettings;
if (taskSettings.IsUsingDefaultSettings && SnapX.DefaultTaskSettings != null)
{
@@ -164,7 +164,7 @@ public void SetDefaultSettings()
{
if (SnapX.DefaultTaskSettings != null)
{
- TaskSettings defaultTaskSettings = SnapX.DefaultTaskSettings.Copy();
+ TaskSettings? defaultTaskSettings = SnapX.DefaultTaskSettings.Copy();
if (UseDefaultAfterCaptureJob)
{
@@ -369,7 +369,7 @@ public class TaskSettingsCapture
// public FFmpegOptions FFmpegOptions = new FFmpegOptions();
public int ScreenRecordFPS = 30;
public int GIFFPS = 15;
- public RegionCaptureOptions SurfaceOptions = new RegionCaptureOptions();
+ public RegionCaptureOptions SurfaceOptions = new();
public bool ScreenRecordShowCursor = true;
public bool ScreenRecordAutoStart = true;
public float ScreenRecordStartDelay = 0f;
@@ -431,13 +431,13 @@ public class TaskSettingsTools
public string ScreenColorPickerFormat = "$hex";
public string ScreenColorPickerFormatCtrl = "$r255, $g255, $b255";
public string ScreenColorPickerInfoText = "RGB: $r255, $g255, $b255$nHex: $hex$nX: $x Y: $y";
- public PinToScreenOptions PinToScreenOptions = new();
+ // public PinToScreenOptions PinToScreenOptions = new();
public IndexerSettings IndexerSettings = new();
public ImageBeautifierOptions ImageBeautifierOptions = new();
public ImageCombinerOptions ImageCombinerOptions = new();
public VideoConverterOptions VideoConverterOptions = new();
public VideoThumbnailOptions VideoThumbnailOptions = new();
- public BorderlessWindowSettings BorderlessWindowSettings = new();
+ // public BorderlessWindowSettings BorderlessWindowSettings = new();
}
public class TaskSettingsAdvanced
diff --git a/SnapX.Core/Job/ThreadWorker.cs b/SnapX.Core/Job/ThreadWorker.cs
index 3b05d21a4..5f91ab36e 100644
--- a/SnapX.Core/Job/ThreadWorker.cs
+++ b/SnapX.Core/Job/ThreadWorker.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Job/WorkerTask.cs b/SnapX.Core/Job/WorkerTask.cs
index d8efdcbd9..0ed239b26 100644
--- a/SnapX.Core/Job/WorkerTask.cs
+++ b/SnapX.Core/Job/WorkerTask.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -6,7 +5,6 @@
using System.Text;
using System.Text.RegularExpressions;
using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.PixelFormats;
using SnapX.Core.Hotkey;
using SnapX.Core.Upload;
using SnapX.Core.Upload.BaseServices;
@@ -40,24 +38,24 @@ public class WorkerTask : IDisposable
public bool StopRequested { get; private set; }
public bool RequestSettingUpdate { get; private set; }
public bool EarlyURLCopied { get; private set; }
- public Stream Data { get; private set; }
- public Image Image { get; private set; }
+ public Stream? Data { get; private set; }
+ public Image? Image { get; private set; }
public bool KeepImage { get; set; }
public string? Text { get; private set; }
private ThreadWorker threadWorker;
- private GenericUploader uploader;
+ private GenericUploader? uploader;
private TaskReferenceHelper taskReferenceHelper;
#region Constructors
- private WorkerTask(TaskSettings taskSettings)
+ private WorkerTask(TaskSettings? taskSettings)
{
Status = TaskStatus.InQueue;
Info = new TaskInfo(taskSettings);
}
- public static WorkerTask CreateDataUploaderTask(EDataType dataType, Stream stream, string? fileName, TaskSettings taskSettings)
+ public static WorkerTask CreateDataUploaderTask(EDataType dataType, Stream stream, string? fileName, TaskSettings? taskSettings)
{
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = TaskJob.DataUpload;
@@ -67,7 +65,7 @@ public static WorkerTask CreateDataUploaderTask(EDataType dataType, Stream strea
return task;
}
- public static WorkerTask CreateFileUploaderTask(string? filePath, TaskSettings taskSettings)
+ public static WorkerTask CreateFileUploaderTask(string? filePath, TaskSettings? taskSettings)
{
WorkerTask task = new WorkerTask(taskSettings);
task.Info.FilePath = filePath;
@@ -98,7 +96,7 @@ public static WorkerTask CreateFileUploaderTask(string? filePath, TaskSettings t
return task;
}
- public static WorkerTask CreateImageUploaderTask(TaskMetadata metadata, TaskSettings taskSettings, string customFileName = null)
+ public static WorkerTask CreateImageUploaderTask(TaskMetadata metadata, TaskSettings? taskSettings, string customFileName = null)
{
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = TaskJob.Job;
@@ -118,7 +116,7 @@ public static WorkerTask CreateImageUploaderTask(TaskMetadata metadata, TaskSett
return task;
}
- public static WorkerTask CreateTextUploaderTask(string? text, TaskSettings taskSettings)
+ public static WorkerTask CreateTextUploaderTask(string? text, TaskSettings? taskSettings)
{
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = TaskJob.TextUpload;
@@ -128,7 +126,7 @@ public static WorkerTask CreateTextUploaderTask(string? text, TaskSettings taskS
return task;
}
- public static WorkerTask CreateURLShortenerTask(string? url, TaskSettings taskSettings)
+ public static WorkerTask CreateURLShortenerTask(string? url, TaskSettings? taskSettings)
{
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = TaskJob.ShortenURL;
@@ -138,7 +136,7 @@ public static WorkerTask CreateURLShortenerTask(string? url, TaskSettings taskSe
return task;
}
- public static WorkerTask CreateShareURLTask(string? url, TaskSettings taskSettings)
+ public static WorkerTask CreateShareURLTask(string? url, TaskSettings? taskSettings)
{
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = TaskJob.ShareURL;
@@ -148,7 +146,7 @@ public static WorkerTask CreateShareURLTask(string? url, TaskSettings taskSettin
return task;
}
- public static WorkerTask CreateFileJobTask(string? filePath, TaskMetadata metadata, TaskSettings taskSettings, string customFileName = null)
+ public static WorkerTask CreateFileJobTask(string? filePath, TaskMetadata metadata, TaskSettings? taskSettings, string customFileName = null)
{
var task = new WorkerTask(taskSettings);
task.Info.FilePath = filePath;
@@ -176,7 +174,7 @@ public static WorkerTask CreateFileJobTask(string? filePath, TaskMetadata metada
return task;
}
- public static WorkerTask CreateDownloadTask(string? url, bool upload, TaskSettings taskSettings)
+ public static WorkerTask CreateDownloadTask(string? url, bool upload, TaskSettings? taskSettings)
{
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = upload ? TaskJob.DownloadUpload : TaskJob.Download;
@@ -288,10 +286,10 @@ private void ThreadDoWork()
Clipboard.Clear();
}
- if ((Info.Job == TaskJob.Job || (Info.Job == TaskJob.FileUpload && Info.TaskSettings.AdvancedSettings.UseAfterCaptureTasksDuringFileUpload))
- && Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.DeleteFile) && !string.IsNullOrEmpty(Info.FilePath) && System.IO.File.Exists(Info.FilePath))
+ if ((Info.Job == TaskJob.Job || (Info.Job == TaskJob.FileUpload && (Info.TaskSettings?.AdvancedSettings.UseAfterCaptureTasksDuringFileUpload ?? true)))
+ && Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.DeleteFile) && !string.IsNullOrEmpty(Info.FilePath) && File.Exists(Info.FilePath))
{
- System.IO.File.Delete(Info.FilePath);
+ File.Delete(Info.FilePath);
}
}
@@ -491,10 +489,7 @@ private void AddErrorMessage(UploaderErrorManager errors)
private void AddErrorMessage(string? error)
{
- if (Info.Result == null)
- {
- Info.Result = new UploadResult();
- }
+ Info.Result ??= new UploadResult();
Info.Result.Errors.Add(error);
}
@@ -671,29 +666,24 @@ private void DoFileJobs()
{
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.PerformActions) && Info.TaskSettings.ExternalPrograms != null)
{
- IEnumerable actions = Info.TaskSettings.ExternalPrograms.Where(x => x.IsActive);
+ var actions = Info.TaskSettings.ExternalPrograms.Where(x => x.IsActive);
- if (actions.Count() > 0)
+ if (actions.Any())
{
- bool isFileModified = false;
- string? fileName = Info.FileName;
+ var isFileModified = false;
+ var fileName = Info.FileName;
foreach (ExternalProgram fileAction in actions)
{
- string? modifiedPath = fileAction.Run(Info.FilePath);
+ var modifiedPath = fileAction.Run(Info.FilePath);
- if (!string.IsNullOrEmpty(modifiedPath))
- {
- isFileModified = true;
- Info.FilePath = modifiedPath;
+ if (string.IsNullOrEmpty(modifiedPath)) continue;
+ isFileModified = true;
+ Info.FilePath = modifiedPath;
- if (Data != null)
- {
- Data.Dispose();
- }
+ Data?.Dispose();
- fileAction.DeletePendingInputFile();
- }
+ fileAction.DeletePendingInputFile();
}
if (isFileModified)
@@ -791,16 +781,7 @@ private void DoAfterUploadJobs()
if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.CopyURLToClipboard))
{
- string? txt;
-
- if (!string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.ClipboardContentFormat))
- {
- txt = new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.ClipboardContentFormat);
- }
- else
- {
- txt = Info.Result.ToString();
- }
+ var txt = !string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.ClipboardContentFormat) ? new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.ClipboardContentFormat) : Info.Result.ToString();
if (!string.IsNullOrEmpty(txt))
{
@@ -810,16 +791,7 @@ private void DoAfterUploadJobs()
if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.OpenURL))
{
- string? result;
-
- if (!string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.OpenURLFormat))
- {
- result = new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.OpenURLFormat);
- }
- else
- {
- result = Info.Result.ToString();
- }
+ var result = !string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.OpenURLFormat) ? new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.OpenURLFormat) : Info.Result.ToString();
URLHelpers.OpenURL(result);
}
diff --git a/SnapX.Core/Media/Enums.cs b/SnapX.Core/Media/Enums.cs
index e4f31497f..a56181466 100644
--- a/SnapX.Core/Media/Enums.cs
+++ b/SnapX.Core/Media/Enums.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/GradientInfo.cs b/SnapX.Core/Media/GradientInfo.cs
new file mode 100644
index 000000000..b65cfb6a9
--- /dev/null
+++ b/SnapX.Core/Media/GradientInfo.cs
@@ -0,0 +1,136 @@
+using System.ComponentModel;
+using System.Text.Json.Serialization;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Drawing.Processing;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+using SnapX.Core.Utils;
+
+namespace SnapX.Core.Media;
+
+public enum LinearGradientMode
+{
+ Horizontal,
+ Vertical
+}
+
+public record GradientStop(Color Color, float Location)
+{
+ public Color Color { get; set; } = Color;
+ public float Location { get; set; } = Location; // 0-100
+}
+
+public class GradientInfo(LinearGradientMode Type)
+{
+ [DefaultValue(LinearGradientMode.Vertical)]
+ public LinearGradientMode Type { get; set; } = Type;
+
+ ///
+ /// Gradient color stops, each with a Ratio in [0,1]
+ ///
+ public List Colors { get; set; } = new();
+
+ [JsonIgnore]
+ public bool IsValid => Colors is { Count: > 0 };
+
+ [JsonIgnore]
+ public bool IsVisible => IsValid && Colors.Any(x => x.Color.ToPixel().A > 0);
+
+ [JsonIgnore]
+ public bool IsTransparent => IsValid && Colors.Any(x => x.Color.ToPixel().A < 255);
+
+ public GradientInfo() : this(LinearGradientMode.Vertical) { }
+
+ public GradientInfo(LinearGradientMode type, params ColorStop[] colors) : this(type)
+ {
+ Colors = colors.ToList();
+ }
+
+ public GradientInfo(LinearGradientMode type, params Color[] colors) : this(type)
+ {
+ var count = colors.Length;
+ for (var i = 0; i < count; i++)
+ {
+ var ratio = (count == 1) ? 0f : i / (float)(count - 1);
+ Colors.Add(new ColorStop(ratio, colors[i]));
+ }
+ }
+
+ public GradientInfo(params ColorStop[] colors) : this(LinearGradientMode.Vertical, colors) { }
+
+ public GradientInfo(params Color[] colors) : this(LinearGradientMode.Vertical, colors) { }
+
+ public void Clear()
+ {
+ Colors.Clear();
+ }
+
+ public void Sort()
+ {
+ Colors.Sort((x, y) => x.Ratio.CompareTo(y.Ratio));
+ }
+
+ public void Reverse()
+ {
+ Colors = Colors
+ .Select(s => new ColorStop(1f - s.Ratio, s.Color))
+ .OrderBy(s => s.Ratio)
+ .ToList();
+ }
+
+ ///
+ /// Returns an ImageSharp LinearGradientBrush based on this gradient info.
+ ///
+ public Brush GetGradientBrush(RectangleF rect)
+ {
+ var stops = Colors
+ .OrderBy(x => x.Ratio)
+ .ToArray();
+
+ if (stops.All(x => x.Ratio != 0f))
+ {
+ var first = stops.FirstOrDefault();
+ stops = new[] { new ColorStop(0f, first.Color) }.Concat(stops).ToArray();
+ }
+
+ if (stops.All(x => x.Ratio != 1f))
+ {
+ var last = stops.LastOrDefault();
+ stops = stops.Append(new ColorStop(1f, last.Color)).ToArray();
+ }
+
+ var start = new PointF(rect.Left, rect.Top);
+
+ var end = Type == LinearGradientMode.Horizontal
+ ? new PointF(rect.Right, rect.Top)
+ : new PointF(rect.Left, rect.Bottom);
+
+ return new LinearGradientBrush(start, end, GradientRepetitionMode.Repeat, stops);
+ }
+
+ public Image CreateGradientPreview(int width, int height, bool border = false, bool checkers = false)
+ {
+ var image = new Image(width, height);
+
+ if (checkers && IsTransparent)
+ {
+ ImageHelpers.DrawCheckerPattern(image, 10, [Color.LightGray, Color.White]);
+ }
+
+ var brush = GetGradientBrush(new RectangleF(0, 0, width, height));
+
+ image.Mutate(ctx =>
+ {
+ ctx.Fill(brush);
+
+ if (border)
+ {
+ ctx.Draw(Color.Black, 1, new RectangleF(0, 0, width - 1, height - 1));
+ }
+ });
+
+ return image;
+ }
+
+ public override string ToString() => "Gradient";
+}
diff --git a/SnapX.Core/Media/ImageBeautifierOptions.cs b/SnapX.Core/Media/ImageBeautifierOptions.cs
new file mode 100644
index 000000000..a8fa37aea
--- /dev/null
+++ b/SnapX.Core/Media/ImageBeautifierOptions.cs
@@ -0,0 +1,47 @@
+using SixLabors.ImageSharp;
+
+namespace SnapX.Core.Media;
+
+public class ImageBeautifierOptions
+{
+ public int Margin { get; set; }
+ public int Padding { get; set; }
+ public bool SmartPadding { get; set; }
+ public int RoundedCorner { get; set; }
+ public int ShadowRadius { get; set; }
+ public int ShadowOpacity { get; set; }
+ public int ShadowDistance { get; set; }
+ public int ShadowAngle { get; set; }
+ public Color ShadowColor { get; set; }
+ public ImageBeautifierBackgroundType BackgroundType { get; set; }
+ public GradientInfo BackgroundGradient { get; set; }
+ public Color BackgroundColor { get; set; }
+ public string BackgroundImageFilePath { get; set; }
+
+ public ImageBeautifierOptions()
+ {
+ ResetOptions();
+ }
+
+ public void ResetOptions()
+ {
+ Margin = 80;
+ Padding = 40;
+ SmartPadding = true;
+ RoundedCorner = 20;
+ ShadowRadius = 30;
+ ShadowOpacity = 80;
+ ShadowDistance = 10;
+ ShadowAngle = 180;
+ ShadowColor = Color.Black;
+ BackgroundType = ImageBeautifierBackgroundType.Gradient;
+ BackgroundGradient = new GradientInfo(
+ LinearGradientMode.Horizontal,
+ Color.FromRgba(255, 81, 47, 255),
+ Color.FromRgba(221, 36, 118, 255)
+ );
+
+ BackgroundColor = Color.FromRgba(34, 34, 34, 255);
+ BackgroundImageFilePath = "";
+ }
+}
diff --git a/SnapX.Core/Media/ImageCombinerOptions.cs b/SnapX.Core/Media/ImageCombinerOptions.cs
index 19d66ad65..340a62008 100644
--- a/SnapX.Core/Media/ImageCombinerOptions.cs
+++ b/SnapX.Core/Media/ImageCombinerOptions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/ScreenRecordManager.cs b/SnapX.Core/Media/ScreenRecordManager.cs
index 54ae5379c..0c0976854 100644
--- a/SnapX.Core/Media/ScreenRecordManager.cs
+++ b/SnapX.Core/Media/ScreenRecordManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/Screenshot_Transparent.cs b/SnapX.Core/Media/Screenshot_Transparent.cs
index 58cf0bd40..b917e1441 100644
--- a/SnapX.Core/Media/Screenshot_Transparent.cs
+++ b/SnapX.Core/Media/Screenshot_Transparent.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/VideoConverterOptions.cs b/SnapX.Core/Media/VideoConverterOptions.cs
index 2c61992a7..a0db5455a 100644
--- a/SnapX.Core/Media/VideoConverterOptions.cs
+++ b/SnapX.Core/Media/VideoConverterOptions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/VideoInfo.cs b/SnapX.Core/Media/VideoInfo.cs
index 8048dc688..597a1a42a 100644
--- a/SnapX.Core/Media/VideoInfo.cs
+++ b/SnapX.Core/Media/VideoInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/VideoThumbnailInfo.cs b/SnapX.Core/Media/VideoThumbnailInfo.cs
index fab83447b..a07a077b6 100644
--- a/SnapX.Core/Media/VideoThumbnailInfo.cs
+++ b/SnapX.Core/Media/VideoThumbnailInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/VideoThumbnailOptions.cs b/SnapX.Core/Media/VideoThumbnailOptions.cs
index 0af393fcf..d5c822ad3 100644
--- a/SnapX.Core/Media/VideoThumbnailOptions.cs
+++ b/SnapX.Core/Media/VideoThumbnailOptions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Media/VideoThumbnailer.cs b/SnapX.Core/Media/VideoThumbnailer.cs
index 3cdd8d4e1..e67faea8b 100644
--- a/SnapX.Core/Media/VideoThumbnailer.cs
+++ b/SnapX.Core/Media/VideoThumbnailer.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Models/SavedConfiguration.cs b/SnapX.Core/Models/SavedConfiguration.cs
deleted file mode 100644
index 440ece770..000000000
--- a/SnapX.Core/Models/SavedConfiguration.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-
-namespace SnapX.Core.Models;
-
-[Table("ApplicationConfig")]
-public record SavedConfiguration
-{
- [Key]
- public int Id { get; set; }
-
- public string ConfigSection { get; set; }
-
- public string SettingKey { get; set; }
-
- public string SettingValue { get; set; }
-
- public string DataType { get; set; }
-
- public DateTime UpdatedAt { get; set; }
-}
diff --git a/SnapX.Core/OSX.props b/SnapX.Core/OSX.props
index 6056f8154..9dc0bc302 100644
--- a/SnapX.Core/OSX.props
+++ b/SnapX.Core/OSX.props
@@ -1,10 +1,7 @@
-
- libsnapxrust.dylib
-
-
+
diff --git a/SnapX.Core/ObservableSink.cs b/SnapX.Core/ObservableSink.cs
new file mode 100644
index 000000000..a4285b718
--- /dev/null
+++ b/SnapX.Core/ObservableSink.cs
@@ -0,0 +1,31 @@
+using Serilog.Core;
+using Serilog.Events;
+
+namespace SnapX.Core;
+
+public class ObservableSink(IFormatProvider? FormatProvider = null) : ILogEventSink
+{
+ private readonly List _buffer = [];
+ private readonly Lock _lock = new();
+
+ public event EventHandler? LogMessageReceived;
+
+ public void Emit(LogEvent logEvent)
+ {
+
+ lock (_lock)
+ {
+ _buffer.Add(logEvent);
+ }
+
+ LogMessageReceived?.Invoke(this, logEvent);
+ }
+
+ public List GetBufferedEvents()
+ {
+ lock (_lock)
+ {
+ return _buffer;
+ }
+ }
+}
diff --git a/SnapX.Core/Services/SerilogLoggerService.cs b/SnapX.Core/Services/SerilogLoggerService.cs
new file mode 100644
index 000000000..a70c7b86c
--- /dev/null
+++ b/SnapX.Core/Services/SerilogLoggerService.cs
@@ -0,0 +1,79 @@
+using Microsoft.Extensions.Configuration;
+using Serilog;
+using Serilog.Context;
+using Serilog.Sinks.SystemConsole.Themes;
+using SnapX.Core.Interfaces;
+
+namespace SnapX.Core.Services;
+public class SerilogLogService : ILoggerService
+{
+ private readonly ILogger _logger;
+
+ public SerilogLogService(
+ string? logFilePath,
+ bool logToConsole,
+ IConfiguration? config = null)
+ {
+ var loggerConfig = new LoggerConfiguration();
+
+#if DEBUG
+ loggerConfig.MinimumLevel.Debug();
+#else
+ loggerConfig.MinimumLevel.Information();
+#endif
+
+ if (!string.IsNullOrWhiteSpace(logFilePath))
+ {
+ loggerConfig = loggerConfig
+ .WriteTo.Async(a => a.File(
+ logFilePath,
+ rollingInterval: RollingInterval.Day,
+ buffered: true,
+ outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}]: {Message:lj}{NewLine}{Exception}"
+ ));
+ }
+
+ if (logToConsole)
+ {
+ loggerConfig = loggerConfig
+ .WriteTo.Console(theme: AnsiConsoleTheme.Sixteen);
+ }
+
+ if (config is not null)
+ {
+ loggerConfig.ReadFrom.Configuration(config);
+ }
+
+ _logger = loggerConfig.CreateLogger();
+ }
+
+ public SerilogLogService(ILogger Logger)
+ {
+ _logger = Logger;
+ }
+ public ILogScope BeginScope(string name)
+ {
+ return new SerilogLogScope(LogContext.PushProperty("Scope", name));
+ }
+ public void Debug(string messageTemplate, params object[] args) =>
+ _logger.Debug(messageTemplate, args);
+
+ public void Information(string messageTemplate, params object[] args) =>
+ _logger.Information(messageTemplate, args);
+
+ public void Warning(string messageTemplate, params object[] args) =>
+ _logger.Warning(messageTemplate, args);
+
+ public void Error(Exception exception, string messageTemplate, params object[] args) =>
+ _logger.Error(exception, messageTemplate, args);
+
+ public void Error(string messageTemplate, params object[] args) =>
+ _logger.Error(messageTemplate, args);
+ private class SerilogLogScope(IDisposable InnerScope) : ILogScope
+ {
+ public void Dispose()
+ {
+ InnerScope.Dispose();
+ }
+ }
+}
diff --git a/SnapX.Core/SettingManager.cs b/SnapX.Core/SettingManager.cs
index 8b1dd357e..5bf0c3af2 100644
--- a/SnapX.Core/SettingManager.cs
+++ b/SnapX.Core/SettingManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -12,6 +11,7 @@
using Esatto.Win32.Registry;
#endif
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
using SnapX.Core.History;
using SnapX.Core.Hotkey;
using SnapX.Core.Job;
@@ -22,13 +22,13 @@
namespace SnapX.Core;
-[JsonSerializable(typeof(RootConfiguration))]
+[JsonSerializable(typeof(ApplicationConfig))]
[JsonSerializable(typeof(IConfiguration))]
[JsonSerializable(typeof(UploadersConfig))]
[JsonSerializable(typeof(HotkeysConfig))]
internal partial class SettingsContext : JsonSerializerContext;
-internal static class SettingManager
+internal class SettingManager(IServiceProvider serviceProvider)
{
private const string ApplicationConfigFileName = "ApplicationConfig.json";
@@ -90,21 +90,20 @@ private static string HotkeysConfigFilePath
public static string? SnapshotFolder => Path.Combine(SnapX.PersonalFolder, "Snapshots");
- private static RootConfiguration Settings { get => SnapX.Settings; set => SnapX.Settings = value; }
- private static TaskSettings DefaultTaskSettings { get => SnapX.DefaultTaskSettings; set => SnapX.DefaultTaskSettings = value; }
+ private static ApplicationConfig Settings { get => SnapX.Settings; set => SnapX.Settings = value; }
+ private static TaskSettings? DefaultTaskSettings { get => SnapX.DefaultTaskSettings; set => SnapX.DefaultTaskSettings = value; }
private static UploadersConfig UploadersConfig { get => SnapX.UploadersConfig; set => SnapX.UploadersConfig = value; }
private static HotkeysConfig HotkeysConfig { get => SnapX.HotkeysConfig; set => SnapX.HotkeysConfig = value; }
- private static VersionEnforcer theLaw;
+ private static VersionEnforcer? theLaw;
private static ManualResetEvent uploadersConfigResetEvent = new(false);
private static ManualResetEvent hotkeysConfigResetEvent = new(false);
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")]
- public static void LoadSettings()
+ public void LoadSettings()
{
- theLaw = new VersionEnforcer(SnapX.LockDirectory);
+ theLaw = serviceProvider.GetRequiredService();
theLaw.Enforce();
- LoadApplicationConfig();
LoadUploadersConfig();
LoadHotkeysConfig();
}
@@ -150,7 +149,7 @@ public static void LoadApplicationConfig(bool fallbackSupport = true)
{
// DebugHelper.WriteLine($"{kv.Key} = {kv.Value}");
}
- var settings = new RootConfiguration();
+ var settings = new ApplicationConfig();
SnapX.Configuration.Bind(settings);
Settings = settings;
if (string.IsNullOrWhiteSpace(Settings.SQLitePath))
@@ -203,60 +202,6 @@ public static void LoadHotkeysConfig(bool fallbackSupport = true)
HotkeysConfigBackwardCompatibilityTasks();
}
- // private static void MigrateApplicationConfigJSONToSQLite()
- // {
- // try
- // {
- // DebugHelper.WriteLine($"JSON -> SQLite Migration: Migrating {ApplicationConfigFileName} at {ApplicationConfigFilePath}");
- // var json = File.ReadAllText(ApplicationConfigFilePath);
- // var node = JsonNode.Parse(json)!.AsObject();
- // node.Remove("RecentTasks");
- //
- // var nodeJSON = node.ToJsonString();
- //
- // var root = JsonDocument.Parse(nodeJSON).RootElement;
- // foreach (var property in root.EnumerateObject())
- // {
- // var key = property.Name;
- // var value = property.Value;
- //
- // switch (value.ValueKind)
- // {
- // case JsonValueKind.Object:
- // FlattenAndInsert(value, key);
- // break;
- //
- // case JsonValueKind.Array:
- // var index = 0;
- // foreach (var item in value.EnumerateArray())
- // {
- // // Compose a "key:index" prefix for each item and recurse
- // FlattenAndInsert(item, $"{key}:{index++}");
- // }
- //
- // break;
- //
- // case JsonValueKind.String:
- // case JsonValueKind.Number:
- // case JsonValueKind.True:
- // case JsonValueKind.False:
- // case JsonValueKind.Null:
- // case JsonValueKind.Undefined:
- // default:
- // FlattenAndInsert(value, key);
- // break;
- // }
- // }
- // var migratedPath = ApplicationConfigFilePath + ".migrated";
- // var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
- // migratedPath = ApplicationConfigFilePath + $"{timestamp}.migrated";
- // File.Move(ApplicationConfigFilePath, migratedPath);
- // }
- // catch (Exception ex)
- // {
- // DebugHelper.WriteException(ex);
- // }
- // }
public static void SaveApplicationConfig()
{
if (SnapX.Sandbox)
@@ -270,7 +215,8 @@ public static void SaveApplicationConfig()
{
WriteIndented = true,
TypeInfoResolver = SettingsContext.Default,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never
+ DefaultIgnoreCondition = JsonIgnoreCondition.Never,
+ Converters = { new JsonStringEnumConverter() }
});
File.WriteAllText(configFilePath, json);
}
@@ -291,7 +237,9 @@ public static void SaveUploadConfig()
var json = JsonSerializer.Serialize(UploadersConfig, new JsonSerializerOptions
{
WriteIndented = true,
- TypeInfoResolver = SettingsContext.Default
+ TypeInfoResolver = SettingsContext.Default,
+ Converters = { new JsonStringEnumConverter() }
+
});
File.WriteAllText(configFilePath, json);
}
@@ -312,7 +260,8 @@ public static void SaveHotkeysConfig()
var json = JsonSerializer.Serialize(HotkeysConfig, new JsonSerializerOptions
{
WriteIndented = true,
- TypeInfoResolver = SettingsContext.Default
+ TypeInfoResolver = SettingsContext.Default,
+ Converters = { new JsonStringEnumConverter() }
});
File.WriteAllText(configFilePath, json);
}
@@ -333,6 +282,12 @@ private static void ApplicationConfigBackwardCompatibilityTasks()
.OrderBy(name => name) // Ensure migrations are processed in numerical order
.ToList();
+ if (SnapX.DbConnection is null)
+ {
+ DebugHelper.WriteLine("SnapX.DbConnection is null, skipping backward compatibility tasks.");
+ return;
+ }
+
// Ensure MigrationLog table exists for the checks below
// This is crucial if it's the very first time running migrations.
SnapX.DbConnection.Execute(@"
@@ -524,21 +479,9 @@ private static void UploadersConfigBackwardCompatibilityTasks()
private static void HotkeysConfigBackwardCompatibilityTasks()
{
-
- // if (Settings.IsUpgradeFrom("15.0.1"))
- // {
- // foreach (var taskSettings in HotkeysConfig.Hotkeys.Select(x => x.TaskSettings))
- // {
- // if (tasktaskSettings.CaptureSettings != null)
- // {
- // // taskSettings.CaptureSettings.ScrollingCaptureOptions = new ScrollingCaptureOptions();
- // // taskSettings.CaptureSettings.FFmpegOptions.FixSources();
- // }
- // }
- // }
}
- public static void Dispose() => theLaw.Dispose();
+ public static void Dispose() => theLaw?.Dispose();
public static void CleanupHotkeysConfig()
{
foreach (var taskSettings in HotkeysConfig.Hotkeys.Select(x => x.TaskSettings))
@@ -653,27 +596,5 @@ public static bool Import(string archivePath)
return false;
}
-
- // This method validates the setting before restoration to ensure it fits the defined type
- private static bool IsValidValue(string value, string dataType)
- {
- if (string.IsNullOrWhiteSpace(value))
- return false; // Prevent null or empty values.
-
- switch (dataType)
- {
- case "int":
- return int.TryParse(value, out _);
- case "double":
- return double.TryParse(value, out _);
- case "bool":
- return bool.TryParse(value, out _);
- case "string":
- return true;
- default:
- DebugHelper.WriteLine($"Unknown data type: {dataType}");
- return false;
- }
- }
}
diff --git a/SnapX.Core/ScreenCapture/Animations/BaseAnimation.cs b/SnapX.Core/SharpCapture/Animations/BaseAnimation.cs
similarity index 94%
rename from SnapX.Core/ScreenCapture/Animations/BaseAnimation.cs
rename to SnapX.Core/SharpCapture/Animations/BaseAnimation.cs
index f4fa50d87..2d777f61f 100644
--- a/SnapX.Core/ScreenCapture/Animations/BaseAnimation.cs
+++ b/SnapX.Core/SharpCapture/Animations/BaseAnimation.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Diagnostics;
-namespace SnapX.Core.ScreenCapture.Animations;
+namespace SnapX.Core.SharpCapture.Animations;
internal class BaseAnimation
{
diff --git a/SnapX.Core/ScreenCapture/Animations/ColorBlinkAnimation.cs b/SnapX.Core/SharpCapture/Animations/ColorBlinkAnimation.cs
similarity index 95%
rename from SnapX.Core/ScreenCapture/Animations/ColorBlinkAnimation.cs
rename to SnapX.Core/SharpCapture/Animations/ColorBlinkAnimation.cs
index 472299490..d7792bb54 100644
--- a/SnapX.Core/ScreenCapture/Animations/ColorBlinkAnimation.cs
+++ b/SnapX.Core/SharpCapture/Animations/ColorBlinkAnimation.cs
@@ -1,11 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using SixLabors.ImageSharp;
using SnapX.Core.Utils;
-namespace SnapX.Core.ScreenCapture.Animations;
+namespace SnapX.Core.SharpCapture.Animations;
internal class ColorBlinkAnimation : BaseAnimation
{
diff --git a/SnapX.Core/ScreenCapture/Animations/OpacityAnimation.cs b/SnapX.Core/SharpCapture/Animations/OpacityAnimation.cs
similarity index 95%
rename from SnapX.Core/ScreenCapture/Animations/OpacityAnimation.cs
rename to SnapX.Core/SharpCapture/Animations/OpacityAnimation.cs
index 33ad1e598..5062e1dc1 100644
--- a/SnapX.Core/ScreenCapture/Animations/OpacityAnimation.cs
+++ b/SnapX.Core/SharpCapture/Animations/OpacityAnimation.cs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
-namespace SnapX.Core.ScreenCapture.Animations;
+namespace SnapX.Core.SharpCapture.Animations;
internal class OpacityAnimation : BaseAnimation
{
diff --git a/SnapX.Core/ScreenCapture/Animations/PointAnimation.cs b/SnapX.Core/SharpCapture/Animations/PointAnimation.cs
similarity index 94%
rename from SnapX.Core/ScreenCapture/Animations/PointAnimation.cs
rename to SnapX.Core/SharpCapture/Animations/PointAnimation.cs
index 8d8fa17e5..e8b322fcf 100644
--- a/SnapX.Core/ScreenCapture/Animations/PointAnimation.cs
+++ b/SnapX.Core/SharpCapture/Animations/PointAnimation.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using SixLabors.ImageSharp;
-namespace SnapX.Core.ScreenCapture.Animations;
+namespace SnapX.Core.SharpCapture.Animations;
internal class PointAnimation : BaseAnimation
{
diff --git a/SnapX.Core/ScreenCapture/Animations/RectangleAnimation.cs b/SnapX.Core/SharpCapture/Animations/RectangleAnimation.cs
similarity index 95%
rename from SnapX.Core/ScreenCapture/Animations/RectangleAnimation.cs
rename to SnapX.Core/SharpCapture/Animations/RectangleAnimation.cs
index bbb847fb2..d7341f749 100644
--- a/SnapX.Core/ScreenCapture/Animations/RectangleAnimation.cs
+++ b/SnapX.Core/SharpCapture/Animations/RectangleAnimation.cs
@@ -1,11 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using SixLabors.ImageSharp;
using SnapX.Core.Utils;
-namespace SnapX.Core.ScreenCapture.Animations;
+namespace SnapX.Core.SharpCapture.Animations;
internal class RectangleAnimation : BaseAnimation
{
diff --git a/SnapX.Core/ScreenCapture/Animations/TextAnimation.cs b/SnapX.Core/SharpCapture/Animations/TextAnimation.cs
similarity index 80%
rename from SnapX.Core/ScreenCapture/Animations/TextAnimation.cs
rename to SnapX.Core/SharpCapture/Animations/TextAnimation.cs
index 0aa338fa2..f33cede58 100644
--- a/SnapX.Core/ScreenCapture/Animations/TextAnimation.cs
+++ b/SnapX.Core/SharpCapture/Animations/TextAnimation.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Drawing;
-namespace SnapX.Core.ScreenCapture.Animations;
+namespace SnapX.Core.SharpCapture.Animations;
internal class TextAnimation : OpacityAnimation
{
diff --git a/SnapX.Core/SharpCapture/BaseCapture.cs b/SnapX.Core/SharpCapture/BaseSharpCapture.cs
similarity index 72%
rename from SnapX.Core/SharpCapture/BaseCapture.cs
rename to SnapX.Core/SharpCapture/BaseSharpCapture.cs
index 3575fe015..105046af1 100644
--- a/SnapX.Core/SharpCapture/BaseCapture.cs
+++ b/SnapX.Core/SharpCapture/BaseSharpCapture.cs
@@ -1,19 +1,21 @@
using SixLabors.ImageSharp;
+using SnapX.Core.Job;
+
#pragma warning disable CS1998
namespace SnapX.Core.SharpCapture;
-public abstract class BaseCapture
+public abstract class BaseSharpCapture
{
- public virtual async Task CaptureScreen(Rectangle bounds) =>
+ public virtual async Task CaptureScreen(Rectangle bounds, TaskSettings? taskSettings = null) =>
throw new NotImplementedException("SharpCapture CaptureScreen is not implemented.");
- public virtual async Task CaptureScreen(Point? pos) =>
+ public virtual async Task CaptureScreen(Point? pos, TaskSettings? taskSettings = null) =>
throw new NotImplementedException("SharpCapture CaptureScreen is not implemented.");
- public virtual async Task CaptureWindow(Point pos) =>
+ public virtual async Task CaptureWindow(Point pos, TaskSettings? taskSettings = null) =>
throw new NotImplementedException("SharpCapture CaptureWindow is not implemented.");
- public virtual async Task CaptureRectangle(Rectangle rect) =>
+ public virtual async Task CaptureRectangle(Rectangle rect, TaskSettings? taskSettings = null) =>
throw new NotImplementedException("SharpCapture CaptureRectangle is not implemented.");
- public virtual async Task CaptureFullscreen() =>
+ public virtual async Task CaptureFullscreen(TaskSettings? taskSettings = null) =>
throw new NotImplementedException("SharpCapture CaptureFullscreen is not implemented.");
public virtual async Task GetWorkingArea() =>
throw new NotImplementedException("SharpCapture GetWorkingArea is not implemented.");
diff --git a/SnapX.Core/SharpCapture/CaptureActiveMonitor.cs b/SnapX.Core/SharpCapture/CaptureActiveMonitor.cs
new file mode 100644
index 000000000..4ce65dfb9
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureActiveMonitor.cs
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+
+public class CaptureActiveMonitor(
+ IMainWindowService MainWindowService,
+ INotificationService NotificationService,
+ IUploadManager UploadManager,
+ IDelayService DelayService,
+ ILoggerService _logger,
+ ICaptureService CaptureService)
+ : CaptureBase(MainWindowService, NotificationService, UploadManager, DelayService, _logger, CaptureService)
+{
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ _logger.Debug("CaptureActiveMonitor started");
+
+ var img = await _captureService
+ .CaptureActiveMonitorAsync(taskSettings)
+ .ConfigureAwait(false);
+ if (img is null)
+ {
+ _logger.Debug("CaptureActiveMonitorAsync returned null. Returning empty TaskMetadata");
+ return new TaskMetadata();
+ }
+ var metadata = CreateMetadata(img.Bounds);
+ metadata.Image = img;
+ return metadata;
+ }
+}
diff --git a/SnapX.Core/SharpCapture/CaptureActiveWindow.cs b/SnapX.Core/SharpCapture/CaptureActiveWindow.cs
new file mode 100644
index 000000000..129806d3b
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureActiveWindow.cs
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+public class CaptureActiveWindow(
+ IMainWindowService MainWindowService,
+ INotificationService NotificationService,
+ IUploadManager UploadManager,
+ IDelayService DelayService,
+ ILoggerService LoggerService,
+ ICaptureService CaptureService)
+ : CaptureBase(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService)
+{
+
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ var metadata = CreateMetadata();
+
+ if (taskSettings.CaptureSettings is { CaptureTransparent: true, CaptureClientArea: false })
+ {
+ LoggerService.Debug("Capture transparent mode is default now. Non transparent mode is not implemented");
+ }
+
+ metadata.Image = await _captureService.CaptureActiveWindowAsync();
+
+ return metadata;
+ }
+}
diff --git a/SnapX.Core/SharpCapture/CaptureBase.cs b/SnapX.Core/SharpCapture/CaptureBase.cs
new file mode 100644
index 000000000..345caa05a
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureBase.cs
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SixLabors.ImageSharp;
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+using SnapX.Core.Utils.Extensions;
+using SnapX.Core.Utils.Native;
+
+namespace SnapX.Core.SharpCapture;
+public abstract class CaptureBase(
+ IMainWindowService MainWindowService,
+ INotificationService NotificationService,
+ IUploadManager UploadManager,
+ IDelayService DelayService,
+ ILoggerService LoggerService,
+ ICaptureService CaptureService)
+{
+ public bool AllowAutoHideForm { get; set; } = true;
+ public bool AllowAnnotation { get; set; } = true;
+
+ internal readonly ICaptureService _captureService = CaptureService;
+
+ public async Task CaptureAsync(TaskSettings? taskSettings = null, bool autoHideForm = false)
+ {
+ using (LoggerService.BeginScope("Capture"))
+ {
+ if (taskSettings == null)
+ {
+ taskSettings = TaskSettings.GetDefaultTaskSettings();
+ LoggerService.Debug("Loaded default task settings");
+ }
+
+ if (taskSettings.CaptureSettings.ScreenshotDelay > 0)
+ {
+ var delay = (int)(taskSettings.CaptureSettings.ScreenshotDelay * 1000);
+ LoggerService.Information("Delaying capture for {Delay} ms as configured", delay);
+ await DelayService.DelayAsync(delay);
+ }
+
+ await CaptureInternalAsync(taskSettings, autoHideForm);
+ }
+ }
+
+ private async Task CaptureInternalAsync(TaskSettings taskSettings, bool autoHideForm)
+ {
+ using (LoggerService.BeginScope("CaptureInternal"))
+ {
+ if (autoHideForm && AllowAutoHideForm)
+ {
+ LoggerService.Debug("Hiding main window for capture");
+ await MainWindowService.HideAsync();
+ await DelayService.DelayAsync(250);
+ }
+
+ TaskMetadata? metadata = null;
+
+ try
+ {
+ AllowAnnotation = true;
+ LoggerService.Debug("Executing capture logic in {CaptureType}", GetType().Name);
+ metadata = await ExecuteAsync(taskSettings);
+ }
+ catch (Exception ex)
+ {
+ LoggerService.Error(ex, "An error occurred during capture");
+ }
+ finally
+ {
+ if (autoHideForm && AllowAutoHideForm)
+ {
+ LoggerService.Debug("Re-activating main window after capture");
+ await MainWindowService.ForceActivateAsync();
+ }
+
+ await AfterCaptureAsync(metadata, taskSettings);
+ }
+ }
+ }
+
+ protected virtual async Task AfterCaptureAsync(TaskMetadata? metadata, TaskSettings taskSettings)
+ {
+ using (LoggerService.BeginScope("AfterCapture"))
+ {
+ if (metadata is { Image: not null })
+ {
+ LoggerService.Debug("Running AfterCapture tasks");
+
+ await NotificationService
+ .PlayNotificationSoundAsync(NotificationSound.Capture, taskSettings);
+
+ if (taskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.AnnotateImage) && !AllowAnnotation)
+ {
+ taskSettings.AfterCaptureJob =
+ taskSettings.AfterCaptureJob.Remove(AfterCaptureTasks.AnnotateImage);
+
+ LoggerService.Information("Annotation disabled. Removed AnnotateImage from AfterCapture tasks");
+ }
+
+ if (taskSettings.ImageSettings.ImageEffectOnlyRegionCapture &&
+ GetType() != typeof(CaptureRegion) && GetType() != typeof(CaptureLastRegion))
+ {
+ taskSettings.AfterCaptureJob =
+ taskSettings.AfterCaptureJob.Remove(AfterCaptureTasks.AddImageEffects);
+
+ LoggerService.Information("Skipped image effects because ImageEffectOnlyRegionCapture is true");
+ }
+
+ await UploadManager.RunImageTaskAsync(metadata, taskSettings);
+ LoggerService.Information("Upload service completed image processing");
+ }
+ else
+ {
+ LoggerService.Warning("No image captured. Skipping AfterCapture tasks");
+ }
+ }
+ }
+
+ protected abstract Task ExecuteAsync(TaskSettings taskSettings);
+
+ protected TaskMetadata CreateMetadata()
+ {
+ return CreateMetadata(Rectangle.Empty, null);
+ }
+
+ protected TaskMetadata CreateMetadata(Rectangle insideRect, string? ignoreProcess = "explorer")
+ {
+ var metadata = new TaskMetadata();
+
+ var windowInfo = Methods.GetForegroundWindow();
+ if ((ignoreProcess == null || !windowInfo.ProcessName.Equals(ignoreProcess, StringComparison.OrdinalIgnoreCase)) &&
+ (insideRect.IsEmpty || windowInfo.Rectangle.Contains(insideRect)))
+ {
+ metadata.UpdateInfo(windowInfo);
+ LoggerService.Debug("Foreground window info added to capture metadata: {ProcessName}", windowInfo.ProcessName);
+ }
+ else
+ {
+ LoggerService.Debug("Window info skipped because it didn't match criteria. IgnoreProcess={IgnoreProcess}", ignoreProcess ?? string.Empty);
+ }
+
+ return metadata;
+ }
+}
diff --git a/SnapX.Core/SharpCapture/CaptureCustomRegion.cs b/SnapX.Core/SharpCapture/CaptureCustomRegion.cs
new file mode 100644
index 000000000..d2e8671f8
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureCustomRegion.cs
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+
+public class CaptureCustomRegion(IMainWindowService MainWindowService, INotificationService NotificationService, IUploadManager UploadManager, IDelayService DelayService, ILoggerService LoggerService, ICaptureService CaptureService) : CaptureBase(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService)
+{
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ var rect = taskSettings.CaptureSettings.CaptureCustomRegion;
+ var metadata = CreateMetadata(rect);
+ metadata.Image = await _captureService.CaptureRectangle(taskSettings, rect);
+ return metadata;
+ }
+}
+
diff --git a/SnapX.Core/SharpCapture/CaptureCustomWindow.cs b/SnapX.Core/SharpCapture/CaptureCustomWindow.cs
new file mode 100644
index 000000000..7d397ba52
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureCustomWindow.cs
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SnapX.Core.Interfaces;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+public class CaptureCustomWindow(IMainWindowService MainWindowService, INotificationService NotificationService, IUploadManager UploadManager, IDelayService DelayService, ILoggerService LoggerService, ICaptureService CaptureService, IntPtr? WindowHandle) : CaptureWindow(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService, WindowHandle)
+{
+ // protected override TaskMetadata Execute(TaskSettings? taskSettings)
+ // {
+ // string windowTitle = taskSettings.CaptureSettings.CaptureCustomWindow;
+ //
+ // if (!string.IsNullOrEmpty(windowTitle))
+ // {
+ // // TODO: Reimplement w/ Windows support & Linux (X11, and KDE Plasma Wayland)
+ // // IntPtr hWnd = NativeMethods.SearchWindow(windowTitle);
+ // //
+ // // if (hWnd == IntPtr.Zero)
+ // // {
+ // // MessageBox.Show(Resources.UnableToFindAWindowWithSpecifiedWindowTitle, "SnapX", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ // // }
+ // // else
+ // // {
+ // // WindowHandle = hWnd;
+ // //
+ // // return base.Execute(taskSettings);
+ // // }
+ // }
+ //
+ // return null;
+ // }
+}
+
diff --git a/SnapX.Core/SharpCapture/CaptureFullscreen.cs b/SnapX.Core/SharpCapture/CaptureFullscreen.cs
new file mode 100644
index 000000000..df7b3e51a
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureFullscreen.cs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+
+public class CaptureFullscreen(IMainWindowService MainWindowService, INotificationService NotificationService, IUploadManager UploadManager, IDelayService DelayService, ILoggerService LoggerService, ICaptureService CaptureService) : CaptureBase(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService)
+{
+ // protected override TaskMetadata Execute(TaskSettings? taskSettings)
+ // {
+ // DebugHelper.WriteLine("CaptureFullscreen");
+ // var img = TaskHelpers.GetScreenshot(taskSettings).CaptureFullscreen();
+ // var metadata = CreateMetadata(img.Bounds);
+ // metadata.Image = img;
+ //
+ // return metadata;
+ // }
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ throw new NotImplementedException();
+ }
+}
+
diff --git a/SnapX.Core/SharpCapture/CaptureLastRegion.cs b/SnapX.Core/SharpCapture/CaptureLastRegion.cs
new file mode 100644
index 000000000..9d5bfeeb0
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureLastRegion.cs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+public class CaptureLastRegion(IMainWindowService MainWindowService, INotificationService NotificationService, IUploadManager UploadManager, IDelayService DelayService, ILoggerService LoggerService, ICaptureService CaptureService, RegionCaptureType RegionCaptureType) : CaptureRegion(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService, RegionCaptureType)
+{
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ throw new NotImplementedException();
+ }
+ // protected override TaskMetadata Execute(TaskSettings taskSettings)
+ // {
+ // switch (lastRegionCaptureType)
+ // {
+ // default:
+ // case RegionCaptureType.Default: return ExecuteRegionCapture(taskSettings);
+ // case RegionCaptureType.Light: return ExecuteRegionCaptureLight(taskSettings);
+ // case RegionCaptureType.Transparent: return ExecuteRegionCaptureTransparent(taskSettings);
+ // }
+ // }
+}
+
diff --git a/SnapX.Core/SharpCapture/CaptureMonitor.cs b/SnapX.Core/SharpCapture/CaptureMonitor.cs
new file mode 100644
index 000000000..e8a2faba2
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureMonitor.cs
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SixLabors.ImageSharp;
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+public class CaptureMonitor(IMainWindowService MainWindowService, INotificationService NotificationService, IUploadManager UploadManager, IDelayService DelayService, ILoggerService LoggerService, ICaptureService CaptureService, Rectangle MonitorRectangle) : CaptureBase(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService)
+{
+ public Rectangle MonitorRectangle { get; private set; } = MonitorRectangle;
+
+
+ // protected override TaskMetadata Execute(TaskSettings taskSettings)
+ // {
+ // DebugHelper.WriteLine("CaptureMonitor Start");
+ // var metadata = CreateMetadata(MonitorRectangle);
+ // metadata.Image = TaskHelpers.GetScreenshot().CaptureRectangle(MonitorRectangle);
+ // return metadata;
+ // }
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ throw new NotImplementedException();
+ }
+}
+
diff --git a/SnapX.Core/Capture/CaptureRegion.cs b/SnapX.Core/SharpCapture/CaptureRegion.cs
similarity index 77%
rename from SnapX.Core/Capture/CaptureRegion.cs
rename to SnapX.Core/SharpCapture/CaptureRegion.cs
index 8828e97c7..08741764a 100644
--- a/SnapX.Core/Capture/CaptureRegion.cs
+++ b/SnapX.Core/SharpCapture/CaptureRegion.cs
@@ -1,38 +1,30 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
+using SnapX.Core.Interfaces;
using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
-namespace SnapX.Core.Capture;
-public class CaptureRegion : CaptureBase
+namespace SnapX.Core.SharpCapture;
+public class CaptureRegion(IMainWindowService MainWindowService, INotificationService NotificationService, IUploadManager UploadManager, IDelayService DelayService, ILoggerService LoggerService, ICaptureService CaptureService, RegionCaptureType RegionCaptureType) : CaptureBase(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService)
{
protected static RegionCaptureType lastRegionCaptureType = RegionCaptureType.Default;
- public RegionCaptureType RegionCaptureType { get; protected set; }
-
- public CaptureRegion()
- {
- }
-
- public CaptureRegion(RegionCaptureType regionCaptureType)
- {
- RegionCaptureType = regionCaptureType;
- }
+ public RegionCaptureType RegionCaptureType { get; protected set; } = RegionCaptureType;
- protected override TaskMetadata Execute(TaskSettings taskSettings)
- {
- switch (RegionCaptureType)
- {
- default:
- case RegionCaptureType.Default:
- return ExecuteRegionCapture(taskSettings);
- case RegionCaptureType.Light:
- return ExecuteRegionCaptureLight(taskSettings);
- case RegionCaptureType.Transparent:
- return ExecuteRegionCaptureTransparent(taskSettings);
- }
- }
+ // protected override TaskMetadata Execute(TaskSettings taskSettings)
+ // {
+ // switch (RegionCaptureType)
+ // {
+ // default:
+ // case RegionCaptureType.Default:
+ // return ExecuteRegionCapture(taskSettings);
+ // case RegionCaptureType.Light:
+ // return ExecuteRegionCaptureLight(taskSettings);
+ // case RegionCaptureType.Transparent:
+ // return ExecuteRegionCaptureTransparent(taskSettings);
+ // }
+ // }
protected TaskMetadata ExecuteRegionCapture(TaskSettings taskSettings)
{
@@ -140,5 +132,10 @@ protected TaskMetadata ExecuteRegionCaptureTransparent(TaskSettings taskSettings
return null;
}
+
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ throw new NotImplementedException();
+ }
}
diff --git a/SnapX.Core/SharpCapture/CaptureWindow.cs b/SnapX.Core/SharpCapture/CaptureWindow.cs
new file mode 100644
index 000000000..ea4a89a14
--- /dev/null
+++ b/SnapX.Core/SharpCapture/CaptureWindow.cs
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+
+using SnapX.Core.Interfaces;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+
+namespace SnapX.Core.SharpCapture;
+public class CaptureWindow(IMainWindowService MainWindowService, INotificationService NotificationService, IUploadManager UploadManager, IDelayService DelayService, ILoggerService LoggerService, ICaptureService CaptureService, IntPtr? WindowHandle = 0) : CaptureBase(MainWindowService, NotificationService, UploadManager, DelayService, LoggerService, CaptureService)
+{
+ public IntPtr WindowHandle { get; protected set; } = WindowHandle.GetValueOrDefault(IntPtr.Zero);
+
+ // protected override TaskMetadata Execute(TaskSettings? taskSettings)
+ // {
+ // WindowInfo windowInfo = new(WindowHandle);
+ //
+ // if (windowInfo.IsMinimized)
+ // {
+ // windowInfo.Restore();
+ // Thread.Sleep(250);
+ // }
+ //
+ // if (!windowInfo.IsActive)
+ // {
+ // windowInfo.Activate();
+ // Thread.Sleep(100);
+ // }
+ //
+ // var metadata = new TaskMetadata();
+ // metadata.UpdateInfo(windowInfo);
+ //
+ // if (taskSettings.CaptureSettings.CaptureTransparent && !taskSettings.CaptureSettings.CaptureClientArea)
+ // {
+ // metadata.Image = TaskHelpers.GetScreenshot(taskSettings).CaptureWindowTransparent(WindowHandle);
+ // }
+ // else
+ // {
+ // metadata.Image = TaskHelpers.GetScreenshot(taskSettings).CaptureWindow(WindowHandle);
+ // }
+ //
+ // return metadata;
+ // }
+ protected override async Task ExecuteAsync(TaskSettings taskSettings)
+ {
+ throw new NotImplementedException();
+ }
+}
+
diff --git a/SnapX.Core/ScreenCapture/Enums.cs b/SnapX.Core/SharpCapture/Enums.cs
similarity index 99%
rename from SnapX.Core/ScreenCapture/Enums.cs
rename to SnapX.Core/SharpCapture/Enums.cs
index 4ea2ad274..17863fa7a 100644
--- a/SnapX.Core/ScreenCapture/Enums.cs
+++ b/SnapX.Core/SharpCapture/Enums.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.ComponentModel;
-namespace SnapX.Core.ScreenCapture;
+namespace SnapX.Core.SharpCapture;
public enum ScreenRecordOutput
{
diff --git a/SnapX.Core/ScreenCapture/Helpers/InputManager.cs b/SnapX.Core/SharpCapture/Helpers/InputManager.cs
similarity index 93%
rename from SnapX.Core/ScreenCapture/Helpers/InputManager.cs
rename to SnapX.Core/SharpCapture/Helpers/InputManager.cs
index 4d6bb8917..4a7eccf4c 100644
--- a/SnapX.Core/ScreenCapture/Helpers/InputManager.cs
+++ b/SnapX.Core/SharpCapture/Helpers/InputManager.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using SixLabors.ImageSharp;
-namespace SnapX.Core.ScreenCapture.Helpers;
+namespace SnapX.Core.SharpCapture.Helpers;
public class InputManager
{
diff --git a/SnapX.Core/ScreenCapture/Helpers/LocationInfo.cs b/SnapX.Core/SharpCapture/Helpers/LocationInfo.cs
similarity index 86%
rename from SnapX.Core/ScreenCapture/Helpers/LocationInfo.cs
rename to SnapX.Core/SharpCapture/Helpers/LocationInfo.cs
index 89a19a93b..cb18921bd 100644
--- a/SnapX.Core/ScreenCapture/Helpers/LocationInfo.cs
+++ b/SnapX.Core/SharpCapture/Helpers/LocationInfo.cs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
-namespace SnapX.Core.ScreenCapture.Helpers;
+namespace SnapX.Core.SharpCapture.Helpers;
public class LocationInfo
diff --git a/SnapX.Core/ScreenCapture/Helpers/SimpleWindowInfo.cs b/SnapX.Core/SharpCapture/Helpers/SimpleWindowInfo.cs
similarity index 92%
rename from SnapX.Core/ScreenCapture/Helpers/SimpleWindowInfo.cs
rename to SnapX.Core/SharpCapture/Helpers/SimpleWindowInfo.cs
index 2a3ef5ec5..937d3aa27 100644
--- a/SnapX.Core/ScreenCapture/Helpers/SimpleWindowInfo.cs
+++ b/SnapX.Core/SharpCapture/Helpers/SimpleWindowInfo.cs
@@ -1,11 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using SixLabors.ImageSharp;
using SnapX.Core.Media;
-namespace SnapX.Core.ScreenCapture.Helpers;
+namespace SnapX.Core.SharpCapture.Helpers;
public class SimpleWindowInfo
diff --git a/SnapX.Core/ScreenCapture/Helpers/SnapSize.cs b/SnapX.Core/SharpCapture/Helpers/SnapSize.cs
similarity index 95%
rename from SnapX.Core/ScreenCapture/Helpers/SnapSize.cs
rename to SnapX.Core/SharpCapture/Helpers/SnapSize.cs
index d7de82598..277e662b2 100644
--- a/SnapX.Core/ScreenCapture/Helpers/SnapSize.cs
+++ b/SnapX.Core/SharpCapture/Helpers/SnapSize.cs
@@ -1,10 +1,9 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Drawing;
-namespace SnapX.Core.ScreenCapture.Helpers;
+namespace SnapX.Core.SharpCapture.Helpers;
public class SnapSize
{
diff --git a/SnapX.Core/ScreenCapture/Helpers/WindowsList.cs b/SnapX.Core/SharpCapture/Helpers/WindowsList.cs
similarity index 96%
rename from SnapX.Core/ScreenCapture/Helpers/WindowsList.cs
rename to SnapX.Core/SharpCapture/Helpers/WindowsList.cs
index 1f3c37b87..31e8eaf2c 100644
--- a/SnapX.Core/ScreenCapture/Helpers/WindowsList.cs
+++ b/SnapX.Core/SharpCapture/Helpers/WindowsList.cs
@@ -4,7 +4,7 @@
using SnapX.Core.Utils.Extensions;
using SnapX.Core.Utils.Native;
-namespace SnapX.Core.ScreenCapture.Helpers;
+namespace SnapX.Core.SharpCapture.Helpers;
public class WindowsList
{
diff --git a/SnapX.Core/SharpCapture/Interfaces/ICaptureService.cs b/SnapX.Core/SharpCapture/Interfaces/ICaptureService.cs
new file mode 100644
index 000000000..f32c6d0bb
--- /dev/null
+++ b/SnapX.Core/SharpCapture/Interfaces/ICaptureService.cs
@@ -0,0 +1,12 @@
+using SixLabors.ImageSharp;
+using SnapX.Core.Job;
+
+namespace SnapX.Core.SharpCapture.Interfaces;
+
+public interface ICaptureService
+{
+ Task CaptureActiveMonitorAsync(TaskSettings? taskSettings = null);
+ Task CaptureFullscreenAsync(TaskSettings? taskSettings = null);
+ Task CaptureRectangle(TaskSettings? taskSettings = null, Rectangle? rect = null);
+ Task CaptureActiveWindowAsync(TaskSettings? taskSettings = null);
+}
diff --git a/SnapX.Core/SharpCapture/Linux/DBus/DesktopDBus.cs b/SnapX.Core/SharpCapture/Linux/DBus/DesktopDBus.cs
index 62a78f26c..5a0e40ee5 100644
--- a/SnapX.Core/SharpCapture/Linux/DBus/DesktopDBus.cs
+++ b/SnapX.Core/SharpCapture/Linux/DBus/DesktopDBus.cs
@@ -5,127 +5,6 @@
namespace SnapX.Core.SharpCapture.Linux.DBus;
-record InhibitProperties
-{
- public uint Version { get; set; } = default!;
-}
-partial class Inhibit : DesktopObject
-{
- private const string __Interface = "org.freedesktop.portal.Inhibit";
- public Inhibit(DesktopService service, ObjectPath path) : base(service, path)
- { }
- public Task InhibitAsync(string window, uint flags, Dictionary options)
- {
- return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this);
- MessageBuffer CreateMessage()
- {
- var writer = this.Connection.GetMessageWriter();
- writer.WriteMethodCallHeader(
- destination: Service.Destination,
- path: Path,
- @interface: __Interface,
- signature: "sua{sv}",
- member: "Inhibit");
- writer.WriteString(window);
- writer.WriteUInt32(flags);
- writer.WriteDictionary(options);
- return writer.CreateMessage();
- }
- }
- public Task CreateMonitorAsync(string window, Dictionary options)
- {
- return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this);
- MessageBuffer CreateMessage()
- {
- var writer = this.Connection.GetMessageWriter();
- writer.WriteMethodCallHeader(
- destination: Service.Destination,
- path: Path,
- @interface: __Interface,
- signature: "sa{sv}",
- member: "CreateMonitor");
- writer.WriteString(window);
- writer.WriteDictionary(options);
- return writer.CreateMessage();
- }
- }
- public Task QueryEndResponseAsync(ObjectPath sessionHandle)
- {
- return this.Connection.CallMethodAsync(CreateMessage());
- MessageBuffer CreateMessage()
- {
- var writer = this.Connection.GetMessageWriter();
- writer.WriteMethodCallHeader(
- destination: Service.Destination,
- path: Path,
- @interface: __Interface,
- signature: "o",
- member: "QueryEndResponse");
- writer.WriteObjectPath(sessionHandle);
- return writer.CreateMessage();
- }
- }
- public ValueTask WatchStateChangedAsync(Action State)> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None)
- => base.WatchSignalAsync(Service.Destination, __Interface, Path, "StateChanged", (Message m, object? s) => ReadMessage_oaesv(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags);
- public Task GetVersionAsync()
- => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this);
- public Task GetPropertiesAsync()
- {
- return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this);
- static InhibitProperties ReadMessage(Message message, DesktopObject _)
- {
- var reader = message.GetBodyReader();
- return ReadProperties(ref reader);
- }
- }
- public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None)
- {
- return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags);
- static PropertyChanges ReadMessage(Message message, DesktopObject _)
- {
- var reader = message.GetBodyReader();
- reader.ReadString(); // interface
- List changed = new(), invalidated = new();
- return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray());
- }
- static string[] ReadInvalidated(ref Reader reader)
- {
- List? invalidated = null;
- ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String);
- while (reader.HasNext(arrayEnd))
- {
- invalidated ??= new();
- var property = reader.ReadString();
- switch (property)
- {
- case "version": invalidated.Add("Version"); break;
- }
- }
- return invalidated?.ToArray() ?? Array.Empty();
- }
- }
- private static InhibitProperties ReadProperties(ref Reader reader, List? changedList = null)
- {
- var props = new InhibitProperties();
- ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct);
- while (reader.HasNext(arrayEnd))
- {
- var property = reader.ReadString();
- switch (property)
- {
- case "version":
- reader.ReadSignature("u"u8);
- props.Version = reader.ReadUInt32();
- changedList?.Add("Version");
- break;
- default:
- reader.ReadVariantValue();
- break;
- }
- }
- return props;
- }
-}
record BackgroundProperties
{
public uint Version { get; set; } = default!;
@@ -227,110 +106,6 @@ private static BackgroundProperties ReadProperties(ref Reader reader, List CreateSessionAsync(Dictionary options)
- {
- return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this);
- MessageBuffer CreateMessage()
- {
- var writer = this.Connection.GetMessageWriter();
- writer.WriteMethodCallHeader(
- destination: Service.Destination,
- path: Path,
- @interface: __Interface,
- signature: "a{sv}",
- member: "CreateSession");
- writer.WriteDictionary(options);
- return writer.CreateMessage();
- }
- }
- public Task StartAsync(ObjectPath sessionHandle, string parentWindow, Dictionary options)
- {
- return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this);
- MessageBuffer CreateMessage()
- {
- var writer = this.Connection.GetMessageWriter();
- writer.WriteMethodCallHeader(
- destination: Service.Destination,
- path: Path,
- @interface: __Interface,
- signature: "osa{sv}",
- member: "Start");
- writer.WriteObjectPath(sessionHandle);
- writer.WriteString(parentWindow);
- writer.WriteDictionary(options);
- return writer.CreateMessage();
- }
- }
- public ValueTask WatchLocationUpdatedAsync(Action Location)> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None)
- => base.WatchSignalAsync(Service.Destination, __Interface, Path, "LocationUpdated", (Message m, object? s) => ReadMessage_oaesv(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags);
- public Task GetVersionAsync()
- => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this);
- public Task GetPropertiesAsync()
- {
- return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this);
- static LocationProperties ReadMessage(Message message, DesktopObject _)
- {
- var reader = message.GetBodyReader();
- return ReadProperties(ref reader);
- }
- }
- public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None)
- {
- return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags);
- static PropertyChanges ReadMessage(Message message, DesktopObject _)
- {
- var reader = message.GetBodyReader();
- reader.ReadString(); // interface
- List changed = new(), invalidated = new();
- return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray());
- }
- static string[] ReadInvalidated(ref Reader reader)
- {
- List? invalidated = null;
- ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String);
- while (reader.HasNext(arrayEnd))
- {
- invalidated ??= new();
- var property = reader.ReadString();
- switch (property)
- {
- case "version": invalidated.Add("Version"); break;
- }
- }
- return invalidated?.ToArray() ?? Array.Empty();
- }
- }
- private static LocationProperties ReadProperties(ref Reader reader, List? changedList = null)
- {
- var props = new LocationProperties();
- ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct);
- while (reader.HasNext(arrayEnd))
- {
- var property = reader.ReadString();
- switch (property)
- {
- case "version":
- reader.ReadSignature("u"u8);
- props.Version = reader.ReadUInt32();
- changedList?.Add("Version");
- break;
- default:
- reader.ReadVariantValue();
- break;
- }
- }
- return props;
- }
-}
record NotificationProperties
{
public Dictionary SupportedOptions { get; set; } = default!;
@@ -2862,91 +2637,6 @@ private static ScreenCastProperties ReadProperties(ref Reader reader, List ComposeEmailAsync(string parentWindow, Dictionary options)
- {
- return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this);
- MessageBuffer CreateMessage()
- {
- var writer = this.Connection.GetMessageWriter();
- writer.WriteMethodCallHeader(
- destination: Service.Destination,
- path: Path,
- @interface: __Interface,
- signature: "sa{sv}",
- member: "ComposeEmail");
- writer.WriteString(parentWindow);
- writer.WriteDictionary(options);
- return writer.CreateMessage();
- }
- }
- public Task GetVersionAsync()
- => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this);
- public Task GetPropertiesAsync()
- {
- return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this);
- static EmailProperties ReadMessage(Message message, DesktopObject _)
- {
- var reader = message.GetBodyReader();
- return ReadProperties(ref reader);
- }
- }
- public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None)
- {
- return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags);
- static PropertyChanges ReadMessage(Message message, DesktopObject _)
- {
- var reader = message.GetBodyReader();
- reader.ReadString(); // interface
- List changed = new(), invalidated = new();
- return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray());
- }
- static string[] ReadInvalidated(ref Reader reader)
- {
- List? invalidated = null;
- ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String);
- while (reader.HasNext(arrayEnd))
- {
- invalidated ??= new();
- var property = reader.ReadString();
- switch (property)
- {
- case "version": invalidated.Add("Version"); break;
- }
- }
- return invalidated?.ToArray() ?? Array.Empty();
- }
- }
- private static EmailProperties ReadProperties(ref Reader reader, List? changedList = null)
- {
- var props = new EmailProperties();
- ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct);
- while (reader.HasNext(arrayEnd))
- {
- var property = reader.ReadString();
- switch (property)
- {
- case "version":
- reader.ReadSignature("u"u8);
- props.Version = reader.ReadUInt32();
- changedList?.Add("Version");
- break;
- default:
- reader.ReadVariantValue();
- break;
- }
- }
- return props;
- }
-}
record TrashProperties
{
public uint Version { get; set; } = default!;
@@ -3327,30 +3017,14 @@ partial class DesktopService
public string Destination { get; }
public DesktopService(Tmds.DBus.Protocol.Connection connection, string destination)
=> (Connection, Destination) = (connection, destination);
- public Inhibit CreateInhibit(ObjectPath path) => new Inhibit(this, path);
- public Background CreateBackground(ObjectPath path) => new Background(this, path);
- public Location CreateLocation(ObjectPath path) => new Location(this, path);
public Notification CreateNotification(ObjectPath path) => new Notification(this, path);
public Screenshot CreateScreenshot(ObjectPath path) => new Screenshot(this, path);
- public Account CreateAccount(ObjectPath path) => new Account(this, path);
- public NetworkMonitor CreateNetworkMonitor(ObjectPath path) => new NetworkMonitor(this, path);
- public Print CreatePrint(ObjectPath path) => new Print(this, path);
- public Settings CreateSettings(ObjectPath path) => new Settings(this, path);
- public GameMode CreateGameMode(ObjectPath path) => new GameMode(this, path);
- public RemoteDesktop CreateRemoteDesktop(ObjectPath path) => new RemoteDesktop(this, path);
- public MemoryMonitor CreateMemoryMonitor(ObjectPath path) => new MemoryMonitor(this, path);
public OpenURI CreateOpenURI(ObjectPath path) => new OpenURI(this, path);
public Realtime CreateRealtime(ObjectPath path) => new Realtime(this, path);
public Secret CreateSecret(ObjectPath path) => new Secret(this, path);
- public Camera CreateCamera(ObjectPath path) => new Camera(this, path);
public InputCapture CreateInputCapture(ObjectPath path) => new InputCapture(this, path);
public GlobalShortcuts CreateGlobalShortcuts(ObjectPath path) => new GlobalShortcuts(this, path);
- public PowerProfileMonitor CreatePowerProfileMonitor(ObjectPath path) => new PowerProfileMonitor(this, path);
- public DynamicLauncher CreateDynamicLauncher(ObjectPath path) => new DynamicLauncher(this, path);
public ScreenCast CreateScreenCast(ObjectPath path) => new ScreenCast(this, path);
- public Email CreateEmail(ObjectPath path) => new Email(this, path);
- public Trash CreateTrash(ObjectPath path) => new Trash(this, path);
- public ProxyResolver CreateProxyResolver(ObjectPath path) => new ProxyResolver(this, path);
public FileChooser CreateFileChooser(ObjectPath path) => new FileChooser(this, path);
public Session CreateSession(ObjectPath path) => new Session(this, path);
}
diff --git a/SnapX.Core/SharpCapture/Linux/DBus/PropertyChanges.cs b/SnapX.Core/SharpCapture/Linux/DBus/PropertyChanges.cs
index ed73bd2d4..6fe1861be 100644
--- a/SnapX.Core/SharpCapture/Linux/DBus/PropertyChanges.cs
+++ b/SnapX.Core/SharpCapture/Linux/DBus/PropertyChanges.cs
@@ -1,12 +1,10 @@
namespace SnapX.Core.SharpCapture.Linux.DBus;
-public class PropertyChanges
+public class PropertyChanges(TProperties Properties, string[] Invalidated, string[] Changed)
{
- public PropertyChanges(TProperties properties, string[] invalidated, string[] changed)
- => (Properties, Invalidated, Changed) = (properties, invalidated, changed);
- public TProperties Properties { get; }
- public string[] Invalidated { get; }
- public string[] Changed { get; }
+ public TProperties Properties { get; } = Properties;
+ public string[] Invalidated { get; } = Invalidated;
+ public string[] Changed { get; } = Changed;
public bool HasChanged(string property) => Array.IndexOf(Changed, property) != -1;
public bool IsInvalidated(string property) => Array.IndexOf(Invalidated, property) != -1;
}
diff --git a/SnapX.Core/SharpCapture/Linux/LinuxCapture.cs b/SnapX.Core/SharpCapture/Linux/LinuxCapture.cs
index c9ec1da04..65fe2915c 100644
--- a/SnapX.Core/SharpCapture/Linux/LinuxCapture.cs
+++ b/SnapX.Core/SharpCapture/Linux/LinuxCapture.cs
@@ -1,5 +1,6 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
+using SnapX.Core.Job;
using SnapX.Core.SharpCapture.Linux.DBus;
using SnapX.Core.Utils.Native;
using Tmds.DBus;
@@ -7,15 +8,15 @@
namespace SnapX.Core.SharpCapture.Linux;
-public class LinuxCapture : BaseCapture
+public class LinuxCapture : BaseSharpCapture
{
- public override async Task CaptureFullscreen()
+ public override async Task CaptureFullscreen(TaskSettings? taskSettings = null)
{
if (LinuxAPI.IsWayland() && !IsCompositorKwin) return await TakeScreenshotWithPortal();
var screen = Methods.GetScreen(Methods.GetCursorPosition());
if (!IsCompositorKwin)
{
- return LinuxAPI.TakeScreenshotWithX11(screen);
+ return ((LinuxAPI)Methods.NativeAPI).TakeScreenshotWithX11(screen);
}
// Todo: replace try catch with method that checks for valid kwin permissions.
@@ -122,7 +123,7 @@ private static Image CropFullscreenScreenshotToBounds(Rectangle bounds, Image im
return img;
}
- public override async Task CaptureScreen(Rectangle bounds)
+ public override async Task CaptureScreen(Rectangle bounds, TaskSettings? taskSettings = null)
{
var fullscreenImage = await CaptureFullscreen().ConfigureAwait(false);
var croppedImage = CropFullscreenScreenshotToBounds(bounds, fullscreenImage);
@@ -132,7 +133,7 @@ private static Image CropFullscreenScreenshotToBounds(Rectangle bounds, Image im
// return LinuxAPI.TakeScreenshotWithX11(screen);
}
- public override async Task CaptureScreen(Point? pos)
+ public override async Task CaptureScreen(Point? pos, TaskSettings? taskSettings = null)
{
if (pos == null || !pos.HasValue) throw new ArgumentNullException(nameof(pos));
return await CaptureScreen(await GetScreen(pos.Value));
@@ -141,7 +142,7 @@ private static Image CropFullscreenScreenshotToBounds(Rectangle bounds, Image im
public override async Task GetScreen(Point pos) => Methods.NativeAPI.GetScreen(pos).Bounds;
public override async Task GetWorkingArea() => ((LinuxAPI)Methods.NativeAPI).GetScreenBounds();
- public override async Task CaptureRectangle(Rectangle rect)
+ public override async Task CaptureRectangle(Rectangle rect, TaskSettings? taskSettings = null)
{
return CropFullscreenScreenshotToBounds(rect, await CaptureFullscreen().ConfigureAwait(false));
}
diff --git a/SnapX.Core/ScreenCapture/RegionCaptureOptions.cs b/SnapX.Core/SharpCapture/RegionCaptureOptions.cs
similarity index 87%
rename from SnapX.Core/ScreenCapture/RegionCaptureOptions.cs
rename to SnapX.Core/SharpCapture/RegionCaptureOptions.cs
index 4a2a7eac4..01588b564 100644
--- a/SnapX.Core/ScreenCapture/RegionCaptureOptions.cs
+++ b/SnapX.Core/SharpCapture/RegionCaptureOptions.cs
@@ -1,12 +1,12 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using SixLabors.ImageSharp;
+using SnapX.Core.History;
using SnapX.Core.ImageEffects;
-using SnapX.Core.ScreenCapture.Helpers;
+using SnapX.Core.SharpCapture.Helpers;
-namespace SnapX.Core.ScreenCapture;
+namespace SnapX.Core.SharpCapture;
public class RegionCaptureOptions
{
@@ -34,16 +34,20 @@ public class RegionCaptureOptions
public string CustomInfoText = "X: $x, Y: $y$nR: $r, G: $g, B: $b$nHex: $hex"; // Formats: $x, $y, $r, $g, $b, $hex, $HEX, $n
public List SnapSizes =
[
- new(426, 240), // 240p
- new(640, 360), // 360p
- new(854, 480), // 480p
- new(1280, 720), // 720p
- new(1920, 1080) // 1080p
+ new(426, 240), // 240p
+ new(640, 360), // 360p
+ new(854, 480), // 480p
+ new(1280, 720), // 720p
+ new(1920, 1080), // 1080p
+ new(2560, 1440), // 1440p
+ new(3840, 2160), // 2160p
+ new(5120, 2880), // 2880p / 5K
+ new(7680, 4320) // 4320p / 8K
];
public bool ShowInfo = true;
public bool ShowMagnifier = true;
public bool UseSquareMagnifier = false;
- public int MagnifierPixelCount = 15; // Must be odd number like 11, 13, 15 etc.
+ public int MagnifierPixelCount = 15; // Must be odd number like 11, 13, 15, etc.
public int MagnifierPixelSize = 10;
public bool ShowCrosshair = false;
public bool UseLightResizeNodes = false;
@@ -76,7 +80,7 @@ public class RegionCaptureOptions
public bool AutoCloseEditorOnTask = false;
public bool ShowEditorPanTip = true;
public ImageInterpolationMode ImageEditorResizeInterpolationMode = ImageInterpolationMode.Bicubic;
- public Size EditorNewImageSize = new Size(800, 600);
+ public Size EditorNewImageSize = new(800, 600);
public bool EditorNewImageTransparent = false;
public Color EditorNewImageBackgroundColor = Color.White;
public Color EditorCanvasColor = Color.Transparent;
diff --git a/SnapX.Core/ScreenCapture/RegionCaptureTasks.cs b/SnapX.Core/SharpCapture/RegionCaptureTasks.cs
similarity index 98%
rename from SnapX.Core/ScreenCapture/RegionCaptureTasks.cs
rename to SnapX.Core/SharpCapture/RegionCaptureTasks.cs
index 7d454c48d..0569accd5 100644
--- a/SnapX.Core/ScreenCapture/RegionCaptureTasks.cs
+++ b/SnapX.Core/SharpCapture/RegionCaptureTasks.cs
@@ -4,9 +4,9 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SnapX.Core.Media;
-using SnapX.Core.ScreenCapture.Helpers;
+using SnapX.Core.SharpCapture.Helpers;
-namespace SnapX.Core.ScreenCapture;
+namespace SnapX.Core.SharpCapture;
public static class RegionCaptureTasks
{
diff --git a/SnapX.Core/ScreenCapture/Rust/Cargo.lock b/SnapX.Core/SharpCapture/Rust/Cargo.lock
similarity index 100%
rename from SnapX.Core/ScreenCapture/Rust/Cargo.lock
rename to SnapX.Core/SharpCapture/Rust/Cargo.lock
diff --git a/SnapX.Core/ScreenCapture/Rust/Cargo.toml b/SnapX.Core/SharpCapture/Rust/Cargo.toml
similarity index 100%
rename from SnapX.Core/ScreenCapture/Rust/Cargo.toml
rename to SnapX.Core/SharpCapture/Rust/Cargo.toml
diff --git a/SnapX.Core/ScreenCapture/Rust/bindings/snapxrust.cs b/SnapX.Core/SharpCapture/Rust/bindings/snapxrust.cs
similarity index 100%
rename from SnapX.Core/ScreenCapture/Rust/bindings/snapxrust.cs
rename to SnapX.Core/SharpCapture/Rust/bindings/snapxrust.cs
diff --git a/SnapX.Core/SharpCapture/Rust/bindings/snapxrust.py b/SnapX.Core/SharpCapture/Rust/bindings/snapxrust.py
new file mode 100644
index 000000000..a8186a831
--- /dev/null
+++ b/SnapX.Core/SharpCapture/Rust/bindings/snapxrust.py
@@ -0,0 +1,1090 @@
+# This file was autogenerated by some hot garbage in the `uniffi` crate.
+# Trust me, you don't want to mess with it!
+
+# Common helper code.
+#
+# Ideally this would live in a separate .py file where it can be unittested etc
+# in isolation, and perhaps even published as a re-useable package.
+#
+# However, it's important that the details of how this helper code works (e.g. the
+# way that different builtin types are passed across the FFI) exactly match what's
+# expected by the rust code on the other side of the interface. In practice right
+# now that means coming from the exact some version of `uniffi` that was used to
+# compile the rust component. The easiest way to ensure this is to bundle the Python
+# helpers directly inline like we're doing here.
+
+import os
+import sys
+import ctypes
+import enum
+import struct
+import contextlib
+import datetime
+import typing
+import platform
+
+# Used for default argument values
+_DEFAULT = object()
+
+
+class _UniffiRustBuffer(ctypes.Structure):
+ _fields_ = [
+ ("capacity", ctypes.c_int32),
+ ("len", ctypes.c_int32),
+ ("data", ctypes.POINTER(ctypes.c_char)),
+ ]
+
+ @staticmethod
+ def alloc(size):
+ return _rust_call(_UniffiLib.ffi_snapxrust_rustbuffer_alloc, size)
+
+ @staticmethod
+ def reserve(rbuf, additional):
+ return _rust_call(_UniffiLib.ffi_snapxrust_rustbuffer_reserve, rbuf, additional)
+
+ def free(self):
+ return _rust_call(_UniffiLib.ffi_snapxrust_rustbuffer_free, self)
+
+ def __str__(self):
+ return "_UniffiRustBuffer(capacity={}, len={}, data={})".format(
+ self.capacity,
+ self.len,
+ self.data[0:self.len]
+ )
+
+ @contextlib.contextmanager
+ def alloc_with_builder(*args):
+ """Context-manger to allocate a buffer using a _UniffiRustBufferBuilder.
+
+ The allocated buffer will be automatically freed if an error occurs, ensuring that
+ we don't accidentally leak it.
+ """
+ builder = _UniffiRustBufferBuilder()
+ try:
+ yield builder
+ except:
+ builder.discard()
+ raise
+
+ @contextlib.contextmanager
+ def consume_with_stream(self):
+ """Context-manager to consume a buffer using a _UniffiRustBufferStream.
+
+ The _UniffiRustBuffer will be freed once the context-manager exits, ensuring that we don't
+ leak it even if an error occurs.
+ """
+ try:
+ s = _UniffiRustBufferStream.from_rust_buffer(self)
+ yield s
+ if s.remaining() != 0:
+ raise RuntimeError("junk data left in buffer at end of consume_with_stream")
+ finally:
+ self.free()
+
+ @contextlib.contextmanager
+ def read_with_stream(self):
+ """Context-manager to read a buffer using a _UniffiRustBufferStream.
+
+ This is like consume_with_stream, but doesn't free the buffer afterwards.
+ It should only be used with borrowed `_UniffiRustBuffer` data.
+ """
+ s = _UniffiRustBufferStream.from_rust_buffer(self)
+ yield s
+ if s.remaining() != 0:
+ raise RuntimeError("junk data left in buffer at end of read_with_stream")
+
+class _UniffiForeignBytes(ctypes.Structure):
+ _fields_ = [
+ ("len", ctypes.c_int32),
+ ("data", ctypes.POINTER(ctypes.c_char)),
+ ]
+
+ def __str__(self):
+ return "_UniffiForeignBytes(len={}, data={})".format(self.len, self.data[0:self.len])
+
+
+class _UniffiRustBufferStream:
+ """
+ Helper for structured reading of bytes from a _UniffiRustBuffer
+ """
+
+ def __init__(self, data, len):
+ self.data = data
+ self.len = len
+ self.offset = 0
+
+ @classmethod
+ def from_rust_buffer(cls, buf):
+ return cls(buf.data, buf.len)
+
+ def remaining(self):
+ return self.len - self.offset
+
+ def _unpack_from(self, size, format):
+ if self.offset + size > self.len:
+ raise InternalError("read past end of rust buffer")
+ value = struct.unpack(format, self.data[self.offset:self.offset+size])[0]
+ self.offset += size
+ return value
+
+ def read(self, size):
+ if self.offset + size > self.len:
+ raise InternalError("read past end of rust buffer")
+ data = self.data[self.offset:self.offset+size]
+ self.offset += size
+ return data
+
+ def read_i8(self):
+ return self._unpack_from(1, ">b")
+
+ def read_u8(self):
+ return self._unpack_from(1, ">B")
+
+ def read_i16(self):
+ return self._unpack_from(2, ">h")
+
+ def read_u16(self):
+ return self._unpack_from(2, ">H")
+
+ def read_i32(self):
+ return self._unpack_from(4, ">i")
+
+ def read_u32(self):
+ return self._unpack_from(4, ">I")
+
+ def read_i64(self):
+ return self._unpack_from(8, ">q")
+
+ def read_u64(self):
+ return self._unpack_from(8, ">Q")
+
+ def read_float(self):
+ v = self._unpack_from(4, ">f")
+ return v
+
+ def read_double(self):
+ return self._unpack_from(8, ">d")
+
+ def read_c_size_t(self):
+ return self._unpack_from(ctypes.sizeof(ctypes.c_size_t) , "@N")
+
+class _UniffiRustBufferBuilder:
+ """
+ Helper for structured writing of bytes into a _UniffiRustBuffer.
+ """
+
+ def __init__(self):
+ self.rbuf = _UniffiRustBuffer.alloc(16)
+ self.rbuf.len = 0
+
+ def finalize(self):
+ rbuf = self.rbuf
+ self.rbuf = None
+ return rbuf
+
+ def discard(self):
+ if self.rbuf is not None:
+ rbuf = self.finalize()
+ rbuf.free()
+
+ @contextlib.contextmanager
+ def _reserve(self, num_bytes):
+ if self.rbuf.len + num_bytes > self.rbuf.capacity:
+ self.rbuf = _UniffiRustBuffer.reserve(self.rbuf, num_bytes)
+ yield None
+ self.rbuf.len += num_bytes
+
+ def _pack_into(self, size, format, value):
+ with self._reserve(size):
+ # XXX TODO: I feel like I should be able to use `struct.pack_into` here but can't figure it out.
+ for i, byte in enumerate(struct.pack(format, value)):
+ self.rbuf.data[self.rbuf.len + i] = byte
+
+ def write(self, value):
+ with self._reserve(len(value)):
+ for i, byte in enumerate(value):
+ self.rbuf.data[self.rbuf.len + i] = byte
+
+ def write_i8(self, v):
+ self._pack_into(1, ">b", v)
+
+ def write_u8(self, v):
+ self._pack_into(1, ">B", v)
+
+ def write_i16(self, v):
+ self._pack_into(2, ">h", v)
+
+ def write_u16(self, v):
+ self._pack_into(2, ">H", v)
+
+ def write_i32(self, v):
+ self._pack_into(4, ">i", v)
+
+ def write_u32(self, v):
+ self._pack_into(4, ">I", v)
+
+ def write_i64(self, v):
+ self._pack_into(8, ">q", v)
+
+ def write_u64(self, v):
+ self._pack_into(8, ">Q", v)
+
+ def write_float(self, v):
+ self._pack_into(4, ">f", v)
+
+ def write_double(self, v):
+ self._pack_into(8, ">d", v)
+
+ def write_c_size_t(self, v):
+ self._pack_into(ctypes.sizeof(ctypes.c_size_t) , "@N", v)
+# A handful of classes and functions to support the generated data structures.
+# This would be a good candidate for isolating in its own ffi-support lib.
+
+class InternalError(Exception):
+ pass
+
+class _UniffiRustCallStatus(ctypes.Structure):
+ """
+ Error runtime.
+ """
+ _fields_ = [
+ ("code", ctypes.c_int8),
+ ("error_buf", _UniffiRustBuffer),
+ ]
+
+ # These match the values from the uniffi::rustcalls module
+ CALL_SUCCESS = 0
+ CALL_ERROR = 1
+ CALL_PANIC = 2
+
+ def __str__(self):
+ if self.code == _UniffiRustCallStatus.CALL_SUCCESS:
+ return "_UniffiRustCallStatus(CALL_SUCCESS)"
+ elif self.code == _UniffiRustCallStatus.CALL_ERROR:
+ return "_UniffiRustCallStatus(CALL_ERROR)"
+ elif self.code == _UniffiRustCallStatus.CALL_PANIC:
+ return "_UniffiRustCallStatus(CALL_PANIC)"
+ else:
+ return "_UniffiRustCallStatus()"
+
+def _rust_call(fn, *args):
+ # Call a rust function
+ return _rust_call_with_error(None, fn, *args)
+
+def _rust_call_with_error(error_ffi_converter, fn, *args):
+ # Call a rust function and handle any errors
+ #
+ # This function is used for rust calls that return Result<> and therefore can set the CALL_ERROR status code.
+ # error_ffi_converter must be set to the _UniffiConverter for the error class that corresponds to the result.
+ call_status = _UniffiRustCallStatus(code=_UniffiRustCallStatus.CALL_SUCCESS, error_buf=_UniffiRustBuffer(0, 0, None))
+
+ args_with_error = args + (ctypes.byref(call_status),)
+ result = fn(*args_with_error)
+ _uniffi_check_call_status(error_ffi_converter, call_status)
+ return result
+
+def _uniffi_check_call_status(error_ffi_converter, call_status):
+ if call_status.code == _UniffiRustCallStatus.CALL_SUCCESS:
+ pass
+ elif call_status.code == _UniffiRustCallStatus.CALL_ERROR:
+ if error_ffi_converter is None:
+ call_status.error_buf.free()
+ raise InternalError("_rust_call_with_error: CALL_ERROR, but error_ffi_converter is None")
+ else:
+ raise error_ffi_converter.lift(call_status.error_buf)
+ elif call_status.code == _UniffiRustCallStatus.CALL_PANIC:
+ # When the rust code sees a panic, it tries to construct a _UniffiRustBuffer
+ # with the message. But if that code panics, then it just sends back
+ # an empty buffer.
+ if call_status.error_buf.len > 0:
+ msg = _UniffiConverterString.lift(call_status.error_buf)
+ else:
+ msg = "Unknown rust panic"
+ raise InternalError(msg)
+ else:
+ raise InternalError("Invalid _UniffiRustCallStatus code: {}".format(
+ call_status.code))
+
+# A function pointer for a callback as defined by UniFFI.
+# Rust definition `fn(handle: u64, method: u32, args: _UniffiRustBuffer, buf_ptr: *mut _UniffiRustBuffer) -> int`
+_UNIFFI_FOREIGN_CALLBACK_T = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_ulonglong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_char), ctypes.c_int, ctypes.POINTER(_UniffiRustBuffer))
+
+# UniFFI future continuation
+_UNIFFI_FUTURE_CONTINUATION_T = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_int8)
+
+class _UniffiPointerManagerCPython:
+ """
+ Manage giving out pointers to Python objects on CPython
+
+ This class is used to generate opaque pointers that reference Python objects to pass to Rust.
+ It assumes a CPython platform. See _UniffiPointerManagerGeneral for the alternative.
+ """
+
+ def new_pointer(self, obj):
+ """
+ Get a pointer for an object as a ctypes.c_size_t instance
+
+ Each call to new_pointer() must be balanced with exactly one call to release_pointer()
+
+ This returns a ctypes.c_size_t. This is always the same size as a pointer and can be
+ interchanged with pointers for FFI function arguments and return values.
+ """
+ # IncRef the object since we're going to pass a pointer to Rust
+ ctypes.pythonapi.Py_IncRef(ctypes.py_object(obj))
+ # id() is the object address on CPython
+ # (https://docs.python.org/3/library/functions.html#id)
+ return id(obj)
+
+ def release_pointer(self, address):
+ py_obj = ctypes.cast(address, ctypes.py_object)
+ obj = py_obj.value
+ ctypes.pythonapi.Py_DecRef(py_obj)
+ return obj
+
+ def lookup(self, address):
+ return ctypes.cast(address, ctypes.py_object).value
+
+class _UniffiPointerManagerGeneral:
+ """
+ Manage giving out pointers to Python objects on non-CPython platforms
+
+ This has the same API as _UniffiPointerManagerCPython, but doesn't assume we're running on
+ CPython and is slightly slower.
+
+ Instead of using real pointers, it maps integer values to objects and returns the keys as
+ c_size_t values.
+ """
+
+ def __init__(self):
+ self._map = {}
+ self._lock = threading.Lock()
+ self._current_handle = 0
+
+ def new_pointer(self, obj):
+ with self._lock:
+ handle = self._current_handle
+ self._current_handle += 1
+ self._map[handle] = obj
+ return handle
+
+ def release_pointer(self, handle):
+ with self._lock:
+ return self._map.pop(handle)
+
+ def lookup(self, handle):
+ with self._lock:
+ return self._map[handle]
+
+# Pick an pointer manager implementation based on the platform
+if platform.python_implementation() == 'CPython':
+ _UniffiPointerManager = _UniffiPointerManagerCPython # type: ignore
+else:
+ _UniffiPointerManager = _UniffiPointerManagerGeneral # type: ignore
+# Types conforming to `_UniffiConverterPrimitive` pass themselves directly over the FFI.
+class _UniffiConverterPrimitive:
+ @classmethod
+ def check(cls, value):
+ return value
+
+ @classmethod
+ def lift(cls, value):
+ return value
+
+ @classmethod
+ def lower(cls, value):
+ return cls.lowerUnchecked(cls.check(value))
+
+ @classmethod
+ def lowerUnchecked(cls, value):
+ return value
+
+ @classmethod
+ def write(cls, value, buf):
+ cls.write_unchecked(cls.check(value), buf)
+
+class _UniffiConverterPrimitiveInt(_UniffiConverterPrimitive):
+ @classmethod
+ def check(cls, value):
+ try:
+ value = value.__index__()
+ except Exception:
+ raise TypeError("'{}' object cannot be interpreted as an integer".format(type(value).__name__))
+ if not isinstance(value, int):
+ raise TypeError("__index__ returned non-int (type {})".format(type(value).__name__))
+ if not cls.VALUE_MIN <= value < cls.VALUE_MAX:
+ raise ValueError("{} requires {} <= value < {}".format(cls.CLASS_NAME, cls.VALUE_MIN, cls.VALUE_MAX))
+ return super().check(value)
+
+class _UniffiConverterPrimitiveFloat(_UniffiConverterPrimitive):
+ @classmethod
+ def check(cls, value):
+ try:
+ value = value.__float__()
+ except Exception:
+ raise TypeError("must be real number, not {}".format(type(value).__name__))
+ if not isinstance(value, float):
+ raise TypeError("__float__ returned non-float (type {})".format(type(value).__name__))
+ return super().check(value)
+
+# Helper class for wrapper types that will always go through a _UniffiRustBuffer.
+# Classes should inherit from this and implement the `read` and `write` static methods.
+class _UniffiConverterRustBuffer:
+ @classmethod
+ def lift(cls, rbuf):
+ with rbuf.consume_with_stream() as stream:
+ return cls.read(stream)
+
+ @classmethod
+ def lower(cls, value):
+ with _UniffiRustBuffer.alloc_with_builder() as builder:
+ cls.write(value, builder)
+ return builder.finalize()
+
+# Contains loading, initialization code, and the FFI Function declarations.
+# Define some ctypes FFI types that we use in the library
+
+"""
+ctypes type for the foreign executor callback. This is a built-in interface for scheduling
+tasks
+
+Args:
+ executor: opaque c_size_t value representing the eventloop
+ delay: delay in ms
+ task: function pointer to the task callback
+ task_data: void pointer to the task callback data
+
+Normally we should call task(task_data) after the detail.
+However, when task is NULL this indicates that Rust has dropped the ForeignExecutor and we should
+decrease the EventLoop refcount.
+"""
+_UNIFFI_FOREIGN_EXECUTOR_CALLBACK_T = ctypes.CFUNCTYPE(ctypes.c_int8, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_void_p, ctypes.c_void_p)
+
+"""
+Function pointer for a Rust task, which a callback function that takes a opaque pointer
+"""
+_UNIFFI_RUST_TASK = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int8)
+
+def _uniffi_future_callback_t(return_type):
+ """
+ Factory function to create callback function types for async functions
+ """
+ return ctypes.CFUNCTYPE(None, ctypes.c_size_t, return_type, _UniffiRustCallStatus)
+
+def _uniffi_load_indirect():
+ """
+ This is how we find and load the dynamic library provided by the component.
+ For now we just look it up by name.
+ """
+ if sys.platform == "darwin":
+ libname = "lib{}.dylib"
+ elif sys.platform.startswith("win"):
+ # As of python3.8, ctypes does not seem to search $PATH when loading DLLs.
+ # We could use `os.add_dll_directory` to configure the search path, but
+ # it doesn't feel right to mess with application-wide settings. Let's
+ # assume that the `.dll` is next to the `.py` file and load by full path.
+ libname = os.path.join(
+ os.path.dirname(__file__),
+ "{}.dll",
+ )
+ else:
+ # Anything else must be an ELF platform - Linux, *BSD, Solaris/illumos
+ libname = "lib{}.so"
+
+ libname = libname.format("uniffi_snapxrust")
+ path = os.path.join(os.path.dirname(__file__), libname)
+ lib = ctypes.cdll.LoadLibrary(path)
+ return lib
+
+def _uniffi_check_contract_api_version(lib):
+ # Get the bindings contract version from our ComponentInterface
+ bindings_contract_version = 24
+ # Get the scaffolding contract version by calling the into the dylib
+ scaffolding_contract_version = lib.ffi_snapxrust_uniffi_contract_version()
+ if bindings_contract_version != scaffolding_contract_version:
+ raise InternalError("UniFFI contract version mismatch: try cleaning and rebuilding your project")
+
+def _uniffi_check_api_checksums(lib):
+ if lib.uniffi_snapxrust_checksum_func_capture_fullscreen() != 6651:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ if lib.uniffi_snapxrust_checksum_func_capture_monitor() != 61593:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ if lib.uniffi_snapxrust_checksum_func_capture_rect() != 15851:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ if lib.uniffi_snapxrust_checksum_func_capture_window() != 52724:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ if lib.uniffi_snapxrust_checksum_func_get_monitor() != 61273:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ if lib.uniffi_snapxrust_checksum_func_get_primary_monitor() != 12932:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ if lib.uniffi_snapxrust_checksum_func_get_screen_dimensions() != 25884:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ if lib.uniffi_snapxrust_checksum_func_get_working_area() != 60391:
+ raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+
+# A ctypes library to expose the extern-C FFI definitions.
+# This is an implementation detail which will be called internally by the public API.
+
+_UniffiLib = _uniffi_load_indirect()
+_UniffiLib.uniffi_snapxrust_fn_func_capture_fullscreen.argtypes = (
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_capture_fullscreen.restype = _UniffiRustBuffer
+_UniffiLib.uniffi_snapxrust_fn_func_capture_monitor.argtypes = (
+ _UniffiRustBuffer,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_capture_monitor.restype = _UniffiRustBuffer
+_UniffiLib.uniffi_snapxrust_fn_func_capture_rect.argtypes = (
+ ctypes.c_uint32,
+ ctypes.c_uint32,
+ ctypes.c_uint32,
+ ctypes.c_uint32,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_capture_rect.restype = _UniffiRustBuffer
+_UniffiLib.uniffi_snapxrust_fn_func_capture_window.argtypes = (
+ ctypes.c_uint32,
+ ctypes.c_uint32,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_capture_window.restype = _UniffiRustBuffer
+_UniffiLib.uniffi_snapxrust_fn_func_get_monitor.argtypes = (
+ ctypes.c_uint32,
+ ctypes.c_uint32,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_get_monitor.restype = _UniffiRustBuffer
+_UniffiLib.uniffi_snapxrust_fn_func_get_primary_monitor.argtypes = (
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_get_primary_monitor.restype = _UniffiRustBuffer
+_UniffiLib.uniffi_snapxrust_fn_func_get_screen_dimensions.argtypes = (
+ _UniffiRustBuffer,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_get_screen_dimensions.restype = _UniffiRustBuffer
+_UniffiLib.uniffi_snapxrust_fn_func_get_working_area.argtypes = (
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.uniffi_snapxrust_fn_func_get_working_area.restype = _UniffiRustBuffer
+_UniffiLib.ffi_snapxrust_rustbuffer_alloc.argtypes = (
+ ctypes.c_int32,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rustbuffer_alloc.restype = _UniffiRustBuffer
+_UniffiLib.ffi_snapxrust_rustbuffer_from_bytes.argtypes = (
+ _UniffiForeignBytes,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rustbuffer_from_bytes.restype = _UniffiRustBuffer
+_UniffiLib.ffi_snapxrust_rustbuffer_free.argtypes = (
+ _UniffiRustBuffer,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rustbuffer_free.restype = None
+_UniffiLib.ffi_snapxrust_rustbuffer_reserve.argtypes = (
+ _UniffiRustBuffer,
+ ctypes.c_int32,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rustbuffer_reserve.restype = _UniffiRustBuffer
+_UniffiLib.ffi_snapxrust_rust_future_continuation_callback_set.argtypes = (
+ _UNIFFI_FUTURE_CONTINUATION_T,
+)
+_UniffiLib.ffi_snapxrust_rust_future_continuation_callback_set.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_poll_u8.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_u8.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u8.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u8.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_u8.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_u8.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_u8.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_u8.restype = ctypes.c_uint8
+_UniffiLib.ffi_snapxrust_rust_future_poll_i8.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_i8.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i8.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i8.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_i8.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_i8.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_i8.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_i8.restype = ctypes.c_int8
+_UniffiLib.ffi_snapxrust_rust_future_poll_u16.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_u16.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u16.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u16.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_u16.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_u16.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_u16.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_u16.restype = ctypes.c_uint16
+_UniffiLib.ffi_snapxrust_rust_future_poll_i16.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_i16.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i16.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i16.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_i16.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_i16.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_i16.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_i16.restype = ctypes.c_int16
+_UniffiLib.ffi_snapxrust_rust_future_poll_u32.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_u32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u32.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_u32.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_u32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_u32.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_u32.restype = ctypes.c_uint32
+_UniffiLib.ffi_snapxrust_rust_future_poll_i32.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_i32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i32.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_i32.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_i32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_i32.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_i32.restype = ctypes.c_int32
+_UniffiLib.ffi_snapxrust_rust_future_poll_u64.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_u64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u64.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_u64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_u64.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_u64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_u64.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_u64.restype = ctypes.c_uint64
+_UniffiLib.ffi_snapxrust_rust_future_poll_i64.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_i64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i64.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_i64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_i64.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_i64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_i64.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_i64.restype = ctypes.c_int64
+_UniffiLib.ffi_snapxrust_rust_future_poll_f32.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_f32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_f32.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_f32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_f32.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_f32.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_f32.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_f32.restype = ctypes.c_float
+_UniffiLib.ffi_snapxrust_rust_future_poll_f64.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_f64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_f64.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_f64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_f64.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_f64.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_f64.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_f64.restype = ctypes.c_double
+_UniffiLib.ffi_snapxrust_rust_future_poll_pointer.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_pointer.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_pointer.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_pointer.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_pointer.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_pointer.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_pointer.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_pointer.restype = ctypes.c_void_p
+_UniffiLib.ffi_snapxrust_rust_future_poll_rust_buffer.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_rust_buffer.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_rust_buffer.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_rust_buffer.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_rust_buffer.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_rust_buffer.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_rust_buffer.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_rust_buffer.restype = _UniffiRustBuffer
+_UniffiLib.ffi_snapxrust_rust_future_poll_void.argtypes = (
+ ctypes.c_void_p,
+ ctypes.c_size_t,
+)
+_UniffiLib.ffi_snapxrust_rust_future_poll_void.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_cancel_void.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_cancel_void.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_free_void.argtypes = (
+ ctypes.c_void_p,
+)
+_UniffiLib.ffi_snapxrust_rust_future_free_void.restype = None
+_UniffiLib.ffi_snapxrust_rust_future_complete_void.argtypes = (
+ ctypes.c_void_p,
+ ctypes.POINTER(_UniffiRustCallStatus),
+)
+_UniffiLib.ffi_snapxrust_rust_future_complete_void.restype = None
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_fullscreen.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_fullscreen.restype = ctypes.c_uint16
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_monitor.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_monitor.restype = ctypes.c_uint16
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_rect.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_rect.restype = ctypes.c_uint16
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_window.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_capture_window.restype = ctypes.c_uint16
+_UniffiLib.uniffi_snapxrust_checksum_func_get_monitor.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_get_monitor.restype = ctypes.c_uint16
+_UniffiLib.uniffi_snapxrust_checksum_func_get_primary_monitor.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_get_primary_monitor.restype = ctypes.c_uint16
+_UniffiLib.uniffi_snapxrust_checksum_func_get_screen_dimensions.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_get_screen_dimensions.restype = ctypes.c_uint16
+_UniffiLib.uniffi_snapxrust_checksum_func_get_working_area.argtypes = (
+)
+_UniffiLib.uniffi_snapxrust_checksum_func_get_working_area.restype = ctypes.c_uint16
+_UniffiLib.ffi_snapxrust_uniffi_contract_version.argtypes = (
+)
+_UniffiLib.ffi_snapxrust_uniffi_contract_version.restype = ctypes.c_uint32
+_uniffi_check_contract_api_version(_UniffiLib)
+_uniffi_check_api_checksums(_UniffiLib)
+
+# Async support
+
+# Public interface members begin here.
+
+
+class _UniffiConverterUInt32(_UniffiConverterPrimitiveInt):
+ CLASS_NAME = "u32"
+ VALUE_MIN = 0
+ VALUE_MAX = 2**32
+
+ @staticmethod
+ def read(buf):
+ return buf.read_u32()
+
+ @staticmethod
+ def write_unchecked(value, buf):
+ buf.write_u32(value)
+
+class _UniffiConverterInt32(_UniffiConverterPrimitiveInt):
+ CLASS_NAME = "i32"
+ VALUE_MIN = -2**31
+ VALUE_MAX = 2**31
+
+ @staticmethod
+ def read(buf):
+ return buf.read_i32()
+
+ @staticmethod
+ def write_unchecked(value, buf):
+ buf.write_i32(value)
+
+class _UniffiConverterString:
+ @staticmethod
+ def check(value):
+ if not isinstance(value, str):
+ raise TypeError("argument must be str, not {}".format(type(value).__name__))
+ return value
+
+ @staticmethod
+ def read(buf):
+ size = buf.read_i32()
+ if size < 0:
+ raise InternalError("Unexpected negative string length")
+ utf8_bytes = buf.read(size)
+ return utf8_bytes.decode("utf-8")
+
+ @staticmethod
+ def write(value, buf):
+ value = _UniffiConverterString.check(value)
+ utf8_bytes = value.encode("utf-8")
+ buf.write_i32(len(utf8_bytes))
+ buf.write(utf8_bytes)
+
+ @staticmethod
+ def lift(buf):
+ with buf.consume_with_stream() as stream:
+ return stream.read(stream.remaining()).decode("utf-8")
+
+ @staticmethod
+ def lower(value):
+ value = _UniffiConverterString.check(value)
+ with _UniffiRustBuffer.alloc_with_builder() as builder:
+ builder.write(value.encode("utf-8"))
+ return builder.finalize()
+
+class _UniffiConverterBytes(_UniffiConverterRustBuffer):
+ @staticmethod
+ def read(buf):
+ size = buf.read_i32()
+ if size < 0:
+ raise InternalError("Unexpected negative byte string length")
+ return buf.read(size)
+
+ @staticmethod
+ def write(value, buf):
+ try:
+ memoryview(value)
+ except TypeError:
+ raise TypeError("a bytes-like object is required, not {!r}".format(type(value).__name__))
+ buf.write_i32(len(value))
+ buf.write(value)
+
+
+class ImageData:
+ image: "bytes";width: "int";height: "int";
+
+ @typing.no_type_check
+ def __init__(self, image: "bytes", width: "int", height: "int"):
+ self.image = image
+ self.width = width
+ self.height = height
+
+ def __str__(self):
+ return "ImageData(image={}, width={}, height={})".format(self.image, self.width, self.height)
+
+ def __eq__(self, other):
+ if self.image != other.image:
+ return False
+ if self.width != other.width:
+ return False
+ if self.height != other.height:
+ return False
+ return True
+
+class _UniffiConverterTypeImageData(_UniffiConverterRustBuffer):
+ @staticmethod
+ def read(buf):
+ return ImageData(
+ image=_UniffiConverterBytes.read(buf),
+ width=_UniffiConverterUInt32.read(buf),
+ height=_UniffiConverterUInt32.read(buf),
+ )
+
+ @staticmethod
+ def write(value, buf):
+ _UniffiConverterBytes.write(value.image, buf)
+ _UniffiConverterUInt32.write(value.width, buf)
+ _UniffiConverterUInt32.write(value.height, buf)
+
+
+class MonitorData:
+ width: "int";height: "int";x: "int";y: "int";name: "str";
+
+ @typing.no_type_check
+ def __init__(self, width: "int", height: "int", x: "int", y: "int", name: "str"):
+ self.width = width
+ self.height = height
+ self.x = x
+ self.y = y
+ self.name = name
+
+ def __str__(self):
+ return "MonitorData(width={}, height={}, x={}, y={}, name={})".format(self.width, self.height, self.x, self.y, self.name)
+
+ def __eq__(self, other):
+ if self.width != other.width:
+ return False
+ if self.height != other.height:
+ return False
+ if self.x != other.x:
+ return False
+ if self.y != other.y:
+ return False
+ if self.name != other.name:
+ return False
+ return True
+
+class _UniffiConverterTypeMonitorData(_UniffiConverterRustBuffer):
+ @staticmethod
+ def read(buf):
+ return MonitorData(
+ width=_UniffiConverterUInt32.read(buf),
+ height=_UniffiConverterUInt32.read(buf),
+ x=_UniffiConverterInt32.read(buf),
+ y=_UniffiConverterInt32.read(buf),
+ name=_UniffiConverterString.read(buf),
+ )
+
+ @staticmethod
+ def write(value, buf):
+ _UniffiConverterUInt32.write(value.width, buf)
+ _UniffiConverterUInt32.write(value.height, buf)
+ _UniffiConverterInt32.write(value.x, buf)
+ _UniffiConverterInt32.write(value.y, buf)
+ _UniffiConverterString.write(value.name, buf)
+
+def capture_fullscreen() -> "ImageData":
+ return _UniffiConverterTypeImageData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_capture_fullscreen,))
+
+
+def capture_monitor(name: "str") -> "ImageData":
+
+ return _UniffiConverterTypeImageData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_capture_monitor,
+ _UniffiConverterString.lower(name)))
+
+
+def capture_rect(x: "int",y: "int",width: "int",height: "int") -> "ImageData":
+
+
+
+
+ return _UniffiConverterTypeImageData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_capture_rect,
+ _UniffiConverterUInt32.lower(x),
+ _UniffiConverterUInt32.lower(y),
+ _UniffiConverterUInt32.lower(width),
+ _UniffiConverterUInt32.lower(height)))
+
+
+def capture_window(x: "int",y: "int") -> "ImageData":
+
+
+ return _UniffiConverterTypeImageData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_capture_window,
+ _UniffiConverterUInt32.lower(x),
+ _UniffiConverterUInt32.lower(y)))
+
+
+def get_monitor(x: "int",y: "int") -> "MonitorData":
+
+
+ return _UniffiConverterTypeMonitorData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_get_monitor,
+ _UniffiConverterUInt32.lower(x),
+ _UniffiConverterUInt32.lower(y)))
+
+
+def get_primary_monitor() -> "MonitorData":
+ return _UniffiConverterTypeMonitorData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_get_primary_monitor,))
+
+
+def get_screen_dimensions(name: "str") -> "MonitorData":
+
+ return _UniffiConverterTypeMonitorData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_get_screen_dimensions,
+ _UniffiConverterString.lower(name)))
+
+
+def get_working_area() -> "MonitorData":
+ return _UniffiConverterTypeMonitorData.lift(_rust_call(_UniffiLib.uniffi_snapxrust_fn_func_get_working_area,))
+
+
+__all__ = [
+ "InternalError",
+ "ImageData",
+ "MonitorData",
+ "capture_fullscreen",
+ "capture_monitor",
+ "capture_rect",
+ "capture_window",
+ "get_monitor",
+ "get_primary_monitor",
+ "get_screen_dimensions",
+ "get_working_area",
+]
+
diff --git a/SnapX.Core/ScreenCapture/Rust/build.rs b/SnapX.Core/SharpCapture/Rust/build.rs
similarity index 100%
rename from SnapX.Core/ScreenCapture/Rust/build.rs
rename to SnapX.Core/SharpCapture/Rust/build.rs
diff --git a/SnapX.Core/ScreenCapture/Rust/src/lib.rs b/SnapX.Core/SharpCapture/Rust/src/lib.rs
similarity index 100%
rename from SnapX.Core/ScreenCapture/Rust/src/lib.rs
rename to SnapX.Core/SharpCapture/Rust/src/lib.rs
diff --git a/SnapX.Core/ScreenCapture/Rust/src/snapxrust.udl b/SnapX.Core/SharpCapture/Rust/src/snapxrust.udl
similarity index 100%
rename from SnapX.Core/ScreenCapture/Rust/src/snapxrust.udl
rename to SnapX.Core/SharpCapture/Rust/src/snapxrust.udl
diff --git a/SnapX.Core/ScreenCapture/ScreenRecording/FFmpegCaptureDevice.cs b/SnapX.Core/SharpCapture/ScreenRecording/FFmpegCaptureDevice.cs
similarity index 95%
rename from SnapX.Core/ScreenCapture/ScreenRecording/FFmpegCaptureDevice.cs
rename to SnapX.Core/SharpCapture/ScreenRecording/FFmpegCaptureDevice.cs
index 46d2cf1a3..f809f9e73 100644
--- a/SnapX.Core/ScreenCapture/ScreenRecording/FFmpegCaptureDevice.cs
+++ b/SnapX.Core/SharpCapture/ScreenRecording/FFmpegCaptureDevice.cs
@@ -1,8 +1,7 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
-namespace SnapX.Core.ScreenCapture.ScreenRecording;
+namespace SnapX.Core.SharpCapture.ScreenRecording;
public class FFmpegCaptureDevice
{
diff --git a/SnapX.Core/ScreenCapture/ScreenRecording/FFmpegOptions.cs b/SnapX.Core/SharpCapture/ScreenRecording/FFmpegOptions.cs
similarity index 99%
rename from SnapX.Core/ScreenCapture/ScreenRecording/FFmpegOptions.cs
rename to SnapX.Core/SharpCapture/ScreenRecording/FFmpegOptions.cs
index 81c821ce8..c64487e1c 100644
--- a/SnapX.Core/ScreenCapture/ScreenRecording/FFmpegOptions.cs
+++ b/SnapX.Core/SharpCapture/ScreenRecording/FFmpegOptions.cs
@@ -2,7 +2,7 @@
using SnapX.Core.Utils;
-namespace SnapX.Core.ScreenCapture.ScreenRecording;
+namespace SnapX.Core.SharpCapture.ScreenRecording;
public class FFmpegOptions
{
diff --git a/SnapX.Core/ScreenCapture/ScreenRecording/HardDiskCache.cs b/SnapX.Core/SharpCapture/ScreenRecording/HardDiskCache.cs
similarity index 95%
rename from SnapX.Core/ScreenCapture/ScreenRecording/HardDiskCache.cs
rename to SnapX.Core/SharpCapture/ScreenRecording/HardDiskCache.cs
index 08d68375e..cbd0e8602 100644
--- a/SnapX.Core/ScreenCapture/ScreenRecording/HardDiskCache.cs
+++ b/SnapX.Core/SharpCapture/ScreenRecording/HardDiskCache.cs
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-3.0-or-later
using SixLabors.ImageSharp;
-using SnapX.Core.ScreenCapture.Helpers;
+using SnapX.Core.SharpCapture.Helpers;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Extensions;
-namespace SnapX.Core.ScreenCapture.ScreenRecording;
+namespace SnapX.Core.SharpCapture.ScreenRecording;
public class HardDiskCache : ImageCache
{
diff --git a/SnapX.Core/ScreenCapture/ScreenRecording/ImageCache.cs b/SnapX.Core/SharpCapture/ScreenRecording/ImageCache.cs
similarity index 97%
rename from SnapX.Core/ScreenCapture/ScreenRecording/ImageCache.cs
rename to SnapX.Core/SharpCapture/ScreenRecording/ImageCache.cs
index e583734c7..9038b0cdb 100644
--- a/SnapX.Core/ScreenCapture/ScreenRecording/ImageCache.cs
+++ b/SnapX.Core/SharpCapture/ScreenRecording/ImageCache.cs
@@ -1,11 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Collections.Concurrent;
using SixLabors.ImageSharp;
-namespace SnapX.Core.ScreenCapture.ScreenRecording;
+namespace SnapX.Core.SharpCapture.ScreenRecording;
public abstract class ImageCache : IDisposable
{
diff --git a/SnapX.Core/ScreenCapture/ScreenRecording/ScreenRecorder.cs b/SnapX.Core/SharpCapture/ScreenRecording/ScreenRecorder.cs
similarity index 99%
rename from SnapX.Core/ScreenCapture/ScreenRecording/ScreenRecorder.cs
rename to SnapX.Core/SharpCapture/ScreenRecording/ScreenRecorder.cs
index b28195deb..e0f807fac 100644
--- a/SnapX.Core/ScreenCapture/ScreenRecording/ScreenRecorder.cs
+++ b/SnapX.Core/SharpCapture/ScreenRecording/ScreenRecorder.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -8,7 +7,7 @@
using SnapX.Core.Media;
using SnapX.Core.Utils;
-namespace SnapX.Core.ScreenCapture.ScreenRecording;
+namespace SnapX.Core.SharpCapture.ScreenRecording;
public class ScreenRecorder : IDisposable
{
diff --git a/SnapX.Core/ScreenCapture/ScreenRecording/ScreenRecordingOptions.cs b/SnapX.Core/SharpCapture/ScreenRecording/ScreenRecordingOptions.cs
similarity index 99%
rename from SnapX.Core/ScreenCapture/ScreenRecording/ScreenRecordingOptions.cs
rename to SnapX.Core/SharpCapture/ScreenRecording/ScreenRecordingOptions.cs
index 9989fbd32..6dfda361f 100644
--- a/SnapX.Core/ScreenCapture/ScreenRecording/ScreenRecordingOptions.cs
+++ b/SnapX.Core/SharpCapture/ScreenRecording/ScreenRecordingOptions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -6,7 +5,7 @@
using System.Text;
using SixLabors.ImageSharp;
-namespace SnapX.Core.ScreenCapture.ScreenRecording;
+namespace SnapX.Core.SharpCapture.ScreenRecording;
public class ScreenRecordingOptions
{
diff --git a/SnapX.Core/SharpCapture/Services/CaptureService.cs b/SnapX.Core/SharpCapture/Services/CaptureService.cs
new file mode 100644
index 000000000..98f63a95a
--- /dev/null
+++ b/SnapX.Core/SharpCapture/Services/CaptureService.cs
@@ -0,0 +1,32 @@
+using SixLabors.ImageSharp;
+using SnapX.Core.Job;
+using SnapX.Core.SharpCapture.Interfaces;
+using SnapX.Core.Utils.Native;
+
+namespace SnapX.Core.SharpCapture.Services;
+
+public class CaptureService(BaseSharpCapture _baseCapture, INativeAPI _nativeAPI) : ICaptureService
+{
+ public async Task CaptureActiveMonitorAsync(TaskSettings? taskSettings = null)
+ {
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
+ var bounds = await _baseCapture.GetScreen(_nativeAPI.GetCursorPosition());
+
+ return await _baseCapture.CaptureScreen(bounds, taskSettings);
+ }
+
+ public async Task CaptureFullscreenAsync(TaskSettings? taskSettings = null)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task CaptureRectangle(TaskSettings? taskSettings = null, Rectangle? rect = null)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task CaptureActiveWindowAsync(TaskSettings? taskSettings = null)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/b1nzyblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/b1nzyblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/b1nzyblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/b1nzyblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/b1nzyblob2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/b1nzyblob2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/b1nzyblob2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/b1nzyblob2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/b4nzyblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/b4nzyblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/b4nzyblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/b4nzyblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob0w0.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob0w0.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob0w0.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob0w0.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob3c.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob3c.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob3c.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob3c.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob3cevil.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob3cevil.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blob3cevil.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blob3cevil.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobaffection.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobaffection.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobaffection.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobaffection.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobamused.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobamused.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobamused.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobamused.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangel.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangel.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangel.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangel.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangery.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangery.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangery.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangery.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangry.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangry.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangry.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangry.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangry2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangry2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangry2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangry2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangrypuff.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangrypuff.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobangrypuff.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobangrypuff.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobartist.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobartist.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobartist.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobartist.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobaviator.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobaviator.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobaviator.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobaviator.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobawkward.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobawkward.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobawkward.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobawkward.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobaww.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobaww.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobaww.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobaww.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbandage.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbandage.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbandage.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbandage.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbanhammer.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbanhammer.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbanhammer.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbanhammer.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbathtub.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbathtub.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbathtub.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbathtub.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobblackcat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobblackcat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobblackcat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobblackcat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobblush.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobblush.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobblush.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobblush.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobboost.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobboost.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobboost.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobboost.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbored.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbored.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbored.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbored.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbot.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbot.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbot.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbot.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbowing.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbowing.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbowing.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbowing.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbroken.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbroken.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobbroken.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobbroken.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcamera.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcamera.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcamera.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcamera.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheeky.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheeky.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheeky.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheeky.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheer.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheer.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheer.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheer.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheerful.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheerful.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheerful.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheerful.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheerful2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheerful2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcheerful2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcheerful2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobclipboard.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobclipboard.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobclipboard.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobclipboard.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcmereyou.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcmereyou.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcmereyou.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcmereyou.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcocoa.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcocoa.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcocoa.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcocoa.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcomfort.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcomfort.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcomfort.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcomfort.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobconcerned.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobconcerned.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobconcerned.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobconcerned.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobconfounded.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobconfounded.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobconfounded.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobconfounded.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobconfused.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobconfused.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobconfused.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobconfused.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcool.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcool.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcool.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcool.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcouncil.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcouncil.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcouncil.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcouncil.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcouple.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcouple.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcouple.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcouple.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcowboy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcowboy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcowboy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcowboy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcry.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcry.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobcry.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobcry.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdancer.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdancer.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdancer.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdancer.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdead.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdead.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdead.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdead.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobderpy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobderpy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobderpy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobderpy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobderpyhappy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobderpyhappy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobderpyhappy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobderpyhappy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdetective.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdetective.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdetective.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdetective.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdevil.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdevil.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdevil.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdevil.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdevilsmile.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdevilsmile.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdevilsmile.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdevilsmile.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdisapproval.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdisapproval.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdisapproval.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdisapproval.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdisguise.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdisguise.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdisguise.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdisguise.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdizzy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdizzy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdizzy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdizzy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdizzy2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdizzy2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdizzy2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdizzy2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdoctor.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdoctor.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdoctor.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdoctor.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdoubt.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdoubt.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdoubt.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdoubt.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdoubtful.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdoubtful.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdoubtful.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdoubtful.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdrool.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdrool.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobdrool.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobdrool.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobeagle.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobeagle.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobeagle.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobeagle.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobembarrassed.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobembarrassed.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobembarrassed.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobembarrassed.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobembarrassed2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobembarrassed2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobembarrassed2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobembarrassed2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobenjoy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobenjoy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobenjoy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobenjoy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloberm.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloberm.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloberm.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloberm.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobexpressionless.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobexpressionless.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobexpressionless.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobexpressionless.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobeyesdown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobeyesdown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobeyesdown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobeyesdown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobeyesup.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobeyesup.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobeyesup.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobeyesup.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfacemask.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfacemask.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfacemask.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfacemask.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfacepalm.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfacepalm.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfacepalm.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfacepalm.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfearful.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfearful.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfearful.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfearful.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfingerguns.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfingerguns.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfingerguns.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfingerguns.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfingerscrossed.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfingerscrossed.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfingerscrossed.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfingerscrossed.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfirefighter.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfirefighter.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfirefighter.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfirefighter.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfistbumpL.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfistbumpL.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfistbumpL.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfistbumpL.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfistbumpR.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfistbumpR.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfistbumpR.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfistbumpR.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobflushed.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobflushed.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobflushed.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobflushed.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfreezing.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfreezing.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfreezing.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfreezing.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrog.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrog.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrog.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrog.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrowning.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrowning.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrowning.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrowning.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrowningbig.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrowningbig.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobfrowningbig.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobfrowningbig.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgamer.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgamer.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgamer.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgamer.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgift.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgift.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgift.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgift.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgiggle.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgiggle.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgiggle.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgiggle.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobglare.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobglare.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobglare.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobglare.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobglarepolice.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobglarepolice.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobglarepolice.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobglarepolice.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobglassesdown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobglassesdown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobglassesdown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobglassesdown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgo.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgo.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgo.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgo.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodmorning.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodmorning.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodmorning.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodmorning.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodmorningreverse.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodmorningreverse.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodmorningreverse.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodmorningreverse.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodnight.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodnight.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodnight.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodnight.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodnightreverse.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodnightreverse.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgoodnightreverse.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgoodnightreverse.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgrimace.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgrimace.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgrimace.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgrimace.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgrin.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgrin.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgrin.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgrin.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgrumpy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgrumpy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobgrumpy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobgrumpy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobheart.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobheart.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobheart.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobheart.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhearteyes.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhearteyes.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhearteyes.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhearteyes.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhero.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhero.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhero.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhero.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhighfive.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhighfive.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhighfive.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhighfive.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhug.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhug.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhug.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhug.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhug2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhug2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhug2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhug2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhuh.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhuh.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhuh.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhuh.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhushed.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhushed.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhushed.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhushed.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhyperthink.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhyperthink.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhyperthink.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhyperthink.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhyperthinkfast.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhyperthinkfast.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhyperthinkfast.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhyperthinkfast.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhypesquad.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhypesquad.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobhypesquad.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobhypesquad.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobidea.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobidea.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobidea.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobidea.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobimfine.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobimfine.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobimfine.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobimfine.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobinlove.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobinlove.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobinlove.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobinlove.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobjam.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobjam.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobjam.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobjam.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobjoy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobjoy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobjoy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobjoy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobkiss.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobkiss.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobkiss.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobkiss.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobkissblush.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobkissblush.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobkissblush.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobkissblush.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobkissheart.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobkissheart.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobkissheart.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobkissheart.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloblamp.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloblamp.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloblamp.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloblamp.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloblul.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloblul.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloblul.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloblul.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmail.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmail.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmail.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmail.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmaracas.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmaracas.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmaracas.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmaracas.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmelt.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmelt.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmelt.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmelt.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmeltblush.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmeltblush.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmeltblush.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmeltblush.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmeltsob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmeltsob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmeltsob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmeltsob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmeltsoblove.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmeltsoblove.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmeltsoblove.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmeltsoblove.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmindblown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmindblown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmindblown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmindblown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmlem.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmlem.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmlem.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmlem.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmorning.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmorning.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmorning.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmorning.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmoustache.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmoustache.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobmoustache.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobmoustache.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnauseated.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnauseated.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnauseated.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnauseated.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnerd.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnerd.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnerd.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnerd.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnervous.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnervous.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnervous.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnervous.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnervous2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnervous2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnervous2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnervous2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnervouspleading.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnervouspleading.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnervouspleading.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnervouspleading.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobneutral.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobneutral.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobneutral.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobneutral.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnight.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnight.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnight.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnight.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobninja.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobninja.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobninja.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobninja.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnitro.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnitro.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnitro.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnitro.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobno.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobno.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobno.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobno.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnogood.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnogood.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnogood.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnogood.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnom.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnom.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnom.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnom.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomchocolate.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomchocolate.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomchocolate.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomchocolate.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomchristmas.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomchristmas.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomchristmas.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomchristmas.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomcookie.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomcookie.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomcookie.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomcookie.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomglobal1.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomglobal1.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomglobal1.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomglobal1.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomglobal2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomglobal2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomglobal2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomglobal2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomglobal3.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomglobal3.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomglobal3.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomglobal3.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomouth.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomouth.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnomouth.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnomouth.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnook.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnook.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnook.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnook.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnostar.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnostar.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnostar.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnostar.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnostar2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnostar2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnostar2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnostar2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnwn.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnwn.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobnwn.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobnwn.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobok.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobok.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobok.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobok.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobokhand.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobokhand.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobokhand.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobokhand.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobomo.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobomo.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobomo.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobomo.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobonfire.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobonfire.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobonfire.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobonfire.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobono.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobono.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobono.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobono.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobooh.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobooh.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobooh.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobooh.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboohcry.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboohcry.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboohcry.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboohcry.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobopenmouth.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobopenmouth.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobopenmouth.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobopenmouth.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboro.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboro.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboro.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboro.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboutage.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboutage.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboutage.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboutage.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboverheated.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboverheated.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bloboverheated.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bloboverheated.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobovo.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobovo.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobovo.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobovo.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowo.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowo.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowo.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowo.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowo2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowo2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowo2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowo2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowoevil.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowoevil.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowoevil.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowoevil.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowosquint.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowosquint.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobowosquint.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobowosquint.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpain.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpain.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpain.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpain.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpainpats.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpainpats.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpainpats.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpainpats.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpan.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpan.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpan.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpan.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpanic.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpanic.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpanic.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpanic.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpanic2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpanic2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpanic2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpanic2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpartlysunny.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpartlysunny.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpartlysunny.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpartlysunny.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobparty.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobparty.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobparty.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobparty.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpatrol.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpatrol.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpatrol.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpatrol.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpats.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpats.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpats.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpats.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpeek.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpeek.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpeek.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpeek.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpensive.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpensive.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpensive.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpensive.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpensivepray.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpensivepray.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpensivepray.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpensivepray.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpin.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpin.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpin.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpin.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpirate.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpirate.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpirate.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpirate.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpleading.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpleading.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpleading.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpleading.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpolice.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpolice.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpolice.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpolice.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpoliceangery.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpoliceangery.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpoliceangery.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpoliceangery.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpoll.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpoll.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpoll.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpoll.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpopcorn.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpopcorn.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpopcorn.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpopcorn.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpopsicle.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpopsicle.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpopsicle.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpopsicle.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpout.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpout.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpout.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpout.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpout2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpout2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpout2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpout2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpray.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpray.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpray.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpray.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpumpkin.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpumpkin.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobpumpkin.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobpumpkin.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrage.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrage.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrage.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrage.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrageangry.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrageangry.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrageangry.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrageangry.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreach.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreach.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreach.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreach.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachdrool.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachdrool.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachdrool.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachdrool.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachfront.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachfront.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachfront.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachfront.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachfrown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachfrown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachfrown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachfrown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachreverse.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachreverse.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachreverse.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachreverse.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachsob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachsob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobreachsob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobreachsob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrelieved.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrelieved.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrelieved.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrelieved.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrofl.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrofl.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrofl.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrofl.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrollingeyes.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrollingeyes.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobrollingeyes.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobrollingeyes.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobross.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobross.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobross.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobross.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsad.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsad.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsad.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsad.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsadpats.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsadpats.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsadpats.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsadpats.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsadrain.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsadrain.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsadrain.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsadrain.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsalute.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsalute.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsalute.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsalute.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsanta.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsanta.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsanta.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsanta.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobscarf.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobscarf.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobscarf.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobscarf.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobscream.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobscream.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobscream.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobscream.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsecret.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsecret.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsecret.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsecret.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobshh.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobshh.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobshh.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobshh.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobshrug.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobshrug.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobshrug.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobshrug.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsick.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsick.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsick.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsick.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsip.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsip.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsip.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsip.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsleeping.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsleeping.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsleeping.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsleeping.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsleepless.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsleepless.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsleepless.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsleepless.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobslightsmile.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobslightsmile.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobslightsmile.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobslightsmile.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmile.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmile.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmile.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmile.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilehappy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilehappy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilehappy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilehappy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilehappyeyes.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilehappyeyes.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilehappyeyes.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilehappyeyes.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilesweat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilesweat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilesweat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilesweat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilesweat2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilesweat2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmilesweat2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmilesweat2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmiletear.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmiletear.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmiletear.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmiletear.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmiley.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmiley.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmiley.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmiley.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmirk.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmirk.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmirk.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmirk.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmirk2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmirk2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsmirk2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsmirk2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsneezing.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsneezing.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsneezing.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsneezing.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsnuggle.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsnuggle.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsnuggle.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsnuggle.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsobglasses.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsobglasses.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsobglasses.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsobglasses.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobspam.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobspam.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobspam.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobspam.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsplosion.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsplosion.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsplosion.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsplosion.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobspy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobspy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobspy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobspy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsquee.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsquee.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsquee.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsquee.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstare.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstare.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstare.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstare.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstarstruck.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstarstruck.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstarstruck.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstarstruck.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstop.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstop.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstop.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstop.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstudent.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstudent.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobstudent.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobstudent.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsunglasses.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsunglasses.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsunglasses.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsunglasses.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsurprised.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsurprised.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsurprised.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsurprised.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsus.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsus.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsus.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsus.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsweats.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsweats.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsweats.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsweats.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsweatsweary.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsweatsweary.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobsweatsweary.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobsweatsweary.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobteefs.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobteefs.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobteefs.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobteefs.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthanks.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthanks.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthanks.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthanks.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthief.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthief.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthief.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthief.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinking.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinking.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinking.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinking.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingcool.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingcool.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingcool.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingcool.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingdown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingdown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingdown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingdown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingeyes.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingeyes.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingeyes.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingeyes.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingfast.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingfast.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingfast.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingfast.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingglare.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingglare.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingglare.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingglare.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingsmirk.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingsmirk.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinkingsmirk.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinkingsmirk.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinksmart.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinksmart.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthinksmart.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthinksmart.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthis.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthis.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthis.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthis.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthonkang.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthonkang.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthonkang.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthonkang.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthumbsdown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthumbsdown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthumbsdown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthumbsdown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthumbsup.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthumbsup.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthumbsup.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthumbsup.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthump.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthump.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobthump.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobthump.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtilt.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtilt.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtilt.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtilt.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtired.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtired.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtired.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtired.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtongue.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtongue.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtongue.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtongue.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtonguewink.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtonguewink.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtonguewink.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtonguewink.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtorch.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtorch.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtorch.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtorch.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtrans.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtrans.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtrans.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtrans.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtriumph.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtriumph.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtriumph.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtriumph.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtriumph2.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtriumph2.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobtriumph2.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobtriumph2.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobugh.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobugh.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobugh.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobugh.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobunamused.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobunamused.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobunamused.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobunamused.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobunsure.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobunsure.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobunsure.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobunsure.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobupset.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobupset.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobupset.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobupset.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobupsidedown.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobupsidedown.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobupsidedown.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobupsidedown.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobuwu.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobuwu.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobuwu.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobuwu.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobvomiting.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobvomiting.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobvomiting.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobvomiting.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwaitwhat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwaitwhat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwaitwhat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwaitwhat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwave.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwave.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwave.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwave.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwavereverse.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwavereverse.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwavereverse.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwavereverse.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwavesob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwavesob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwavesob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwavesob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobweary.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobweary.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobweary.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobweary.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwhistle.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwhistle.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwhistle.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwhistle.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwink.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwink.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwink.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwink.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwitch.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwitch.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwitch.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwitch.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwizard.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwizard.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwizard.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwizard.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwoah.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwoah.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwoah.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwoah.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwoahopenmouth.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwoahopenmouth.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwoahopenmouth.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwoahopenmouth.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwooloo.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwooloo.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwooloo.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwooloo.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwoozy.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwoozy.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobwoozy.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobwoozy.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobworker.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobworker.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobworker.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobworker.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobworried.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobworried.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobworried.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobworried.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobxd.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobxd.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobxd.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobxd.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyawn.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyawn.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyawn.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyawn.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyes.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyes.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyes.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyes.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyikes.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyikes.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyikes.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyikes.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyum.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyum.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobyum.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobyum.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobzippermouth.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobzippermouth.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/blobzippermouth.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/blobzippermouth.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bolb.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/bolb.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/bolb.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/bolb.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/doggoblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/doggoblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/doggoblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/doggoblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/feelsblobman.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/feelsblobman.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/feelsblobman.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/feelsblobman.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/ferretblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/ferretblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/ferretblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/ferretblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/gentleblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/gentleblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/gentleblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/gentleblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlebear.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlebear.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlebear.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlebear.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlebee.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlebee.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlebee.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlebee.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlebird.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlebird.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlebird.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlebird.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleblueheart.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleblueheart.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleblueheart.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleblueheart.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecake.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecake.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecake.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecake.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecatface.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecatface.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecatface.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecatface.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecatheart.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecatheart.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecatheart.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecatheart.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlechick.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlechick.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlechick.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlechick.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlechicken.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlechicken.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlechicken.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlechicken.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlechristmastree.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlechristmastree.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlechristmastree.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlechristmastree.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecow.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecow.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecow.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecow.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecrab.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecrab.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlecrab.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlecrab.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googledog.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googledog.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googledog.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googledog.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googledove.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googledove.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googledove.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googledove.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleduck.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleduck.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleduck.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleduck.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleeagle.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleeagle.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleeagle.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleeagle.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlefire.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlefire.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlefire.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlefire.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlefox.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlefox.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlefox.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlefox.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleghost.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleghost.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleghost.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleghost.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlegift.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlegift.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlegift.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlegift.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlegoat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlegoat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlegoat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlegoat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlegun.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlegun.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlegun.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlegun.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleicecream.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleicecream.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleicecream.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleicecream.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlekoala.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlekoala.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlekoala.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlekoala.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlelion.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlelion.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlelion.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlelion.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlemouse.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlemouse.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlemouse.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlemouse.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlemuscleL.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlemuscleL.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlemuscleL.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlemuscleL.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlemuscleR.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlemuscleR.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlemuscleR.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlemuscleR.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleoctopus.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleoctopus.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleoctopus.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleoctopus.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepanda.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepanda.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepanda.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepanda.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepenguin.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepenguin.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepenguin.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepenguin.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepig.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepig.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepig.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepig.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepizza.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepizza.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlepizza.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlepizza.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlerabbit.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlerabbit.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlerabbit.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlerabbit.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlerat.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlerat.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlerat.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlerat.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleredheart.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleredheart.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleredheart.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleredheart.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlescorpion.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlescorpion.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlescorpion.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlescorpion.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesheep.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesheep.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesheep.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesheep.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesnail.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesnail.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesnail.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesnail.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesnake.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesnake.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesnake.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesnake.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesquirrel.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesquirrel.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlesquirrel.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlesquirrel.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleturtle.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleturtle.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googleturtle.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googleturtle.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlewhale.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlewhale.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/googlewhale.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/googlewhale.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/greentick.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/greentick.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/greentick.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/greentick.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/jakeblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/jakeblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/jakeblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/jakeblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/kirbyblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/kirbyblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/kirbyblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/kirbyblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/nellyblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/nellyblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/nellyblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/nellyblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/nikoblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/nikoblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/nikoblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/nikoblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/notlikeblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/notlikeblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/notlikeblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/notlikeblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/pandablob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/pandablob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/pandablob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/pandablob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/photoblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/photoblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/photoblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/photoblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/pikablob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/pikablob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/pikablob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/pikablob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/pusheenblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/pusheenblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/pusheenblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/pusheenblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/rainblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/rainblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/rainblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/rainblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/redtick.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/redtick.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/redtick.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/redtick.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/reindeerblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/reindeerblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/reindeerblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/reindeerblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/rickblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/rickblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/rickblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/rickblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/superblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/superblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/superblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/superblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/thinkingwithblobs.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/thinkingwithblobs.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/thinkingwithblobs.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/thinkingwithblobs.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/wolfiriblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/wolfiriblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/wolfiriblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/wolfiriblob.png
diff --git a/SnapX.Core/ScreenCapture/Stickers/BlobEmoji/wumpusblob.png b/SnapX.Core/SharpCapture/Stickers/BlobEmoji/wumpusblob.png
similarity index 100%
rename from SnapX.Core/ScreenCapture/Stickers/BlobEmoji/wumpusblob.png
rename to SnapX.Core/SharpCapture/Stickers/BlobEmoji/wumpusblob.png
diff --git a/SnapX.Core/SharpCapture/Windows/WindowsCapture.cs b/SnapX.Core/SharpCapture/Windows/WindowsCapture.cs
index 46be2d75f..27ab3c8da 100644
--- a/SnapX.Core/SharpCapture/Windows/WindowsCapture.cs
+++ b/SnapX.Core/SharpCapture/Windows/WindowsCapture.cs
@@ -10,13 +10,14 @@
using Windows.Graphics.DirectX;
using Windows.Graphics.DirectX.Direct3D11;
using Windows.Win32;
+using SnapX.Core.Job;
using WinRT;
namespace SnapX.Core.SharpCapture.Windows;
[SupportedOSPlatform("windows10.0.19045")]
-public class WindowsCapture : BaseCapture
+public class WindowsCapture : BaseSharpCapture
{
private bool IsSupportedFeatureLevel(IDXGIAdapter1 adapter, FeatureLevel featureLevel,
DeviceCreationFlags creationFlags)
@@ -40,7 +41,7 @@ private bool IsSupportedFeatureLevel(IDXGIAdapter1 adapter, FeatureLevel feature
return false;
}
- public override async Task CaptureFullscreen()
+ public override async Task CaptureFullscreen(TaskSettings? taskSettings = null)
{
var factory = DXGI.CreateDXGIFactory1()!;
@@ -103,7 +104,7 @@ private bool IsSupportedFeatureLevel(IDXGIAdapter1 adapter, FeatureLevel feature
}
- public override async Task CaptureScreen(Point? pos)
+ public override async Task CaptureScreen(Point? pos, TaskSettings? taskSettings = null)
{
var factory = DXGI.CreateDXGIFactory1()!;
@@ -184,7 +185,7 @@ private static ID3D11Texture2D Texture2DFromSurface(IDirect3DSurface surface)
var texture = access.QueryInterface();
return texture;
}
- public override async Task CaptureWindow(Point pos)
+ public override async Task CaptureWindow(Point pos, TaskSettings? taskSettings = null)
{
if (!GraphicsCaptureSession.IsSupported())
{
diff --git a/SnapX.Core/SharpCapture/macOS/macOSCapture.cs b/SnapX.Core/SharpCapture/macOS/macOSCapture.cs
index e05f48e50..0b3a31dd6 100644
--- a/SnapX.Core/SharpCapture/macOS/macOSCapture.cs
+++ b/SnapX.Core/SharpCapture/macOS/macOSCapture.cs
@@ -1,4 +1,5 @@
using SixLabors.ImageSharp;
+using SnapX.Core.Job;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Native;
using uniffi.snapxrust;
@@ -319,29 +320,29 @@ namespace SnapX.Core.SharpCapture.macOS;
// }
// }
-public class macOSCapture : BaseCapture
+public class macOSCapture : BaseSharpCapture
{
- public override async Task CaptureFullscreen()
+ public override async Task CaptureFullscreen(TaskSettings? taskSettings = null)
{
return ImageHelpers.ImageDataToImage(SnapxrustMethods.CaptureFullscreen());
}
- public override async Task CaptureScreen(Rectangle bounds)
+ public override async Task CaptureScreen(Rectangle bounds, TaskSettings? taskSettings = null)
{
return CaptureRectangleNative(bounds);
}
- public override async Task CaptureScreen(Point? pos)
+ public override async Task CaptureScreen(Point? pos, TaskSettings? taskSettings = null)
{
return CaptureMonitor(Methods.GetCursorPosition());
}
- public override async Task CaptureRectangle(Rectangle rect)
+ public override async Task CaptureRectangle(Rectangle rect, TaskSettings? taskSettings = null)
{
return CaptureRectangleNative(rect);
}
- public override async Task CaptureWindow(Point pos)
+ public override async Task CaptureWindow(Point pos, TaskSettings? taskSettings = null)
{
return ImageHelpers.ImageDataToImage(SnapxrustMethods.CaptureWindow((uint)pos.X, (uint)pos.Y));
}
diff --git a/SnapX.Core/SnapX.Core.csproj b/SnapX.Core/SnapX.Core.csproj
index 59966636f..31172f869 100644
--- a/SnapX.Core/SnapX.Core.csproj
+++ b/SnapX.Core/SnapX.Core.csproj
@@ -48,6 +48,7 @@
+
@@ -55,11 +56,6 @@
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
@@ -71,7 +67,6 @@
-
@@ -80,6 +75,7 @@
while these are only useful for Linux,
hiding them behind a compiler conditional makes debugging more difficult. -->
+
@@ -116,17 +112,15 @@
-
+
-
+
-
-
-
+
diff --git a/SnapX.Core/SnapX.cs b/SnapX.Core/SnapX.cs
index 04606c0b1..5b253bf78 100644
--- a/SnapX.Core/SnapX.cs
+++ b/SnapX.Core/SnapX.cs
@@ -1,16 +1,18 @@
using System.Diagnostics;
-using System.Reflection;
using System.Text;
using System.Text.Json;
using Aptabase.Core;
using Dapper;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using SnapX.Core.CLI;
using SnapX.Core.Hotkey;
+using SnapX.Core.Interfaces;
using SnapX.Core.Job;
+using SnapX.Core.Services;
using SnapX.Core.Upload;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Extensions;
@@ -23,7 +25,7 @@
namespace SnapX.Core;
-public class SnapX
+public class SnapX(IServiceProvider serviceProvider)
{
public const string AppName = "SnapX";
public static string Qualifier { get; set; } = "";
@@ -88,6 +90,18 @@ public static void quit()
{
CloseSequence();
}
+
+ public static void ConfigureServices(ServiceCollection services)
+ {
+ services.AddLogging(loggingBuilder =>
+ loggingBuilder.AddSerilog(dispose: true));
+ services.AddSingleton(_ => new SerilogLogService(LogsFilePath, true, Configuration));
+ services.AddSingleton(provider =>
+ {
+ var logger = provider.GetRequiredService();
+ return new VersionEnforcer(LockDirectory, logger);
+ });
+ }
public static string Title
{
get
@@ -119,13 +133,13 @@ public static string Title
public static bool IgnoreHotkeyWarning { get; private set; }
public static bool PuushMode { get; private set; }
- public static RootConfiguration Settings { get; set; } = new();
+ public static ApplicationConfig Settings { get; set; } = new();
public static List Flags { get; set; } = new();
internal static IConfiguration Configuration { get; set; }
- internal static TaskSettings DefaultTaskSettings { get; set; } = TaskSettings.GetDefaultTaskSettings();
- internal static UploadersConfig UploadersConfig { get; set; }
- internal static HotkeysConfig HotkeysConfig { get; set; }
+ internal static TaskSettings? DefaultTaskSettings { get; set; } = TaskSettings.GetDefaultTaskSettings();
+ internal static UploadersConfig? UploadersConfig { get; set; } = new();
+ internal static HotkeysConfig? HotkeysConfig { get; set; } = new();
internal static Stopwatch StartTimer { get; private set; }
internal static HotkeyManager HotkeyManager { get; set; }
@@ -162,11 +176,10 @@ private static string PersonalPathConfigFilePath
AppName, PersonalPathConfigFileName);
private static readonly string PortableCheckFilePath = FileHelpers.GetAbsolutePath("Portable");
- public static EventAggregator EventAggregator { get; } = new();
private static string CustomPersonalPath { get; set; }
private static string CustomConfigPath { get; set; }
- public static SqliteConnection DbConnection { get; set; }
+ public static SqliteConnection? DbConnection { get; set; }
public static string ShortenPath(string? path) =>
OperatingSystem.IsWindows() ? path : path.Replace(Environment.GetEnvironmentVariable("HOME") ?? "", "~");
@@ -263,11 +276,10 @@ public void shutdown()
{
CloseSequence();
}
- public Assembly[] GetAssemblies() => AppDomain.CurrentDomain.GetAssemblies();
public void start(string?[] args)
{
HandleExceptions();
-
+ new SettingManager(serviceProvider).LoadSettings();
StartTimer = Stopwatch.StartNew();
// TODO: Implement CLI in a better way than what it is now.
CLIManager = new SnapXCLIManager(args);
@@ -290,7 +302,11 @@ public void start(string?[] args)
}
public long getStartupTime() => StartTimer.ElapsedMilliseconds;
- public EventAggregator getEventAggregator() => EventAggregator;
+ public static IServiceCollection ConfigureCoreSnapXServices(IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddSingleton(configuration);
+ return services;
+ }
public bool isSilent() => SilentRun;
public static AptabaseClient? aptabaseClient;
@@ -302,8 +318,12 @@ public static bool CanUpload() =>
public static bool CanAutoUpdate() =>
!FeatureFlags.DisableAutoUpdates && Settings.AutoCheckUpdate;
+ public void loadApplicationSettingsPartial()
+ {
+ SettingManager.LoadApplicationConfig();
+ }
[DapperAot]
- private static void Run()
+ private void Run()
{
DebugHelper.WriteLine("SnapX starting.");
DebugHelper.WriteLine("Version: " + VersionText);
@@ -371,6 +391,10 @@ private static void Run()
var connectionString = new SqliteConnectionStringBuilder { DataSource = dataSource, Mode = SqliteOpenMode.ReadWriteCreate, Cache = SqliteCacheMode.Shared, ForeignKeys = true, Pooling = true, }.ToString();
DbConnection = new SqliteConnection(connectionString);
RunWithTimeout(() => DbConnection.OpenAsync(), $"Opening the database connection at {DBPath}");
+ RunWithTimeout(() => DbConnection.ExecuteAsync("PRAGMA busy_timeout = 5000;"), "Setting busy timeout");
+ RunWithTimeout(() => DbConnection.ExecuteAsync("PRAGMA temp_store = MEMORY;"), "Setting temp_store");
+ RunWithTimeout(() => DbConnection.ExecuteAsync("PRAGMA mmap_size = 30000000000;"), "Setting mmap_size");
+ RunWithTimeout(() => DbConnection.ExecuteAsync("PRAGMA cache_size = -64000;"), "Setting cache_size");
RunWithTimeout(() => DbConnection.ExecuteAsync("PRAGMA journal_mode=WAL;"), "Setting journal mode");
_ = Task.Run(() =>
{
@@ -404,7 +428,6 @@ private static void Run()
{
DebugHelper.WriteLine($"DB: {Args.CurrentState}");
};
- SettingManager.LoadSettings();
if (TelemetryEnabled())
{
var loggerFactory = LoggerFactory.Create(builder =>
@@ -423,7 +446,9 @@ private static void Run()
IsDebugMode = false
#endif
}, logger);
- var telemetry = new Telemetry(DbConnection, aptabaseClient);
+ var loggerService = serviceProvider.GetRequiredService();
+
+ var telemetry = new Telemetry(DbConnection, aptabaseClient, loggerService);
SnapX.aptabaseClient = aptabaseClient;
telemetry.TrackEvent("app_started", new Dictionary
{
@@ -458,7 +483,6 @@ private static void Run()
#if DEBUG
options.Environment = "development";
options.CreateHttpMessageHandler = () => new LoggingHttpMessageHandler(new SentryHttpMessageHandler(), DebugHelper.Logger);
- options.DisableSentryHttpMessageHandler = true;
#else
options.Environment = "production";
#endif
@@ -518,7 +542,7 @@ static void RunWithTimeout(Func taskFactory, string description = "SQLite
task.GetAwaiter().GetResult(); // propagate exceptions
}
public SnapXCLIManager GetCLIManager() => CLIManager;
- public RootConfiguration GetConfiguration() => Settings;
+ public ApplicationConfig GetConfiguration() => Settings;
public static void CloseSequence()
{
@@ -715,7 +739,7 @@ private static void HandleExceptions()
#endif
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
- AppDomain.CurrentDomain.ProcessExit += ((_, _) => CloseSequence());
+ AppDomain.CurrentDomain.ProcessExit += (_, _) => CloseSequence();
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) => OnError((Exception)e.ExceptionObject);
private static void OnError(Exception e) => DebugHelper.WriteException(e);
diff --git a/SnapX.Core/SnapXResources.cs b/SnapX.Core/SnapXResources.cs
index 39c0f87b4..c47680546 100644
--- a/SnapX.Core/SnapXResources.cs
+++ b/SnapX.Core/SnapXResources.cs
@@ -1,9 +1,12 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
+using System.ComponentModel;
using System.Runtime.InteropServices;
+using SixLabors.ImageSharp;
using SnapX.Core.Utils;
+using SnapX.Core.Utils.Converters;
+using SnapX.Core.Utils.Extensions;
using SnapX.Core.Utils.Miscellaneous;
namespace SnapX.Core;
@@ -15,5 +18,240 @@ public static class SnapXResources
public static OsInfo.GenericGraphicsInfo graphicsInfo => OsInfo.GetGenericGraphicsInfo();
public static string Dotnet => RuntimeInformation.FrameworkDescription;
public static string fancyOsName => Helpers.GetOperatingSystemProductName();
- public static string? UserAgent => $"{SnapX.AppName}/{Helpers.GetApplicationVersion()} (+{Links.GitHub})";
+ public static string UserAgent => $"{SnapX.AppName}/{Helpers.GetApplicationVersion()} (+{Links.GitHub})";
+}
+
+
+public class Theme
+{
+ public string Name { get; set; } = "Dark";
+
+ private Color backgroundColor;
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color BackgroundColor
+ {
+ get => backgroundColor;
+ set
+ {
+ if (!value.IsTransparent()) backgroundColor = value;
+ }
+ }
+
+ private Color lightBackgroundColor;
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color LightBackgroundColor
+ {
+ get => lightBackgroundColor;
+ set
+ {
+ if (!value.IsTransparent()) lightBackgroundColor = value;
+ }
+ }
+
+ private Color darkBackgroundColor;
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color DarkBackgroundColor
+ {
+ get => darkBackgroundColor;
+ set
+ {
+ if (!value.IsTransparent()) darkBackgroundColor = value;
+ }
+ }
+
+ private Color textColor;
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color TextColor
+ {
+ get => textColor;
+ set
+ {
+ if (!value.IsTransparent()) textColor = value;
+ }
+ }
+
+ private Color borderColor;
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color BorderColor
+ {
+ get => borderColor;
+ set
+ {
+ if (!value.IsTransparent()) borderColor = value;
+ }
+ }
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color CheckerColor { get; set; }
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color CheckerColor2 { get; set; }
+
+ public int CheckerSize { get; set; } = 15;
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color LinkColor { get; set; }
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color MenuHighlightColor { get; set; }
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color MenuHighlightBorderColor { get; set; }
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color MenuBorderColor { get; set; }
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color MenuCheckBackgroundColor { get; set; }
+ public record UIFont(string Name, float Size);
+ public UIFont MenuFont { get; set; } = new("Inter", 11f);
+
+ public UIFont ContextMenuFont { get; set; } = new("Inter", 11f);
+
+ public int ContextMenuOpacity { get; set; } = 100;
+
+ [Browsable(false)]
+ public double ContextMenuOpacityDouble => ContextMenuOpacity.Clamp(10, 100) / 100d;
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color SeparatorLightColor { get; set; }
+
+ [TypeConverter(typeof(MyColorConverter))]
+ public Color SeparatorDarkColor { get; set; }
+
+ [Browsable(false)]
+ public bool IsDarkTheme => ColorHelpers.IsDarkColor(BackgroundColor);
+
+
+ public static Theme DarkTheme => new()
+ {
+ Name = "Dark",
+ BackgroundColor = Color.FromRgba(39, 39, 39, 255),
+ LightBackgroundColor = Color.FromRgba(46, 46, 46, 255),
+ DarkBackgroundColor = Color.FromRgba(34, 34, 34, 255),
+ TextColor = Color.FromRgba(231, 233, 234, 255),
+ BorderColor = Color.FromRgba(31, 31, 31, 255),
+ CheckerColor = Color.FromRgba(46, 46, 46, 255),
+ CheckerColor2 = Color.FromRgba(39, 39, 39, 255),
+ LinkColor = Color.FromRgba(166, 212, 255, 255),
+ MenuHighlightColor = Color.FromRgba(46, 46, 46, 255),
+ MenuHighlightBorderColor = Color.FromRgba(63, 63, 63, 255),
+ MenuBorderColor = Color.FromRgba(63, 63, 63, 255),
+ MenuCheckBackgroundColor = Color.FromRgba(51, 51, 51, 255),
+ SeparatorLightColor = Color.FromRgba(44, 44, 44, 255),
+ SeparatorDarkColor = Color.FromRgba(31, 31, 31, 255)
+ };
+
+ public static Theme LightTheme => new()
+ {
+ Name = "Light",
+ BackgroundColor = Color.FromRgba(242, 242, 242, 255),
+ LightBackgroundColor = Color.FromRgba(247, 247, 247, 255),
+ DarkBackgroundColor = Color.FromRgba(235, 235, 235, 255),
+ TextColor = Color.FromRgba(69, 69, 69, 255),
+ BorderColor = Color.FromRgba(201, 201, 201, 255),
+ CheckerColor = Color.FromRgba(247, 247, 247, 255),
+ CheckerColor2 = Color.FromRgba(235, 235, 235, 255),
+ LinkColor = Color.FromRgba(166, 212, 255, 255),
+ MenuHighlightColor = Color.FromRgba(247, 247, 247, 255),
+ MenuHighlightBorderColor = Color.FromRgba(96, 143, 226, 255),
+ MenuBorderColor = Color.FromRgba(201, 201, 201, 255),
+ MenuCheckBackgroundColor = Color.FromRgba(225, 233, 244, 255),
+ SeparatorLightColor = Color.FromRgba(253, 253, 253, 255),
+ SeparatorDarkColor = Color.FromRgba(189, 189, 189, 255)
+ };
+
+ public static Theme NightTheme => new()
+ {
+ Name = "Night",
+ BackgroundColor = Color.FromRgba(42, 47, 56, 255),
+ LightBackgroundColor = Color.FromRgba(52, 57, 65, 255),
+ DarkBackgroundColor = Color.FromRgba(28, 32, 38, 255),
+ TextColor = Color.FromRgba(235, 235, 235, 255),
+ BorderColor = Color.FromRgba(28, 32, 38, 255),
+ CheckerColor = Color.FromRgba(60, 60, 60, 255),
+ CheckerColor2 = Color.FromRgba(50, 50, 50, 255),
+ LinkColor = Color.FromRgba(166, 212, 255, 255),
+ MenuHighlightColor = Color.FromRgba(30, 34, 40, 255),
+ MenuHighlightBorderColor = Color.FromRgba(116, 129, 152, 255),
+ MenuBorderColor = Color.FromRgba(22, 26, 31, 255),
+ MenuCheckBackgroundColor = Color.FromRgba(56, 64, 75, 255),
+ SeparatorLightColor = Color.FromRgba(56, 64, 75, 255),
+ SeparatorDarkColor = Color.FromRgba(22, 26, 31, 255)
+ };
+
+ // https://www.nordtheme.com
+ public static Theme NordDarkTheme => new()
+ {
+ Name = "Nord Dark",
+ BackgroundColor = Color.FromRgba(46, 52, 64, 255),
+ LightBackgroundColor = Color.FromRgba(59, 66, 82, 255),
+ DarkBackgroundColor = Color.FromRgba(38, 44, 57, 255),
+ TextColor = Color.FromRgba(229, 233, 240, 255),
+ BorderColor = Color.FromRgba(30, 38, 54, 255),
+ CheckerColor = Color.FromRgba(46, 52, 64, 255),
+ CheckerColor2 = Color.FromRgba(36, 42, 54, 255),
+ LinkColor = Color.FromRgba(136, 192, 208, 255),
+ MenuHighlightColor = Color.FromRgba(36, 42, 54, 255),
+ MenuHighlightBorderColor = Color.FromRgba(24, 30, 42, 255),
+ MenuBorderColor = Color.FromRgba(24, 30, 42, 255),
+ MenuCheckBackgroundColor = Color.FromRgba(59, 66, 82, 255),
+ SeparatorLightColor = Color.FromRgba(59, 66, 82, 255),
+ SeparatorDarkColor = Color.FromRgba(30, 38, 54, 255)
+ };
+
+ // https://www.nordtheme.com
+ public static Theme NordLightTheme => new()
+ {
+ Name = "Nord Light",
+ BackgroundColor = Color.FromRgba(229, 233, 240, 255),
+ LightBackgroundColor = Color.FromRgba(236, 239, 244, 255),
+ DarkBackgroundColor = Color.FromRgba(216, 222, 233, 255),
+ TextColor = Color.FromRgba(59, 66, 82, 255),
+ BorderColor = Color.FromRgba(207, 216, 233, 255),
+ CheckerColor = Color.FromRgba(229, 233, 240, 255),
+ CheckerColor2 = Color.FromRgba(216, 222, 233, 255),
+ LinkColor = Color.FromRgba(106, 162, 178, 255),
+ MenuHighlightColor = Color.FromRgba(236, 239, 244, 255),
+ MenuHighlightBorderColor = Color.FromRgba(207, 216, 233, 255),
+ MenuBorderColor = Color.FromRgba(216, 222, 233, 255),
+ MenuCheckBackgroundColor = Color.FromRgba(229, 233, 240, 255),
+ SeparatorLightColor = Color.FromRgba(236, 239, 244, 255),
+ SeparatorDarkColor = Color.FromRgba(207, 216, 233, 255)
+ };
+
+ // https://draculatheme.com
+ public static Theme DraculaTheme => new()
+ {
+ Name = "Dracula",
+ BackgroundColor = Color.FromRgba(40, 42, 54, 255),
+ LightBackgroundColor = Color.FromRgba(68, 71, 90, 255),
+ DarkBackgroundColor = Color.FromRgba(36, 38, 48, 255),
+ TextColor = Color.FromRgba(248, 248, 242, 255),
+ BorderColor = Color.FromRgba(33, 35, 43, 255),
+ CheckerColor = Color.FromRgba(40, 42, 54, 255),
+ CheckerColor2 = Color.FromRgba(36, 38, 48, 255),
+ LinkColor = Color.FromRgba(98, 114, 164, 255),
+ MenuHighlightColor = Color.FromRgba(36, 38, 48, 255),
+ MenuHighlightBorderColor = Color.FromRgba(255, 121, 198, 255),
+ MenuBorderColor = Color.FromRgba(33, 35, 43, 255),
+ MenuCheckBackgroundColor = Color.FromRgba(45, 47, 61, 255),
+ SeparatorLightColor = Color.FromRgba(45, 47, 61, 255),
+ SeparatorDarkColor = Color.FromRgba(33, 35, 43, 255)
+ };
+
+ public static List GetDefaultThemes()
+ {
+ return [DarkTheme, LightTheme, NightTheme, NordDarkTheme, NordLightTheme, DraculaTheme];
+ }
+
+ public override string ToString()
+ {
+ return Name;
+ }
}
diff --git a/SnapX.Core/Telemetry.cs b/SnapX.Core/Telemetry.cs
index bfe79675e..00c481bfb 100644
--- a/SnapX.Core/Telemetry.cs
+++ b/SnapX.Core/Telemetry.cs
@@ -1,9 +1,9 @@
-using System.Diagnostics.CodeAnalysis;
-using System.Text.Json;
+using System.Text.Json;
using System.Text.Json.Serialization;
using Aptabase.Core;
using Dapper;
using Microsoft.Data.Sqlite;
+using SnapX.Core.Interfaces;
using SnapX.Core.Utils;
namespace SnapX.Core;
@@ -43,7 +43,7 @@ internal partial class SentryContext : JsonSerializerContext;
[JsonSerializable(typeof(OsInfo.GenericGraphicsInfo))]
internal partial class AptabaseContext : JsonSerializerContext;
-public sealed class Telemetry(SqliteConnection Connection, AptabaseClient AptabaseClient)
+public sealed class Telemetry(SqliteConnection Connection, AptabaseClient AptabaseClient, ILoggerService Logger)
{
[DapperAot]
public void LogTelemetry(string provider, string eventName, string envelope)
@@ -60,14 +60,11 @@ INSERT INTO TelemetryLog (EventName, Provider, Envelope)
}
catch (Exception ex)
{
- // Do not use DebugHelper.WriteException, that will call this function again!
- DebugHelper.WriteLine($"Telemetry Logger Error: {ex.Message}");
- DebugHelper.WriteLine(ex.ToString());
+ Logger.Error("Telemetry Logger Error: {ExMessage}", ex.ToString());
}
});
}
- [RequiresUnreferencedCode("Uses reflection to access properties that may be removed by the trimmer.")]
public void TrackEvent(string EventName, Dictionary? Envelope = null)
{
if (string.IsNullOrWhiteSpace(EventName)) return;
diff --git a/SnapX.Core/Upload/APIKeys.cs b/SnapX.Core/Upload/APIKeys.cs
index 1dc7fbcff..dadbeb57c 100644
--- a/SnapX.Core/Upload/APIKeys.cs
+++ b/SnapX.Core/Upload/APIKeys.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/FileUploaderService.cs b/SnapX.Core/Upload/BaseServices/FileUploaderService.cs
index c482b71f0..792e09c7a 100644
--- a/SnapX.Core/Upload/BaseServices/FileUploaderService.cs
+++ b/SnapX.Core/Upload/BaseServices/FileUploaderService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/IGenericUploaderService.cs b/SnapX.Core/Upload/BaseServices/IGenericUploaderService.cs
index 3a35ccfe1..793b16d0d 100644
--- a/SnapX.Core/Upload/BaseServices/IGenericUploaderService.cs
+++ b/SnapX.Core/Upload/BaseServices/IGenericUploaderService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/IUploaderService.cs b/SnapX.Core/Upload/BaseServices/IUploaderService.cs
index 72bc1f37f..6a315d6de 100644
--- a/SnapX.Core/Upload/BaseServices/IUploaderService.cs
+++ b/SnapX.Core/Upload/BaseServices/IUploaderService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/ImageUploaderService.cs b/SnapX.Core/Upload/BaseServices/ImageUploaderService.cs
index 2d48d4805..5ce1a44ef 100644
--- a/SnapX.Core/Upload/BaseServices/ImageUploaderService.cs
+++ b/SnapX.Core/Upload/BaseServices/ImageUploaderService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/TextUploaderService.cs b/SnapX.Core/Upload/BaseServices/TextUploaderService.cs
index b8d3148e8..5d3455e26 100644
--- a/SnapX.Core/Upload/BaseServices/TextUploaderService.cs
+++ b/SnapX.Core/Upload/BaseServices/TextUploaderService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/URLSharingService.cs b/SnapX.Core/Upload/BaseServices/URLSharingService.cs
index 5715c5733..c7bfe506a 100644
--- a/SnapX.Core/Upload/BaseServices/URLSharingService.cs
+++ b/SnapX.Core/Upload/BaseServices/URLSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/URLShortenerService.cs b/SnapX.Core/Upload/BaseServices/URLShortenerService.cs
index 2c6e0cb93..f9b5a9212 100644
--- a/SnapX.Core/Upload/BaseServices/URLShortenerService.cs
+++ b/SnapX.Core/Upload/BaseServices/URLShortenerService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseServices/UploaderService.cs b/SnapX.Core/Upload/BaseServices/UploaderService.cs
index 20c372f0a..12097be24 100644
--- a/SnapX.Core/Upload/BaseServices/UploaderService.cs
+++ b/SnapX.Core/Upload/BaseServices/UploaderService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseUploaders/GenericUploader.cs b/SnapX.Core/Upload/BaseUploaders/GenericUploader.cs
index 67535c588..d154505a5 100644
--- a/SnapX.Core/Upload/BaseUploaders/GenericUploader.cs
+++ b/SnapX.Core/Upload/BaseUploaders/GenericUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseUploaders/ImageUploader.cs b/SnapX.Core/Upload/BaseUploaders/ImageUploader.cs
index eae6feaf5..a05b02772 100644
--- a/SnapX.Core/Upload/BaseUploaders/ImageUploader.cs
+++ b/SnapX.Core/Upload/BaseUploaders/ImageUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseUploaders/TextUploader.cs b/SnapX.Core/Upload/BaseUploaders/TextUploader.cs
index f54adbefe..e586908e6 100644
--- a/SnapX.Core/Upload/BaseUploaders/TextUploader.cs
+++ b/SnapX.Core/Upload/BaseUploaders/TextUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseUploaders/URLSharer.cs b/SnapX.Core/Upload/BaseUploaders/URLSharer.cs
index 90205b4f6..a32d1ed45 100644
--- a/SnapX.Core/Upload/BaseUploaders/URLSharer.cs
+++ b/SnapX.Core/Upload/BaseUploaders/URLSharer.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseUploaders/URLShortener.cs b/SnapX.Core/Upload/BaseUploaders/URLShortener.cs
index 745c00089..b59ece41f 100644
--- a/SnapX.Core/Upload/BaseUploaders/URLShortener.cs
+++ b/SnapX.Core/Upload/BaseUploaders/URLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/BaseUploaders/Uploader.cs b/SnapX.Core/Upload/BaseUploaders/Uploader.cs
index 298c32ce7..3035fc010 100644
--- a/SnapX.Core/Upload/BaseUploaders/Uploader.cs
+++ b/SnapX.Core/Upload/BaseUploaders/Uploader.cs
@@ -1,10 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Collections.Specialized;
using System.Net;
using System.Text;
+using MimeTypeCore;
using SnapX.Core.Upload.OAuth;
using SnapX.Core.Upload.Utils;
using SnapX.Core.Utils;
@@ -256,7 +256,7 @@ protected UploadResult SendRequestFileRange(string? url, Stream data, string? fi
}
contentLength = Math.Min(contentLength, data.Length - contentPosition);
- string contentType = MimeTypes.GetMimeType(fileName);
+ var contentType = MimeTypeMap.GetMimeType(fileName);
if (headers == null)
{
diff --git a/SnapX.Core/Upload/Custom/CustomUploaderInput.cs b/SnapX.Core/Upload/Custom/CustomUploaderInput.cs
index f6f23b1a1..648b3ad00 100644
--- a/SnapX.Core/Upload/Custom/CustomUploaderInput.cs
+++ b/SnapX.Core/Upload/Custom/CustomUploaderInput.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/CustomUploaderItem.cs b/SnapX.Core/Upload/Custom/CustomUploaderItem.cs
index fb4d1de17..da6b046c1 100644
--- a/SnapX.Core/Upload/Custom/CustomUploaderItem.cs
+++ b/SnapX.Core/Upload/Custom/CustomUploaderItem.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunction.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunction.cs
index 38d573e67..e0ba1792c 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunction.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunction.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionBase64.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionBase64.cs
index 0aa624e91..35d702b07 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionBase64.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionBase64.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionFileName.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionFileName.cs
index 8a9b486a6..bca367219 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionFileName.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionFileName.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionHeader.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionHeader.cs
index a11b2ed31..423109ea4 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionHeader.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionHeader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInput.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInput.cs
index dabc7a685..ec4f26a78 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInput.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInput.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInputBox.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInputBox.cs
index 8e4fb1ce3..920b0f4fa 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInputBox.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionInputBox.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionJson.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionJson.cs
index 105a18147..6bd26d591 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionJson.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionJson.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionOutputBox.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionOutputBox.cs
index f1a1f4d54..c136b9d59 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionOutputBox.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionOutputBox.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRandom.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRandom.cs
index 7e2c88651..6fd64b676 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRandom.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRandom.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRegex.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRegex.cs
index 63718675c..11dbcfb5e 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRegex.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionRegex.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponse.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponse.cs
index b8b16f32a..4c4071fe5 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponse.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponse.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponseURL.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponseURL.cs
index 40462401c..c9e0944d9 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponseURL.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionResponseURL.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionSelect.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionSelect.cs
index 96c783636..82c01ceef 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionSelect.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionSelect.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionXml.cs b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionXml.cs
index abe22c9be..2bf1701a5 100644
--- a/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionXml.cs
+++ b/SnapX.Core/Upload/Custom/Functions/CustomUploaderFunctionXml.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/ShareXCustomUploaderSyntaxParser.cs b/SnapX.Core/Upload/Custom/ShareXCustomUploaderSyntaxParser.cs
index de53c3a9e..dc0100be0 100644
--- a/SnapX.Core/Upload/Custom/ShareXCustomUploaderSyntaxParser.cs
+++ b/SnapX.Core/Upload/Custom/ShareXCustomUploaderSyntaxParser.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Custom/ShareXSyntaxParser.cs b/SnapX.Core/Upload/Custom/ShareXSyntaxParser.cs
index 7407eaaa9..28a4928a7 100644
--- a/SnapX.Core/Upload/Custom/ShareXSyntaxParser.cs
+++ b/SnapX.Core/Upload/Custom/ShareXSyntaxParser.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/AmazonS3.cs b/SnapX.Core/Upload/File/AmazonS3.cs
index 4f1c37ecd..2cf82941b 100644
--- a/SnapX.Core/Upload/File/AmazonS3.cs
+++ b/SnapX.Core/Upload/File/AmazonS3.cs
@@ -1,10 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Custom;
@@ -109,7 +109,7 @@ public override UploadResult Upload(Stream stream, string? fileName)
var scope = URLHelpers.CombineURL(credentialDate, region, "s3", "aws4_request");
var credential = URLHelpers.CombineURL(Settings.AccessKeyID, scope);
var timeStamp = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture);
- var contentType = MimeTypes.GetMimeType(fileName);
+ var contentType = MimeTypeMap.GetMimeType(fileName);
string hashedPayload;
if (Settings.SignedPayload)
diff --git a/SnapX.Core/Upload/File/AmazonS3Endpoint.cs b/SnapX.Core/Upload/File/AmazonS3Endpoint.cs
index dfb949707..2c1c644aa 100644
--- a/SnapX.Core/Upload/File/AmazonS3Endpoint.cs
+++ b/SnapX.Core/Upload/File/AmazonS3Endpoint.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/AmazonS3Settings.cs b/SnapX.Core/Upload/File/AmazonS3Settings.cs
index 542a5c442..397778724 100644
--- a/SnapX.Core/Upload/File/AmazonS3Settings.cs
+++ b/SnapX.Core/Upload/File/AmazonS3Settings.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/AzureStorage.cs b/SnapX.Core/Upload/File/AzureStorage.cs
index e934fc58a..d3f024817 100644
--- a/SnapX.Core/Upload/File/AzureStorage.cs
+++ b/SnapX.Core/Upload/File/AzureStorage.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -6,6 +5,7 @@
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Utils;
@@ -74,7 +74,7 @@ public override UploadResult Upload(Stream stream, string? fileName)
OnEarlyURLCopyRequested(resultURL);
- var contentType = MimeTypes.GetMimeType(fileName);
+ var contentType = MimeTypeMap.GetMimeType(fileName);
var requestHeaders = new NameValueCollection
{
{ "x-ms-date", date },
diff --git a/SnapX.Core/Upload/File/BackblazeB2.cs b/SnapX.Core/Upload/File/BackblazeB2.cs
index 9ad977fa9..a59e27873 100644
--- a/SnapX.Core/Upload/File/BackblazeB2.cs
+++ b/SnapX.Core/Upload/File/BackblazeB2.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -10,6 +9,7 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Utils;
@@ -405,7 +405,7 @@ private B2UploadResult B2ApiUploadFile(B2UploadUrl b2UploadUrl, string? destinat
["X-Bz-Info-b2-content-disposition"] = URLHelpers.URLEncode(contentDisposition.ToString()),
};
- string contentType = MimeTypes.GetMimeType(destinationPath);
+ string contentType = MimeTypeMap.GetMimeType(destinationPath);
using var response = GetResponse(HttpMethod.Post, b2UploadUrl.uploadUrl,
data: file, contentType: contentType, headers: headers, allowNon2xxResponses: true);
diff --git a/SnapX.Core/Upload/File/Box.cs b/SnapX.Core/Upload/File/Box.cs
index 5bf3a8275..b20a59da5 100644
--- a/SnapX.Core/Upload/File/Box.cs
+++ b/SnapX.Core/Upload/File/Box.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Copy.cs b/SnapX.Core/Upload/File/Copy.cs
index 495bb9901..dd741dec6 100644
--- a/SnapX.Core/Upload/File/Copy.cs
+++ b/SnapX.Core/Upload/File/Copy.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/CustomFileUploader.cs b/SnapX.Core/Upload/File/CustomFileUploader.cs
index ffb236698..ebf4dbf28 100644
--- a/SnapX.Core/Upload/File/CustomFileUploader.cs
+++ b/SnapX.Core/Upload/File/CustomFileUploader.cs
@@ -1,7 +1,7 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Custom;
@@ -64,7 +64,7 @@ public override UploadResult Upload(Stream stream, string? fileName)
}
else if (uploader.Body == CustomUploaderBody.Binary)
{
- result.Response = SendRequest(uploader.RequestMethod, uploader.GetRequestURL(input), stream, MimeTypes.GetMimeType(fileName), null,
+ result.Response = SendRequest(uploader.RequestMethod, uploader.GetRequestURL(input), stream, MimeTypeMap.GetMimeType(fileName), null,
uploader.GetHeaders(input));
}
else
diff --git a/SnapX.Core/Upload/File/DropIO.cs b/SnapX.Core/Upload/File/DropIO.cs
index d71652814..3c9bafd05 100644
--- a/SnapX.Core/Upload/File/DropIO.cs
+++ b/SnapX.Core/Upload/File/DropIO.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Dropbox.cs b/SnapX.Core/Upload/File/Dropbox.cs
index e2cf1b641..e55c04dca 100644
--- a/SnapX.Core/Upload/File/Dropbox.cs
+++ b/SnapX.Core/Upload/File/Dropbox.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Email.cs b/SnapX.Core/Upload/File/Email.cs
index 5bc29c660..43a73b0bc 100644
--- a/SnapX.Core/Upload/File/Email.cs
+++ b/SnapX.Core/Upload/File/Email.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/FTP.cs b/SnapX.Core/Upload/File/FTP.cs
index 22d022688..5343bc553 100644
--- a/SnapX.Core/Upload/File/FTP.cs
+++ b/SnapX.Core/Upload/File/FTP.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/FTPAccount.cs b/SnapX.Core/Upload/File/FTPAccount.cs
index e3a8b2fd5..b64867695 100644
--- a/SnapX.Core/Upload/File/FTPAccount.cs
+++ b/SnapX.Core/Upload/File/FTPAccount.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/FileBin.cs b/SnapX.Core/Upload/File/FileBin.cs
index e78e54fa3..c9abbf8cb 100644
--- a/SnapX.Core/Upload/File/FileBin.cs
+++ b/SnapX.Core/Upload/File/FileBin.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/FileSonic.cs b/SnapX.Core/Upload/File/FileSonic.cs
index 608df1ac1..64c97fbf8 100644
--- a/SnapX.Core/Upload/File/FileSonic.cs
+++ b/SnapX.Core/Upload/File/FileSonic.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/GoogleCloudStorage.cs b/SnapX.Core/Upload/File/GoogleCloudStorage.cs
index f1788a488..84bf5733a 100644
--- a/SnapX.Core/Upload/File/GoogleCloudStorage.cs
+++ b/SnapX.Core/Upload/File/GoogleCloudStorage.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/GoogleDrive.cs b/SnapX.Core/Upload/File/GoogleDrive.cs
index 2ffce4649..72801cf26 100644
--- a/SnapX.Core/Upload/File/GoogleDrive.cs
+++ b/SnapX.Core/Upload/File/GoogleDrive.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Hostr.cs b/SnapX.Core/Upload/File/Hostr.cs
index 0c0c67b66..0502fdc6e 100644
--- a/SnapX.Core/Upload/File/Hostr.cs
+++ b/SnapX.Core/Upload/File/Hostr.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Jira.cs b/SnapX.Core/Upload/File/Jira.cs
index e91ab0c3b..cd29a2fea 100644
--- a/SnapX.Core/Upload/File/Jira.cs
+++ b/SnapX.Core/Upload/File/Jira.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Lambda.cs b/SnapX.Core/Upload/File/Lambda.cs
index 21c5be97a..3255ab245 100644
--- a/SnapX.Core/Upload/File/Lambda.cs
+++ b/SnapX.Core/Upload/File/Lambda.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/LobFile.cs b/SnapX.Core/Upload/File/LobFile.cs
index 43ecdf632..479eba7c2 100644
--- a/SnapX.Core/Upload/File/LobFile.cs
+++ b/SnapX.Core/Upload/File/LobFile.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/LocalhostAccount.cs b/SnapX.Core/Upload/File/LocalhostAccount.cs
index 3d3049180..84469cf05 100644
--- a/SnapX.Core/Upload/File/LocalhostAccount.cs
+++ b/SnapX.Core/Upload/File/LocalhostAccount.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/MediaFire.cs b/SnapX.Core/Upload/File/MediaFire.cs
index 193db5ac5..c2bbdb1fd 100644
--- a/SnapX.Core/Upload/File/MediaFire.cs
+++ b/SnapX.Core/Upload/File/MediaFire.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Mega.cs b/SnapX.Core/Upload/File/Mega.cs
index 54a051138..0086b85c5 100644
--- a/SnapX.Core/Upload/File/Mega.cs
+++ b/SnapX.Core/Upload/File/Mega.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/MegaAuthInfos.cs b/SnapX.Core/Upload/File/MegaAuthInfos.cs
index 83094a402..9f473d22c 100644
--- a/SnapX.Core/Upload/File/MegaAuthInfos.cs
+++ b/SnapX.Core/Upload/File/MegaAuthInfos.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/OneDrive.cs b/SnapX.Core/Upload/File/OneDrive.cs
index b4f5f4d89..64003e3f6 100644
--- a/SnapX.Core/Upload/File/OneDrive.cs
+++ b/SnapX.Core/Upload/File/OneDrive.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/OwnCloud.cs b/SnapX.Core/Upload/File/OwnCloud.cs
index 34f43bddf..1b920e490 100644
--- a/SnapX.Core/Upload/File/OwnCloud.cs
+++ b/SnapX.Core/Upload/File/OwnCloud.cs
@@ -1,10 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Utils;
@@ -89,7 +89,7 @@ public override UploadResult Upload(Stream stream, string? fileName)
var headers = RequestHelpers.CreateAuthenticationHeader(Username, Password);
headers["OCS-APIREQUEST"] = "true";
- var response = SendRequest(HttpMethod.Put, url, stream, MimeTypes.GetMimeType(fileName), null, headers);
+ var response = SendRequest(HttpMethod.Put, url, stream, MimeTypeMap.GetMimeType(fileName), null, headers);
var result = new UploadResult(response);
diff --git a/SnapX.Core/Upload/File/Plik.cs b/SnapX.Core/Upload/File/Plik.cs
index b8820c3ec..6e3533daf 100644
--- a/SnapX.Core/Upload/File/Plik.cs
+++ b/SnapX.Core/Upload/File/Plik.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -6,6 +5,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Utils;
@@ -54,7 +54,7 @@ public override UploadResult Upload(Stream stream, string? fileName)
metaDataReq.Files = new UploadMetadataRequestFile0();
metaDataReq.Files.File0 = new UploadMetadataRequestFile();
metaDataReq.Files.File0.FileName = fileName;
- metaDataReq.Files.File0.FileType = MimeTypes.GetMimeType(fileName);
+ metaDataReq.Files.File0.FileType = MimeTypeMap.GetMimeType(fileName);
metaDataReq.Files.File0.FileSize = Convert.ToInt32(stream.Length);
metaDataReq.Removable = Settings.Removable;
metaDataReq.OneShot = Settings.OneShot;
diff --git a/SnapX.Core/Upload/File/PlikSettings.cs b/SnapX.Core/Upload/File/PlikSettings.cs
index 304d1d72c..0e8b30fb3 100644
--- a/SnapX.Core/Upload/File/PlikSettings.cs
+++ b/SnapX.Core/Upload/File/PlikSettings.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Pomf.cs b/SnapX.Core/Upload/File/Pomf.cs
index b040cc5e0..707950052 100644
--- a/SnapX.Core/Upload/File/Pomf.cs
+++ b/SnapX.Core/Upload/File/Pomf.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/PomfUploader.cs b/SnapX.Core/Upload/File/PomfUploader.cs
index 6b6b851a2..9eff96338 100644
--- a/SnapX.Core/Upload/File/PomfUploader.cs
+++ b/SnapX.Core/Upload/File/PomfUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Pushbullet.cs b/SnapX.Core/Upload/File/Pushbullet.cs
index 067958d7d..5d2fafa1b 100644
--- a/SnapX.Core/Upload/File/Pushbullet.cs
+++ b/SnapX.Core/Upload/File/Pushbullet.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Puush.cs b/SnapX.Core/Upload/File/Puush.cs
index a2e233130..f9ba45941 100644
--- a/SnapX.Core/Upload/File/Puush.cs
+++ b/SnapX.Core/Upload/File/Puush.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/SFTP.cs b/SnapX.Core/Upload/File/SFTP.cs
index 60d06ee76..f186c035a 100644
--- a/SnapX.Core/Upload/File/SFTP.cs
+++ b/SnapX.Core/Upload/File/SFTP.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Seafile.cs b/SnapX.Core/Upload/File/Seafile.cs
index 369f78bcc..074dc4fc4 100644
--- a/SnapX.Core/Upload/File/Seafile.cs
+++ b/SnapX.Core/Upload/File/Seafile.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/SendSpace.cs b/SnapX.Core/Upload/File/SendSpace.cs
index ecdedc38b..35ab45537 100644
--- a/SnapX.Core/Upload/File/SendSpace.cs
+++ b/SnapX.Core/Upload/File/SendSpace.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/SendSpaceManager.cs b/SnapX.Core/Upload/File/SendSpaceManager.cs
index f2aef5936..4d577b2f5 100644
--- a/SnapX.Core/Upload/File/SendSpaceManager.cs
+++ b/SnapX.Core/Upload/File/SendSpaceManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/ShareCX.cs b/SnapX.Core/Upload/File/ShareCX.cs
index 5f6a13f6e..78f1b704d 100644
--- a/SnapX.Core/Upload/File/ShareCX.cs
+++ b/SnapX.Core/Upload/File/ShareCX.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/SharedFolderUploader.cs b/SnapX.Core/Upload/File/SharedFolderUploader.cs
index cef89855c..024e77cdd 100644
--- a/SnapX.Core/Upload/File/SharedFolderUploader.cs
+++ b/SnapX.Core/Upload/File/SharedFolderUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Streamable.cs b/SnapX.Core/Upload/File/Streamable.cs
index 5230ac86f..0e9d636b8 100644
--- a/SnapX.Core/Upload/File/Streamable.cs
+++ b/SnapX.Core/Upload/File/Streamable.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Sul.cs b/SnapX.Core/Upload/File/Sul.cs
index 4f38a675c..2d996dfe9 100644
--- a/SnapX.Core/Upload/File/Sul.cs
+++ b/SnapX.Core/Upload/File/Sul.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Transfersh.cs b/SnapX.Core/Upload/File/Transfersh.cs
index 5301aa842..b21dade6f 100644
--- a/SnapX.Core/Upload/File/Transfersh.cs
+++ b/SnapX.Core/Upload/File/Transfersh.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Uguu.cs b/SnapX.Core/Upload/File/Uguu.cs
index baa4e1197..4159c78de 100644
--- a/SnapX.Core/Upload/File/Uguu.cs
+++ b/SnapX.Core/Upload/File/Uguu.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/Vault_ooo.cs b/SnapX.Core/Upload/File/Vault_ooo.cs
index d859bde4e..e977dafa5 100644
--- a/SnapX.Core/Upload/File/Vault_ooo.cs
+++ b/SnapX.Core/Upload/File/Vault_ooo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/File/YouTube.cs b/SnapX.Core/Upload/File/YouTube.cs
index d8411095f..b60909903 100644
--- a/SnapX.Core/Upload/File/YouTube.cs
+++ b/SnapX.Core/Upload/File/YouTube.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/Chevereto.cs b/SnapX.Core/Upload/Img/Chevereto.cs
index fc51fce04..eed164a20 100644
--- a/SnapX.Core/Upload/Img/Chevereto.cs
+++ b/SnapX.Core/Upload/Img/Chevereto.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/CheveretoUploader.cs b/SnapX.Core/Upload/Img/CheveretoUploader.cs
index 962325fb0..67e65145d 100644
--- a/SnapX.Core/Upload/Img/CheveretoUploader.cs
+++ b/SnapX.Core/Upload/Img/CheveretoUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/CustomImageUploader.cs b/SnapX.Core/Upload/Img/CustomImageUploader.cs
index 959de309e..052baa64b 100644
--- a/SnapX.Core/Upload/Img/CustomImageUploader.cs
+++ b/SnapX.Core/Upload/Img/CustomImageUploader.cs
@@ -1,7 +1,7 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Custom;
@@ -57,7 +57,7 @@ public override UploadResult Upload(Stream stream, string? fileName)
}
else if (uploader.Body == CustomUploaderBody.Binary)
{
- ur.Response = SendRequest(uploader.RequestMethod, uploader.GetRequestURL(input), stream, MimeTypes.GetMimeType(fileName),
+ ur.Response = SendRequest(uploader.RequestMethod, uploader.GetRequestURL(input), stream, MimeTypeMap.GetMimeType(fileName),
null, uploader.GetHeaders(input));
}
else
diff --git a/SnapX.Core/Upload/Img/FlickrUploader.cs b/SnapX.Core/Upload/Img/FlickrUploader.cs
index c755e8266..a860f2530 100644
--- a/SnapX.Core/Upload/Img/FlickrUploader.cs
+++ b/SnapX.Core/Upload/Img/FlickrUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/ImageBin.cs b/SnapX.Core/Upload/Img/ImageBin.cs
index 3192fabf5..62f042d99 100644
--- a/SnapX.Core/Upload/Img/ImageBin.cs
+++ b/SnapX.Core/Upload/Img/ImageBin.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/ImageShackUploader.cs b/SnapX.Core/Upload/Img/ImageShackUploader.cs
index 19e94029a..7f4a31164 100644
--- a/SnapX.Core/Upload/Img/ImageShackUploader.cs
+++ b/SnapX.Core/Upload/Img/ImageShackUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/Img1Uploader.cs b/SnapX.Core/Upload/Img/Img1Uploader.cs
index 7f05556b2..1aa73cd9c 100644
--- a/SnapX.Core/Upload/Img/Img1Uploader.cs
+++ b/SnapX.Core/Upload/Img/Img1Uploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/Imgur.cs b/SnapX.Core/Upload/Img/Imgur.cs
index 591e6d5ec..c2db2f0c6 100644
--- a/SnapX.Core/Upload/Img/Imgur.cs
+++ b/SnapX.Core/Upload/Img/Imgur.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/ImmioUploader.cs b/SnapX.Core/Upload/Img/ImmioUploader.cs
index 42b8ed383..86b62981b 100644
--- a/SnapX.Core/Upload/Img/ImmioUploader.cs
+++ b/SnapX.Core/Upload/Img/ImmioUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/Photobucket.cs b/SnapX.Core/Upload/Img/Photobucket.cs
index f48014f7a..5762a8b55 100644
--- a/SnapX.Core/Upload/Img/Photobucket.cs
+++ b/SnapX.Core/Upload/Img/Photobucket.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/TwitPicUploader.cs b/SnapX.Core/Upload/Img/TwitPicUploader.cs
index 1b0431aa0..065e72653 100644
--- a/SnapX.Core/Upload/Img/TwitPicUploader.cs
+++ b/SnapX.Core/Upload/Img/TwitPicUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/TwitSnapsUploader.cs b/SnapX.Core/Upload/Img/TwitSnapsUploader.cs
index c3060a06e..eba820e64 100644
--- a/SnapX.Core/Upload/Img/TwitSnapsUploader.cs
+++ b/SnapX.Core/Upload/Img/TwitSnapsUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/Twitter.cs b/SnapX.Core/Upload/Img/Twitter.cs
index b4978bfe7..affbc70ed 100644
--- a/SnapX.Core/Upload/Img/Twitter.cs
+++ b/SnapX.Core/Upload/Img/Twitter.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/UploadScreenshot.cs b/SnapX.Core/Upload/Img/UploadScreenshot.cs
index 29047cae8..7ac985524 100644
--- a/SnapX.Core/Upload/Img/UploadScreenshot.cs
+++ b/SnapX.Core/Upload/Img/UploadScreenshot.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/VgymeUploader.cs b/SnapX.Core/Upload/Img/VgymeUploader.cs
index cd4ca8ef4..5d77f0c9e 100644
--- a/SnapX.Core/Upload/Img/VgymeUploader.cs
+++ b/SnapX.Core/Upload/Img/VgymeUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Img/YfrogUploader.cs b/SnapX.Core/Upload/Img/YfrogUploader.cs
index 5231821b5..09db7f885 100644
--- a/SnapX.Core/Upload/Img/YfrogUploader.cs
+++ b/SnapX.Core/Upload/Img/YfrogUploader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/GoogleOAuth2.cs b/SnapX.Core/Upload/OAuth/GoogleOAuth2.cs
index b3af891eb..413a3cfbc 100644
--- a/SnapX.Core/Upload/OAuth/GoogleOAuth2.cs
+++ b/SnapX.Core/Upload/OAuth/GoogleOAuth2.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/IOAuth.cs b/SnapX.Core/Upload/OAuth/IOAuth.cs
index caf0996e8..be7d71422 100644
--- a/SnapX.Core/Upload/OAuth/IOAuth.cs
+++ b/SnapX.Core/Upload/OAuth/IOAuth.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/IOAuth2.cs b/SnapX.Core/Upload/OAuth/IOAuth2.cs
index 40f9d9423..e419f23dc 100644
--- a/SnapX.Core/Upload/OAuth/IOAuth2.cs
+++ b/SnapX.Core/Upload/OAuth/IOAuth2.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/IOAuth2Basic.cs b/SnapX.Core/Upload/OAuth/IOAuth2Basic.cs
index e1f27f4a0..73aa121dd 100644
--- a/SnapX.Core/Upload/OAuth/IOAuth2Basic.cs
+++ b/SnapX.Core/Upload/OAuth/IOAuth2Basic.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/IOAuthBase.cs b/SnapX.Core/Upload/OAuth/IOAuthBase.cs
index 1bd0a3bb0..91ca502e8 100644
--- a/SnapX.Core/Upload/OAuth/IOAuthBase.cs
+++ b/SnapX.Core/Upload/OAuth/IOAuthBase.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/IOauth2Loopback.cs b/SnapX.Core/Upload/OAuth/IOauth2Loopback.cs
index 81a421d7b..223479434 100644
--- a/SnapX.Core/Upload/OAuth/IOauth2Loopback.cs
+++ b/SnapX.Core/Upload/OAuth/IOauth2Loopback.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/OAuth2Info.cs b/SnapX.Core/Upload/OAuth/OAuth2Info.cs
index d1e3eadef..1fd8a1ea0 100644
--- a/SnapX.Core/Upload/OAuth/OAuth2Info.cs
+++ b/SnapX.Core/Upload/OAuth/OAuth2Info.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/OAuth2ProofKey.cs b/SnapX.Core/Upload/OAuth/OAuth2ProofKey.cs
index 7e01fe9d6..7592f2af4 100644
--- a/SnapX.Core/Upload/OAuth/OAuth2ProofKey.cs
+++ b/SnapX.Core/Upload/OAuth/OAuth2ProofKey.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/OAuth2Token.cs b/SnapX.Core/Upload/OAuth/OAuth2Token.cs
index 318a021c4..6bf27b9d1 100644
--- a/SnapX.Core/Upload/OAuth/OAuth2Token.cs
+++ b/SnapX.Core/Upload/OAuth/OAuth2Token.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/OAuthInfo.cs b/SnapX.Core/Upload/OAuth/OAuthInfo.cs
index e872a3656..3b824e88e 100644
--- a/SnapX.Core/Upload/OAuth/OAuthInfo.cs
+++ b/SnapX.Core/Upload/OAuth/OAuthInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/OAuthListener.cs b/SnapX.Core/Upload/OAuth/OAuthListener.cs
index 265b3e433..65a57fcc5 100644
--- a/SnapX.Core/Upload/OAuth/OAuthListener.cs
+++ b/SnapX.Core/Upload/OAuth/OAuthListener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/OAuthManager.cs b/SnapX.Core/Upload/OAuth/OAuthManager.cs
index bc13ead7b..8fbb66375 100644
--- a/SnapX.Core/Upload/OAuth/OAuthManager.cs
+++ b/SnapX.Core/Upload/OAuth/OAuthManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/OAuth/OAuthUserInfo.cs b/SnapX.Core/Upload/OAuth/OAuthUserInfo.cs
index 10f1246f4..c4d5a07ef 100644
--- a/SnapX.Core/Upload/OAuth/OAuthUserInfo.cs
+++ b/SnapX.Core/Upload/OAuth/OAuthUserInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/BingVisualSearchSharingService.cs b/SnapX.Core/Upload/SharingServices/BingVisualSearchSharingService.cs
index 01d4cd2cf..e67882fb9 100644
--- a/SnapX.Core/Upload/SharingServices/BingVisualSearchSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/BingVisualSearchSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/CustomURLSharingService.cs b/SnapX.Core/Upload/SharingServices/CustomURLSharingService.cs
index 84bbaa955..bf650a936 100644
--- a/SnapX.Core/Upload/SharingServices/CustomURLSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/CustomURLSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/DeliciousSharingService.cs b/SnapX.Core/Upload/SharingServices/DeliciousSharingService.cs
index 415831fa8..ec7222cf8 100644
--- a/SnapX.Core/Upload/SharingServices/DeliciousSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/DeliciousSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/EmailSharingService.cs b/SnapX.Core/Upload/SharingServices/EmailSharingService.cs
index 0155073a0..99b106bc5 100644
--- a/SnapX.Core/Upload/SharingServices/EmailSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/EmailSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/FacebookSharingService.cs b/SnapX.Core/Upload/SharingServices/FacebookSharingService.cs
index f4a58be39..6637ce52e 100644
--- a/SnapX.Core/Upload/SharingServices/FacebookSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/FacebookSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/GoogleLensSharingService.cs b/SnapX.Core/Upload/SharingServices/GoogleLensSharingService.cs
index 80bcc8a73..b0580693c 100644
--- a/SnapX.Core/Upload/SharingServices/GoogleLensSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/GoogleLensSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/LinkedInSharingService.cs b/SnapX.Core/Upload/SharingServices/LinkedInSharingService.cs
index 43d268393..636ab1d37 100644
--- a/SnapX.Core/Upload/SharingServices/LinkedInSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/LinkedInSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/PinterestSharingService.cs b/SnapX.Core/Upload/SharingServices/PinterestSharingService.cs
index 7e1a0aebe..11bd50235 100644
--- a/SnapX.Core/Upload/SharingServices/PinterestSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/PinterestSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/PushbulletSharingService.cs b/SnapX.Core/Upload/SharingServices/PushbulletSharingService.cs
index 040e6c752..48b64e9ff 100644
--- a/SnapX.Core/Upload/SharingServices/PushbulletSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/PushbulletSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/RedditSharingService.cs b/SnapX.Core/Upload/SharingServices/RedditSharingService.cs
index ec20c0989..5c774a622 100644
--- a/SnapX.Core/Upload/SharingServices/RedditSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/RedditSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/SimpleURLSharingService.cs b/SnapX.Core/Upload/SharingServices/SimpleURLSharingService.cs
index 7f93bf687..553e2f6ae 100644
--- a/SnapX.Core/Upload/SharingServices/SimpleURLSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/SimpleURLSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/StumbleUponSharingService.cs b/SnapX.Core/Upload/SharingServices/StumbleUponSharingService.cs
index f33f98d10..fbc5175a0 100644
--- a/SnapX.Core/Upload/SharingServices/StumbleUponSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/StumbleUponSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/TumblrSharingService.cs b/SnapX.Core/Upload/SharingServices/TumblrSharingService.cs
index a6ca77256..43f5557ca 100644
--- a/SnapX.Core/Upload/SharingServices/TumblrSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/TumblrSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/TwitterSharingService.cs b/SnapX.Core/Upload/SharingServices/TwitterSharingService.cs
index 3f572e628..cd56c2cd8 100644
--- a/SnapX.Core/Upload/SharingServices/TwitterSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/TwitterSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/SharingServices/VkSharingService.cs b/SnapX.Core/Upload/SharingServices/VkSharingService.cs
index b666d2477..3c757b4d8 100644
--- a/SnapX.Core/Upload/SharingServices/VkSharingService.cs
+++ b/SnapX.Core/Upload/SharingServices/VkSharingService.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/CustomTextUploader.cs b/SnapX.Core/Upload/Text/CustomTextUploader.cs
index 69cc5b50e..e3f3b39cd 100644
--- a/SnapX.Core/Upload/Text/CustomTextUploader.cs
+++ b/SnapX.Core/Upload/Text/CustomTextUploader.cs
@@ -1,8 +1,8 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Text;
+using MimeTypeCore;
using SnapX.Core.Upload.BaseServices;
using SnapX.Core.Upload.BaseUploaders;
using SnapX.Core.Upload.Custom;
@@ -123,7 +123,7 @@ public override UploadResult UploadText(string? text, string? fileName)
uploader.RequestMethod,
uploader.GetRequestURL(input),
binaryStream,
- MimeTypes.GetMimeType(fileName),
+ MimeTypeMap.GetMimeType(fileName),
null,
uploader.GetHeaders(input)
);
diff --git a/SnapX.Core/Upload/Text/GitHubGist.cs b/SnapX.Core/Upload/Text/GitHubGist.cs
index 44fd40eb4..69851caed 100644
--- a/SnapX.Core/Upload/Text/GitHubGist.cs
+++ b/SnapX.Core/Upload/Text/GitHubGist.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Hastebin.cs b/SnapX.Core/Upload/Text/Hastebin.cs
index 0a41b3591..e1bfc467c 100644
--- a/SnapX.Core/Upload/Text/Hastebin.cs
+++ b/SnapX.Core/Upload/Text/Hastebin.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/OneTimeSecret.cs b/SnapX.Core/Upload/Text/OneTimeSecret.cs
index f67d65b3c..db0c9fece 100644
--- a/SnapX.Core/Upload/Text/OneTimeSecret.cs
+++ b/SnapX.Core/Upload/Text/OneTimeSecret.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Paste2.cs b/SnapX.Core/Upload/Text/Paste2.cs
index a621c8ab1..84aeadaac 100644
--- a/SnapX.Core/Upload/Text/Paste2.cs
+++ b/SnapX.Core/Upload/Text/Paste2.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Paste_ee.cs b/SnapX.Core/Upload/Text/Paste_ee.cs
index 3ec4eef7f..6c3b749c9 100644
--- a/SnapX.Core/Upload/Text/Paste_ee.cs
+++ b/SnapX.Core/Upload/Text/Paste_ee.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Pastebin.cs b/SnapX.Core/Upload/Text/Pastebin.cs
index df5f8b175..38973a515 100644
--- a/SnapX.Core/Upload/Text/Pastebin.cs
+++ b/SnapX.Core/Upload/Text/Pastebin.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Pastebin_ca.cs b/SnapX.Core/Upload/Text/Pastebin_ca.cs
index f0af2c3e8..91ed4a5ce 100644
--- a/SnapX.Core/Upload/Text/Pastebin_ca.cs
+++ b/SnapX.Core/Upload/Text/Pastebin_ca.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Pastie.cs b/SnapX.Core/Upload/Text/Pastie.cs
index b7638dacc..cd06fd7f2 100644
--- a/SnapX.Core/Upload/Text/Pastie.cs
+++ b/SnapX.Core/Upload/Text/Pastie.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Slexy.cs b/SnapX.Core/Upload/Text/Slexy.cs
index 33481740c..a26074dc5 100644
--- a/SnapX.Core/Upload/Text/Slexy.cs
+++ b/SnapX.Core/Upload/Text/Slexy.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Text/Upaste.cs b/SnapX.Core/Upload/Text/Upaste.cs
index 2dcb3e8bb..6199c9110 100644
--- a/SnapX.Core/Upload/Text/Upaste.cs
+++ b/SnapX.Core/Upload/Text/Upaste.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/BitlyURLShortener.cs b/SnapX.Core/Upload/URL/BitlyURLShortener.cs
index e176b4233..b92bf0fa3 100644
--- a/SnapX.Core/Upload/URL/BitlyURLShortener.cs
+++ b/SnapX.Core/Upload/URL/BitlyURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/CustomURLShortener.cs b/SnapX.Core/Upload/URL/CustomURLShortener.cs
index 5e5755cc0..d2a1b1fdf 100644
--- a/SnapX.Core/Upload/URL/CustomURLShortener.cs
+++ b/SnapX.Core/Upload/URL/CustomURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/FirebaseDynamicLinksURLShortener.cs b/SnapX.Core/Upload/URL/FirebaseDynamicLinksURLShortener.cs
index dcacb1eb4..201b107dd 100644
--- a/SnapX.Core/Upload/URL/FirebaseDynamicLinksURLShortener.cs
+++ b/SnapX.Core/Upload/URL/FirebaseDynamicLinksURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/IsgdURLShortener.cs b/SnapX.Core/Upload/URL/IsgdURLShortener.cs
index a76e5a884..f0c3719ac 100644
--- a/SnapX.Core/Upload/URL/IsgdURLShortener.cs
+++ b/SnapX.Core/Upload/URL/IsgdURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/KuttURLShortener.cs b/SnapX.Core/Upload/URL/KuttURLShortener.cs
index 58cb636d8..2a0cbcfc8 100644
--- a/SnapX.Core/Upload/URL/KuttURLShortener.cs
+++ b/SnapX.Core/Upload/URL/KuttURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/NlcmURLShortener.cs b/SnapX.Core/Upload/URL/NlcmURLShortener.cs
index 36e0ef190..94747ebe3 100644
--- a/SnapX.Core/Upload/URL/NlcmURLShortener.cs
+++ b/SnapX.Core/Upload/URL/NlcmURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/PolrURLShortener.cs b/SnapX.Core/Upload/URL/PolrURLShortener.cs
index b83be2f43..1fb928129 100644
--- a/SnapX.Core/Upload/URL/PolrURLShortener.cs
+++ b/SnapX.Core/Upload/URL/PolrURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/QRnetURLShortener.cs b/SnapX.Core/Upload/URL/QRnetURLShortener.cs
index 020c24d9b..4ec537265 100644
--- a/SnapX.Core/Upload/URL/QRnetURLShortener.cs
+++ b/SnapX.Core/Upload/URL/QRnetURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/TinyURLShortener.cs b/SnapX.Core/Upload/URL/TinyURLShortener.cs
index 20338434a..b094e38c8 100644
--- a/SnapX.Core/Upload/URL/TinyURLShortener.cs
+++ b/SnapX.Core/Upload/URL/TinyURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/TurlURLShortener.cs b/SnapX.Core/Upload/URL/TurlURLShortener.cs
index a8c2df575..240b5021f 100644
--- a/SnapX.Core/Upload/URL/TurlURLShortener.cs
+++ b/SnapX.Core/Upload/URL/TurlURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/TwoGPURLShortener.cs b/SnapX.Core/Upload/URL/TwoGPURLShortener.cs
index a971d5b9f..4077e3136 100644
--- a/SnapX.Core/Upload/URL/TwoGPURLShortener.cs
+++ b/SnapX.Core/Upload/URL/TwoGPURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/VURLShortener.cs b/SnapX.Core/Upload/URL/VURLShortener.cs
index 72fee0c7c..c92b2dac3 100644
--- a/SnapX.Core/Upload/URL/VURLShortener.cs
+++ b/SnapX.Core/Upload/URL/VURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/VgdURLShortener.cs b/SnapX.Core/Upload/URL/VgdURLShortener.cs
index 19339f5bf..884d54a77 100644
--- a/SnapX.Core/Upload/URL/VgdURLShortener.cs
+++ b/SnapX.Core/Upload/URL/VgdURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/YourlsURLShortener.cs b/SnapX.Core/Upload/URL/YourlsURLShortener.cs
index 235d74247..d9d0fcb40 100644
--- a/SnapX.Core/Upload/URL/YourlsURLShortener.cs
+++ b/SnapX.Core/Upload/URL/YourlsURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/URL/ZeroWidthURLShortener.cs b/SnapX.Core/Upload/URL/ZeroWidthURLShortener.cs
index e1f04e9a7..887e18aa1 100644
--- a/SnapX.Core/Upload/URL/ZeroWidthURLShortener.cs
+++ b/SnapX.Core/Upload/URL/ZeroWidthURLShortener.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploadInfoManager.cs b/SnapX.Core/Upload/UploadInfoManager.cs
index 7b766caba..0da68edca 100644
--- a/SnapX.Core/Upload/UploadInfoManager.cs
+++ b/SnapX.Core/Upload/UploadInfoManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploadInfoParser.cs b/SnapX.Core/Upload/UploadInfoParser.cs
index 616e489f2..2228cd775 100644
--- a/SnapX.Core/Upload/UploadInfoParser.cs
+++ b/SnapX.Core/Upload/UploadInfoParser.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploadInfoStatus.cs b/SnapX.Core/Upload/UploadInfoStatus.cs
index d4d1c5659..c40227bc8 100644
--- a/SnapX.Core/Upload/UploadInfoStatus.cs
+++ b/SnapX.Core/Upload/UploadInfoStatus.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploadManager.cs b/SnapX.Core/Upload/UploadManager.cs
index 69f10251c..51383d518 100644
--- a/SnapX.Core/Upload/UploadManager.cs
+++ b/SnapX.Core/Upload/UploadManager.cs
@@ -1,11 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Runtime.InteropServices;
using System.Web;
using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.PixelFormats;
+using SnapX.Core.Interfaces;
using SnapX.Core.Job;
using SnapX.Core.Utils;
using SnapX.Core.Utils.Extensions;
@@ -14,11 +13,17 @@
namespace SnapX.Core.Upload;
-public static class UploadManager
+public class UploadManager
{
+ private static IFilePicker _filePicker;
+
+ public UploadManager(IFilePicker filePicker)
+ {
+ _filePicker = filePicker;
+ }
public static void UploadFile(string? filePath, TaskSettings? taskSettings = null)
{
- if (taskSettings == null) taskSettings = TaskSettings.GetDefaultTaskSettings();
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
if (!string.IsNullOrEmpty(filePath))
{
@@ -72,16 +77,25 @@ private static bool IsUploadConfirmed(int length)
public static void UploadFile(TaskSettings? taskSettings = null)
{
taskSettings ??= TaskSettings.GetDefaultTaskSettings();
- var data = new NeedFileOpenerEvent()
- {
- Title = Lang.UploadManagerUploadFile,
- Multiselect = true,
- Directory = IsValidDirectory(SnapX.Settings.FileUploadDefaultDirectory) ? SnapX.Settings.FileUploadDefaultDirectory : UserDirectory.DesktopDir,
- TaskSettings = taskSettings
- };
+ var title = Lang.UploadManagerUploadFile;
+ var initialDir = IsValidDirectory(SnapX.Settings.FileUploadDefaultDirectory)
+ ? SnapX.Settings.FileUploadDefaultDirectory
+ : UserDirectory.DesktopDir;
+
DebugHelper.WriteLine("Need file to upload. Asking UI for file.");
- // The UI will now do the rest.
- SnapX.EventAggregator.Publish(data);
+ var selectedFiles = _filePicker.PickFilesAsync(
+ title,
+ initialDir,
+ allowMultiple: true).GetAwaiter().GetResult();
+
+ if (selectedFiles.Length == 0)
+ {
+ DebugHelper.WriteLine("User cancelled file picker.");
+ return;
+ }
+
+ DebugHelper.WriteLine($"User selected {selectedFiles.Length} file(s) to upload.");
+ UploadFile(selectedFiles);
}
public static bool IsValidDirectory(string? dir)
@@ -89,7 +103,7 @@ public static bool IsValidDirectory(string? dir)
return !string.IsNullOrEmpty(dir) && Directory.Exists(dir);
}
- public static void UploadFolder(TaskSettings taskSettings = null)
+ public static void UploadFolder(TaskSettings? taskSettings = null)
{
// using (FolderSelectDialog folderDialog = new FolderSelectDialog())
// {
@@ -112,7 +126,7 @@ public static void UploadFolder(TaskSettings taskSettings = null)
// }
}
- public static void ProcessImageUpload(Image image, TaskSettings taskSettings)
+ public static void ProcessImageUpload(Image image, TaskSettings? taskSettings)
{
if (image != null)
{
@@ -125,7 +139,7 @@ public static void ProcessImageUpload(Image image, TaskSettings taskSettings)
}
}
- public static void ProcessTextUpload(string? text, TaskSettings taskSettings)
+ public static void ProcessTextUpload(string? text, TaskSettings? taskSettings)
{
if (string.IsNullOrEmpty(text))
return;
@@ -163,7 +177,7 @@ public static void ProcessTextUpload(string? text, TaskSettings taskSettings)
}
}
- public static void ProcessFilesUpload(string?[] files, TaskSettings taskSettings)
+ public static void ProcessFilesUpload(string?[] files, TaskSettings? taskSettings)
{
if (files?.Length > 0)
{
@@ -172,19 +186,15 @@ public static void ProcessFilesUpload(string?[] files, TaskSettings taskSettings
}
- public static void ClipboardUpload(TaskSettings taskSettings = null)
+ public static void ClipboardUpload(TaskSettings? taskSettings = null)
{
- if (taskSettings == null) taskSettings = TaskSettings.GetDefaultTaskSettings();
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
try
{
if (Clipboard.ContainsImage())
{
- Image image;
-
-
- image = Clipboard.GetImage();
-
+ var image = Clipboard.GetImage();
ProcessImageUpload(image, taskSettings);
}
@@ -214,9 +224,9 @@ public static void ClipboardUpload(TaskSettings taskSettings = null)
}
}
- public static void UploadURL(TaskSettings taskSettings = null, string? url = null)
+ public static void UploadURL(TaskSettings? taskSettings = null, string? url = null)
{
- if (taskSettings == null) taskSettings = TaskSettings.GetDefaultTaskSettings();
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
string? inputText = null;
@@ -233,22 +243,22 @@ public static void UploadURL(TaskSettings taskSettings = null, string? url = nul
DownloadAndUploadFile(url, taskSettings);
}
}
- public static void RunImageTask(Image image, TaskSettings taskSettings)
+ public static void RunImageTask(Image image, TaskSettings? taskSettings)
{
var metadata = new TaskMetadata(image);
RunImageTask(metadata, taskSettings);
}
- public static void RunImageTask(Image image, TaskSettings taskSettings, bool skipQuickTaskMenu = false, bool skipAfterCaptureWindow = false)
+ public static void RunImageTask(Image image, TaskSettings? taskSettings, bool skipQuickTaskMenu = false, bool skipAfterCaptureWindow = false)
{
var metadata = new TaskMetadata(image);
RunImageTask(metadata, taskSettings, skipQuickTaskMenu, skipAfterCaptureWindow);
}
- public static void RunImageTask(TaskMetadata metadata, TaskSettings taskSettings, bool skipQuickTaskMenu = false, bool skipAfterCaptureWindow = false)
+ public static void RunImageTask(TaskMetadata metadata, TaskSettings? taskSettings, bool skipQuickTaskMenu = false, bool skipAfterCaptureWindow = false)
{
- if (taskSettings == null) taskSettings = TaskSettings.GetDefaultTaskSettings();
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
- if (metadata != null && metadata.Image != null && taskSettings != null)
+ if (metadata is { Image: not null } && taskSettings != null)
{
if (!skipQuickTaskMenu && taskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.ShowQuickTaskMenu))
{
@@ -264,45 +274,34 @@ public static void RunImageTask(TaskMetadata metadata, TaskSettings taskSettings
}
}
- public static void UploadImage(Image image, TaskSettings taskSettings = null)
+ public static void UploadImage(Image? image, TaskSettings? taskSettings = null)
{
- if (image != null)
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
+ if (image == null) return;
+ if (taskSettings is { IsSafeTaskSettings: true })
{
- if (taskSettings == null)
- {
- taskSettings = TaskSettings.GetDefaultTaskSettings();
- }
-
- if (taskSettings.IsSafeTaskSettings)
- {
- taskSettings.UseDefaultAfterCaptureJob = false;
- taskSettings.AfterCaptureJob = AfterCaptureTasks.UploadImageToHost;
- }
-
- RunImageTask(image, taskSettings);
+ taskSettings.UseDefaultAfterCaptureJob = false;
+ taskSettings.AfterCaptureJob = AfterCaptureTasks.UploadImageToHost;
}
+
+ RunImageTask(image, taskSettings);
}
- public static void UploadImage(Image image, ImageDestination imageDestination, FileDestination imageFileDestination, TaskSettings taskSettings = null)
+ public static void UploadImage(Image? image, ImageDestination imageDestination, FileDestination imageFileDestination, TaskSettings? taskSettings = null)
{
- if (image != null)
- {
- if (taskSettings == null)
- {
- taskSettings = TaskSettings.GetDefaultTaskSettings();
- }
-
- if (taskSettings.IsSafeTaskSettings)
- {
- taskSettings.UseDefaultAfterCaptureJob = false;
- taskSettings.AfterCaptureJob = AfterCaptureTasks.UploadImageToHost;
- taskSettings.UseDefaultDestinations = false;
- taskSettings.ImageDestination = imageDestination;
- taskSettings.ImageFileDestination = imageFileDestination;
- }
+ if (image == null) return;
+ taskSettings ??= TaskSettings.GetDefaultTaskSettings();
- RunImageTask(image, taskSettings);
+ if (taskSettings is { IsSafeTaskSettings: true })
+ {
+ taskSettings.UseDefaultAfterCaptureJob = false;
+ taskSettings.AfterCaptureJob = AfterCaptureTasks.UploadImageToHost;
+ taskSettings.UseDefaultDestinations = false;
+ taskSettings.ImageDestination = imageDestination;
+ taskSettings.ImageFileDestination = imageFileDestination;
}
+
+ RunImageTask(image, taskSettings);
}
public static void UploadText(string? text, TaskSettings? taskSettings = null, bool allowCustomText = false)
{
@@ -312,11 +311,11 @@ public static void UploadText(string? text, TaskSettings? taskSettings = null, b
if (allowCustomText)
{
- string input = taskSettings.AdvancedSettings.TextCustom;
+ var input = taskSettings?.AdvancedSettings.TextCustom;
if (!string.IsNullOrEmpty(input))
{
- if (taskSettings.AdvancedSettings.TextCustomEncodeInput)
+ if (taskSettings is { AdvancedSettings.TextCustomEncodeInput: true })
{
text = HttpUtility.HtmlEncode(text);
}
@@ -329,7 +328,7 @@ public static void UploadText(string? text, TaskSettings? taskSettings = null, b
TaskManager.Start(task);
}
- public static void UploadImageStream(Stream stream, string? fileName, TaskSettings taskSettings = null)
+ public static void UploadImageStream(Stream? stream, string? fileName, TaskSettings? taskSettings = null)
{
taskSettings ??= TaskSettings.GetDefaultTaskSettings();
@@ -341,7 +340,7 @@ public static void UploadImageStream(Stream stream, string? fileName, TaskSettin
}
- public static void ShortenURL(string? url, TaskSettings taskSettings = null)
+ public static void ShortenURL(string? url, TaskSettings? taskSettings = null)
{
if (string.IsNullOrEmpty(url))
return;
@@ -365,7 +364,7 @@ public static void ShortenURL(string? url, UrlShortenerType urlShortener)
}
- public static void ShareURL(string? url, TaskSettings taskSettings = null)
+ public static void ShareURL(string? url, TaskSettings? taskSettings = null)
{
if (string.IsNullOrEmpty(url))
return;
@@ -389,10 +388,10 @@ public static void ShareURL(string? url, URLSharingServices urlSharingService)
TaskManager.Start(task);
}
- public static void DownloadFile(string? url, TaskSettings taskSettings = null)
+ public static void DownloadFile(string? url, TaskSettings? taskSettings = null)
=> DownloadFile(url, false, taskSettings);
- public static void DownloadAndUploadFile(string? url, TaskSettings taskSettings = null)
+ public static void DownloadAndUploadFile(string? url, TaskSettings? taskSettings = null)
=> DownloadFile(url, true, taskSettings);
private static void DownloadFile(string? url, bool upload, TaskSettings? taskSettings = null)
diff --git a/SnapX.Core/Upload/UploadResult.cs b/SnapX.Core/Upload/UploadResult.cs
index 396d1338a..521649e68 100644
--- a/SnapX.Core/Upload/UploadResult.cs
+++ b/SnapX.Core/Upload/UploadResult.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploaderFactory.cs b/SnapX.Core/Upload/UploaderFactory.cs
index bc8d5c36c..5c4e11887 100644
--- a/SnapX.Core/Upload/UploaderFactory.cs
+++ b/SnapX.Core/Upload/UploaderFactory.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploaderFilter.cs b/SnapX.Core/Upload/UploaderFilter.cs
index e20ecbc49..e3df00784 100644
--- a/SnapX.Core/Upload/UploaderFilter.cs
+++ b/SnapX.Core/Upload/UploaderFilter.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploadersConfig.cs b/SnapX.Core/Upload/UploadersConfig.cs
index f5b8ad24d..727fd330f 100644
--- a/SnapX.Core/Upload/UploadersConfig.cs
+++ b/SnapX.Core/Upload/UploadersConfig.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/UploadersConfigValidator.cs b/SnapX.Core/Upload/UploadersConfigValidator.cs
index c43dd5630..5a24b92d7 100644
--- a/SnapX.Core/Upload/UploadersConfigValidator.cs
+++ b/SnapX.Core/Upload/UploadersConfigValidator.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Utils/AccountInfo.cs b/SnapX.Core/Upload/Utils/AccountInfo.cs
index b53a303ef..1ba50a7fb 100644
--- a/SnapX.Core/Upload/Utils/AccountInfo.cs
+++ b/SnapX.Core/Upload/Utils/AccountInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Utils/Argument.cs b/SnapX.Core/Upload/Utils/Argument.cs
index ff7f1b94a..6518e3cf8 100644
--- a/SnapX.Core/Upload/Utils/Argument.cs
+++ b/SnapX.Core/Upload/Utils/Argument.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Utils/EscapeHelper.cs b/SnapX.Core/Upload/Utils/EscapeHelper.cs
index a2492a08c..ac2c450c6 100644
--- a/SnapX.Core/Upload/Utils/EscapeHelper.cs
+++ b/SnapX.Core/Upload/Utils/EscapeHelper.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Utils/ProgressManager.cs b/SnapX.Core/Upload/Utils/ProgressManager.cs
index 2a7f9c0d6..d41f8479c 100644
--- a/SnapX.Core/Upload/Utils/ProgressManager.cs
+++ b/SnapX.Core/Upload/Utils/ProgressManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Upload/Utils/RequestHelpers.cs b/SnapX.Core/Upload/Utils/RequestHelpers.cs
index ed615dd63..6e58caab0 100644
--- a/SnapX.Core/Upload/Utils/RequestHelpers.cs
+++ b/SnapX.Core/Upload/Utils/RequestHelpers.cs
@@ -1,10 +1,10 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Collections.Specialized;
using System.Net;
using System.Text;
+using MimeTypeCore;
using SnapX.Core.Utils.Cryptographic;
namespace SnapX.Core.Upload.Utils;
@@ -139,14 +139,14 @@ public static byte[] MakeInputContent(string boundary, Dictionary())
+ {
+ if (e.GetLocalizedDescription() == (string)value)
+ {
+ return e;
+ }
+ }
+
+ return Enum.Parse(enumType, (string)value);
+ }
+}
diff --git a/SnapX.Core/Utils/Converters/EnumProperNameConverter.cs b/SnapX.Core/Utils/Converters/EnumProperNameConverter.cs
new file mode 100644
index 000000000..513d2219c
--- /dev/null
+++ b/SnapX.Core/Utils/Converters/EnumProperNameConverter.cs
@@ -0,0 +1,38 @@
+using System.ComponentModel;
+using System.Globalization;
+
+namespace SnapX.Core.Utils.Converters;
+
+public class EnumProperNameConverter(Type Type) : EnumConverter(Type)
+{
+ private readonly Type enumType = Type;
+
+ public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destType)
+ {
+ return destType == typeof(string);
+ }
+
+ public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destType)
+ {
+ ArgumentNullException.ThrowIfNull(value);
+ return Helpers.GetProperName(value.ToString()!);
+ }
+
+ public override bool CanConvertFrom(ITypeDescriptorContext? context, Type srcType)
+ {
+ return srcType == typeof(string);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
+ {
+ foreach (Enum e in Enum.GetValues(enumType).OfType())
+ {
+ if (Helpers.GetProperName(e.ToString()) == (string)value)
+ {
+ return e;
+ }
+ }
+
+ return Enum.Parse(enumType, (string)value);
+ }
+}
diff --git a/SnapX.Core/Utils/Converters/EnumProperNameKeepCaseConverter.cs b/SnapX.Core/Utils/Converters/EnumProperNameKeepCaseConverter.cs
new file mode 100644
index 000000000..c2e9b737c
--- /dev/null
+++ b/SnapX.Core/Utils/Converters/EnumProperNameKeepCaseConverter.cs
@@ -0,0 +1,39 @@
+using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+
+namespace SnapX.Core.Utils.Converters;
+
+public class EnumProperNameKeepCaseConverter(Type Type) : EnumConverter(Type)
+{
+ private Type enumType = Type;
+
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
+ {
+ return destType == typeof(string);
+ }
+
+ public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destType)
+ {
+ return Helpers.GetProperName(value.ToString(), true);
+ }
+
+ public override bool CanConvertFrom(ITypeDescriptorContext? context, Type srcType)
+ {
+ return srcType == typeof(string);
+ }
+
+ [RequiresUnreferencedCode("Uses Enum.GetValues")]
+ public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
+ {
+ foreach (Enum e in Enum.GetValues(enumType).OfType())
+ {
+ if (Helpers.GetProperName(e.ToString(), true) == (string)value)
+ {
+ return e;
+ }
+ }
+
+ return Enum.Parse(enumType, (string)value);
+ }
+}
diff --git a/SnapX.Core/Utils/Converters/MyColorConverter.cs b/SnapX.Core/Utils/Converters/MyColorConverter.cs
new file mode 100644
index 000000000..01702e878
--- /dev/null
+++ b/SnapX.Core/Utils/Converters/MyColorConverter.cs
@@ -0,0 +1,42 @@
+using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
+using SixLabors.ImageSharp;
+
+namespace SnapX.Core.Utils.Converters;
+
+public class MyColorConverter : TypeConverter
+{
+ public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
+ {
+ return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value)
+ {
+ if (value is string colorStr)
+ {
+ // Try to parse named color first (e.g. "Red")
+ var knownColor = TryParseKnownColor(colorStr);
+ if (knownColor is not null)
+ {
+ return knownColor.Value;
+ }
+
+ // Try parse hex value (#RRGGBB or #AARRGGBB)
+ return colorStr.StartsWith("#") ? Color.ParseHex(colorStr) : throw new FormatException($"Cannot convert '{colorStr}' to ImageSharp Color.");
+ }
+
+ return base.ConvertFrom(context, culture, value) ?? throw new FormatException($"Cannot convert '{value}' to ImageSharp Color.");
+ }
+ [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")]
+ [RequiresUnreferencedCode("Checks SixLabors predefined colors")]
+ private Color? TryParseKnownColor(string name)
+ {
+ var colorProperty = typeof(Color).GetProperty(name, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
+ if (colorProperty is not null && colorProperty.PropertyType == typeof(Color))
+ {
+ return (Color)colorProperty.GetValue(null)!;
+ }
+ return null;
+ }
+}
diff --git a/SnapX.Core/Utils/Converters/StringCollectionToStringTypeConverter.cs b/SnapX.Core/Utils/Converters/StringCollectionToStringTypeConverter.cs
new file mode 100644
index 000000000..102f1b7dc
--- /dev/null
+++ b/SnapX.Core/Utils/Converters/StringCollectionToStringTypeConverter.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel;
+using System.Globalization;
+
+namespace SnapX.Core.Utils.UITypeEditors;
+
+public class StringCollectionToStringTypeConverter : TypeConverter
+{
+ public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
+ {
+ ArgumentNullException.ThrowIfNull(value);
+ if (destinationType != typeof(string)) return base.ConvertTo(context, culture, value, destinationType) ?? throw new FormatException($"Cannot convert '{value}' to ImageSharp Color.");
+ var list = (List)value;
+ return string.Join(", ", list);
+
+ }
+}
diff --git a/SnapX.Core/Utils/Cryptographic/HashChecker.cs b/SnapX.Core/Utils/Cryptographic/HashChecker.cs
index 2120252ce..2eeb56ca6 100644
--- a/SnapX.Core/Utils/Cryptographic/HashChecker.cs
+++ b/SnapX.Core/Utils/Cryptographic/HashChecker.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Cryptographic/Translator.cs b/SnapX.Core/Utils/Cryptographic/Translator.cs
index a5a56dab9..31251d0bc 100644
--- a/SnapX.Core/Utils/Cryptographic/Translator.cs
+++ b/SnapX.Core/Utils/Cryptographic/Translator.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Cryptographic/TranslatorHelper.cs b/SnapX.Core/Utils/Cryptographic/TranslatorHelper.cs
index ee7e3736a..633854a00 100644
--- a/SnapX.Core/Utils/Cryptographic/TranslatorHelper.cs
+++ b/SnapX.Core/Utils/Cryptographic/TranslatorHelper.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/DNS/AdapterInfo.cs b/SnapX.Core/Utils/DNS/AdapterInfo.cs
index 96b9eff31..54440f6ac 100644
--- a/SnapX.Core/Utils/DNS/AdapterInfo.cs
+++ b/SnapX.Core/Utils/DNS/AdapterInfo.cs
@@ -1,19 +1,11 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Net.NetworkInformation;
namespace SnapX.Core.Utils.DNS;
-public class AdapterInfo : IDisposable
+public class AdapterInfo(NetworkInterface Adapter) : IDisposable
{
- private NetworkInterface adapter;
-
- public AdapterInfo(NetworkInterface adapter)
- {
- this.adapter = adapter;
- }
-
public static List GetEnabledAdapters()
{
var adapters = new List();
@@ -28,21 +20,21 @@ public static List GetEnabledAdapters()
return adapters;
}
- public bool IsEnabled() => adapter.OperationalStatus == OperationalStatus.Up;
+ public bool IsEnabled() => Adapter.OperationalStatus == OperationalStatus.Up;
- public string? GetCaption() => adapter.ToString();
+ public string? GetCaption() => Adapter.ToString();
- public string GetDescription() => adapter.Description;
+ public string GetDescription() => Adapter.Description;
- public string[] GetDNS() => adapter.GetIPProperties().UnicastAddresses.ToList().Select(x => x.Address.ToString()).ToArray();
+ public string[] GetDNS() => Adapter.GetIPProperties().UnicastAddresses.ToList().Select(x => x.Address.ToString()).ToArray();
// TODO: SetDNS needs to be implemented on a per platform basis
- public uint SetDNS(string primary, string secondary) => throw new NotImplementedException("SetDNS is not implemented.");
+ public uint SetDNS(string primary, string? secondary) => throw new NotImplementedException("SetDNS is not implemented.");
public uint SetDNSAutomatic()
{
return SetDNS(null, null);
}
- public void Dispose() => Console.WriteLine($"Disposed adapter {adapter.Description}");
+ public void Dispose() => Console.WriteLine($"Disposed adapter {Adapter.Description}");
public override string ToString() => GetDescription();
}
diff --git a/SnapX.Core/Utils/DNS/DNSInfo.cs b/SnapX.Core/Utils/DNS/DNSInfo.cs
index 02c12c0b0..18678003d 100644
--- a/SnapX.Core/Utils/DNS/DNSInfo.cs
+++ b/SnapX.Core/Utils/DNS/DNSInfo.cs
@@ -1,21 +1,13 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
namespace SnapX.Core.Utils.DNS;
-public class DNSInfo
+public class DNSInfo(string Name, string PrimaryDns, string SecondaryDns)
{
- public string Name { get; set; }
- public string PrimaryDNS { get; set; }
- public string SecondaryDNS { get; set; }
-
- public DNSInfo(string name, string primaryDNS, string secondaryDNS)
- {
- Name = name;
- PrimaryDNS = primaryDNS;
- SecondaryDNS = secondaryDNS;
- }
+ public string Name { get; set; } = Name;
+ public string PrimaryDNS { get; set; } = PrimaryDns;
+ public string SecondaryDNS { get; set; } = SecondaryDns;
public override string ToString()
{
diff --git a/SnapX.Core/Utils/Extensions/EnumExtensions.cs b/SnapX.Core/Utils/Extensions/EnumExtensions.cs
index a37b52e38..7b4a400ef 100644
--- a/SnapX.Core/Utils/Extensions/EnumExtensions.cs
+++ b/SnapX.Core/Utils/Extensions/EnumExtensions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Extensions/Extensions.cs b/SnapX.Core/Utils/Extensions/Extensions.cs
index ebefe6a73..dcad94d00 100644
--- a/SnapX.Core/Utils/Extensions/Extensions.cs
+++ b/SnapX.Core/Utils/Extensions/Extensions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -6,6 +5,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.PixelFormats;
namespace SnapX.Core.Utils.Extensions;
@@ -229,7 +229,10 @@ public static List Range(this List source, T start, T end)
return Range(source, startIndex, endIndex);
}
- public static bool IsTransparent(this Color color) => color.IsTransparent();
+ public static bool IsTransparent(this Color color)
+ {
+ return color.ToPixel().A < 255;
+ }
public static string ToStringProper(this Rectangle rect) =>
$"X: {rect.X}, Y: {rect.Y}, Width: {rect.Width}, Height: {rect.Height}";
}
diff --git a/SnapX.Core/Utils/Extensions/NumberExtensions.cs b/SnapX.Core/Utils/Extensions/NumberExtensions.cs
index 24e0af8d5..93926734b 100644
--- a/SnapX.Core/Utils/Extensions/NumberExtensions.cs
+++ b/SnapX.Core/Utils/Extensions/NumberExtensions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Extensions/ObjectExtensions.cs b/SnapX.Core/Utils/Extensions/ObjectExtensions.cs
index c7e1aea7e..ac87012fc 100644
--- a/SnapX.Core/Utils/Extensions/ObjectExtensions.cs
+++ b/SnapX.Core/Utils/Extensions/ObjectExtensions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Extensions/StreamExtensions.cs b/SnapX.Core/Utils/Extensions/StreamExtensions.cs
index deb8e431e..7dfec72c2 100644
--- a/SnapX.Core/Utils/Extensions/StreamExtensions.cs
+++ b/SnapX.Core/Utils/Extensions/StreamExtensions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Extensions/StringExtensions.cs b/SnapX.Core/Utils/Extensions/StringExtensions.cs
index 4b48df2e7..46e598f0c 100644
--- a/SnapX.Core/Utils/Extensions/StringExtensions.cs
+++ b/SnapX.Core/Utils/Extensions/StringExtensions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Extensions/XMLExtensions.cs b/SnapX.Core/Utils/Extensions/XMLExtensions.cs
index 7696ce3bc..05ed2a26b 100644
--- a/SnapX.Core/Utils/Extensions/XMLExtensions.cs
+++ b/SnapX.Core/Utils/Extensions/XMLExtensions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/FileDownloader.cs b/SnapX.Core/Utils/FileDownloader.cs
index 45d6160dd..fcbcde35a 100644
--- a/SnapX.Core/Utils/FileDownloader.cs
+++ b/SnapX.Core/Utils/FileDownloader.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/FileHelpers.cs b/SnapX.Core/Utils/FileHelpers.cs
index 0724c839a..cdc14fefa 100644
--- a/SnapX.Core/Utils/FileHelpers.cs
+++ b/SnapX.Core/Utils/FileHelpers.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Helpers.cs b/SnapX.Core/Utils/Helpers.cs
index 910b181e3..cfde37c9c 100644
--- a/SnapX.Core/Utils/Helpers.cs
+++ b/SnapX.Core/Utils/Helpers.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/ImageHelpers.cs b/SnapX.Core/Utils/ImageHelpers.cs
index 326f3f65a..552367f66 100644
--- a/SnapX.Core/Utils/ImageHelpers.cs
+++ b/SnapX.Core/Utils/ImageHelpers.cs
@@ -27,29 +27,22 @@ internal static Image ImageDataToImage(uniffi.snapxrust.ImageData imageData) =>
Image.LoadPixelData(imageData.image, (int)imageData.width, (int)imageData.height);
public static Size ApplyAspectRatio(int width, int height, Image img)
{
- // Get the original aspect ratio of the image
- float aspectRatio = (float)img.Width / img.Height;
+ var aspectRatio = (float)img.Width / img.Height;
- // Determine the target aspect ratio (width to height ratio)
- float targetAspectRatio = (float)width / height;
+ var targetAspectRatio = (float)width / height;
- // Variables to hold the new width and height
- int newWidth = width;
- int newHeight = height;
+ var newWidth = width;
+ var newHeight = height;
- // Adjust the size based on the aspect ratio comparison
if (aspectRatio > targetAspectRatio)
{
- // The image is wider than the target aspect ratio, so adjust based on width
- newHeight = (int)(width / aspectRatio); // Calculate new height to maintain aspect ratio
+ newHeight = (int)(width / aspectRatio);
}
else if (aspectRatio < targetAspectRatio)
{
- // The image is taller than the target aspect ratio, so adjust based on height
- newWidth = (int)(height * aspectRatio); // Calculate new width to maintain aspect ratio
+ newWidth = (int)(height * aspectRatio);
}
- // Return the new size that maintains the aspect ratio
return new Size(newWidth, newHeight);
}
// See how clean the code is?!
@@ -57,7 +50,7 @@ public static Size ApplyAspectRatio(int width, int height, Image img)
// BLESSED.
public static Image ResizeImage(Image img, Size TargetSize, bool preserveAspectRatio = false, bool fill = false, Color? growFillColor = null)
{
- if (growFillColor == null) growFillColor = Color.Transparent;
+ growFillColor ??= Color.Transparent;
// Mutate the image to apply resizing and fill (if necessary)
img.Mutate(ctx =>
{
@@ -431,7 +424,24 @@ public static Image DrawReflection(
return finalImage;
}
-
+ ///
+ /// Fills the image with a checkerboard pattern.
+ ///
+ public static void DrawCheckerPattern(Image image, int cellSize, Color[] colors)
+ {
+ image.Mutate(ctx =>
+ {
+ for (var y = 0; y < image.Height; y += cellSize)
+ {
+ for (var x = 0; x < image.Width; x += cellSize)
+ {
+ var isEven = ((x / cellSize) + (y / cellSize)) % 2 == 0;
+ var color = isEven ? colors[0] : colors[1];
+ ctx.Fill(color, new RectangleF(x, y, cellSize, cellSize));
+ }
+ }
+ });
+ }
private static float[] CreateAlphaGradient(int height, float maxAlpha, float minAlpha)
{
float[] gradient = new float[height];
@@ -618,14 +628,10 @@ public static Color GetMostCommonColor(Rgba32[] pixelRow)
foreach (var pixel in pixelRow)
{
var color = new Rgba32(pixel.R, pixel.G, pixel.B);
- if (colorCounts.ContainsKey(color))
+ if (!colorCounts.TryAdd(color, 1))
{
colorCounts[color]++;
}
- else
- {
- colorCounts[color] = 1;
- }
}
// Find the color with the maximum count
diff --git a/SnapX.Core/Utils/JsonHelpers.cs b/SnapX.Core/Utils/JsonHelpers.cs
index fd8db2c05..cd1977925 100644
--- a/SnapX.Core/Utils/JsonHelpers.cs
+++ b/SnapX.Core/Utils/JsonHelpers.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/MathHelpers.cs b/SnapX.Core/Utils/MathHelpers.cs
index f16449545..568b7b834 100644
--- a/SnapX.Core/Utils/MathHelpers.cs
+++ b/SnapX.Core/Utils/MathHelpers.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/ExternalProgram.cs b/SnapX.Core/Utils/Miscellaneous/ExternalProgram.cs
index a81b4da67..22335c7da 100644
--- a/SnapX.Core/Utils/Miscellaneous/ExternalProgram.cs
+++ b/SnapX.Core/Utils/Miscellaneous/ExternalProgram.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/FPSManager.cs b/SnapX.Core/Utils/Miscellaneous/FPSManager.cs
index ca918300d..101be9d61 100644
--- a/SnapX.Core/Utils/Miscellaneous/FPSManager.cs
+++ b/SnapX.Core/Utils/Miscellaneous/FPSManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -6,30 +5,19 @@
namespace SnapX.Core.Utils.Miscellaneous;
-public class FPSManager
+public class FPSManager(int FPSLimit)
{
public event Action FPSUpdated;
public int FPS { get; private set; }
- public int FPSLimit { get; set; }
private int frameCount;
- private Stopwatch fpsTimer, frameTimer;
-
- public FPSManager()
- {
- fpsTimer = new Stopwatch();
- frameTimer = new Stopwatch();
- }
+ private readonly Stopwatch fpsTimer = new();
+ private readonly Stopwatch frameTimer = new();
- public FPSManager(int fpsLimit) : this()
+ private void OnFPSUpdated()
{
- FPSLimit = fpsLimit;
- }
-
- protected void OnFPSUpdated()
- {
- FPSUpdated?.Invoke();
+ FPSUpdated.Invoke();
}
public void Update()
@@ -39,7 +27,7 @@ public void Update()
if (!fpsTimer.IsRunning) fpsTimer.Start();
else if (fpsTimer.ElapsedMilliseconds >= 1000)
{
- FPS = (int)System.Math.Round(frameCount / fpsTimer.Elapsed.TotalSeconds);
+ FPS = (int)Math.Round(frameCount / fpsTimer.Elapsed.TotalSeconds);
OnFPSUpdated();
@@ -47,29 +35,27 @@ public void Update()
fpsTimer.Restart();
}
- if (FPSLimit > 0)
+ if (FPSLimit <= 0) return;
+ if (!frameTimer.IsRunning)
{
- if (!frameTimer.IsRunning)
- {
- frameTimer.Start();
- }
- else
+ frameTimer.Start();
+ }
+ else
+ {
+ var currentFrameDuration = frameTimer.Elapsed.TotalMilliseconds;
+ var targetFrameDuration = 1000d / FPSLimit;
+
+ if (currentFrameDuration < targetFrameDuration)
{
- double currentFrameDuration = frameTimer.Elapsed.TotalMilliseconds;
- double targetFrameDuration = 1000d / FPSLimit;
+ var sleepDuration = (int)Math.Round(targetFrameDuration - currentFrameDuration);
- if (currentFrameDuration < targetFrameDuration)
+ if (sleepDuration > 0)
{
- int sleepDuration = (int)System.Math.Round(targetFrameDuration - currentFrameDuration);
-
- if (sleepDuration > 0)
- {
- Thread.Sleep(sleepDuration);
- }
+ Thread.Sleep(sleepDuration);
}
-
- frameTimer.Restart();
}
+
+ frameTimer.Restart();
}
}
}
diff --git a/SnapX.Core/Utils/Miscellaneous/FastDateTime.cs b/SnapX.Core/Utils/Miscellaneous/FastDateTime.cs
deleted file mode 100644
index 00af5b7a5..000000000
--- a/SnapX.Core/Utils/Miscellaneous/FastDateTime.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-
-namespace SnapX.Core.Utils.Miscellaneous;
-
-public static class FastDateTime
-{
- public static TimeSpan LocalUtcOffset { get; private set; }
-
- public static DateTime Now
- {
- get
- {
- return ToLocalTime(DateTime.UtcNow);
- }
- }
-
- public static long NowUnix
- {
- get
- {
- return (DateTime.UtcNow.Ticks - 621355968000000000) / 10000000;
- }
- }
-
- static FastDateTime()
- {
- LocalUtcOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
- }
-
- public static DateTime ToLocalTime(DateTime dateTime)
- {
- return dateTime + LocalUtcOffset;
- }
-}
-
diff --git a/SnapX.Core/Utils/Miscellaneous/FixedSizedQueue.cs b/SnapX.Core/Utils/Miscellaneous/FixedSizedQueue.cs
index da68b7343..6a9b4565a 100644
--- a/SnapX.Core/Utils/Miscellaneous/FixedSizedQueue.cs
+++ b/SnapX.Core/Utils/Miscellaneous/FixedSizedQueue.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/HelpersOptions.cs b/SnapX.Core/Utils/Miscellaneous/HelpersOptions.cs
index 3aad0be08..378abe078 100644
--- a/SnapX.Core/Utils/Miscellaneous/HelpersOptions.cs
+++ b/SnapX.Core/Utils/Miscellaneous/HelpersOptions.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/HttpClientFactory.cs b/SnapX.Core/Utils/Miscellaneous/HttpClientFactory.cs
index 188fece7e..3336fb985 100644
--- a/SnapX.Core/Utils/Miscellaneous/HttpClientFactory.cs
+++ b/SnapX.Core/Utils/Miscellaneous/HttpClientFactory.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/Links.cs b/SnapX.Core/Utils/Miscellaneous/Links.cs
index e14a30a9e..ad6e2dbb9 100644
--- a/SnapX.Core/Utils/Miscellaneous/Links.cs
+++ b/SnapX.Core/Utils/Miscellaneous/Links.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/MaxLengthStream.cs b/SnapX.Core/Utils/Miscellaneous/MaxLengthStream.cs
index 57c6a832a..169a631f8 100644
--- a/SnapX.Core/Utils/Miscellaneous/MaxLengthStream.cs
+++ b/SnapX.Core/Utils/Miscellaneous/MaxLengthStream.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/MimeTypesPlus.cs b/SnapX.Core/Utils/Miscellaneous/MimeTypesPlus.cs
deleted file mode 100644
index b3ec28e08..000000000
--- a/SnapX.Core/Utils/Miscellaneous/MimeTypesPlus.cs
+++ /dev/null
@@ -1,1008 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-namespace SnapX.Core.Utils.Miscellaneous;
-
-public static class MimeTypesPlus
-{
- public static bool IsImageMimeType(string mimeType)
- {
- return !string.IsNullOrEmpty(mimeType) &&
- (mimeType.Equals(Mappings["png"], StringComparison.OrdinalIgnoreCase) ||
- mimeType.Equals(Mappings["apng"], StringComparison.OrdinalIgnoreCase) ||
- mimeType.Equals(Mappings["jpeg"], StringComparison.OrdinalIgnoreCase) ||
- mimeType.Equals(Mappings["gif"], StringComparison.OrdinalIgnoreCase) ||
- mimeType.Equals(Mappings["bmp"], StringComparison.OrdinalIgnoreCase) ||
- mimeType.Equals(Mappings["webp"], StringComparison.OrdinalIgnoreCase) ||
- mimeType.Equals(Mappings["tiff"], StringComparison.OrdinalIgnoreCase));
- }
-
- // http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
- private static Dictionary Mappings = new(StringComparer.OrdinalIgnoreCase)
- {
- { "123", "application/vnd.lotus-1-2-3" },
- { "3dml", "text/vnd.in3d.3dml" },
- { "3ds", "image/x-3ds" },
- { "3g2", "video/3gpp2" },
- { "3gp", "video/3gpp" },
- { "7z", "application/x-7z-compressed" },
- { "aab", "application/x-authorware-bin" },
- { "aac", "audio/x-aac" },
- { "aam", "application/x-authorware-map" },
- { "aas", "application/x-authorware-seg" },
- { "abw", "application/x-abiword" },
- { "ac", "application/pkix-attr-cert" },
- { "acc", "application/vnd.americandynamics.acc" },
- { "ace", "application/x-ace-compressed" },
- { "acu", "application/vnd.acucobol" },
- { "acutc", "application/vnd.acucorp" },
- { "adp", "audio/adpcm" },
- { "aep", "application/vnd.audiograph" },
- { "afm", "application/x-font-type1" },
- { "afp", "application/vnd.ibm.modcap" },
- { "ahead", "application/vnd.ahead.space" },
- { "ai", "application/postscript" },
- { "aif", "audio/x-aiff" },
- { "aifc", "audio/x-aiff" },
- { "aiff", "audio/x-aiff" },
- { "air", "application/vnd.adobe.air-application-installer-package+zip" },
- { "ait", "application/vnd.dvb.ait" },
- { "ami", "application/vnd.amiga.ami" },
- { "apk", "application/vnd.android.package-archive" },
- { "apng", "image/apng" },
- { "appcache", "text/cache-manifest" },
- { "application", "application/x-ms-application" },
- { "apr", "application/vnd.lotus-approach" },
- { "arc", "application/x-freearc" },
- { "asc", "application/pgp-signature" },
- { "asf", "video/x-ms-asf" },
- { "asm", "text/x-asm" },
- { "aso", "application/vnd.accpac.simply.aso" },
- { "asx", "video/x-ms-asf" },
- { "atc", "application/vnd.acucorp" },
- { "atom", "application/atom+xml" },
- { "atomcat", "application/atomcat+xml" },
- { "atomsvc", "application/atomsvc+xml" },
- { "atx", "application/vnd.antix.game-component" },
- { "au", "audio/basic" },
- { "avi", "video/x-msvideo" },
- { "aw", "application/applixware" },
- { "azf", "application/vnd.airzip.filesecure.azf" },
- { "azs", "application/vnd.airzip.filesecure.azs" },
- { "azw", "application/vnd.amazon.ebook" },
- { "bat", "application/x-msdownload" },
- { "bcpio", "application/x-bcpio" },
- { "bdf", "application/x-font-bdf" },
- { "bdm", "application/vnd.syncml.dm+wbxml" },
- { "bed", "application/vnd.realvnc.bed" },
- { "bh2", "application/vnd.fujitsu.oasysprs" },
- { "bin", "application/octet-stream" },
- { "blb", "application/x-blorb" },
- { "blorb", "application/x-blorb" },
- { "bmi", "application/vnd.bmi" },
- { "bmp", "image/bmp" },
- { "book", "application/vnd.framemaker" },
- { "box", "application/vnd.previewsystems.box" },
- { "boz", "application/x-bzip2" },
- { "bpk", "application/octet-stream" },
- { "btif", "image/prs.btif" },
- { "bz", "application/x-bzip" },
- { "bz2", "application/x-bzip2" },
- { "c", "text/x-c" },
- { "c11amc", "application/vnd.cluetrust.cartomobile-config" },
- { "c11amz", "application/vnd.cluetrust.cartomobile-config-pkg" },
- { "c4d", "application/vnd.clonk.c4group" },
- { "c4f", "application/vnd.clonk.c4group" },
- { "c4g", "application/vnd.clonk.c4group" },
- { "c4p", "application/vnd.clonk.c4group" },
- { "c4u", "application/vnd.clonk.c4group" },
- { "cab", "application/vnd.ms-cab-compressed" },
- { "caf", "audio/x-caf" },
- { "cap", "application/vnd.tcpdump.pcap" },
- { "car", "application/vnd.curl.car" },
- { "cat", "application/vnd.ms-pki.seccat" },
- { "cb7", "application/x-cbr" },
- { "cba", "application/x-cbr" },
- { "cbr", "application/x-cbr" },
- { "cbt", "application/x-cbr" },
- { "cbz", "application/x-cbr" },
- { "cc", "text/x-c" },
- { "cct", "application/x-director" },
- { "ccxml", "application/ccxml+xml" },
- { "cdbcmsg", "application/vnd.contact.cmsg" },
- { "cdf", "application/x-netcdf" },
- { "cdkey", "application/vnd.mediastation.cdkey" },
- { "cdmia", "application/cdmi-capability" },
- { "cdmic", "application/cdmi-container" },
- { "cdmid", "application/cdmi-domain" },
- { "cdmio", "application/cdmi-object" },
- { "cdmiq", "application/cdmi-queue" },
- { "cdx", "chemical/x-cdx" },
- { "cdxml", "application/vnd.chemdraw+xml" },
- { "cdy", "application/vnd.cinderella" },
- { "cer", "application/pkix-cert" },
- { "cfs", "application/x-cfs-compressed" },
- { "cgm", "image/cgm" },
- { "chat", "application/x-chat" },
- { "chm", "application/vnd.ms-htmlhelp" },
- { "chrt", "application/vnd.kde.kchart" },
- { "cif", "chemical/x-cif" },
- { "cii", "application/vnd.anser-web-certificate-issue-initiation" },
- { "cil", "application/vnd.ms-artgalry" },
- { "cla", "application/vnd.claymore" },
- { "class", "application/java-vm" },
- { "clkk", "application/vnd.crick.clicker.keyboard" },
- { "clkp", "application/vnd.crick.clicker.palette" },
- { "clkt", "application/vnd.crick.clicker.template" },
- { "clkw", "application/vnd.crick.clicker.wordbank" },
- { "clkx", "application/vnd.crick.clicker" },
- { "clp", "application/x-msclip" },
- { "cmc", "application/vnd.cosmocaller" },
- { "cmdf", "chemical/x-cmdf" },
- { "cml", "chemical/x-cml" },
- { "cmp", "application/vnd.yellowriver-custom-menu" },
- { "cmx", "image/x-cmx" },
- { "cod", "application/vnd.rim.cod" },
- { "com", "application/x-msdownload" },
- { "conf", "text/plain" },
- { "cpio", "application/x-cpio" },
- { "cpp", "text/x-c" },
- { "cpt", "application/mac-compactpro" },
- { "crd", "application/x-mscardfile" },
- { "crl", "application/pkix-crl" },
- { "crt", "application/x-x509-ca-cert" },
- { "cryptonote", "application/vnd.rig.cryptonote" },
- { "csh", "application/x-csh" },
- { "csml", "chemical/x-csml" },
- { "csp", "application/vnd.commonspace" },
- { "css", "text/css" },
- { "cst", "application/x-director" },
- { "csv", "text/csv" },
- { "cu", "application/cu-seeme" },
- { "curl", "text/vnd.curl" },
- { "cww", "application/prs.cww" },
- { "cxt", "application/x-director" },
- { "cxx", "text/x-c" },
- { "dae", "model/vnd.collada+xml" },
- { "daf", "application/vnd.mobius.daf" },
- { "dart", "application/vnd.dart" },
- { "dataless", "application/vnd.fdsn.seed" },
- { "davmount", "application/davmount+xml" },
- { "dbk", "application/docbook+xml" },
- { "dcr", "application/x-director" },
- { "dcurl", "text/vnd.curl.dcurl" },
- { "dd2", "application/vnd.oma.dd2+xml" },
- { "ddd", "application/vnd.fujixerox.ddd" },
- { "deb", "application/x-debian-package" },
- { "def", "text/plain" },
- { "deploy", "application/octet-stream" },
- { "der", "application/x-x509-ca-cert" },
- { "dfac", "application/vnd.dreamfactory" },
- { "dgc", "application/x-dgc-compressed" },
- { "dic", "text/x-c" },
- { "dir", "application/x-director" },
- { "dis", "application/vnd.mobius.dis" },
- { "dist", "application/octet-stream" },
- { "distz", "application/octet-stream" },
- { "djv", "image/vnd.djvu" },
- { "djvu", "image/vnd.djvu" },
- { "dll", "application/x-msdownload" },
- { "dmg", "application/x-apple-diskimage" },
- { "dmp", "application/vnd.tcpdump.pcap" },
- { "dms", "application/octet-stream" },
- { "dna", "application/vnd.dna" },
- { "doc", "application/msword" },
- { "docm", "application/vnd.ms-word.document.macroenabled.12" },
- { "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
- { "dot", "application/msword" },
- { "dotm", "application/vnd.ms-word.template.macroenabled.12" },
- { "dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template" },
- { "dp", "application/vnd.osgi.dp" },
- { "dpg", "application/vnd.dpgraph" },
- { "dra", "audio/vnd.dra" },
- { "dsc", "text/prs.lines.tag" },
- { "dssc", "application/dssc+der" },
- { "dtb", "application/x-dtbook+xml" },
- { "dtd", "application/xml-dtd" },
- { "dts", "audio/vnd.dts" },
- { "dtshd", "audio/vnd.dts.hd" },
- { "dump", "application/octet-stream" },
- { "dvb", "video/vnd.dvb.file" },
- { "dvi", "application/x-dvi" },
- { "dwf", "model/vnd.dwf" },
- { "dwg", "image/vnd.dwg" },
- { "dxf", "image/vnd.dxf" },
- { "dxp", "application/vnd.spotfire.dxp" },
- { "dxr", "application/x-director" },
- { "ecelp4800", "audio/vnd.nuera.ecelp4800" },
- { "ecelp7470", "audio/vnd.nuera.ecelp7470" },
- { "ecelp9600", "audio/vnd.nuera.ecelp9600" },
- { "ecma", "application/ecmascript" },
- { "edm", "application/vnd.novadigm.edm" },
- { "edx", "application/vnd.novadigm.edx" },
- { "efif", "application/vnd.picsel" },
- { "ei6", "application/vnd.pg.osasli" },
- { "elc", "application/octet-stream" },
- { "emf", "application/x-msmetafile" },
- { "eml", "message/rfc822" },
- { "emma", "application/emma+xml" },
- { "emz", "application/x-msmetafile" },
- { "eol", "audio/vnd.digital-winds" },
- { "eot", "application/vnd.ms-fontobject" },
- { "eps", "application/postscript" },
- { "epub", "application/epub+zip" },
- { "es3", "application/vnd.eszigno3+xml" },
- { "esa", "application/vnd.osgi.subsystem" },
- { "esf", "application/vnd.epson.esf" },
- { "et3", "application/vnd.eszigno3+xml" },
- { "etx", "text/x-setext" },
- { "eva", "application/x-eva" },
- { "evy", "application/x-envoy" },
- { "exe", "application/x-msdownload" },
- { "exi", "application/exi" },
- { "ext", "application/vnd.novadigm.ext" },
- { "ez", "application/andrew-inset" },
- { "ez2", "application/vnd.ezpix-album" },
- { "ez3", "application/vnd.ezpix-package" },
- { "f", "text/x-fortran" },
- { "f4v", "video/x-f4v" },
- { "f77", "text/x-fortran" },
- { "f90", "text/x-fortran" },
- { "fbs", "image/vnd.fastbidsheet" },
- { "fcdt", "application/vnd.adobe.formscentral.fcdt" },
- { "fcs", "application/vnd.isac.fcs" },
- { "fdf", "application/vnd.fdf" },
- { "fe_launch", "application/vnd.denovo.fcselayout-link" },
- { "fg5", "application/vnd.fujitsu.oasysgp" },
- { "fgd", "application/x-director" },
- { "fh", "image/x-freehand" },
- { "fh4", "image/x-freehand" },
- { "fh5", "image/x-freehand" },
- { "fh7", "image/x-freehand" },
- { "fhc", "image/x-freehand" },
- { "fig", "application/x-xfig" },
- { "flac", "audio/x-flac" },
- { "fli", "video/x-fli" },
- { "flo", "application/vnd.micrografx.flo" },
- { "flv", "video/x-flv" },
- { "flw", "application/vnd.kde.kivio" },
- { "flx", "text/vnd.fmi.flexstor" },
- { "fly", "text/vnd.fly" },
- { "fm", "application/vnd.framemaker" },
- { "fnc", "application/vnd.frogans.fnc" },
- { "for", "text/x-fortran" },
- { "fpx", "image/vnd.fpx" },
- { "frame", "application/vnd.framemaker" },
- { "fsc", "application/vnd.fsc.weblaunch" },
- { "fst", "image/vnd.fst" },
- { "ftc", "application/vnd.fluxtime.clip" },
- { "fti", "application/vnd.anser-web-funds-transfer-initiation" },
- { "fvt", "video/vnd.fvt" },
- { "fxp", "application/vnd.adobe.fxp" },
- { "fxpl", "application/vnd.adobe.fxp" },
- { "fzs", "application/vnd.fuzzysheet" },
- { "g2w", "application/vnd.geoplan" },
- { "g3", "image/g3fax" },
- { "g3w", "application/vnd.geospace" },
- { "gac", "application/vnd.groove-account" },
- { "gam", "application/x-tads" },
- { "gbr", "application/rpki-ghostbusters" },
- { "gca", "application/x-gca-compressed" },
- { "gdl", "model/vnd.gdl" },
- { "geo", "application/vnd.dynageo" },
- { "gex", "application/vnd.geometry-explorer" },
- { "ggb", "application/vnd.geogebra.file" },
- { "ggt", "application/vnd.geogebra.tool" },
- { "ghf", "application/vnd.groove-help" },
- { "gif", "image/gif" },
- { "gim", "application/vnd.groove-identity-message" },
- { "gml", "application/gml+xml" },
- { "gmx", "application/vnd.gmx" },
- { "gnumeric", "application/x-gnumeric" },
- { "gph", "application/vnd.flographit" },
- { "gpx", "application/gpx+xml" },
- { "gqf", "application/vnd.grafeq" },
- { "gqs", "application/vnd.grafeq" },
- { "gram", "application/srgs" },
- { "gramps", "application/x-gramps-xml" },
- { "gre", "application/vnd.geometry-explorer" },
- { "grv", "application/vnd.groove-injector" },
- { "grxml", "application/srgs+xml" },
- { "gsf", "application/x-font-ghostscript" },
- { "gtar", "application/x-gtar" },
- { "gtm", "application/vnd.groove-tool-message" },
- { "gtw", "model/vnd.gtw" },
- { "gv", "text/vnd.graphviz" },
- { "gxf", "application/gxf" },
- { "gxt", "application/vnd.geonext" },
- { "h", "text/x-c" },
- { "h261", "video/h261" },
- { "h263", "video/h263" },
- { "h264", "video/h264" },
- { "hal", "application/vnd.hal+xml" },
- { "hbci", "application/vnd.hbci" },
- { "hdf", "application/x-hdf" },
- { "hh", "text/x-c" },
- { "hlp", "application/winhlp" },
- { "hpgl", "application/vnd.hp-hpgl" },
- { "hpid", "application/vnd.hp-hpid" },
- { "hps", "application/vnd.hp-hps" },
- { "hqx", "application/mac-binhex40" },
- { "htke", "application/vnd.kenameaapp" },
- { "htm", "text/html" },
- { "html", "text/html" },
- { "hvd", "application/vnd.yamaha.hv-dic" },
- { "hvp", "application/vnd.yamaha.hv-voice" },
- { "hvs", "application/vnd.yamaha.hv-script" },
- { "i2g", "application/vnd.intergeo" },
- { "icc", "application/vnd.iccprofile" },
- { "ice", "x-conference/x-cooltalk" },
- { "icm", "application/vnd.iccprofile" },
- { "ico", "image/x-icon" },
- { "ics", "text/calendar" },
- { "ief", "image/ief" },
- { "ifb", "text/calendar" },
- { "ifm", "application/vnd.shana.informed.formdata" },
- { "iges", "model/iges" },
- { "igl", "application/vnd.igloader" },
- { "igm", "application/vnd.insors.igm" },
- { "igs", "model/iges" },
- { "igx", "application/vnd.micrografx.igx" },
- { "iif", "application/vnd.shana.informed.interchange" },
- { "imp", "application/vnd.accpac.simply.imp" },
- { "ims", "application/vnd.ms-ims" },
- { "in", "text/plain" },
- { "ink", "application/inkml+xml" },
- { "inkml", "application/inkml+xml" },
- { "install", "application/x-install-instructions" },
- { "iota", "application/vnd.astraea-software.iota" },
- { "ipfix", "application/ipfix" },
- { "ipk", "application/vnd.shana.informed.package" },
- { "irm", "application/vnd.ibm.rights-management" },
- { "irp", "application/vnd.irepository.package+xml" },
- { "iso", "application/x-iso9660-image" },
- { "itp", "application/vnd.shana.informed.formtemplate" },
- { "ivp", "application/vnd.immervision-ivp" },
- { "ivu", "application/vnd.immervision-ivu" },
- { "jad", "text/vnd.sun.j2me.app-descriptor" },
- { "jam", "application/vnd.jam" },
- { "jar", "application/java-archive" },
- { "java", "text/x-java-source" },
- { "jisp", "application/vnd.jisp" },
- { "jlt", "application/vnd.hp-jlyt" },
- { "jnlp", "application/x-java-jnlp-file" },
- { "joda", "application/vnd.joost.joda-archive" },
- { "jpe", "image/jpeg" },
- { "jpeg", "image/jpeg" },
- { "jpg", "image/jpeg" },
- { "jpgm", "video/jpm" },
- { "jpgv", "video/jpeg" },
- { "jpm", "video/jpm" },
- { "js", "application/javascript" },
- { "json", "application/json" },
- { "jsonml", "application/jsonml+json" },
- { "kar", "audio/midi" },
- { "karbon", "application/vnd.kde.karbon" },
- { "kfo", "application/vnd.kde.kformula" },
- { "kia", "application/vnd.kidspiration" },
- { "kml", "application/vnd.google-earth.kml+xml" },
- { "kmz", "application/vnd.google-earth.kmz" },
- { "kne", "application/vnd.kinar" },
- { "knp", "application/vnd.kinar" },
- { "kon", "application/vnd.kde.kontour" },
- { "kpr", "application/vnd.kde.kpresenter" },
- { "kpt", "application/vnd.kde.kpresenter" },
- { "kpxx", "application/vnd.ds-keypoint" },
- { "ksp", "application/vnd.kde.kspread" },
- { "ktr", "application/vnd.kahootz" },
- { "ktx", "image/ktx" },
- { "ktz", "application/vnd.kahootz" },
- { "kwd", "application/vnd.kde.kword" },
- { "kwt", "application/vnd.kde.kword" },
- { "lasxml", "application/vnd.las.las+xml" },
- { "latex", "application/x-latex" },
- { "lbd", "application/vnd.llamagraphics.life-balance.desktop" },
- { "lbe", "application/vnd.llamagraphics.life-balance.exchange+xml" },
- { "les", "application/vnd.hhe.lesson-player" },
- { "lha", "application/x-lzh-compressed" },
- { "link66", "application/vnd.route66.link66+xml" },
- { "list", "text/plain" },
- { "list3820", "application/vnd.ibm.modcap" },
- { "listafp", "application/vnd.ibm.modcap" },
- { "lnk", "application/x-ms-shortcut" },
- { "log", "text/plain" },
- { "lostxml", "application/lost+xml" },
- { "lrf", "application/octet-stream" },
- { "lrm", "application/vnd.ms-lrm" },
- { "ltf", "application/vnd.frogans.ltf" },
- { "lvp", "audio/vnd.lucent.voice" },
- { "lwp", "application/vnd.lotus-wordpro" },
- { "lzh", "application/x-lzh-compressed" },
- { "m13", "application/x-msmediaview" },
- { "m14", "application/x-msmediaview" },
- { "m1v", "video/mpeg" },
- { "m21", "application/mp21" },
- { "m2a", "audio/mpeg" },
- { "m2v", "video/mpeg" },
- { "m3a", "audio/mpeg" },
- { "m3u", "audio/x-mpegurl" },
- { "m3u8", "application/vnd.apple.mpegurl" },
- { "m4u", "video/vnd.mpegurl" },
- { "m4v", "video/x-m4v" },
- { "ma", "application/mathematica" },
- { "mads", "application/mads+xml" },
- { "mag", "application/vnd.ecowin.chart" },
- { "maker", "application/vnd.framemaker" },
- { "man", "text/troff" },
- { "mar", "application/octet-stream" },
- { "mathml", "application/mathml+xml" },
- { "mb", "application/mathematica" },
- { "mbk", "application/vnd.mobius.mbk" },
- { "mbox", "application/mbox" },
- { "mc1", "application/vnd.medcalcdata" },
- { "mcd", "application/vnd.mcd" },
- { "mcurl", "text/vnd.curl.mcurl" },
- { "mdb", "application/x-msaccess" },
- { "mdi", "image/vnd.ms-modi" },
- { "me", "text/troff" },
- { "mesh", "model/mesh" },
- { "meta4", "application/metalink4+xml" },
- { "metalink", "application/metalink+xml" },
- { "mets", "application/mets+xml" },
- { "mfm", "application/vnd.mfmp" },
- { "mft", "application/rpki-manifest" },
- { "mgp", "application/vnd.osgeo.mapguide.package" },
- { "mgz", "application/vnd.proteus.magazine" },
- { "mid", "audio/midi" },
- { "midi", "audio/midi" },
- { "mie", "application/x-mie" },
- { "mif", "application/vnd.mif" },
- { "mime", "message/rfc822" },
- { "mj2", "video/mj2" },
- { "mjp2", "video/mj2" },
- { "mk3d", "video/x-matroska" },
- { "mka", "audio/x-matroska" },
- { "mks", "video/x-matroska" },
- { "mkv", "video/x-matroska" },
- { "mlp", "application/vnd.dolby.mlp" },
- { "mmd", "application/vnd.chipnuts.karaoke-mmd" },
- { "mmf", "application/vnd.smaf" },
- { "mmr", "image/vnd.fujixerox.edmics-mmr" },
- { "mng", "video/x-mng" },
- { "mny", "application/x-msmoney" },
- { "mobi", "application/x-mobipocket-ebook" },
- { "mods", "application/mods+xml" },
- { "mov", "video/quicktime" },
- { "movie", "video/x-sgi-movie" },
- { "mp2", "audio/mpeg" },
- { "mp21", "application/mp21" },
- { "mp2a", "audio/mpeg" },
- { "mp3", "audio/mpeg" },
- { "mp4", "video/mp4" },
- { "mp4a", "audio/mp4" },
- { "mp4s", "application/mp4" },
- { "mp4v", "video/mp4" },
- { "mpc", "application/vnd.mophun.certificate" },
- { "mpe", "video/mpeg" },
- { "mpeg", "video/mpeg" },
- { "mpg", "video/mpeg" },
- { "mpg4", "video/mp4" },
- { "mpga", "audio/mpeg" },
- { "mpkg", "application/vnd.apple.installer+xml" },
- { "mpm", "application/vnd.blueice.multipass" },
- { "mpn", "application/vnd.mophun.application" },
- { "mpp", "application/vnd.ms-project" },
- { "mpt", "application/vnd.ms-project" },
- { "mpy", "application/vnd.ibm.minipay" },
- { "mqy", "application/vnd.mobius.mqy" },
- { "mrc", "application/marc" },
- { "mrcx", "application/marcxml+xml" },
- { "ms", "text/troff" },
- { "mscml", "application/mediaservercontrol+xml" },
- { "mseed", "application/vnd.fdsn.mseed" },
- { "mseq", "application/vnd.mseq" },
- { "msf", "application/vnd.epson.msf" },
- { "msh", "model/mesh" },
- { "msi", "application/x-msdownload" },
- { "msl", "application/vnd.mobius.msl" },
- { "msty", "application/vnd.muvee.style" },
- { "mts", "model/vnd.mts" },
- { "mus", "application/vnd.musician" },
- { "musicxml", "application/vnd.recordare.musicxml+xml" },
- { "mvb", "application/x-msmediaview" },
- { "mwf", "application/vnd.mfer" },
- { "mxf", "application/mxf" },
- { "mxl", "application/vnd.recordare.musicxml" },
- { "mxml", "application/xv+xml" },
- { "mxs", "application/vnd.triscape.mxs" },
- { "mxu", "video/vnd.mpegurl" },
- { "n3", "text/n3" },
- { "nb", "application/mathematica" },
- { "nbp", "application/vnd.wolfram.player" },
- { "nc", "application/x-netcdf" },
- { "ncx", "application/x-dtbncx+xml" },
- { "nfo", "text/x-nfo" },
- { "n-gage", "application/vnd.nokia.n-gage.symbian.install" },
- { "ngdat", "application/vnd.nokia.n-gage.data" },
- { "nitf", "application/vnd.nitf" },
- { "nlu", "application/vnd.neurolanguage.nlu" },
- { "nml", "application/vnd.enliven" },
- { "nnd", "application/vnd.noblenet-directory" },
- { "nns", "application/vnd.noblenet-sealer" },
- { "nnw", "application/vnd.noblenet-web" },
- { "npx", "image/vnd.net-fpx" },
- { "nsc", "application/x-conference" },
- { "nsf", "application/vnd.lotus-notes" },
- { "ntf", "application/vnd.nitf" },
- { "nzb", "application/x-nzb" },
- { "oa2", "application/vnd.fujitsu.oasys2" },
- { "oa3", "application/vnd.fujitsu.oasys3" },
- { "oas", "application/vnd.fujitsu.oasys" },
- { "obd", "application/x-msbinder" },
- { "obj", "application/x-tgif" },
- { "oda", "application/oda" },
- { "odb", "application/vnd.oasis.opendocument.database" },
- { "odc", "application/vnd.oasis.opendocument.chart" },
- { "odf", "application/vnd.oasis.opendocument.formula" },
- { "odft", "application/vnd.oasis.opendocument.formula-template" },
- { "odg", "application/vnd.oasis.opendocument.graphics" },
- { "odi", "application/vnd.oasis.opendocument.image" },
- { "odm", "application/vnd.oasis.opendocument.text-master" },
- { "odp", "application/vnd.oasis.opendocument.presentation" },
- { "ods", "application/vnd.oasis.opendocument.spreadsheet" },
- { "odt", "application/vnd.oasis.opendocument.text" },
- { "oga", "audio/ogg" },
- { "ogg", "audio/ogg" },
- { "ogv", "video/ogg" },
- { "ogx", "application/ogg" },
- { "omdoc", "application/omdoc+xml" },
- { "onepkg", "application/onenote" },
- { "onetmp", "application/onenote" },
- { "onetoc", "application/onenote" },
- { "onetoc2", "application/onenote" },
- { "opf", "application/oebps-package+xml" },
- { "opml", "text/x-opml" },
- { "oprc", "application/vnd.palm" },
- { "org", "application/vnd.lotus-organizer" },
- { "osf", "application/vnd.yamaha.openscoreformat" },
- { "osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml" },
- { "otc", "application/vnd.oasis.opendocument.chart-template" },
- { "otf", "application/x-font-otf" },
- { "otg", "application/vnd.oasis.opendocument.graphics-template" },
- { "oth", "application/vnd.oasis.opendocument.text-web" },
- { "oti", "application/vnd.oasis.opendocument.image-template" },
- { "otp", "application/vnd.oasis.opendocument.presentation-template" },
- { "ots", "application/vnd.oasis.opendocument.spreadsheet-template" },
- { "ott", "application/vnd.oasis.opendocument.text-template" },
- { "oxps", "application/oxps" },
- { "oxt", "application/vnd.openofficeorg.extension" },
- { "p", "text/x-pascal" },
- { "p10", "application/pkcs10" },
- { "p12", "application/x-pkcs12" },
- { "p7b", "application/x-pkcs7-certificates" },
- { "p7c", "application/pkcs7-mime" },
- { "p7m", "application/pkcs7-mime" },
- { "p7r", "application/x-pkcs7-certreqresp" },
- { "p7s", "application/pkcs7-signature" },
- { "p8", "application/pkcs8" },
- { "pas", "text/x-pascal" },
- { "paw", "application/vnd.pawaafile" },
- { "pbd", "application/vnd.powerbuilder6" },
- { "pbm", "image/x-portable-bitmap" },
- { "pcap", "application/vnd.tcpdump.pcap" },
- { "pcf", "application/x-font-pcf" },
- { "pcl", "application/vnd.hp-pcl" },
- { "pclxl", "application/vnd.hp-pclxl" },
- { "pct", "image/x-pict" },
- { "pcurl", "application/vnd.curl.pcurl" },
- { "pcx", "image/x-pcx" },
- { "pdb", "application/vnd.palm" },
- { "pdf", "application/pdf" },
- { "pfa", "application/x-font-type1" },
- { "pfb", "application/x-font-type1" },
- { "pfm", "application/x-font-type1" },
- { "pfr", "application/font-tdpfr" },
- { "pfx", "application/x-pkcs12" },
- { "pgm", "image/x-portable-graymap" },
- { "pgn", "application/x-chess-pgn" },
- { "pgp", "application/pgp-encrypted" },
- { "pic", "image/x-pict" },
- { "pkg", "application/octet-stream" },
- { "pki", "application/pkixcmp" },
- { "pkipath", "application/pkix-pkipath" },
- { "plb", "application/vnd.3gpp.pic-bw-large" },
- { "plc", "application/vnd.mobius.plc" },
- { "plf", "application/vnd.pocketlearn" },
- { "pls", "application/pls+xml" },
- { "pml", "application/vnd.ctc-posml" },
- { "png", "image/png" },
- { "pnm", "image/x-portable-anymap" },
- { "portpkg", "application/vnd.macports.portpkg" },
- { "pot", "application/vnd.ms-powerpoint" },
- { "potm", "application/vnd.ms-powerpoint.template.macroenabled.12" },
- { "potx", "application/vnd.openxmlformats-officedocument.presentationml.template" },
- { "ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12" },
- { "ppd", "application/vnd.cups-ppd" },
- { "ppm", "image/x-portable-pixmap" },
- { "pps", "application/vnd.ms-powerpoint" },
- { "ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12" },
- { "ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow" },
- { "ppt", "application/vnd.ms-powerpoint" },
- { "pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12" },
- { "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
- { "pqa", "application/vnd.palm" },
- { "prc", "application/x-mobipocket-ebook" },
- { "pre", "application/vnd.lotus-freelance" },
- { "prf", "application/pics-rules" },
- { "ps", "application/postscript" },
- { "psb", "application/vnd.3gpp.pic-bw-small" },
- { "psd", "image/vnd.adobe.photoshop" },
- { "psf", "application/x-font-linux-psf" },
- { "pskcxml", "application/pskc+xml" },
- { "ptid", "application/vnd.pvi.ptid1" },
- { "pub", "application/x-mspublisher" },
- { "pvb", "application/vnd.3gpp.pic-bw-var" },
- { "pwn", "application/vnd.3m.post-it-notes" },
- { "pya", "audio/vnd.ms-playready.media.pya" },
- { "pyv", "video/vnd.ms-playready.media.pyv" },
- { "qam", "application/vnd.epson.quickanime" },
- { "qbo", "application/vnd.intu.qbo" },
- { "qfx", "application/vnd.intu.qfx" },
- { "qps", "application/vnd.publishare-delta-tree" },
- { "qt", "video/quicktime" },
- { "qwd", "application/vnd.quark.quarkxpress" },
- { "qwt", "application/vnd.quark.quarkxpress" },
- { "qxb", "application/vnd.quark.quarkxpress" },
- { "qxd", "application/vnd.quark.quarkxpress" },
- { "qxl", "application/vnd.quark.quarkxpress" },
- { "qxt", "application/vnd.quark.quarkxpress" },
- { "ra", "audio/x-pn-realaudio" },
- { "ram", "audio/x-pn-realaudio" },
- { "rar", "application/x-rar-compressed" },
- { "ras", "image/x-cmu-raster" },
- { "rcprofile", "application/vnd.ipunplugged.rcprofile" },
- { "rdf", "application/rdf+xml" },
- { "rdz", "application/vnd.data-vision.rdz" },
- { "rep", "application/vnd.businessobjects" },
- { "res", "application/x-dtbresource+xml" },
- { "rgb", "image/x-rgb" },
- { "rif", "application/reginfo+xml" },
- { "rip", "audio/vnd.rip" },
- { "ris", "application/x-research-info-systems" },
- { "rl", "application/resource-lists+xml" },
- { "rlc", "image/vnd.fujixerox.edmics-rlc" },
- { "rld", "application/resource-lists-diff+xml" },
- { "rm", "application/vnd.rn-realmedia" },
- { "rmi", "audio/midi" },
- { "rmp", "audio/x-pn-realaudio-plugin" },
- { "rms", "application/vnd.jcp.javame.midlet-rms" },
- { "rmvb", "application/vnd.rn-realmedia-vbr" },
- { "rnc", "application/relax-ng-compact-syntax" },
- { "roa", "application/rpki-roa" },
- { "roff", "text/troff" },
- { "rp9", "application/vnd.cloanto.rp9" },
- { "rpss", "application/vnd.nokia.radio-presets" },
- { "rpst", "application/vnd.nokia.radio-preset" },
- { "rq", "application/sparql-query" },
- { "rs", "application/rls-services+xml" },
- { "rsd", "application/rsd+xml" },
- { "rss", "application/rss+xml" },
- { "rtf", "application/rtf" },
- { "rtx", "text/richtext" },
- { "s", "text/x-asm" },
- { "s3m", "audio/s3m" },
- { "saf", "application/vnd.yamaha.smaf-audio" },
- { "sbml", "application/sbml+xml" },
- { "sc", "application/vnd.ibm.secure-container" },
- { "scd", "application/x-msschedule" },
- { "scm", "application/vnd.lotus-screencam" },
- { "scq", "application/scvp-cv-request" },
- { "scs", "application/scvp-cv-response" },
- { "scurl", "text/vnd.curl.scurl" },
- { "sda", "application/vnd.stardivision.draw" },
- { "sdc", "application/vnd.stardivision.calc" },
- { "sdd", "application/vnd.stardivision.impress" },
- { "sdkd", "application/vnd.solent.sdkm+xml" },
- { "sdkm", "application/vnd.solent.sdkm+xml" },
- { "sdp", "application/sdp" },
- { "sdw", "application/vnd.stardivision.writer" },
- { "see", "application/vnd.seemail" },
- { "seed", "application/vnd.fdsn.seed" },
- { "sema", "application/vnd.sema" },
- { "semd", "application/vnd.semd" },
- { "semf", "application/vnd.semf" },
- { "ser", "application/java-serialized-object" },
- { "setpay", "application/set-payment-initiation" },
- { "setreg", "application/set-registration-initiation" },
- { "sfd-hdstx", "application/vnd.hydrostatix.sof-data" },
- { "sfs", "application/vnd.spotfire.sfs" },
- { "sfv", "text/x-sfv" },
- { "sgi", "image/sgi" },
- { "sgl", "application/vnd.stardivision.writer-global" },
- { "sgm", "text/sgml" },
- { "sgml", "text/sgml" },
- { "sh", "application/x-sh" },
- { "shar", "application/x-shar" },
- { "shf", "application/shf+xml" },
- { "sid", "image/x-mrsid-image" },
- { "sig", "application/pgp-signature" },
- { "sil", "audio/silk" },
- { "silo", "model/mesh" },
- { "sis", "application/vnd.symbian.install" },
- { "sisx", "application/vnd.symbian.install" },
- { "sit", "application/x-stuffit" },
- { "sitx", "application/x-stuffitx" },
- { "skd", "application/vnd.koan" },
- { "skm", "application/vnd.koan" },
- { "skp", "application/vnd.koan" },
- { "skt", "application/vnd.koan" },
- { "sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12" },
- { "sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide" },
- { "slt", "application/vnd.epson.salt" },
- { "sm", "application/vnd.stepmania.stepchart" },
- { "smf", "application/vnd.stardivision.math" },
- { "smi", "application/smil+xml" },
- { "smil", "application/smil+xml" },
- { "smv", "video/x-smv" },
- { "smzip", "application/vnd.stepmania.package" },
- { "snd", "audio/basic" },
- { "snf", "application/x-font-snf" },
- { "so", "application/octet-stream" },
- { "spc", "application/x-pkcs7-certificates" },
- { "spf", "application/vnd.yamaha.smaf-phrase" },
- { "spl", "application/x-futuresplash" },
- { "spot", "text/vnd.in3d.spot" },
- { "spp", "application/scvp-vp-response" },
- { "spq", "application/scvp-vp-request" },
- { "spx", "audio/ogg" },
- { "sql", "application/x-sql" },
- { "src", "application/x-wais-source" },
- { "srt", "application/x-subrip" },
- { "sru", "application/sru+xml" },
- { "srx", "application/sparql-results+xml" },
- { "ssdl", "application/ssdl+xml" },
- { "sse", "application/vnd.kodak-descriptor" },
- { "ssf", "application/vnd.epson.ssf" },
- { "ssml", "application/ssml+xml" },
- { "st", "application/vnd.sailingtracker.track" },
- { "stc", "application/vnd.sun.xml.calc.template" },
- { "std", "application/vnd.sun.xml.draw.template" },
- { "stf", "application/vnd.wt.stf" },
- { "sti", "application/vnd.sun.xml.impress.template" },
- { "stk", "application/hyperstudio" },
- { "stl", "application/vnd.ms-pki.stl" },
- { "str", "application/vnd.pg.format" },
- { "stw", "application/vnd.sun.xml.writer.template" },
- { "sub", "image/vnd.dvb.subtitle" },
- { "sus", "application/vnd.sus-calendar" },
- { "susp", "application/vnd.sus-calendar" },
- { "sv4cpio", "application/x-sv4cpio" },
- { "sv4crc", "application/x-sv4crc" },
- { "svc", "application/vnd.dvb.service" },
- { "svd", "application/vnd.svd" },
- { "svg", "image/svg+xml" },
- { "svgz", "image/svg+xml" },
- { "swa", "application/x-director" },
- { "swf", "application/x-shockwave-flash" },
- { "swi", "application/vnd.aristanetworks.swi" },
- { "sxc", "application/vnd.sun.xml.calc" },
- { "sxd", "application/vnd.sun.xml.draw" },
- { "sxg", "application/vnd.sun.xml.writer.global" },
- { "sxi", "application/vnd.sun.xml.impress" },
- { "sxm", "application/vnd.sun.xml.math" },
- { "sxw", "application/vnd.sun.xml.writer" },
- { "t", "text/troff" },
- { "t3", "application/x-t3vm-image" },
- { "taglet", "application/vnd.mynfc" },
- { "tao", "application/vnd.tao.intent-module-archive" },
- { "tar", "application/x-tar" },
- { "tcap", "application/vnd.3gpp2.tcap" },
- { "tcl", "application/x-tcl" },
- { "teacher", "application/vnd.smart.teacher" },
- { "tei", "application/tei+xml" },
- { "teicorpus", "application/tei+xml" },
- { "tex", "application/x-tex" },
- { "texi", "application/x-texinfo" },
- { "texinfo", "application/x-texinfo" },
- { "text", "text/plain" },
- { "tfi", "application/thraud+xml" },
- { "tfm", "application/x-tex-tfm" },
- { "tga", "image/x-tga" },
- { "thmx", "application/vnd.ms-officetheme" },
- { "tif", "image/tiff" },
- { "tiff", "image/tiff" },
- { "tmo", "application/vnd.tmobile-livetv" },
- { "torrent", "application/x-bittorrent" },
- { "tpl", "application/vnd.groove-tool-template" },
- { "tpt", "application/vnd.trid.tpt" },
- { "tr", "text/troff" },
- { "tra", "application/vnd.trueapp" },
- { "trm", "application/x-msterminal" },
- { "tsd", "application/timestamped-data" },
- { "tsv", "text/tab-separated-values" },
- { "ttc", "application/x-font-ttf" },
- { "ttf", "application/x-font-ttf" },
- { "ttl", "text/turtle" },
- { "twd", "application/vnd.simtech-mindmapper" },
- { "twds", "application/vnd.simtech-mindmapper" },
- { "txd", "application/vnd.genomatix.tuxedo" },
- { "txf", "application/vnd.mobius.txf" },
- { "txt", "text/plain" },
- { "u32", "application/x-authorware-bin" },
- { "udeb", "application/x-debian-package" },
- { "ufd", "application/vnd.ufdl" },
- { "ufdl", "application/vnd.ufdl" },
- { "ulx", "application/x-glulx" },
- { "umj", "application/vnd.umajin" },
- { "unityweb", "application/vnd.unity" },
- { "uoml", "application/vnd.uoml+xml" },
- { "uri", "text/uri-list" },
- { "uris", "text/uri-list" },
- { "urls", "text/uri-list" },
- { "ustar", "application/x-ustar" },
- { "utz", "application/vnd.uiq.theme" },
- { "uu", "text/x-uuencode" },
- { "uva", "audio/vnd.dece.audio" },
- { "uvd", "application/vnd.dece.data" },
- { "uvf", "application/vnd.dece.data" },
- { "uvg", "image/vnd.dece.graphic" },
- { "uvh", "video/vnd.dece.hd" },
- { "uvi", "image/vnd.dece.graphic" },
- { "uvm", "video/vnd.dece.mobile" },
- { "uvp", "video/vnd.dece.pd" },
- { "uvs", "video/vnd.dece.sd" },
- { "uvt", "application/vnd.dece.ttml+xml" },
- { "uvu", "video/vnd.uvvu.mp4" },
- { "uvv", "video/vnd.dece.video" },
- { "uvva", "audio/vnd.dece.audio" },
- { "uvvd", "application/vnd.dece.data" },
- { "uvvf", "application/vnd.dece.data" },
- { "uvvg", "image/vnd.dece.graphic" },
- { "uvvh", "video/vnd.dece.hd" },
- { "uvvi", "image/vnd.dece.graphic" },
- { "uvvm", "video/vnd.dece.mobile" },
- { "uvvp", "video/vnd.dece.pd" },
- { "uvvs", "video/vnd.dece.sd" },
- { "uvvt", "application/vnd.dece.ttml+xml" },
- { "uvvu", "video/vnd.uvvu.mp4" },
- { "uvvv", "video/vnd.dece.video" },
- { "uvvx", "application/vnd.dece.unspecified" },
- { "uvvz", "application/vnd.dece.zip" },
- { "uvx", "application/vnd.dece.unspecified" },
- { "uvz", "application/vnd.dece.zip" },
- { "vcard", "text/vcard" },
- { "vcd", "application/x-cdlink" },
- { "vcf", "text/x-vcard" },
- { "vcg", "application/vnd.groove-vcard" },
- { "vcs", "text/x-vcalendar" },
- { "vcx", "application/vnd.vcx" },
- { "vis", "application/vnd.visionary" },
- { "viv", "video/vnd.vivo" },
- { "vob", "video/x-ms-vob" },
- { "vor", "application/vnd.stardivision.writer" },
- { "vox", "application/x-authorware-bin" },
- { "vrml", "model/vrml" },
- { "vsd", "application/vnd.visio" },
- { "vsf", "application/vnd.vsf" },
- { "vss", "application/vnd.visio" },
- { "vst", "application/vnd.visio" },
- { "vsw", "application/vnd.visio" },
- { "vtu", "model/vnd.vtu" },
- { "vxml", "application/voicexml+xml" },
- { "w3d", "application/x-director" },
- { "wad", "application/x-doom" },
- { "wav", "audio/x-wav" },
- { "wax", "audio/x-ms-wax" },
- { "wbmp", "image/vnd.wap.wbmp" },
- { "wbs", "application/vnd.criticaltools.wbs+xml" },
- { "wbxml", "application/vnd.wap.wbxml" },
- { "wcm", "application/vnd.ms-works" },
- { "wdb", "application/vnd.ms-works" },
- { "wdp", "image/vnd.ms-photo" },
- { "weba", "audio/webm" },
- { "webm", "video/webm" },
- { "webp", "image/webp" },
- { "wg", "application/vnd.pmi.widget" },
- { "wgt", "application/widget" },
- { "wks", "application/vnd.ms-works" },
- { "wm", "video/x-ms-wm" },
- { "wma", "audio/x-ms-wma" },
- { "wmd", "application/x-ms-wmd" },
- { "wmf", "application/x-msmetafile" },
- { "wml", "text/vnd.wap.wml" },
- { "wmlc", "application/vnd.wap.wmlc" },
- { "wmls", "text/vnd.wap.wmlscript" },
- { "wmlsc", "application/vnd.wap.wmlscriptc" },
- { "wmv", "video/x-ms-wmv" },
- { "wmx", "video/x-ms-wmx" },
- { "wmz", "application/x-ms-wmz" },
- { "woff", "application/font-woff" },
- { "wpd", "application/vnd.wordperfect" },
- { "wpl", "application/vnd.ms-wpl" },
- { "wps", "application/vnd.ms-works" },
- { "wqd", "application/vnd.wqd" },
- { "wri", "application/x-mswrite" },
- { "wrl", "model/vrml" },
- { "wsdl", "application/wsdl+xml" },
- { "wspolicy", "application/wspolicy+xml" },
- { "wtb", "application/vnd.webturbo" },
- { "wvx", "video/x-ms-wvx" },
- { "x32", "application/x-authorware-bin" },
- { "x3d", "model/x3d+xml" },
- { "x3db", "model/x3d+binary" },
- { "x3dbz", "model/x3d+binary" },
- { "x3dv", "model/x3d+vrml" },
- { "x3dvz", "model/x3d+vrml" },
- { "x3dz", "model/x3d+xml" },
- { "xaml", "application/xaml+xml" },
- { "xap", "application/x-silverlight-app" },
- { "xar", "application/vnd.xara" },
- { "xbap", "application/x-ms-xbap" },
- { "xbd", "application/vnd.fujixerox.docuworks.binder" },
- { "xbm", "image/x-xbitmap" },
- { "xdf", "application/xcap-diff+xml" },
- { "xdm", "application/vnd.syncml.dm+xml" },
- { "xdp", "application/vnd.adobe.xdp+xml" },
- { "xdssc", "application/dssc+xml" },
- { "xdw", "application/vnd.fujixerox.docuworks" },
- { "xenc", "application/xenc+xml" },
- { "xer", "application/patch-ops-error+xml" },
- { "xfdf", "application/vnd.adobe.xfdf" },
- { "xfdl", "application/vnd.xfdl" },
- { "xht", "application/xhtml+xml" },
- { "xhtml", "application/xhtml+xml" },
- { "xhvml", "application/xv+xml" },
- { "xif", "image/vnd.xiff" },
- { "xla", "application/vnd.ms-excel" },
- { "xlam", "application/vnd.ms-excel.addin.macroenabled.12" },
- { "xlc", "application/vnd.ms-excel" },
- { "xlf", "application/x-xliff+xml" },
- { "xlm", "application/vnd.ms-excel" },
- { "xls", "application/vnd.ms-excel" },
- { "xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12" },
- { "xlsm", "application/vnd.ms-excel.sheet.macroenabled.12" },
- { "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
- { "xlt", "application/vnd.ms-excel" },
- { "xltm", "application/vnd.ms-excel.template.macroenabled.12" },
- { "xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template" },
- { "xlw", "application/vnd.ms-excel" },
- { "xm", "audio/xm" },
- { "xml", "application/xml" },
- { "xo", "application/vnd.olpc-sugar" },
- { "xop", "application/xop+xml" },
- { "xpi", "application/x-xpinstall" },
- { "xpl", "application/xproc+xml" },
- { "xpm", "image/x-xpixmap" },
- { "xpr", "application/vnd.is-xpr" },
- { "xps", "application/vnd.ms-xpsdocument" },
- { "xpw", "application/vnd.intercon.formnet" },
- { "xpx", "application/vnd.intercon.formnet" },
- { "xsl", "application/xml" },
- { "xslt", "application/xslt+xml" },
- { "xsm", "application/vnd.syncml+xml" },
- { "xspf", "application/xspf+xml" },
- { "xul", "application/vnd.mozilla.xul+xml" },
- { "xvm", "application/xv+xml" },
- { "xvml", "application/xv+xml" },
- { "xwd", "image/x-xwindowdump" },
- { "xyz", "chemical/x-xyz" },
- { "xz", "application/x-xz" },
- { "yang", "application/yang" },
- { "yin", "application/yin+xml" },
- { "z1", "application/x-zmachine" },
- { "z2", "application/x-zmachine" },
- { "z3", "application/x-zmachine" },
- { "z4", "application/x-zmachine" },
- { "z5", "application/x-zmachine" },
- { "z6", "application/x-zmachine" },
- { "z7", "application/x-zmachine" },
- { "z8", "application/x-zmachine" },
- { "zaz", "application/vnd.zzazz.deck+xml" },
- { "zip", "application/zip" },
- { "zir", "application/vnd.zul" },
- { "zirz", "application/vnd.zul" },
- { "zmm", "application/vnd.handheld-entertainment+xml" }
- };
-}
-
diff --git a/SnapX.Core/Utils/Miscellaneous/PingHelper.cs b/SnapX.Core/Utils/Miscellaneous/PingHelper.cs
index b1bd114c9..673a050c9 100644
--- a/SnapX.Core/Utils/Miscellaneous/PingHelper.cs
+++ b/SnapX.Core/Utils/Miscellaneous/PingHelper.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/PingResult.cs b/SnapX.Core/Utils/Miscellaneous/PingResult.cs
index 73abb0dfe..ccac2bcdb 100644
--- a/SnapX.Core/Utils/Miscellaneous/PingResult.cs
+++ b/SnapX.Core/Utils/Miscellaneous/PingResult.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/ProxyInfo.cs b/SnapX.Core/Utils/Miscellaneous/ProxyInfo.cs
index 0918093a1..906462a8a 100644
--- a/SnapX.Core/Utils/Miscellaneous/ProxyInfo.cs
+++ b/SnapX.Core/Utils/Miscellaneous/ProxyInfo.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/SevenZipManager.cs b/SnapX.Core/Utils/Miscellaneous/SevenZipManager.cs
index d53caa370..9b2d91c0b 100644
--- a/SnapX.Core/Utils/Miscellaneous/SevenZipManager.cs
+++ b/SnapX.Core/Utils/Miscellaneous/SevenZipManager.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/Miscellaneous/StringLineReader.cs b/SnapX.Core/Utils/Miscellaneous/StringLineReader.cs
deleted file mode 100644
index acf37397b..000000000
--- a/SnapX.Core/Utils/Miscellaneous/StringLineReader.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-
-using System.Text;
-
-namespace SnapX.Core.Utils.Miscellaneous;
-
-public class StringLineReader
-{
- public string Text { get; private set; }
- public int Position { get; private set; }
- public int Length { get; private set; }
-
- public StringLineReader(string text)
- {
- Text = text;
- Length = Text.Length;
- }
-
- public string ReadLine()
- {
- var builder = new StringBuilder();
-
- while (!string.IsNullOrEmpty(Text) && Position < Length)
- {
- var ch = Text[Position];
- builder.Append(ch);
- Position++;
-
- if (ch != '\r' && ch != '\n' && Position != Length)
- {
- return builder.ToString();
- }
-
- if (ch == '\r' && Position < Length && Text[Position] == '\n')
- {
- continue;
- }
-
- return builder.ToString();
- }
-
- return null;
- }
-
- public string[] ReadAllLines(bool autoTrim = true)
- {
- List lines = [];
-
- string line;
-
- while ((line = ReadLine()) != null)
- {
- if (autoTrim) line = line.Trim();
- lines.Add(line);
- }
-
- return lines.ToArray();
- }
-
- public void Reset()
- {
- Position = 0;
- }
-}
-
diff --git a/SnapX.Core/Utils/Native/INativeAPI.cs b/SnapX.Core/Utils/Native/INativeAPI.cs
new file mode 100644
index 000000000..256030773
--- /dev/null
+++ b/SnapX.Core/Utils/Native/INativeAPI.cs
@@ -0,0 +1,21 @@
+using SixLabors.ImageSharp;
+using SnapX.Core.Media;
+
+namespace SnapX.Core.Utils.Native;
+
+// Secure, Contain, & Protect.
+public interface INativeAPI
+{
+ void ShowWindow(WindowInfo windowInfo);
+ void ShowWindow(IntPtr hwnd);
+ Image GetJumboFileIcon(string filePath, bool jumboSize = true);
+ void HideWindow(WindowInfo windowInfo);
+ void HideWindow(IntPtr handle);
+ List GetWindowList();
+ void CopyText(string text);
+ void CopyImage(Image image, string? fileName);
+ Rectangle GetWindowRectangle(WindowInfo window);
+ Rectangle GetWindowRectangle(IntPtr windowHandle);
+ Point GetCursorPosition();
+ Screen? GetScreen(Point pos);
+}
diff --git a/SnapX.Core/Utils/Native/InputHelpers.cs b/SnapX.Core/Utils/Native/InputHelpers.cs
deleted file mode 100644
index e47370d55..000000000
--- a/SnapX.Core/Utils/Native/InputHelpers.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace SnapX.Core.Utils.Native;
-
-public static class InputHelpers
-{
- public static void SendKeyPress()
- {
-
- }
-}
diff --git a/SnapX.Core/Utils/Native/LinuxAPI.cs b/SnapX.Core/Utils/Native/LinuxAPI.cs
index 985cf9c28..b3d19f3c7 100644
--- a/SnapX.Core/Utils/Native/LinuxAPI.cs
+++ b/SnapX.Core/Utils/Native/LinuxAPI.cs
@@ -3,11 +3,12 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
+using SnapX.Core.Interfaces;
using SnapX.Core.Media;
namespace SnapX.Core.Utils.Native;
-public partial class LinuxAPI : NativeAPI
+public partial class LinuxAPI(ILoggerService Logger) : INativeAPI
{
private const string LibX11 = "libX11.so.6";
@@ -30,12 +31,17 @@ internal static bool IsGNOME()
&& sessionVersion.Contains("gnome", StringComparison.OrdinalIgnoreCase);
}
- public override Rectangle GetWindowRectangle(IntPtr windowHandle)
+ public Rectangle GetWindowRectangle(WindowInfo window)
+ {
+ return GetWindowRectangleX11(window.Handle);
+ }
+
+ public Rectangle GetWindowRectangle(IntPtr windowHandle)
{
return GetWindowRectangleX11(windowHandle);
}
- public override Screen? GetScreen(Point pos)
+ public Screen? GetScreen(Point pos)
{
var display = XOpenDisplay(null);
if (display == IntPtr.Zero)
@@ -62,7 +68,7 @@ out _
if (pos.X < x || pos.X > x + (int)width || pos.Y < y || pos.Y > y + (int)height)
continue;
- DebugHelper.Logger?.Debug("Point {Pos} is within screen {I} bounds", pos, i);
+ Logger.Debug("Point {Pos} is within screen {I} bounds", pos, i);
return new Screen()
{
Bounds = new Rectangle(x, y, (int)width, (int)height),
@@ -75,22 +81,47 @@ out _
return null;
}
- public override List GetWindowList()
+ public void ShowWindow(WindowInfo windowInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ShowWindow(IntPtr hwnd)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Image GetJumboFileIcon(string filePath, bool jumboSize = true)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void HideWindow(WindowInfo windowInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void HideWindow(IntPtr handle)
+ {
+ throw new NotImplementedException();
+ }
+
+ public List GetWindowList()
{
var windows = new List();
if (IsWayland())
{
- if (IsPlasma())
- {
- // Interact with Plasmashell over DBus
- return windows;
- }
-
- if (IsGNOME())
- {
- // Interact with GNOME Shell
- return windows;
- }
+ // if (IsPlasma())
+ // {
+ // // Interact with Plasmashell over DBus
+ // return windows;
+ // }
+ //
+ // if (IsGNOME())
+ // {
+ // // Interact with GNOME Shell
+ // return windows;
+ // }
return windows;
}
@@ -98,7 +129,7 @@ public override List GetWindowList()
var display = XOpenDisplay(null);
if (display == IntPtr.Zero)
{
- DebugHelper.Logger?.Debug("Unable to open X display");
+ Logger.Debug("Unable to open X display");
return windows;
}
@@ -115,7 +146,7 @@ out var nchildren
);
if (status == 0)
{
- DebugHelper.Logger?.Debug("XQueryTree failed");
+ Logger.Debug("XQueryTree failed");
XCloseDisplay(display);
return windows;
}
@@ -279,7 +310,7 @@ private static bool IsWindowMinimized(IntPtr display, IntPtr hwnd)
private const long ALL_PLANES = -1;
public const int ZPIXMAP = 2;
- internal static Image TakeScreenshotWithX11(Screen screen)
+ internal Image TakeScreenshotWithX11(Screen screen)
{
unsafe
{
@@ -305,18 +336,18 @@ internal static Image TakeScreenshotWithX11(Screen screen)
}
XGetWindowAttributes(display, rootWindow, out var attributes);
- DebugHelper.Logger?.Debug("x: {AttributesX}", attributes.x);
- DebugHelper.Logger?.Debug("y: {AttributesY}", attributes.y);
- DebugHelper.Logger?.Debug("width: {AttributesWidth}", attributes.width);
- DebugHelper.Logger?.Debug("height: {AttributesHeight}", attributes.height);
- DebugHelper.Logger?.Debug(
+ Logger.Debug("x: {AttributesX}", attributes.x);
+ Logger.Debug("y: {AttributesY}", attributes.y);
+ Logger.Debug("width: {AttributesWidth}", attributes.width);
+ Logger.Debug("height: {AttributesHeight}", attributes.height);
+ Logger.Debug(
"border_width: {AttributesBorderWidth}",
attributes.border_width
);
- DebugHelper.Logger?.Debug("depth: {AttributesDepth}", attributes.depth);
- DebugHelper.Logger?.Debug("visual: {AttributesVisual}", attributes.visual);
- DebugHelper.Logger?.Debug("root: {AttributesRoot}", attributes.root);
- DebugHelper.Logger?.Debug("colormap: {AttributesColormap}", attributes.colormap);
+ Logger.Debug("depth: {AttributesDepth}", attributes.depth);
+ Logger.Debug("visual: {AttributesVisual}", attributes.visual);
+ Logger.Debug("root: {AttributesRoot}", attributes.root);
+ Logger.Debug("colormap: {AttributesColormap}", attributes.colormap);
var screenBounds = screen.Bounds;
var imagePtr = XGetImage(
@@ -345,8 +376,8 @@ internal static Image TakeScreenshotWithX11(Screen screen)
// For simplicity, assuming a direct byte copy is feasible for common ZPIXMAP depths (e.g., 24 or 32 bits).
var bytesPerPixel = xImage.depth / 8;
var pixelDataSize = xImage.width * xImage.height * bytesPerPixel;
- DebugHelper.Logger?.Debug("bytesPerPixel: {bytesPerPixel}", bytesPerPixel);
- DebugHelper.Logger?.Debug("pixelDataSize: {pixelDataSize}", pixelDataSize);
+ Logger.Debug("bytesPerPixel: {BytesPerPixel}", bytesPerPixel);
+ Logger.Debug("pixelDataSize: {PixelDataSize}", pixelDataSize);
// Create a byte array to hold the pixel data
var pixelData = new byte[pixelDataSize];
@@ -529,7 +560,7 @@ public struct XSelectionRequestEvent
// private static readonly IntPtr XA_PRIMARY = 1;
internal const IntPtr XA_CLIPBOARD = 2;
- public override void CopyText(string text)
+ public void CopyText(string text)
{
if (IsWayland())
{
@@ -540,7 +571,7 @@ public override void CopyText(string text)
var display = XOpenDisplay(null);
if (display == IntPtr.Zero)
{
- DebugHelper.Logger?.Debug("Unable to open X11 display");
+ Logger.Debug("Unable to open X11 display");
return;
}
var root = XDefaultRootWindow(display);
@@ -621,7 +652,7 @@ public Rectangle GetScreenBounds()
}
}
- public override void CopyImage(Image image, string? filename)
+ public void CopyImage(Image image, string? filename)
{
using var ms = new MemoryStream();
// Save the image in a format that ImageSharp understands for re-loading/processing
@@ -635,7 +666,7 @@ public override void CopyImage(Image image, string? filename)
if (IsWayland())
{
- DebugHelper.Logger?.Debug("LinuxAPI.CopyImage - Wayland only code");
+ Logger.Debug("LinuxAPI.CopyImage - Wayland only code");
// For Wayland, you'd need wl-clipboard or similar native Wayland protocols.
// This X11 implementation does not apply to Wayland.
// return;
@@ -644,12 +675,12 @@ public override void CopyImage(Image image, string? filename)
try
{
// Get the singleton instance of the clipboard handler and set the image
- X11ClipboardHandler.Instance.SetImage(imageForClipboard, filename);
- DebugHelper.Logger?.Debug("X11 image clipboard initiated.");
+ new X11ClipboardHandler(Logger).SetImage(imageForClipboard, filename);
+ Logger.Debug("X11 image clipboard initiated");
}
catch (Exception ex)
{
- DebugHelper.Logger?.Error($"Failed to set X11 clipboard image: {ex.Message}");
+ Logger.Error("Failed to set X11 clipboard image: {ExMessage}", ex.Message);
}
}
@@ -659,13 +690,7 @@ private static Rectangle GetWindowRectangleX11(IntPtr windowHandle)
if (display == IntPtr.Zero)
throw new InvalidOperationException("Unable to open X11 display.");
- var attributes = new XWindowAttributes();
- if (XGetWindowAttributes(display, windowHandle, out attributes) != 0)
- {
- return new Rectangle(attributes.x, attributes.y, attributes.width, attributes.height);
- }
-
- throw new InvalidOperationException("Unable to get window attributes.");
+ return XGetWindowAttributes(display, windowHandle, out var attributes) != 0 ? new Rectangle(attributes.x, attributes.y, attributes.width, attributes.height) : throw new InvalidOperationException("Unable to get window attributes.");
}
[LibraryImport(LibX11)]
@@ -681,9 +706,9 @@ internal static partial int XQueryPointer(
out int mask
);
- public override Point GetCursorPosition()
+ public Point GetCursorPosition()
{
- DebugHelper.Logger?.Debug("Get cursor position");
+ Logger.Debug("Get cursor position");
var display = XOpenDisplay(null);
if (display == IntPtr.Zero)
{
@@ -707,7 +732,7 @@ out var mask
);
XCloseDisplay(display);
- DebugHelper.Logger?.Debug(
+ Logger.Debug(
"Cursor position: {RootX}, {RootY}, {WinX}, {WinY}, {Mask}",
rootX,
rootY,
diff --git a/SnapX.Core/Utils/Native/MacOSAPI.cs b/SnapX.Core/Utils/Native/MacOSAPI.cs
index 1c82e836a..d2a69bf7e 100644
--- a/SnapX.Core/Utils/Native/MacOSAPI.cs
+++ b/SnapX.Core/Utils/Native/MacOSAPI.cs
@@ -3,10 +3,11 @@
using System.Text.RegularExpressions;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
+using SnapX.Core.Media;
namespace SnapX.Core.Utils.Native;
-public class MacOSAPI : NativeAPI
+public partial class MacOSAPI : INativeAPI
{
private static string GenerateFastString(int length)
{
@@ -17,13 +18,12 @@ private static string GenerateFastString(int length)
result[i] = chars[random.Next(chars.Length)];
return new string(result);
}
- public override void CopyImage(Image image)
- {
- CopyImage(image, GenerateFastString(8) + ".png");
- }
+ private const string CoreGraphics = "/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics";
- public override void CopyImage(Image image, string? fileName)
+
+ public void CopyImage(Image image, string? fileName)
{
+ fileName ??= GenerateFastString(8) + ".png";
var tempPath = Path.Combine(Path.GetTempPath(), $"{Path.GetFileNameWithoutExtension(fileName)}.jpg");
image.Save(tempPath, new JpegEncoder());
var appleScript = $"set the clipboard to (read (POSIX file \"{tempPath}\") as JPEG picture)";
@@ -51,30 +51,65 @@ public override void CopyImage(Image image, string? fileName)
File.Delete(tempPath);
}
+ public Rectangle GetWindowRectangle(WindowInfo window)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Rectangle GetWindowRectangle(IntPtr windowHandle)
+ {
+ throw new NotImplementedException();
+ }
+
+
+ public void ShowWindow(WindowInfo windowInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ShowWindow(IntPtr hwnd)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Image GetJumboFileIcon(string filePath, bool jumboSize = true)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void HideWindow(WindowInfo windowInfo)
+ {
+ throw new NotImplementedException();
+ }
- public override void CopyText(string text)
+ public void HideWindow(IntPtr handle)
+ {
+ throw new NotImplementedException();
+ }
+
+ public List GetWindowList()
+ {
+ throw new NotImplementedException();
+ }
+ public void CopyText(string text)
{
// Escape quotes in the text to ensure AppleScript handles them correctly
// 1. Escape double quotes by replacing `"` with `""` for AppleScript
var escapedText = text.Replace("\"", "\"\"");
- // 2. Escape backslashes by replacing `\` with `\\` (for C# string formatting)
- escapedText = "\"" + Regex.Replace(escapedText, @"(\\+)$", @"$1$1") + "\""; ;
+ // 2. Escape backslashes by replacing `\` with `\\`
+ escapedText = "\"" + Regex.Replace(escapedText, @"(\\+)$", @"$1$1") + "\"";
- // Properly format the AppleScript to set the clipboard
var appleScript = $"set the clipboard to \"{escapedText}\"";
- // Create the process to execute the AppleScript
var process = new Process();
process.StartInfo.FileName = "osascript";
process.StartInfo.Arguments = $"-e \"{appleScript}\"";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
- // Start the process
process.Start();
- // Wait for the process to finish
process.WaitForExit();
}
[StructLayout(LayoutKind.Sequential)]
@@ -83,19 +118,23 @@ struct CGPoint
public double X;
public double Y;
}
+ [LibraryImport(CoreGraphics)]
+ private static partial CGPoint CGEventGetLocation(IntPtr eventRef);
- [DllImport("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics")]
- static extern CGPoint CGEventGetLocation(IntPtr eventRef);
-
- [DllImport("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics")]
- static extern IntPtr CGEventCreate(IntPtr source);
- [DllImport("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics")]
- static extern IntPtr CFRelease(IntPtr eventRef);
- public override Point GetCursorPosition()
+ [LibraryImport(CoreGraphics)]
+ private static partial IntPtr CGEventCreate(IntPtr source);
+ [LibraryImport(CoreGraphics)]
+ private static partial void CFRelease(IntPtr eventRef);
+ public Point GetCursorPosition()
{
var ev = CGEventCreate(IntPtr.Zero);
var point = CGEventGetLocation(ev);
CFRelease(ev);
return new Point((int)point.X, (int)point.Y);
}
+
+ public Screen? GetScreen(Point pos)
+ {
+ throw new NotImplementedException();
+ }
}
diff --git a/SnapX.Core/Utils/Native/Methods.cs b/SnapX.Core/Utils/Native/Methods.cs
index 3e7f0726e..40c322ac7 100644
--- a/SnapX.Core/Utils/Native/Methods.cs
+++ b/SnapX.Core/Utils/Native/Methods.cs
@@ -1,23 +1,26 @@
using SixLabors.ImageSharp;
+using SnapX.Core.Interfaces;
using SnapX.Core.Media;
using SnapX.Core.SharpCapture;
using SnapX.Core.SharpCapture.Linux;
using SnapX.Core.SharpCapture.macOS;
+using SnapX.Core.Utils.Extensions;
#if TARGET_WINDOWS
using SnapX.Core.SharpCapture.Windows;
#endif
namespace SnapX.Core.Utils.Native;
-public static class Methods
+public class Methods(ILoggerService _logger)
{
+ private ILoggerService Logger => _logger;
private static bool IsMacOS => OperatingSystem.IsMacOS();
private static bool IsLinux => OperatingSystem.IsLinux();
private static bool IsWindows => OperatingSystem.IsWindows();
private static bool IsFreeBSD => OperatingSystem.IsFreeBSD();
- internal static NativeAPI NativeAPI
+ internal static INativeAPI NativeAPI
{
get
{
@@ -25,12 +28,12 @@ internal static NativeAPI NativeAPI
return new WindowsAPI();
#else
if (IsMacOS) return new MacOSAPI();
- if (IsLinux || IsFreeBSD) return new LinuxAPI();
+ if (IsLinux || IsFreeBSD) return new LinuxAPI(DebugHelper.Logger as ILoggerService);
throw new PlatformNotSupportedException("This platform is not supported for native API calls.");
#endif
}
}
- private static BaseCapture SharpCapture
+ private static BaseSharpCapture SharpCapture
{
get
{
@@ -44,7 +47,6 @@ private static BaseCapture SharpCapture
}
}
public static List GetWindowList() => NativeAPI.GetWindowList();
-
public static Image GetJumboFileIcon(string filePath, bool jumboSize = true) =>
NativeAPI.GetJumboFileIcon(filePath, jumboSize);
public static void ShowWindow(WindowInfo window) => NativeAPI.ShowWindow(window);
@@ -75,7 +77,7 @@ public static Point GetCursorPosition()
}
catch (Exception ex)
{
- DebugHelper.Logger.Warning(ex.ToString());
+ ex.ShowError();
}
DebugHelper.WriteLine($"GetCursorPosition returned {point}");
return point;
diff --git a/SnapX.Core/Utils/Native/NativeAPI.cs b/SnapX.Core/Utils/Native/NativeAPI.cs
deleted file mode 100644
index 5107f4465..000000000
--- a/SnapX.Core/Utils/Native/NativeAPI.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using SixLabors.ImageSharp;
-using SnapX.Core.Media;
-
-namespace SnapX.Core.Utils.Native;
-
-// Secure, Contain, & Protect.
-public class NativeAPI
-{
- public virtual void ShowWindow(WindowInfo windowInfo) => throw new NotImplementedException("NativeAPI.ShowWindow is not implemented.");
-
- public virtual void ShowWindow(IntPtr hwnd) => throw new NotImplementedException("NativeAPI.ShowWindow is not implemented.");
- public virtual Image GetJumboFileIcon(string filePath, bool jumboSize = true) => throw new NotImplementedException("NativeAPI.GetJumboFileIcon is not implemented.");
- public virtual void HideWindow(WindowInfo windowInfo) => throw new NotImplementedException("NativeAPI.HideWindow is not implemented.");
- public virtual List GetWindowList() => throw new NotImplementedException("NativeAPI.GetWindowList is not implemented.");
- public virtual void HideWindow(IntPtr handle) => throw new NotImplementedException("NativeAPI.HideWindow is not implemented.");
- public virtual void CopyText(string text) => throw new NotImplementedException("NativeAPI.CopyText is not implemented.");
- public virtual void CopyImage(Image image) => CopyImage(image, "image.png"); // this could will never run
-
- public virtual void CopyImage(Image image, string? fileName) => throw new NotImplementedException("NativeAPI.CopyImage is not implemented.");
- public virtual Rectangle GetWindowRectangle(WindowInfo window) => throw new NotImplementedException("NativeAPI.GetWindowRect is not implemented.");
- public virtual Rectangle GetWindowRectangle(IntPtr windowHandle) => throw new NotImplementedException("NativeAPI.GetWindowRect is not implemented.");
- public virtual Point GetCursorPosition() => throw new NotImplementedException("NativeAPI.GetCursorPosition is not implemented.");
- public virtual Screen? GetScreen(Point pos) =>
- throw new NotImplementedException("NativeAPI.GetScreen is not implemented");
-}
diff --git a/SnapX.Core/Utils/Native/WindowsAPI.cs b/SnapX.Core/Utils/Native/WindowsAPI.cs
index 783f2aaee..bf4471c59 100644
--- a/SnapX.Core/Utils/Native/WindowsAPI.cs
+++ b/SnapX.Core/Utils/Native/WindowsAPI.cs
@@ -19,14 +19,14 @@ namespace SnapX.Core.Utils.Native;
// Windows 10 version 1903
[SupportedOSPlatform("windows10.0.18362")]
-public class WindowsAPI : NativeAPI
+public class WindowsAPI : INativeAPI
{
// Constants for allocating memory and setting data format
public const uint CF_TEXT = 1;
private const uint CF_DIB = 8;
private const uint CF_HDROP = 15;
- public override void ShowWindow(WindowInfo Window)
+ public void ShowWindow(WindowInfo Window)
{
var handle = Window.Handle;
if (handle == IntPtr.Zero)
@@ -37,7 +37,7 @@ public override void ShowWindow(WindowInfo Window)
PInvoke.ShowWindow(new HWND(handle), SHOW_WINDOW_CMD.SW_SHOW);
}
- public override void ShowWindow(IntPtr hwnd)
+ public void ShowWindow(IntPtr hwnd)
{
if (hwnd == IntPtr.Zero)
{
@@ -47,6 +47,21 @@ public override void ShowWindow(IntPtr hwnd)
PInvoke.ShowWindow(new HWND(hwnd), SHOW_WINDOW_CMD.SW_SHOW);
}
+ public Image GetJumboFileIcon(string filePath, bool jumboSize = true)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void HideWindow(WindowInfo windowInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void HideWindow(IntPtr handle)
+ {
+ throw new NotImplementedException();
+ }
+
// Method to check if a window is minimized
public static bool IsWindowMinimized(IntPtr hwnd)
{
@@ -99,7 +114,7 @@ private static BOOL EnumWindowsCallback(HWND hwnd, LPARAM lParam)
private static List windowList = [];
- public override List GetWindowList()
+ public List GetWindowList()
{
windowList.Clear();
unsafe
@@ -114,7 +129,7 @@ public override List GetWindowList()
return windowList;
}
- public override void CopyText(string text)
+ public void CopyText(string text)
{
if (!PInvoke.OpenClipboard(new HWND()))
{
@@ -142,12 +157,23 @@ public override void CopyText(string text)
}
}
- public override Point GetCursorPosition()
+ public Rectangle GetWindowRectangle(IntPtr windowHandle)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Point GetCursorPosition()
{
PInvoke.GetCursorPos(out var LpPoint);
return new Point(LpPoint.X, LpPoint.Y);
}
- public override void CopyImage(Image image, string? filename = null)
+
+ public Screen? GetScreen(Point pos)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void CopyImage(Image image, string? filename = null)
{
PInvoke.OpenClipboard(new HWND());
PInvoke.EmptyClipboard();
@@ -202,7 +228,7 @@ public override void CopyImage(Image image, string? filename = null)
}
}
- public override Rectangle GetWindowRectangle(WindowInfo Window)
+ public Rectangle GetWindowRectangle(WindowInfo Window)
{
var handle = Window.Handle;
if (handle == IntPtr.Zero)
diff --git a/SnapX.Core/Utils/Native/X11ClipboardHandler.cs b/SnapX.Core/Utils/Native/X11ClipboardHandler.cs
index a08e4ea6f..505b2d0e1 100644
--- a/SnapX.Core/Utils/Native/X11ClipboardHandler.cs
+++ b/SnapX.Core/Utils/Native/X11ClipboardHandler.cs
@@ -2,14 +2,14 @@
using System.Text;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
+using SnapX.Core.Interfaces;
namespace SnapX.Core.Utils.Native;
public class X11ClipboardHandler : IDisposable
{
- private static X11ClipboardHandler? _instance;
private static readonly Lock _lock = new();
-
+ private readonly ILoggerService Logger;
private IntPtr _display;
private IntPtr _clipboardWindow;
private Thread? _eventThread;
@@ -25,16 +25,16 @@ public class X11ClipboardHandler : IDisposable
private Image? _currentImage;
private string? _currentFilename;
- private X11ClipboardHandler()
+ public X11ClipboardHandler(ILoggerService Logger)
{
_display = LinuxAPI.XOpenDisplay(null);
if (_display == IntPtr.Zero)
{
- throw new Exception("Unable to open X11 display for clipboard handler.");
+ throw new Exception("Unable to open X11 display for clipboard handler");
}
- _clipboardWindow = LinuxAPI.XCreateSimpleWindow(_display, LinuxAPI.XDefaultRootWindow(_display),
- 0, 0, 1, 1, 0, 0, 0);
+ _clipboardWindow = LinuxAPI.XCreateSimpleWindow(_display, LinuxAPI.XDefaultRootWindow(_display), 0, 0, 1, 1, 0, 0, 0);
+ this.Logger = Logger;
LinuxAPI.XSelectInput(_display, _clipboardWindow,
LinuxAPI.SelectionClearMask | LinuxAPI.SelectionRequestMask);
@@ -48,19 +48,7 @@ private X11ClipboardHandler()
};
_eventThread.Start();
- DebugHelper.Logger?.Debug("X11ClipboardHandler initialized and event loop started.");
- }
-
- public static X11ClipboardHandler Instance
- {
- get
- {
- lock (_lock)
- {
- _instance ??= new X11ClipboardHandler();
- return _instance;
- }
- }
+ Logger.Debug("X11ClipboardHandler initialized and event loop started");
}
private void InitializeAtoms()
@@ -85,11 +73,11 @@ public void SetImage(Image image, string? filename = null)
var owner = LinuxAPI.XGetSelectionOwner(_display, _atomClipboard);
if (owner == _clipboardWindow)
{
- DebugHelper.Logger?.Debug($"Successfully claimed X11 CLIPBOARD ownership for image and filename '{_currentFilename}'.");
+ Logger.Debug("Successfully claimed X11 CLIPBOARD ownership for image and filename \'{CurrentFilename}\'", _currentFilename);
}
else
{
- DebugHelper.Logger?.Warning("Failed to claim X11 CLIPBOARD ownership. Another application might be the owner.");
+ Logger.Warning("Failed to claim X11 CLIPBOARD ownership. Another application might be the owner");
}
}
}
@@ -114,16 +102,14 @@ private void EventLoop(CancellationToken cancellationToken)
case LinuxAPI.SelectionClear:
HandleSelectionClear(eventData.xselectionclear);
break;
- default:
- break;
}
}
- DebugHelper.Logger?.Debug("X11ClipboardHandler event loop terminated.");
+ Logger.Debug("X11ClipboardHandler event loop terminated");
}
private void HandleSelectionRequest(LinuxAPI.XSelectionRequestEvent request)
{
- DebugHelper.Logger?.Debug($"SelectionRequest received: Target {GetAtomName(request.target)}");
+ Logger.Debug("SelectionRequest received: Target {AtomName}", GetAtomName(request.target));
var property = request.property;
var type = IntPtr.Zero;
@@ -135,20 +121,20 @@ private void HandleSelectionRequest(LinuxAPI.XSelectionRequestEvent request)
{
if (request.selection != _atomClipboard)
{
- DebugHelper.Logger?.Debug("Selection request for non-CLIPBOARD selection ignored.");
+ Logger.Debug("Selection request for non-CLIPBOARD selection ignored");
return;
}
if (_currentImage == null)
{
- DebugHelper.Logger?.Warning("Selection request received but no image is set.");
+ Logger.Warning("Selection request received but no image is set");
property = IntPtr.Zero;
type = IntPtr.Zero;
}
else if (request.target == _atomTargets)
{
- DebugHelper.Logger?.Debug("Responding to TARGETS request.");
- IntPtr[] supportedTargets = { _atomTargets, _atomPng, _atomImagePng, _atomUtf8String };
+ Logger.Debug("Responding to TARGETS request");
+ IntPtr[] supportedTargets = [_atomTargets, _atomPng, _atomImagePng, _atomUtf8String];
data = new byte[supportedTargets.Length * Marshal.SizeOf()];
for (int i = 0; i < supportedTargets.Length; i++)
{
@@ -160,7 +146,7 @@ private void HandleSelectionRequest(LinuxAPI.XSelectionRequestEvent request)
}
else if (request.target == _atomPng || request.target == _atomImagePng)
{
- DebugHelper.Logger?.Debug($"Responding to image/png request. Image dimensions: {_currentImage.Width}x{_currentImage.Height}");
+ Logger.Debug("Responding to image/png request. Image dimensions: {Width}x{Height}", _currentImage.Width, _currentImage.Height);
using var ms = new MemoryStream();
_currentImage.Save(ms, new PngEncoder());
data = ms.ToArray();
@@ -170,7 +156,7 @@ private void HandleSelectionRequest(LinuxAPI.XSelectionRequestEvent request)
}
else if (request.target == _atomUtf8String && !string.IsNullOrEmpty(_currentFilename))
{
- DebugHelper.Logger?.Debug("Responding to UTF8_STRING request (filename).");
+ Logger.Debug("Responding to UTF8_STRING request (filename)");
data = Encoding.UTF8.GetBytes(_currentFilename);
type = _atomUtf8String;
format = 8;
@@ -178,7 +164,7 @@ private void HandleSelectionRequest(LinuxAPI.XSelectionRequestEvent request)
}
else
{
- DebugHelper.Logger?.Debug($"Unsupported selection target: {GetAtomName(request.target)}.");
+ Logger.Debug("Unsupported selection target: {AtomName}", GetAtomName(request.target));
property = IntPtr.Zero;
type = IntPtr.Zero;
}
@@ -186,17 +172,17 @@ private void HandleSelectionRequest(LinuxAPI.XSelectionRequestEvent request)
if (property != IntPtr.Zero && data != null)
{
LinuxAPI.XChangeProperty(_display, request.requestor, property, type, format, LinuxAPI.PropModeReplace, data, nElements);
- DebugHelper.Logger?.Debug($"XChangeProperty successful for target {GetAtomName(request.target)}.");
+ Logger.Debug("XChangeProperty successful for target {AtomName}", GetAtomName(request.target));
}
else if (property != IntPtr.Zero && data == null)
{
- DebugHelper.Logger?.Debug($"No data to provide for target {GetAtomName(request.target)}, setting property to None.");
+ Logger.Debug("No data to provide for target {AtomName}, setting property to None", GetAtomName(request.target));
property = IntPtr.Zero;
}
}
catch (Exception ex)
{
- DebugHelper.Logger?.Error($"Error handling SelectionRequest: {ex.Message}");
+ Logger.Error("Error handling SelectionRequest: {ExMessage}", ex.Message);
property = IntPtr.Zero;
}
finally
@@ -231,11 +217,11 @@ private void SendSelectionNotify(IntPtr requestor, IntPtr selection, IntPtr targ
if (status == 0)
{
- DebugHelper.Logger?.Warning("XSendEvent for SelectionNotify failed.");
+ Logger.Warning("XSendEvent for SelectionNotify failed");
}
else
{
- DebugHelper.Logger?.Debug($"SelectionNotify sent to {requestor} (property: {GetAtomName(property)}).");
+ Logger.Debug("SelectionNotify sent to {Requestor} (property: {AtomName})", requestor, GetAtomName(property));
}
}
finally
@@ -248,7 +234,7 @@ private void HandleSelectionClear(LinuxAPI.XSelectionClearEvent clear)
{
if (clear.selection == _atomClipboard)
{
- DebugHelper.Logger?.Debug("CLIPBOARD ownership lost (SelectionClear event).");
+ Logger.Debug("CLIPBOARD ownership lost (SelectionClear event)");
lock (_lock)
{
_currentImage = null;
@@ -269,7 +255,7 @@ private string GetAtomName(IntPtr atom)
public void Dispose()
{
- DebugHelper.Logger?.Debug("Disposing X11ClipboardHandler.");
+ Logger.Debug("Disposing X11ClipboardHandler");
_cts.Cancel();
_eventThread?.Join();
@@ -278,11 +264,9 @@ public void Dispose()
LinuxAPI.XDestroyWindow(_display, _clipboardWindow);
_clipboardWindow = IntPtr.Zero;
}
- if (_display != IntPtr.Zero)
- {
- LinuxAPI.XCloseDisplay(_display);
- _display = IntPtr.Zero;
- }
- _instance = null;
+
+ if (_display == IntPtr.Zero) return;
+ LinuxAPI.XCloseDisplay(_display);
+ _display = IntPtr.Zero;
}
}
diff --git a/SnapX.Core/Utils/Parsers/CodeMenuEntry.cs b/SnapX.Core/Utils/Parsers/CodeMenuEntry.cs
index a832d3184..666be06a8 100644
--- a/SnapX.Core/Utils/Parsers/CodeMenuEntry.cs
+++ b/SnapX.Core/Utils/Parsers/CodeMenuEntry.cs
@@ -1,23 +1,11 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
namespace SnapX.Core.Utils.Parsers;
-public abstract class CodeMenuEntry
+public abstract class CodeMenuEntry(string Value, string Description, string? Category = null)
{
protected abstract string Prefix { get; }
- public string Value { get; private set; }
- public string Description { get; private set; }
- public string Category { get; private set; }
-
- public CodeMenuEntry(string value, string description, string category = null)
- {
- Value = value;
- Description = description;
- Category = category;
- }
-
public string ToPrefixString()
{
return ToPrefixString(Prefix);
diff --git a/SnapX.Core/Utils/Parsers/CodeMenuEntryActions.cs b/SnapX.Core/Utils/Parsers/CodeMenuEntryActions.cs
index ca9bf211a..38a28eda2 100644
--- a/SnapX.Core/Utils/Parsers/CodeMenuEntryActions.cs
+++ b/SnapX.Core/Utils/Parsers/CodeMenuEntryActions.cs
@@ -1,16 +1,12 @@
namespace SnapX.Core.Utils.Parsers;
-public class CodeMenuEntryActions : CodeMenuEntry
+public class CodeMenuEntryActions(string Value, string Description) : CodeMenuEntry(Value, Description)
{
protected override string Prefix { get; } = "$";
public static readonly CodeMenuEntryActions input = new("input", "File path");
public static readonly CodeMenuEntryActions output = new("output", "File path with output file name extension");
- public CodeMenuEntryActions(string value, string description) : base(value, description)
- {
- }
-
public static string Parse(string pattern, string inputPath, string outputPath)
{
var result = pattern;
diff --git a/SnapX.Core/Utils/Parsers/CodeMenuEntryFilename.cs b/SnapX.Core/Utils/Parsers/CodeMenuEntryFilename.cs
index 549d13506..9507f9990 100644
--- a/SnapX.Core/Utils/Parsers/CodeMenuEntryFilename.cs
+++ b/SnapX.Core/Utils/Parsers/CodeMenuEntryFilename.cs
@@ -1,6 +1,7 @@
namespace SnapX.Core.Utils.Parsers;
-public class CodeMenuEntryFilename : CodeMenuEntry
+public class CodeMenuEntryFilename(string Value, string Description, string Category = null)
+ : CodeMenuEntry(Value, Description, Category)
{
protected override string Prefix => "%";
@@ -38,9 +39,5 @@ public class CodeMenuEntryFilename : CodeMenuEntry
public static readonly CodeMenuEntryFilename uln = new("uln", "User login name", "Computer");
public static readonly CodeMenuEntryFilename cn = new("cn", "Computer name/HOSTNAME", "Computer");
public static readonly CodeMenuEntryFilename n = new("n", "New line");
-
- public CodeMenuEntryFilename(string value, string description, string category = null) : base(value, description, category)
- {
- }
}
diff --git a/SnapX.Core/Utils/Parsers/CodeMenuEntryPixelInfo.cs b/SnapX.Core/Utils/Parsers/CodeMenuEntryPixelInfo.cs
index b93c80135..ddb552dbd 100644
--- a/SnapX.Core/Utils/Parsers/CodeMenuEntryPixelInfo.cs
+++ b/SnapX.Core/Utils/Parsers/CodeMenuEntryPixelInfo.cs
@@ -4,7 +4,7 @@
namespace SnapX.Core.Utils.Parsers;
-public class CodeMenuEntryPixelInfo : CodeMenuEntry
+public class CodeMenuEntryPixelInfo(string Value, string Description) : CodeMenuEntry(Value, Description)
{
protected override string Prefix { get; } = "$";
@@ -36,10 +36,6 @@ public class CodeMenuEntryPixelInfo : CodeMenuEntry
public static readonly CodeMenuEntryPixelInfo y = new("y", "Y position");
public static readonly CodeMenuEntryPixelInfo n = new("n", "New line");
- public CodeMenuEntryPixelInfo(string value, string description) : base(value, description)
- {
- }
-
public static string Parse(string input, Rgba64 color, Point position)
{
input = input.Replace(r255.ToPrefixString(), color.R.ToString(), StringComparison.InvariantCultureIgnoreCase).
diff --git a/SnapX.Core/Utils/Parsers/NameParser.cs b/SnapX.Core/Utils/Parsers/NameParser.cs
index a84be9f87..491cd1d10 100644
--- a/SnapX.Core/Utils/Parsers/NameParser.cs
+++ b/SnapX.Core/Utils/Parsers/NameParser.cs
@@ -107,14 +107,7 @@ public NameParser(NameParserType nameParserType)
string hour;
- if (sb.ToString().Contains(CodeMenuEntryFilename.pm.ToPrefixString()))
- {
- hour = Helpers.HourTo12(dt.Hour);
- }
- else
- {
- hour = Helpers.AddZeroes(dt.Hour);
- }
+ hour = sb.ToString().Contains(CodeMenuEntryFilename.pm.ToPrefixString()) ? Helpers.HourTo12(dt.Hour) : Helpers.AddZeroes(dt.Hour);
sb.Replace(CodeMenuEntryFilename.h.ToPrefixString(), hour)
.Replace(CodeMenuEntryFilename.mi.ToPrefixString(), Helpers.AddZeroes(dt.Minute))
diff --git a/SnapX.Core/Utils/Random/RandomCrypto.cs b/SnapX.Core/Utils/Random/RandomCrypto.cs
index 105b2e063..55868a70c 100644
--- a/SnapX.Core/Utils/Random/RandomCrypto.cs
+++ b/SnapX.Core/Utils/Random/RandomCrypto.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -9,8 +8,8 @@ namespace SnapX.Core.Utils.Random;
// https://docs.microsoft.com/en-us/archive/msdn-magazine/2007/september/net-matters-tales-from-the-cryptorandom
public static class RandomCrypto
{
- private static readonly object randomLock = new object();
- private static byte[] uint32Buffer = new byte[4];
+ private static readonly Lock randomLock = new();
+ private static readonly byte[] uint32Buffer = new byte[4];
/// Returns a non-negative random integer.
/// A 32-bit signed integer that is greater than or equal to 0 and less than System.Int32.MaxValue.
diff --git a/SnapX.Core/Utils/Random/RandomFast.cs b/SnapX.Core/Utils/Random/RandomFast.cs
index 79b81c3cc..563e8c000 100644
--- a/SnapX.Core/Utils/Random/RandomFast.cs
+++ b/SnapX.Core/Utils/Random/RandomFast.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -6,8 +5,8 @@ namespace SnapX.Core.Utils.Random;
public static class RandomFast
{
- private static readonly object randomLock = new object();
- private static readonly System.Random random = new System.Random();
+ private static readonly Lock randomLock = new();
+ private static readonly System.Random random = new();
/// Returns a non-negative random integer.
/// A 32-bit signed integer that is greater than or equal to 0 and less than System.Int32.MaxValue.
diff --git a/SnapX.Core/Utils/URLHelpers.cs b/SnapX.Core/Utils/URLHelpers.cs
index 19a93ae3a..eafc375e8 100644
--- a/SnapX.Core/Utils/URLHelpers.cs
+++ b/SnapX.Core/Utils/URLHelpers.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/Utils/WebHelpers.cs b/SnapX.Core/Utils/WebHelpers.cs
index 351d5e379..d0891b3b9 100644
--- a/SnapX.Core/Utils/WebHelpers.cs
+++ b/SnapX.Core/Utils/WebHelpers.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -26,7 +25,7 @@ public static async Task DownloadFileAsync(string url, string? filePath)
if (!responseMessage.IsSuccessStatusCode)
{
- DebugHelper.Logger.Error("{url}: {responseMessage.ReasonPhrase}", url, responseMessage);
+ DebugHelper.Logger?.Error("{Url}: {ResponseMessageReasonPhrase}", url, responseMessage);
return;
}
@@ -55,14 +54,14 @@ public static async Task DataURLToImage(string? url)
var base64Data = match.Groups["data"].Value;
- byte[] imageBytes = Convert.FromBase64String(base64Data);
+ var imageBytes = Convert.FromBase64String(base64Data);
using var ms = new MemoryStream(imageBytes);
var image = await Image.LoadAsync(ms);
return image;
}
- public static async Task DownloadStringAsync(string url)
+ public static async Task DownloadStringAsync(string url)
{
if (string.IsNullOrEmpty(url))
{
@@ -71,13 +70,10 @@ public static async Task DownloadStringAsync(string url)
var client = HttpClientFactory.Get();
using var responseMessage = await client.GetAsync(url);
- if (!responseMessage.IsSuccessStatusCode)
- {
- DebugHelper.Logger.Error("{url}: {responseMessage.ReasonPhrase}", url, responseMessage);
- return null;
- }
+ if (responseMessage.IsSuccessStatusCode) return await responseMessage.Content.ReadAsStringAsync();
+ DebugHelper.Logger?.Error("{Url}: {ResponseMessageReasonPhrase}", url, responseMessage);
+ return null;
- return await responseMessage.Content.ReadAsStringAsync();
}
@@ -95,7 +91,7 @@ public static async Task DownloadStringAsync(string url)
}
- public static async Task DownloadImageAsync(string? url)
+ public static async Task DownloadImageAsync(string? url)
{
if (string.IsNullOrEmpty(url)) return null;
@@ -109,13 +105,13 @@ public static async Task DownloadImageAsync(string? url)
return null;
}
- var mediaType = responseMessage.Content.Headers.ContentType.MediaType;
+ var mediaType = responseMessage.Content.Headers.ContentType?.MediaType;
if (mediaType == null)
{
- DebugHelper.Logger.Error("{url}: mediaType is null.", url);
+ DebugHelper.Logger?.Error("{Url}: mediaType is null", url);
return null;
}
- if (!MimeTypesPlus.IsImageMimeType(mediaType))
+ if (!mediaType.Contains("image/"))
return null;
var data = await responseMessage.Content.ReadAsByteArrayAsync();
@@ -127,7 +123,7 @@ public static async Task DownloadImageAsync(string? url)
}
catch (Exception ex)
{
- DebugHelper.Logger.Error("{url}: {message}", url, ex.Message);
+ DebugHelper.Logger?.Error("{Url}: {Message}", url, ex.Message);
DebugHelper.WriteException(ex);
return null;
}
diff --git a/SnapX.Core/VersionEnforcer.cs b/SnapX.Core/VersionEnforcer.cs
index 411b6f5c1..aa0f7b17f 100644
--- a/SnapX.Core/VersionEnforcer.cs
+++ b/SnapX.Core/VersionEnforcer.cs
@@ -3,43 +3,45 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
+using SnapX.Core.Interfaces;
namespace SnapX.Core;
-// I might've lost my marbles working on this class.
-// Sorry for the bad code, but, it works!
-
[JsonSerializable(typeof(VersionEnforcer.LockFileContent))]
internal sealed partial class VersionEnforcerContext : JsonSerializerContext;
public sealed class VersionEnforcer : IDisposable
{
+ private ILoggerService _logger;
private readonly string _lockFilePath;
private FileStream? _lockFileStream;
private readonly string _currentVersion;
private readonly int _currentPID;
private readonly bool _startupFailed;
private bool _ownsLockFile;
+
internal record LockFileContent
{
- public int ProcessId { get; set; }
- public string Version { get; set; }
+ public required int ProcessId { get; set; }
+ public required string Version { get; set; }
}
- public VersionEnforcer(string lockDirectory)
+ public VersionEnforcer(string lockDirectory, ILoggerService logger)
{
if (string.IsNullOrWhiteSpace(lockDirectory))
{
- throw new ArgumentException("Lock directory cannot be null or empty.", nameof(lockDirectory));
+ throw new ArgumentException($"Lock directory cannot be null or empty {nameof(lockDirectory)}");
}
+ _logger = logger;
+
try
{
Directory.CreateDirectory(lockDirectory);
}
catch (Exception ex)
{
- DebugHelper.WriteLine($"VersionEnforcer failed to create lock directory '{lockDirectory}' . Skipping version lock checks. Good luck.");
- DebugHelper.WriteException(ex);
+ _logger.Information("VersionEnforcer failed to create lock directory \'{LockDirectory}\' . Skipping version lock checks. Good luck", lockDirectory);
+ _logger.Error(ex.ToString());
_startupFailed = true;
}
@@ -135,7 +137,7 @@ private void HandleExistingVersion(LockFileContent? lockFileInfo, string existin
var statement = !isPreviousInstanceRunning
? $"Took ownership from previous dead instance (same version, PID: {previousInstance})"
: $"An existing instance (same version, PID: {lockFileInfo?.ProcessId}) was detected. This is supported. :)";
- DebugHelper.WriteLine($"Application (Version: {_currentVersion}) started. {statement}");
+ _logger.Information("Application (Version: {CurrentVersion}) started. {Statement}", _currentVersion, statement);
}
private void HandleNoExistingVersion(ref LockFileContent? lockFileInfo)
@@ -147,14 +149,12 @@ private void HandleNoExistingVersion(ref LockFileContent? lockFileInfo)
};
_ownsLockFile = true;
WriteVersionInfoToLockFile(lockFileInfo);
- DebugHelper.WriteLine(
- $"Application (Version: {_currentVersion}) started. First instance of this version (or lock file was empty).");
+ _logger.Information("Application (Version: {CurrentVersion}) started. First instance of this version (or lock file was empty)", _currentVersion);
}
private void HandleLockFileInUse()
{
- DebugHelper.WriteLine(
- $"Application (Version: {_currentVersion}) detected another instance running which holds the lock. This instance will try to read its version.");
+ _logger.Information("Application (Version: {CurrentVersion}) detected another instance running which holds the lock. This instance will try to read its version", _currentVersion);
try
{
@@ -187,8 +187,7 @@ private void HandleLockFileInUse()
}
if (lockFileInfo?.ProcessId == _currentPID) _ownsLockFile = true;
- DebugHelper.WriteLine(
- $"Application Lock (Version: {_currentVersion}) is compatible with the running instance (same version). Running alongside.");
+ _logger.Information("Application Lock (Version: {CurrentVersion}) is compatible with the running instance (same version). Running alongside", _currentVersion);
}
catch (Exception innerEx)
{
@@ -221,7 +220,7 @@ private void HandleLockFileInUse()
}
catch (Exception ex)
{
- DebugHelper.WriteLine($"VersionLock failed to parse/deserialize LockFile at {_lockFilePath}. Nuking file from orbit.");
+ _logger.Information("VersionLock failed to parse/deserialize LockFile at {LockFilePath}. Nuking file from orbit", _lockFilePath);
DebugHelper.WriteException(ex);
try
{
@@ -260,7 +259,7 @@ private static bool IsProcessRunning(int pid)
}
catch (InvalidOperationException)
{
- // Process has exited (may occur if HasExited was not yet updated).
+ // The process has exited (may occur if HasExited was not yet updated).
return false;
}
catch (Exception)
@@ -274,7 +273,7 @@ private void WriteVersionInfoToLockFile(LockFileContent versionInfo)
{
if (_lockFileStream == null)
{
- DebugHelper.WriteLine($"VersionEnforcer.WriteVersionInfoToLockFile() called when _lockFileStream is null. Redefining.");
+ _logger.Information($"VersionEnforcer.WriteVersionInfoToLockFile() called when _lockFileStream is null. Redefining.");
_lockFileStream = new FileStream(
_lockFilePath,
FileMode.OpenOrCreate,
@@ -302,9 +301,10 @@ public void Dispose()
{
if (_lockFileStream == null)
{
- DebugHelper.WriteLine(_ownsLockFile
- ? $"VersionEnforcer owns the lock file at {_lockFilePath} yet _lockFileStream is null! BUG!"
- : $"VersionLock _lockFileStream is null! Lockfile at {_lockFilePath} ");
+ _logger.Information(_ownsLockFile
+ ? string.Format($"VersionEnforcer owns the lock file at {{0}} yet {nameof(_lockFileStream)} is null! BUG!",
+ _lockFilePath)
+ : string.Format($"VersionLock {nameof(_lockFileStream)} is null! Lockfile at {{0}} ", _lockFilePath));
}
var lockfileInfo = ReadLockFileContent();
if (lockfileInfo is not null && !IsProcessRunning(lockfileInfo.ProcessId)) _ownsLockFile = true;
@@ -317,13 +317,12 @@ public void Dispose()
}
catch (Exception ex)
{
- DebugHelper.WriteLine($"VersionLock failed to delete lockfile {_lockFilePath} while disposing.");
- DebugHelper.WriteException(ex);
+ _logger.Error(ex, "VersionLock failed to delete lockfile {LockFilePath} while disposing", _lockFilePath);
}
}
else
{
- DebugHelper.WriteLine($"VersionEnforcer does not own lockfile {_lockFilePath}. Leaving it be.");
+ _logger.Information("VersionEnforcer does not own lockfile {LockFilePath}. Leaving it be", _lockFilePath);
}
_lockFileStream?.Dispose();
_lockFileStream = null;
diff --git a/SnapX.Core/Watch/WatchFolder.cs b/SnapX.Core/Watch/WatchFolder.cs
index f26ce4493..7767f95b9 100644
--- a/SnapX.Core/Watch/WatchFolder.cs
+++ b/SnapX.Core/Watch/WatchFolder.cs
@@ -1,140 +1,264 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
using System.Diagnostics;
+using Microsoft.Extensions.FileProviders;
using SnapX.Core.Job;
using SnapX.Core.Utils;
namespace SnapX.Core.Watch;
-public class WatchFolder : IDisposable
+public sealed class WatchFolder : IDisposable
{
- public WatchFolderSettings Settings { get; set; }
- public TaskSettings TaskSettings { get; set; }
+ public WatchFolderSettings? Settings { get; set; }
+ public TaskSettings? TaskSettings { get; set; } // Assuming this is for other task-related settings
public delegate void FileWatcherTriggerEventHandler(string? path);
+ public event FileWatcherTriggerEventHandler? FileWatcherTrigger;
- public event FileWatcherTriggerEventHandler FileWatcherTrigger;
-
- private SynchronizationContext context;
- private FileSystemWatcher fileWatcher;
- private List timers = [];
+ private SynchronizationContext _context;
+ private FileSystemWatcher? _fileSystemWatcher;
+ private List _timers = [];
+ private PhysicalFileProvider? _fileProvider;
- public virtual void Enable()
+ ///
+ /// Enables the file watcher.
+ ///
+ public void Enable()
{
Dispose();
- string? folderPath = FileHelpers.ExpandFolderVariables(Settings.FolderPath);
+ if (Settings == null)
+ {
+ DebugHelper.WriteLine("WatchFolder settings are not configured.");
+ return;
+ }
+
+ var folderPath = FileHelpers.ExpandFolderVariables(Settings.FolderPath);
+
+ if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
+ {
+ DebugHelper.WriteLine($"Invalid or non-existent folder path: {folderPath}");
+ return;
+ }
+
+ _context = SynchronizationContext.Current ?? new SynchronizationContext();
- if (!string.IsNullOrEmpty(folderPath) && Directory.Exists(folderPath))
+ try
{
- context = SynchronizationContext.Current ?? new SynchronizationContext();
+ _fileSystemWatcher = new FileSystemWatcher(folderPath);
+ if (!string.IsNullOrEmpty(Settings.Filter))
+ {
+ _fileSystemWatcher.Filter = Settings.Filter;
+ }
+ _fileSystemWatcher.IncludeSubdirectories = Settings.IncludeSubdirectories;
+
+ _fileSystemWatcher.Created += FileWatcher_Created;
+ _fileSystemWatcher.Changed += FileWatcher_Changed;
+ _fileSystemWatcher.Renamed += FileWatcher_Renamed;
+ _fileSystemWatcher.Deleted += FileWatcher_Deleted;
- fileWatcher = new FileSystemWatcher(folderPath);
- if (!string.IsNullOrEmpty(Settings.Filter)) fileWatcher.Filter = Settings.Filter;
- fileWatcher.IncludeSubdirectories = Settings.IncludeSubdirectories;
- fileWatcher.Created += fileWatcher_Created;
- fileWatcher.EnableRaisingEvents = true;
+ _fileSystemWatcher.EnableRaisingEvents = true;
+ DebugHelper.WriteLine($"Started monitoring directory: {folderPath} with filter: {_fileSystemWatcher.Filter}");
+
+ // If you still want to initialize PhysicalFileProvider for other (non-event) purposes:
+ _fileProvider = new PhysicalFileProvider(folderPath)
+ {
+ UsePollingFileWatcher = true,
+ UseActivePolling = true
+ };
+ // Note: _fileProvider won't directly trigger the FileWatcherTrigger event.
+ // You'd need to manually check for changes using IChangeToken if you wanted to use it for eventing.
+ }
+ catch (Exception ex)
+ {
+ DebugHelper.WriteException(ex, $"Error enabling file watcher for {folderPath}");
}
}
- protected void OnFileWatcherTrigger(string? path)
+ ///
+ /// Invokes the FileWatcherTrigger event on the synchronization context.
+ ///
+ /// The path of the file that triggered the event.
+ private void OnFileWatcherTrigger(string? path)
{
- FileWatcherTrigger?.Invoke(path);
+ _context.Post(state => FileWatcherTrigger?.Invoke((string?)state), path);
}
- private async void fileWatcher_Created(object sender, FileSystemEventArgs e)
+ ///
+ /// Handles the FileSystemWatcher.Created event.
+ ///
+ private async void FileWatcher_Created(object sender, FileSystemEventArgs e)
{
- CleanElapsedTimers();
+ DebugHelper.WriteLine($"File created event: {e.FullPath}");
+ await HandleFileEvent(e.FullPath);
+ }
+
+ ///
+ /// Handles the FileSystemWatcher.Changed event.
+ ///
+ private async void FileWatcher_Changed(object sender, FileSystemEventArgs e)
+ {
+ DebugHelper.WriteLine($"File changed event: {e.FullPath}");
+ await HandleFileEvent(e.FullPath);
+ }
+
+ ///
+ /// Handles the FileSystemWatcher.Renamed event.
+ ///
+ private async void FileWatcher_Renamed(object sender, RenamedEventArgs e)
+ {
+ DebugHelper.WriteLine($"File renamed event: Old path: {e.OldFullPath}, New path: {e.FullPath}");
+ // For renamed, we typically care about the new path
+ await HandleFileEvent(e.FullPath);
+ }
- string? path = e.FullPath;
+ ///
+ /// Handles the FileSystemWatcher.Deleted event.
+ ///
+ private void FileWatcher_Deleted(object sender, FileSystemEventArgs e)
+ {
+ DebugHelper.WriteLine($"File deleted event: {e.FullPath}");
+ // No need to wait for file unlock/size for deleted files, just log or trigger if needed.
+ // For deletion, you might have a separate event or just log.
+ // If you need to trigger something for deleted files, consider a separate event or flag in FileWatcherTrigger.
+ }
+
+
+ ///
+ /// Common handler for file system events, including debounce and file locking checks.
+ ///
+ /// The full path of the file.
+ private async Task HandleFileEvent(string path)
+ {
+ CleanElapsedTimers();
- foreach (WatchFolderDuplicateEventTimer timer in timers)
+ // Skip directories for file processing
+ if (Directory.Exists(path))
{
- if (timer.IsDuplicateEvent(path))
- {
- return;
- }
+ DebugHelper.WriteLine($"Skipping directory event for: {path}");
+ return;
}
- timers.Add(new WatchFolderDuplicateEventTimer(path));
+ // Debounce duplicate events
+ if (_timers.Any(timer => timer.IsDuplicateEvent(path)))
+ {
+ DebugHelper.WriteLine($"Skipping duplicate event for: {path}");
+ return;
+ }
+ _timers.Add(new WatchFolderDuplicateEventTimer(path));
- int successCount = 0;
+ var successCount = 0;
long previousSize = -1;
- await Helpers.WaitWhileAsync(() =>
- {
- if (!FileHelpers.IsFileLocked(path))
+ // Wait until the file is no longer locked and its size stabilizes
+ await Helpers.WaitWhileAsync(
+ check: () =>
{
- long currentSize = FileHelpers.GetFileSize(path);
-
- if (currentSize > 0 && currentSize == previousSize)
+ if (!File.Exists(path))
{
- successCount++;
+ DebugHelper.WriteLine($"File {path} no longer exists during processing.");
+ return false;
}
- previousSize = currentSize;
- return successCount < 4;
- }
+ if (!FileHelpers.IsFileLocked(path))
+ {
+ var currentSize = FileHelpers.GetFileSize(path);
- previousSize = -1;
- return true;
- }, 250, 5000, () =>
- {
- context.Post(state => OnFileWatcherTrigger(path), null);
- }, 1000);
+ if (currentSize > 0 && currentSize == previousSize)
+ {
+ successCount++;
+ }
+ else
+ {
+ successCount = 0;
+ }
+
+ previousSize = currentSize;
+ return successCount < 4; // Wait for 4 consecutive stable size readings
+ }
+
+ previousSize = -1; // Reset previous size if file is locked
+ return true;
+ },
+ interval: 250,
+ timeout: 5000,
+ waitStart: 0,
+ onSuccess: () =>
+ {
+ OnFileWatcherTrigger(path);
+ });
}
- protected void CleanElapsedTimers()
+ ///
+ /// Cleans up elapsed duplicate event timers.
+ ///
+ private void CleanElapsedTimers()
{
- for (int i = 0; i < timers.Count; i++)
- {
- if (timers[i].IsElapsed)
- {
- timers.Remove(timers[i]);
- }
- }
+ _timers.RemoveAll(timer => timer.IsElapsed);
}
+ ///
+ /// Disposes the FileSystemWatcher.
+ ///
public void Dispose()
{
- if (fileWatcher != null)
+ if (_fileSystemWatcher != null)
{
- fileWatcher.Dispose();
+ _fileSystemWatcher.EnableRaisingEvents = false;
+ _fileSystemWatcher.Created -= FileWatcher_Created;
+ _fileSystemWatcher.Changed -= FileWatcher_Changed;
+ _fileSystemWatcher.Renamed -= FileWatcher_Renamed;
+ _fileSystemWatcher.Deleted -= FileWatcher_Deleted;
+ _fileSystemWatcher.Dispose();
+ _fileSystemWatcher = null;
+ DebugHelper.WriteLine("FileSystemWatcher disposed.");
}
+ _fileProvider?.Dispose();
+ _fileProvider = null;
}
}
public class WatchFolderDuplicateEventTimer
{
- private const int expireTime = 1000;
+ private const int ExpireTimeMs = 1000; // Timer expires after 1 second
- private Stopwatch timer;
- private string? path;
+ private Stopwatch _timer;
+ private string? _path;
+ ///
+ /// Indicates if the timer has elapsed.
+ ///
public bool IsElapsed
{
get
{
- return timer.ElapsedMilliseconds >= expireTime;
+ return _timer.ElapsedMilliseconds >= ExpireTimeMs;
}
}
+ ///
+ /// Initializes a new instance of the WatchFolderDuplicateEventTimer.
+ ///
+ /// The path of the file.
public WatchFolderDuplicateEventTimer(string? path)
{
- timer = Stopwatch.StartNew();
- this.path = path;
+ _timer = Stopwatch.StartNew();
+ _path = path;
}
+ ///
+ /// Checks if the given path is a duplicate event and restarts the timer if it is.
+ ///
+ /// The path to check.
+ /// True if it's a duplicate event within the expiration time, otherwise false.
public bool IsDuplicateEvent(string? path)
{
- bool result = path == this.path && !IsElapsed;
+ bool result = path == _path && !IsElapsed;
if (result)
{
- timer = Stopwatch.StartNew();
+ _timer.Restart(); // Restart the timer for the duplicate event
}
return result;
}
}
-
diff --git a/SnapX.Core/Watch/WatchFolderManager.cs b/SnapX.Core/Watch/WatchFolderManager.cs
index d3942e982..f47923bc1 100644
--- a/SnapX.Core/Watch/WatchFolderManager.cs
+++ b/SnapX.Core/Watch/WatchFolderManager.cs
@@ -1,8 +1,6 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
-using SnapX.Core.Hotkey;
using SnapX.Core.Job;
using SnapX.Core.Upload;
using SnapX.Core.Utils;
@@ -11,7 +9,7 @@ namespace SnapX.Core.Watch;
public class WatchFolderManager : IDisposable
{
- public List WatchFolders { get; private set; }
+ public List? WatchFolders { get; private set; }
public void UpdateWatchFolders()
{
@@ -27,16 +25,16 @@ public void UpdateWatchFolders()
AddWatchFolder(defaultWatchFolderSetting, SnapX.DefaultTaskSettings);
}
- foreach (HotkeySettings hotkeySetting in SnapX.HotkeysConfig.Hotkeys)
+ foreach (var hotkeySetting in SnapX.HotkeysConfig.Hotkeys)
{
- foreach (WatchFolderSettings watchFolderSetting in hotkeySetting.TaskSettings.WatchFolderList)
+ foreach (var watchFolderSetting in hotkeySetting.TaskSettings.WatchFolderList)
{
AddWatchFolder(watchFolderSetting, hotkeySetting.TaskSettings);
}
}
}
- private WatchFolder FindWatchFolder(WatchFolderSettings watchFolderSetting)
+ private WatchFolder? FindWatchFolder(WatchFolderSettings watchFolderSetting)
{
return WatchFolders.FirstOrDefault(watchFolder => watchFolder.Settings == watchFolderSetting);
}
@@ -46,7 +44,7 @@ private bool IsExist(WatchFolderSettings watchFolderSetting)
return FindWatchFolder(watchFolderSetting) != null;
}
- public void AddWatchFolder(WatchFolderSettings watchFolderSetting, TaskSettings taskSettings)
+ public void AddWatchFolder(WatchFolderSettings watchFolderSetting, TaskSettings? taskSettings)
{
if (!IsExist(watchFolderSetting))
{
@@ -55,19 +53,19 @@ public void AddWatchFolder(WatchFolderSettings watchFolderSetting, TaskSettings
taskSettings.WatchFolderList.Add(watchFolderSetting);
}
- WatchFolder watchFolder = new WatchFolder();
+ var watchFolder = new WatchFolder();
watchFolder.Settings = watchFolderSetting;
watchFolder.TaskSettings = taskSettings;
watchFolder.FileWatcherTrigger += origPath =>
{
var taskSettingsCopy = TaskSettings.GetSafeTaskSettings(taskSettings);
- string? destPath = origPath;
+ var destPath = origPath;
if (watchFolderSetting.MoveFilesToScreenshotsFolder)
{
- string? screenshotsFolder = TaskHelpers.GetScreenshotsFolder(taskSettingsCopy);
- string fileName = Path.GetFileName(origPath);
+ var screenshotsFolder = TaskHelpers.GetScreenshotsFolder(taskSettingsCopy);
+ var fileName = Path.GetFileName(origPath);
destPath = Path.Combine(screenshotsFolder, fileName);
FileHelpers.CreateDirectoryFromFilePath(destPath);
File.Move(origPath, destPath);
@@ -87,43 +85,32 @@ public void AddWatchFolder(WatchFolderSettings watchFolderSetting, TaskSettings
public void RemoveWatchFolder(WatchFolderSettings watchFolderSetting)
{
- using (WatchFolder watchFolder = FindWatchFolder(watchFolderSetting))
- {
- if (watchFolder != null)
- {
- watchFolder.TaskSettings.WatchFolderList.Remove(watchFolderSetting);
- WatchFolders.Remove(watchFolder);
- }
- }
+ using var watchFolder = FindWatchFolder(watchFolderSetting);
+ if (watchFolder == null) return;
+ watchFolder.TaskSettings?.WatchFolderList.Remove(watchFolderSetting);
+ WatchFolders?.Remove(watchFolder);
}
public void UpdateWatchFolderState(WatchFolderSettings watchFolderSetting)
{
- WatchFolder watchFolder = FindWatchFolder(watchFolderSetting);
- if (watchFolder != null)
+ var watchFolder = FindWatchFolder(watchFolderSetting);
+ if (watchFolder == null) return;
+ if (watchFolder.TaskSettings?.WatchFolderEnabled ?? false)
{
- if (watchFolder.TaskSettings.WatchFolderEnabled)
- {
- watchFolder.Enable();
- }
- else
- {
- watchFolder.Dispose();
- }
+ watchFolder.Enable();
+ }
+ else
+ {
+ watchFolder.Dispose();
}
}
public void UnregisterAllWatchFolders()
{
- if (WatchFolders != null)
+ if (WatchFolders == null) return;
+ foreach (var watchFolder in WatchFolders.OfType())
{
- foreach (WatchFolder watchFolder in WatchFolders)
- {
- if (watchFolder != null)
- {
- watchFolder.Dispose();
- }
- }
+ watchFolder.Dispose();
}
}
diff --git a/SnapX.Core/Watch/WatchFolderSettings.cs b/SnapX.Core/Watch/WatchFolderSettings.cs
index ec1edf7c1..e26a06956 100644
--- a/SnapX.Core/Watch/WatchFolderSettings.cs
+++ b/SnapX.Core/Watch/WatchFolderSettings.cs
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/SnapX.Core/XML/org.freedesktop.DBus.xml b/SnapX.Core/XML/org.freedesktop.DBus.xml
new file mode 100644
index 000000000..3f2b33864
--- /dev/null
+++ b/SnapX.Core/XML/org.freedesktop.DBus.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SnapX.Core/XML/org.kde.KWin.ScreenShot2.xml b/SnapX.Core/XML/org.kde.KWin.ScreenShot2.xml
new file mode 100644
index 000000000..bc4eb4039
--- /dev/null
+++ b/SnapX.Core/XML/org.kde.KWin.ScreenShot2.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SnapX.Core/wayland.xml b/SnapX.Core/XML/wayland.xml
similarity index 100%
rename from SnapX.Core/wayland.xml
rename to SnapX.Core/XML/wayland.xml
diff --git a/SnapX.NativeMessagingHost/Program.cs b/SnapX.NativeMessagingHost/Program.cs
index f4495d83f..dd3b84773 100644
--- a/SnapX.NativeMessagingHost/Program.cs
+++ b/SnapX.NativeMessagingHost/Program.cs
@@ -7,7 +7,7 @@
if (args.Length == 0)
{
- Console.WriteLine("This executable is used to receive data from a browser addon and send it to SnapX.");
+ Console.WriteLine(@"This executable is used to receive data from a browser addon and send it to SnapX.");
return;
}
diff --git a/SnapX.NativeMessagingHost/SnapX.NativeMessagingHost.csproj b/SnapX.NativeMessagingHost/SnapX.NativeMessagingHost.csproj
index 7a7743e09..401e124b4 100644
--- a/SnapX.NativeMessagingHost/SnapX.NativeMessagingHost.csproj
+++ b/SnapX.NativeMessagingHost/SnapX.NativeMessagingHost.csproj
@@ -2,6 +2,7 @@
Exe
SnapX_NativeMessagingHost
+ SnapX.NativeMessagingHost.Tests
SnapX NativeMessagingHost
none
false
diff --git a/SnapX.sln b/SnapX.sln
index a21af2f2d..9396cf703 100644
--- a/SnapX.sln
+++ b/SnapX.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32112.339
@@ -21,62 +21,105 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SnapX.NativeMessagingHost",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "build", "build\build.csproj", "{96432C2D-0F1D-4B69-97CB-9F54C1873C1E}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05-4346-4AA6-1389-037BE0695223}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build.Tests", "tests\Build.Tests\Build.Tests.csproj", "{3783A9EF-B03E-48C3-9EF8-91A9E40372B4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C5AE4585-E9EC-4FA3-B75A-E1210635ACB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C5AE4585-E9EC-4FA3-B75A-E1210635ACB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C5AE4585-E9EC-4FA3-B75A-E1210635ACB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C5AE4585-E9EC-4FA3-B75A-E1210635ACB6}.Release|Any CPU.Build.0 = Release|Any CPU
- {E7DE6237-AEA2-498B-8F56-9B392472C490}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E7DE6237-AEA2-498B-8F56-9B392472C490}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E7DE6237-AEA2-498B-8F56-9B392472C490}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E7DE6237-AEA2-498B-8F56-9B392472C490}.Release|Any CPU.Build.0 = Release|Any CPU
- {DBDB0DAA-B3AE-4CC4-A8C2-20550B7F32E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DBDB0DAA-B3AE-4CC4-A8C2-20550B7F32E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DBDB0DAA-B3AE-4CC4-A8C2-20550B7F32E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DBDB0DAA-B3AE-4CC4-A8C2-20550B7F32E3}.Release|Any CPU.Build.0 = Release|Any CPU
- {E1C94415-3424-4517-A2A1-B2FDD1F59C67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E1C94415-3424-4517-A2A1-B2FDD1F59C67}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E1C94415-3424-4517-A2A1-B2FDD1F59C67}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E1C94415-3424-4517-A2A1-B2FDD1F59C67}.Release|Any CPU.Build.0 = Release|Any CPU
- {750C6F46-2C5A-4488-81D3-3B35CA50F3EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {750C6F46-2C5A-4488-81D3-3B35CA50F3EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {750C6F46-2C5A-4488-81D3-3B35CA50F3EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {750C6F46-2C5A-4488-81D3-3B35CA50F3EE}.Release|Any CPU.Build.0 = Release|Any CPU
- {D13441B6-96E1-4D1B-8A95-58A7D6CB1E24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D13441B6-96E1-4D1B-8A95-58A7D6CB1E24}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D13441B6-96E1-4D1B-8A95-58A7D6CB1E24}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D13441B6-96E1-4D1B-8A95-58A7D6CB1E24}.Release|Any CPU.Build.0 = Release|Any CPU
- {1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Release|Any CPU.Build.0 = Release|Any CPU
- {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|x64.Build.0 = Debug|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|x86.Build.0 = Debug|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|x64.ActiveCfg = Release|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|x64.Build.0 = Release|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|x86.ActiveCfg = Release|Any CPU
+ {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|x86.Build.0 = Release|Any CPU
{74428450-9146-4434-B34F-D9D3213D7B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74428450-9146-4434-B34F-D9D3213D7B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Debug|x64.Build.0 = Debug|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Debug|x86.Build.0 = Debug|Any CPU
{74428450-9146-4434-B34F-D9D3213D7B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74428450-9146-4434-B34F-D9D3213D7B0E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Release|x64.ActiveCfg = Release|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Release|x64.Build.0 = Release|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Release|x86.ActiveCfg = Release|Any CPU
+ {74428450-9146-4434-B34F-D9D3213D7B0E}.Release|x86.Build.0 = Release|Any CPU
{89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Debug|x64.Build.0 = Debug|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Debug|x86.Build.0 = Debug|Any CPU
{89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Release|Any CPU.Build.0 = Release|Any CPU
- {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9C0D2877-B8F3-4D84-BD4C-E89173EBDD96}.Release|Any CPU.Build.0 = Release|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Release|x64.ActiveCfg = Release|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Release|x64.Build.0 = Release|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Release|x86.ActiveCfg = Release|Any CPU
+ {89525D3B-F639-4C0B-8CFF-F55A0C52D344}.Release|x86.Build.0 = Release|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|x64.Build.0 = Debug|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Debug|x86.Build.0 = Debug|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|x64.ActiveCfg = Release|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|x64.Build.0 = Release|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|x86.ActiveCfg = Release|Any CPU
+ {3AAB8CC5-156D-4738-93D3-625BAA9D2ABD}.Release|x86.Build.0 = Release|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Debug|x64.Build.0 = Debug|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Debug|x86.Build.0 = Debug|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Release|x64.ActiveCfg = Release|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Release|x64.Build.0 = Release|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Release|x86.ActiveCfg = Release|Any CPU
+ {254E398D-F7F5-4B2A-9024-5C121EA6C564}.Release|x86.Build.0 = Release|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Debug|x64.Build.0 = Debug|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Debug|x86.Build.0 = Debug|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Release|x64.ActiveCfg = Release|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Release|x64.Build.0 = Release|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Release|x86.ActiveCfg = Release|Any CPU
+ {96432C2D-0F1D-4B69-97CB-9F54C1873C1E}.Release|x86.Build.0 = Release|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Debug|x64.Build.0 = Debug|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Debug|x86.Build.0 = Debug|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Release|x64.ActiveCfg = Release|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Release|x64.Build.0 = Release|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Release|x86.ActiveCfg = Release|Any CPU
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {3783A9EF-B03E-48C3-9EF8-91A9E40372B4} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
+ EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DEACF1C2-28EE-44DF-B55E-2234F6137272}
EndGlobalSection
diff --git a/SnapX.slnx b/SnapX.slnx
index 364873989..7272b6be3 100644
--- a/SnapX.slnx
+++ b/SnapX.slnx
@@ -4,11 +4,12 @@
-
+
-
+
+
\ No newline at end of file
diff --git a/build/Build.cs b/build/Build.cs
index 9b986b6d0..29cc2d14f 100644
--- a/build/Build.cs
+++ b/build/Build.cs
@@ -78,7 +78,7 @@ await FileSystem.FileWriteAllTextAsync(manifestFile, json.ToJsonString(new JsonS
private Task HandleRustLibCopy(string rootDirectory, string outputDir)
{
const string rustLib = "libsnapxrust.dylib";
- var sourcePath = Path.Combine(rootDirectory, "SnapX.Core", "ScreenCapture", "Rust", "target", "release", rustLib);
+ var sourcePath = Path.Combine(rootDirectory, "SnapX.Core", "SharpCapture", "Rust", "target", "release", rustLib);
if (!File.Exists(sourcePath)) return Task.CompletedTask;
diff --git a/build/BuildConfig.cs b/build/BuildConfig.cs
index cb0660494..06aab9622 100644
--- a/build/BuildConfig.cs
+++ b/build/BuildConfig.cs
@@ -34,7 +34,7 @@ public string Docdir
public string Icondir => Path.Join(Datadir, "icons", "hicolor");
public string Runtime { get; set; } = RuntimeInformation.RuntimeIdentifier;
public string Metainfodir => Path.Join(Datadir, "metainfo");
- public string RootDirectory { get; } = Path.GetRelativePath(Directory.GetCurrentDirectory(), DirectoryService.FindRoot());
+ public string RootDirectory { get; set; } = Path.GetRelativePath(Directory.GetCurrentDirectory(), DirectoryService.FindRoot());
public string PackagingDirectory => Path.Combine(RootDirectory, "packaging");
public string Tarballdir => Path.Combine(PackagingDirectory, "tarball");
public string Appdir => Path.Combine(PackagingDirectory, "AppDir");
@@ -82,7 +82,11 @@ public bool ShouldSkip(string stepName)
public string[] Targets { get; init; } = [];
public string[] SkippedStepsRaw { get; init; } = [];
- public string OutputDir { get; init; } = "Output";
+ public string OutputDir
+ {
+ get => field ??= Path.Combine(RootDirectory, "Output");
+ set;
+ }
public string Configuration { get; init; } = "Release";
public bool EnableWrapperScriptFallback { get; init; }
public bool DisableWrapperScript { get; set; } = OperatingSystem.IsWindows();
diff --git a/build/CLI.cs b/build/CLI.cs
index d9b68c2a5..2faabb6d1 100644
--- a/build/CLI.cs
+++ b/build/CLI.cs
@@ -100,7 +100,6 @@ public async Task InvokeAsync(string[] args, Func handle
{
Description = "The directory to output builds artifacts to.",
Arity = ArgumentArity.ExactlyOne,
- DefaultValueFactory = _ => "Output"
};
rootCommand.Options.Add(outputDirOption);
@@ -169,7 +168,7 @@ public async Task InvokeAsync(string[] args, Func handle
var config = new BuildConfig
{
Targets = parseResult.GetValue(targetsArgument) ?? [],
- OutputDir = parseResult.GetValue(outputDirOption) ?? "Output",
+ OutputDir = parseResult.GetValue(outputDirOption)!,
Configuration = parseResult.GetValue(configurationOption) ?? "Release",
ExtraArgs = parseResult.GetValue(extraArgsOption) ?? "",
SkippedStepsRaw = parseResult.GetValue(skipStepOption) ?? [],
@@ -202,7 +201,6 @@ public async Task InvokeAsync(string[] args, Func handle
if (prefix is not null) config.Prefix = prefix;
if (libDir is not null) config.LibDir = libDir;
if (docDir is not null) config.Docdir = docDir;
-
// Set skipped steps based on parsed options
config.SetSkippedSteps(config.SkippedStepsRaw);
diff --git a/build/CommandRunner.cs b/build/CommandRunner.cs
index e9dca3e59..8730c8af4 100644
--- a/build/CommandRunner.cs
+++ b/build/CommandRunner.cs
@@ -16,7 +16,7 @@ public async Task InstallFile(string source, string destination, string permissi
var directoryPath = Path.GetDirectoryName(destination);
if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath) && !File.Exists(directoryPath))
{
- DirectoryService.EnsureDirectoryExists(directoryPath);
+ new DirectoryService(Logger, this).EnsureDirectoryExists(directoryPath);
}
if (source.Contains("dSYM", StringComparison.InvariantCultureIgnoreCase))
{
diff --git a/build/DirectoryService.cs b/build/DirectoryService.cs
index 014fa7cc4..b0d954768 100644
--- a/build/DirectoryService.cs
+++ b/build/DirectoryService.cs
@@ -53,7 +53,7 @@ public static void TryDeleteMatchingFiles(string directoryPath, string[] searchP
TryDeleteFile(file);
}
}
- public static void EnsureDirectoryExists(string directory)
+ public void EnsureDirectoryExists(string directory)
{
if (Directory.Exists(directory)) return;
try
diff --git a/build/FS.cs b/build/FS.cs
index c98b55545..1e3f8b7e0 100644
--- a/build/FS.cs
+++ b/build/FS.cs
@@ -1,6 +1,6 @@
namespace DefaultNamespace;
-public class FS(IBuildLogger Logger, CommandRunner CommandRunner) : IFileSystem
+public class FS(IBuildLogger Logger, ICommandRunner CommandRunner) : IFileSystem
{
public async Task TryDeleteFile(string path)
{
@@ -89,7 +89,7 @@ public async Task FileWriteAllTextAsync(string path, string contents)
public Task EnsureDirectoryExistsAsync(string path)
{
- DirectoryService.EnsureDirectoryExists(path);
+ new DirectoryService(Logger, CommandRunner).EnsureDirectoryExists(path);
return Task.CompletedTask;
}
}
diff --git a/build/IFileSystem.cs b/build/IFileSystem.cs
index 14650de91..e941a491f 100644
--- a/build/IFileSystem.cs
+++ b/build/IFileSystem.cs
@@ -4,6 +4,9 @@ public interface IFileSystem
{
void FileCopy(string sourceFileName, string destFileName, bool overwrite);
void DirectoryDelete(string path, bool recursive);
+ Task TryDeleteMatchingFiles(string directory, string[] searchPatterns);
+ Task TryDeleteEmptyDir(string directory);
+ Task TryDeleteFile(string path);
string[] DirectoryGetFiles(string path, string searchPattern, SearchOption searchOption);
string[] DirectoryGetDirectories(string path, string searchPattern, SearchOption searchOption);
Task FileReadAllTextAsync(string path);
diff --git a/build/Install.cs b/build/Install.cs
index 5f47f496c..65323d8b7 100644
--- a/build/Install.cs
+++ b/build/Install.cs
@@ -1,6 +1,6 @@
namespace DefaultNamespace;
-public class Install(IBuildLogger Logger, ICommandRunner CommandRunner, FS FileSystem, BuildConfig config)
+public class Install(IBuildLogger Logger, ICommandRunner CommandRunner, IFileSystem FileSystem, BuildConfig config)
{
public async Task ProcessInstall()
{
@@ -13,6 +13,7 @@ public async Task ProcessInstall()
private void LogInstallationPaths()
{
Logger.Information($"--- Installation Paths ---");
+ Logger.Information($"Build Output: {config.OutputDir}");
Logger.Information($"Root directory: {config.RootDirectory}");
Logger.Information($"Destination Directory (DESTDIR): {config.DestDir}");
Logger.Information($"Prefix: {config.Prefix}");
diff --git a/build/Program.cs b/build/Program.cs
index 5b2ae808a..916de18d1 100644
--- a/build/Program.cs
+++ b/build/Program.cs
@@ -8,9 +8,8 @@ namespace DefaultNamespace;
internal class Program
{
- private static readonly ConsoleLogger logger = new();
- private static readonly CommandRunner commandRunner = new(logger);
- internal static readonly DirectoryService directoryService = new(logger, commandRunner);
+ private static readonly IBuildLogger logger = new ConsoleLogger();
+ private static readonly ICommandRunner commandRunner = new CommandRunner(logger);
private static readonly FS fileSystem = new(logger, commandRunner);
private async Task ExecuteAsync(BuildConfig config)
diff --git a/build/Tarball.cs b/build/Tarball.cs
index d9fd7419c..b236caec2 100644
--- a/build/Tarball.cs
+++ b/build/Tarball.cs
@@ -1,6 +1,6 @@
namespace DefaultNamespace;
-public class Tarball(IBuildLogger Logger, ICommandRunner CommandRunner, FS FileSystem, BuildConfig config)
+public class Tarball(IBuildLogger Logger, ICommandRunner CommandRunner, IFileSystem FileSystem, BuildConfig config)
{
public async Task ProcessTarball()
{
diff --git a/build/Uninstall.cs b/build/Uninstall.cs
index 6903773dd..3dacbe882 100644
--- a/build/Uninstall.cs
+++ b/build/Uninstall.cs
@@ -1,6 +1,6 @@
namespace DefaultNamespace;
-public class Uninstall(IBuildLogger Logger, FS FileSystem, BuildConfig config)
+public class Uninstall(IBuildLogger Logger, IFileSystem FileSystem, BuildConfig config)
{
private static readonly string[] libraryExtensions = ["*.so", "*.dylib", "*.dll"];
public async Task ProcessUninstall()
diff --git a/build/build.csproj b/build/build.csproj
index d700adb55..7cd3f33cd 100644
--- a/build/build.csproj
+++ b/build/build.csproj
@@ -5,6 +5,7 @@
Exe
DefaultNamespace
preview
+ Build.Tests
diff --git a/tests/Build.Tests/Build.Tests.csproj b/tests/Build.Tests/Build.Tests.csproj
new file mode 100644
index 000000000..6c4f38f52
--- /dev/null
+++ b/tests/Build.Tests/Build.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ enable
+ enable
+ Exe
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Build.Tests/BuildTests.cs b/tests/Build.Tests/BuildTests.cs
new file mode 100644
index 000000000..d8a30e2ce
--- /dev/null
+++ b/tests/Build.Tests/BuildTests.cs
@@ -0,0 +1,65 @@
+namespace DefaultNamespace;
+
+public class BuildTests
+{
+ private static readonly IBuildLogger logger = new ConsoleLogger();
+ private static readonly ICommandRunner commandRunner = new CommandRunner(logger);
+ private static readonly FS fileSystem = new(logger, commandRunner);
+
+ [Test]
+ public async Task Builds()
+ {
+ var cli = new CLI();
+ BuildConfig? config = null;
+ await cli.InvokeAsync([], buildconfig =>
+ {
+ config = buildconfig;
+ return Task.CompletedTask;
+ });
+ if (config is null) throw new NullReferenceException(nameof(config));
+ var buildProcessor = new Build(logger, commandRunner, fileSystem, config);
+
+ await buildProcessor.ProcessBuildProject(config.ProjectsToBuild[0]);
+ }
+
+ [Test, DependsOn(nameof(Builds))]
+ public async Task Installs()
+ {
+ // var snapx = new SnapX.Core.SnapX();
+ // #if RELEASE
+ // snapx.silenceLogging();
+ // #elif DEBUG
+ // #else
+ // snapx.silenceLogging();
+ // #endif
+ // snapx.start([]);
+ //
+ // var CLIManager = snapx.GetCLIManager();
+ //
+ // Task.Run(() => CLIManager.UseCommandLineArgs().GetAwaiter().GetResult()).ConfigureAwait(false).GetAwaiter().GetResult();
+ var cli = new CLI();
+ BuildConfig? config = null;
+ await cli.InvokeAsync([], buildconfig =>
+ {
+ config = buildconfig;
+ return Task.CompletedTask;
+ });
+ if (config is null) throw new NullReferenceException(nameof(config));
+ config.Prefix = Path.Join(Path.DirectorySeparatorChar.ToString(), "usr");
+ config.DestDir = Path.Join(AppContext.BaseDirectory, nameof(BuildTests));
+
+ var installer = new Install(logger, commandRunner, fileSystem, config);
+
+ await installer.ProcessInstall();
+ }
+ [After(Test)]
+ public void Cleanup()
+ {
+ var testDir = Path.Join(AppContext.BaseDirectory, nameof(BuildTests));
+ if (Directory.Exists(testDir))
+ {
+ Directory.Delete(testDir, recursive: true);
+ }
+ }
+
+}
diff --git a/tests/Build.Tests/GlobalHooks.cs b/tests/Build.Tests/GlobalHooks.cs
new file mode 100644
index 000000000..6275eee25
--- /dev/null
+++ b/tests/Build.Tests/GlobalHooks.cs
@@ -0,0 +1,23 @@
+// You can use attributes at the assembly level to apply to all tests in the assembly
+// Here you could define global logic that would affect all tests
+
+[assembly: Retry(3)]
+[assembly: System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+
+namespace DefaultNamespace;
+
+
+public class GlobalHooks
+{
+ [Before(TestSession)]
+ public static void SetUp()
+ {
+ Console.WriteLine(@"Or you can define methods that do stuff before...");
+ }
+
+ [After(TestSession)]
+ public static void CleanUp()
+ {
+ Console.WriteLine(@"...and after!");
+ }
+}