Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions src/Snaply.App/ImageExportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,45 +64,6 @@ internal async Task<string> SaveAutomaticallyAsync(
}
}

internal async Task SaveAsAsync(
RenderedImage image,
string path,
CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrWhiteSpace(path);
string? directory = Path.GetDirectoryName(path);
if (string.IsNullOrWhiteSpace(directory))
{
throw new DirectoryNotFoundException();
}

Directory.CreateDirectory(directory);
string temporaryPath = Path.Combine(
directory,
$".{Path.GetFileName(path)}.{Environment.ProcessId}.{Interlocked.Increment(ref _temporarySequence)}.tmp");
try
{
await using (var stream = new FileStream(
temporaryPath,
FileMode.CreateNew,
FileAccess.Write,
FileShare.None,
131_072,
FileOptions.Asynchronous | FileOptions.WriteThrough))
{
await stream.WriteAsync(image.Png, cancellationToken);
await stream.FlushAsync(cancellationToken);
stream.Flush(true);
}

File.Move(temporaryPath, path, true);
}
finally
{
DeleteTemporaryFile(temporaryPath);
}
}

internal static async Task CopyAsync(RenderedImage image, CancellationToken cancellationToken)
{
for (int attempt = 0; ; attempt++)
Expand Down
55 changes: 0 additions & 55 deletions src/Snaply.App/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@ internal MainViewModel(

internal CaptureMode LastCaptureMode { get; private set; } = CaptureMode.Region;

internal int ImageWidth => _image?.Width ?? 0;

internal int ImageHeight => _image?.Height ?? 0;

internal static string SuggestedFileName =>
ImageExportService.CreateSuggestedFileName(DateTimeOffset.Now);

internal async Task CaptureAsync(CaptureMode mode)
{
if (IsBusy)
Expand Down Expand Up @@ -87,8 +80,6 @@ internal async Task CaptureAsync(CaptureMode mode)
_image = image;
Preview = preview;
HasImage = true;
OnPropertyChanged(nameof(ImageWidth));
OnPropertyChanged(nameof(ImageHeight));

Task<bool> save = TrySaveAutomaticallyAsync(image, operation.Token);
Task<bool> copy = TryCopyAsync(image, operation.Token);
Expand Down Expand Up @@ -128,44 +119,6 @@ internal async Task CaptureAsync(CaptureMode mode)
}
}

internal async Task CopyAsync()
{
if (_image is null || IsBusy)
{
return;
}

HasError = false;
if (await TryCopyAsync(_image, CancellationToken.None))
{
StatusMessage = ResourceText.Get("StatusCopied");
}
else
{
ShowError("ErrorClipboard");
}
}

internal async Task SaveAsAsync(string path)
{
if (_image is null || IsBusy)
{
return;
}

HasError = false;
try
{
await _export.SaveAsAsync(_image, path, CancellationToken.None);
StatusMessage = ResourceText.Get("StatusSaved");
}
catch (Exception exception)
{
LogFailure("SaveAs", exception);
ShowError("ErrorSave");
}
}

internal void OpenFolder()
{
HasError = false;
Expand All @@ -180,14 +133,6 @@ internal void OpenFolder()
}
}

internal void Cancel() => _operation?.Cancel();

internal void ReportSaveFailure(Exception exception)
{
LogFailure("SavePicker", exception);
ShowError("ErrorSave");
}

public void Dispose()
{
_operation?.Cancel();
Expand Down
42 changes: 0 additions & 42 deletions tests/Snaply.App.Tests/ImageExportServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,48 +59,6 @@ await Assert.ThrowsAnyAsync<OperationCanceledException>(() =>
Assert.Empty(Directory.EnumerateFiles(_directory));
}

[Fact]
public async Task Save_as_atomically_replaces_existing_file()
{
Directory.CreateDirectory(_directory);
string path = Path.Combine(_directory, "capture.png");
CancellationToken cancellationToken = TestContext.Current.CancellationToken;
await File.WriteAllBytesAsync(path, [9], cancellationToken);
var service = new ImageExportService(_directory);
var image = new RenderedImage([7, 8], 1, 1);

await service.SaveAsAsync(image, path, cancellationToken);

Assert.Equal(image.Png, await File.ReadAllBytesAsync(path, cancellationToken));
Assert.Empty(TemporaryFiles());
}

[Fact]
public async Task Locked_destination_preserves_existing_file_and_removes_temporary_file()
{
Directory.CreateDirectory(_directory);
string path = Path.Combine(_directory, "capture.png");
CancellationToken cancellationToken = TestContext.Current.CancellationToken;
await File.WriteAllBytesAsync(path, [9], cancellationToken);
var service = new ImageExportService(_directory);
await using (var locked = new FileStream(
path,
FileMode.Open,
FileAccess.Read,
FileShare.None))
{
Exception? exception = await Record.ExceptionAsync(() =>
service.SaveAsAsync(
new RenderedImage([7, 8], 1, 1),
path,
cancellationToken));
Assert.True(exception is IOException or UnauthorizedAccessException);
}

Assert.Equal(new byte[] { 9 }, await File.ReadAllBytesAsync(path, cancellationToken));
Assert.Empty(TemporaryFiles());
}

public void Dispose()
{
if (Directory.Exists(_directory))
Expand Down
Loading