diff --git a/.gitignore b/.gitignore index d9fe42b..909f9f0 100644 --- a/.gitignore +++ b/.gitignore @@ -824,6 +824,7 @@ FodyWeavers.xml.bak *.exe *.pdb *.dll +!EasyExtractUnitypackageRework/EasyExtractCrossPlatform/ThirdParty/EverythingSdk/Everything64.dll *.dylib # Other @@ -832,4 +833,4 @@ FodyWeavers.xml.bak *.psess *.vsp *.vspx -*.sap \ No newline at end of file +*.sap diff --git a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform.Tests/Services/EverythingSdkBootstrapperTests.cs b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform.Tests/Services/EverythingSdkBootstrapperTests.cs index 3e212ec..19b6116 100644 --- a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform.Tests/Services/EverythingSdkBootstrapperTests.cs +++ b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform.Tests/Services/EverythingSdkBootstrapperTests.cs @@ -118,7 +118,8 @@ public async Task EnsureDllForTestsAsync_ReusesValidExistingDllWithoutRewrite() EverythingSdkBootstrapper.ConfigureForTests( appDataPathOverride: () => appDataPath, validateDllHashOverride: (path, _) => - string.Equals(Path.GetFullPath(path), Path.GetFullPath(dllPath), StringComparison.OrdinalIgnoreCase)); + string.Equals(Path.GetFullPath(path), Path.GetFullPath(dllPath), StringComparison.OrdinalIgnoreCase), + localProbeDirectoriesOverride: () => new[] { sdkDirectory }); var resolvedPath = await EverythingSdkBootstrapper.EnsureDllForTestsAsync(); var currentWriteTime = File.GetLastWriteTimeUtc(dllPath); @@ -132,7 +133,7 @@ public async Task EnsureDllForTestsAsync_ReusesValidExistingDllWithoutRewrite() } [Fact] - public async Task EnsureDllForTestsAsync_SerializesConcurrentReuseWhileValidationRetries() + public async Task EnsureDllForTestsAsync_SerializesConcurrentBundledDllResolution() { if (!OperatingSystem.IsWindows()) return; @@ -160,11 +161,10 @@ public async Task EnsureDllForTestsAsync_SerializesConcurrentReuseWhileValidatio StringComparison.OrdinalIgnoreCase)) return true; - if (Interlocked.Increment(ref validationAttempts) == 1) - throw new SharingViolationIOException(); - + Interlocked.Increment(ref validationAttempts); return true; - }); + }, + localProbeDirectoriesOverride: () => new[] { sdkDirectory }); var callers = Enumerable.Range(0, 4) .Select(_ => EverythingSdkBootstrapper.EnsureDllForTestsAsync()) @@ -173,13 +173,13 @@ public async Task EnsureDllForTestsAsync_SerializesConcurrentReuseWhileValidatio var resolvedPaths = await Task.WhenAll(callers); Assert.All(resolvedPaths, path => Assert.Equal(dllPath, path, true)); - Assert.True(validationAttempts >= 2); + Assert.Equal(1, validationAttempts); Directory.Delete(root, true); } [Fact] - public async Task EnsureDllForTestsAsync_CleansOrphanedTemporaryDlls() + public async Task EnsureDllForTestsAsync_LeavesUnrelatedTemporaryFilesUntouched() { if (!OperatingSystem.IsWindows()) return; @@ -214,12 +214,13 @@ public async Task EnsureDllForTestsAsync_CleansOrphanedTemporaryDlls() return string.Equals(Path.GetFullPath(path), Path.GetFullPath(dllPath), StringComparison.OrdinalIgnoreCase); - }); + }, + localProbeDirectoriesOverride: () => new[] { sdkDirectory }); var resolvedPath = await EverythingSdkBootstrapper.EnsureDllForTestsAsync(); Assert.Equal(dllPath, resolvedPath, true); - Assert.False(File.Exists(orphanedTempPath)); + Assert.True(File.Exists(orphanedTempPath)); Directory.Delete(root, true); } @@ -291,6 +292,18 @@ public void IsTransientDownloadFailure_TruncatedHttpResponse_IsRetryable() Assert.True(EverythingSdkBootstrapper.IsTransientDownloadFailure(exception)); } + [Fact] + public async Task EnsureDllForTestsAsync_MissingBundledDll_DoesNotDownload() + { + if (!OperatingSystem.IsWindows()) + return; + + EverythingSdkBootstrapper.ResetForTests(); + EverythingSdkBootstrapper.ConfigureForTests(localProbeDirectoriesOverride: Array.Empty); + + await Assert.ThrowsAsync(() => EverythingSdkBootstrapper.EnsureDllForTestsAsync()); + } + [Fact] public async Task EnsureDllForTestsAsync_FallsBackToDllNextToTheExecutable() { @@ -368,4 +381,4 @@ public SharingViolationIOException() : base("Simulated sharing violation") HResult = SharingViolationHResult; } } -} \ No newline at end of file +} diff --git a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform.Tests/Utilities/ResponsiveWindowHelperTests.cs b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform.Tests/Utilities/ResponsiveWindowHelperTests.cs new file mode 100644 index 0000000..12762c1 --- /dev/null +++ b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform.Tests/Utilities/ResponsiveWindowHelperTests.cs @@ -0,0 +1,39 @@ +using Avalonia.Controls; +using Avalonia.Threading; +using EasyExtractCrossPlatform.Tests.Support; +using EasyExtractCrossPlatform.Utilities; +using Xunit; + +namespace EasyExtractCrossPlatform.Tests.Utilities; + +public sealed class ResponsiveWindowHelperTests +{ + [Fact] + public Task Enable_WhenWindowWidthChanges_UpdatesLayoutClasses() + { + return HeadlessUi.RunAsync(() => + { + var window = new Window + { + Width = 1700, + Height = 900 + }; + using var subscription = ResponsiveWindowHelper.Enable(window); + + window.Show(); + Assert.Contains("wide", window.Classes); + + window.Width = 1000; + Dispatcher.UIThread.RunJobs(); + Assert.Contains("cozy", window.Classes); + Assert.DoesNotContain("wide", window.Classes); + + window.Width = 900; + Dispatcher.UIThread.RunJobs(); + Assert.Contains("compact", window.Classes); + Assert.DoesNotContain("cozy", window.Classes); + + window.Close(); + }); + } +} diff --git a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/EasyExtractCrossPlatform.csproj b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/EasyExtractCrossPlatform.csproj index f78d31c..4eec19d 100644 --- a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/EasyExtractCrossPlatform.csproj +++ b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/EasyExtractCrossPlatform.csproj @@ -47,6 +47,15 @@ + + + + + + Everything64.dll + PreserveNewest + PreserveNewest + diff --git a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.Appearance.cs b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.Appearance.cs index aabbcdf..9b0d47d 100644 --- a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.Appearance.cs +++ b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.Appearance.cs @@ -171,6 +171,21 @@ private void ApplyResponsiveLayouts() if (_heroGrid is not null) _heroGrid.ColumnDefinitions = new ColumnDefinitions(isCompact ? "*" : "Auto,*"); + if (_startExtractionHeaderContent is not null) + { + _startExtractionHeaderContent.ColumnDefinitions = + new ColumnDefinitions(isCompact ? "*" : "Auto,*"); + _startExtractionHeaderContent.RowDefinitions = + new RowDefinitions(isCompact ? "Auto,Auto" : "Auto"); + } + + if (_queueHeaderGrid is not null) + { + _queueHeaderGrid.ColumnDefinitions = + new ColumnDefinitions(isCompact ? "Auto,*" : "Auto,*,Auto"); + _queueHeaderGrid.RowDefinitions = new RowDefinitions(isCompact ? "Auto,Auto" : "Auto"); + } + if (_footerGrid is not null) { if (isCompact) @@ -300,4 +315,4 @@ private IBrush ResolveDefaultBackgroundBrush() return Background ?? new SolidColorBrush(Colors.Black); } -} \ No newline at end of file +} diff --git a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.SettingsAndLifecycle.cs b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.SettingsAndLifecycle.cs index f5e1dad..4282acf 100644 --- a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.SettingsAndLifecycle.cs +++ b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.SettingsAndLifecycle.cs @@ -16,24 +16,8 @@ private void ApplyWindowPlacement(AppSettings settings) if (sharedPlacement is not null) { ApplyWindowPlacementState(sharedPlacement); - return; } - - var savedWidth = settings.WindowWidth; - var savedHeight = settings.WindowHeight; - - if (savedWidth.HasValue && savedWidth.Value > 0 && !double.IsNaN(savedWidth.Value)) - Width = savedWidth.Value; - - if (savedHeight.HasValue && savedHeight.Value > 0 && !double.IsNaN(savedHeight.Value)) - Height = savedHeight.Value; - - if (savedWidth.HasValue && savedHeight.HasValue && - savedWidth.Value > 0 && savedHeight.Value > 0 && - !double.IsNaN(savedWidth.Value) && !double.IsNaN(savedHeight.Value)) - _lastNormalSize = new Size(savedWidth.Value, savedHeight.Value); - - if (settings.WindowPositionX.HasValue && settings.WindowPositionY.HasValue) + else if (settings.WindowPositionX.HasValue && settings.WindowPositionY.HasValue) { var requestedPosition = new PixelPoint(settings.WindowPositionX.Value, settings.WindowPositionY.Value); var adjustedPosition = EnsureWindowIsVisible(requestedPosition, new Size(Width, Height)); @@ -41,35 +25,11 @@ private void ApplyWindowPlacement(AppSettings settings) _lastNormalPosition = adjustedPosition; } - var restoredState = settings.WindowState == WindowState.Minimized - ? WindowState.Normal - : settings.WindowState; - - WindowState = Enum.IsDefined(typeof(WindowState), restoredState) - ? restoredState - : WindowState.Normal; - - CaptureCurrentBoundsIfNormal(); + EnforceFixedWindowSize(); } private void ApplyWindowPlacementState(WindowPlacementService.WindowPlacementState placement) { - if (placement.Width.HasValue && placement.Width.Value > 0 && !double.IsNaN(placement.Width.Value)) - { - Width = placement.Width.Value; - _settings.WindowWidth = placement.Width.Value; - } - - if (placement.Height.HasValue && placement.Height.Value > 0 && !double.IsNaN(placement.Height.Value)) - { - Height = placement.Height.Value; - _settings.WindowHeight = placement.Height.Value; - } - - if (placement.Width.HasValue && placement.Height.HasValue && - placement.Width.Value > 0 && placement.Height.Value > 0) - _lastNormalSize = new Size(placement.Width.Value, placement.Height.Value); - if (placement.PositionX.HasValue && placement.PositionY.HasValue) { var requestedPosition = new PixelPoint(placement.PositionX.Value, placement.PositionY.Value); @@ -80,15 +40,20 @@ private void ApplyWindowPlacementState(WindowPlacementService.WindowPlacementSta _settings.WindowPositionY = adjustedPosition.Y; } - var restoredState = placement.WindowState == WindowState.Minimized - ? WindowState.Normal - : placement.WindowState; + } - if (Enum.IsDefined(typeof(WindowState), restoredState)) - { - WindowState = restoredState; - _settings.WindowState = restoredState; - } + private void EnforceFixedWindowSize() + { + WindowState = WindowState.Normal; + Width = FixedWindowWidth; + Height = FixedWindowHeight; + _lastNormalSize = new Size(FixedWindowWidth, FixedWindowHeight); + _settings.WindowWidth = FixedWindowWidth; + _settings.WindowHeight = FixedWindowHeight; + _settings.WindowState = WindowState.Normal; + + if (_lastNormalPosition.HasValue) + Position = EnsureWindowIsVisible(_lastNormalPosition.Value, _lastNormalSize.Value); CaptureCurrentBoundsIfNormal(); } @@ -270,4 +235,4 @@ private async void DashboardButton_OnClick(object? sender, RoutedEventArgs e) } } } -} \ No newline at end of file +} diff --git a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.axaml b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.axaml index a36dfec..eaad8f4 100644 --- a/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.axaml +++ b/EasyExtractUnitypackageRework/EasyExtractCrossPlatform/MainWindow.axaml @@ -12,6 +12,14 @@ x:Class="EasyExtractCrossPlatform.MainWindow" Title="{loc:Loc MainWindow_Easyextract}" Icon="/Assets/logo-flat.ico" + Width="1207" + Height="918" + MinWidth="1207" + MaxWidth="1207" + MinHeight="918" + MaxHeight="918" + CanResize="False" + WindowStartupLocation="CenterScreen" TransparencyLevelHint="AcrylicBlur" TransparencyBackgroundFallback="{DynamicResource EasyWindowBackgroundBrush}"> @@ -20,7 +28,7 @@ - + @@ -86,11 +94,11 @@ + + + + + + + + + +