Fix downloadFile

This commit is contained in:
2025-12-30 17:40:08 +01:00
parent 37d66c90d2
commit ce86cba86c
17 changed files with 168 additions and 47 deletions

View File

@@ -0,0 +1,6 @@
namespace salesbook.Maui.Core.Interface;
public interface IFilePreviewService
{
Task Preview(string fileName, string filePath);
}

View File

@@ -1,9 +1,10 @@
using salesbook.Shared.Core.Dto;
using salesbook.Maui.Core.Interface;
using salesbook.Shared.Core.Dto;
using salesbook.Shared.Core.Interface;
namespace salesbook.Maui.Core.Services;
public class AttachedService : IAttachedService
public class AttachedService(IFilePreviewService filePreviewService) : IAttachedService
{
public async Task<AttachedDTO?> SelectImageFromCamera()
{
@@ -95,48 +96,34 @@ public class AttachedService : IAttachedService
};
}
private static async Task<string?> SaveToTempStorage(Stream file, string fileName)
public async Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default)
{
var cacheDirectory = FileSystem.CacheDirectory;
var targetDirectory = Path.Combine(cacheDirectory, "file");
ArgumentNullException.ThrowIfNull(file);
if (!Directory.Exists(targetDirectory)) Directory.CreateDirectory(targetDirectory);
if (file.CanSeek)
file.Position = 0;
var tempFilePath = Path.Combine(targetDirectory, fileName + ".temp");
var filePath = Path.Combine(targetDirectory, fileName);
fileName = Path.GetFileName(fileName);
if (File.Exists(filePath)) return filePath;
var dir = FileSystem.CacheDirectory;
var filePath = Path.Combine(dir, fileName);
try
{
await using var fileStream =
new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
await file.CopyToAsync(fileStream);
File.Move(tempFilePath, filePath);
}
catch (Exception e)
{
Console.WriteLine($"Errore durante il salvataggio dello stream: {e.Message}");
SentrySdk.CaptureException(e);
return null;
}
finally
{
if (File.Exists(tempFilePath)) File.Delete(tempFilePath);
}
await using var fileStream = File.Create(filePath);
await file.CopyToAsync(fileStream, ct);
return filePath;
}
public async Task OpenFile(Stream file, string fileName)
public Task OpenFile(string fileName, string filePath)
{
var filePath = await SaveToTempStorage(file, fileName);
if (filePath is null) return;
await Launcher.OpenAsync(new OpenFileRequest
#if IOS
return filePreviewService.Preview(fileName, filePath);
#else
return Launcher.OpenAsync(new OpenFileRequest
{
Title = "Apri file",
File = new ReadOnlyFile(filePath)
});
#endif
}
}

View File

@@ -5,6 +5,8 @@ using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.Logging;
using MudBlazor.Services;
using MudExtensions.Services;
using salesbook.Maui.Core;
using salesbook.Maui.Core.Interface;
using salesbook.Maui.Core.RestClient.IntegryApi;
using salesbook.Maui.Core.Services;
using salesbook.Maui.Core.System;
@@ -106,6 +108,7 @@ namespace salesbook.Maui
builder.Services.AddSingleton<INetworkService, NetworkService>();
builder.Services.AddSingleton<IGenericSystemService, GenericSystemService>();
builder.Services.AddSingleton<LocalDbService>();
builder.Services.AddSingleton<IFilePreviewService, FilePreviewService>();
_ = typeof(System.Runtime.InteropServices.SafeHandle);
_ = typeof(System.IO.FileStream);

View File

@@ -0,0 +1,11 @@
using salesbook.Maui.Core.Interface;
namespace salesbook.Maui.Core;
public class FilePreviewService :IFilePreviewService
{
public Task Preview(string fileName, string filePath)
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,24 @@
using QuickLook;
using salesbook.Maui.Core.Interface;
using salesbook.Maui.Helpers;
using UIKit;
namespace salesbook.Maui.Core;
public class FilePreviewService : IFilePreviewService
{
public Task Preview(string fileName, string filePath)
{
var currentController = UIApplication.SharedApplication.KeyWindow?.RootViewController;
while (currentController?.PresentedViewController != null)
currentController = currentController.PresentedViewController;
var currentView = currentController?.View;
var qLPreview = new QLPreviewController();
var item = new QlPreviewItemBundle(fileName, filePath);
qLPreview.DataSource = new PreviewControllerDs(item);
currentController?.PresentViewController(qLPreview, true, null);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,16 @@
using QuickLook;
namespace salesbook.Maui.Helpers;
public class PreviewControllerDs(QLPreviewItem item) : QLPreviewControllerDataSource
{
public override nint PreviewItemCount(QLPreviewController controller)
{
return 1;
}
public override IQLPreviewItem GetPreviewItem(QLPreviewController controller, nint index)
{
return item;
}
}

View File

@@ -0,0 +1,19 @@
using Foundation;
using QuickLook;
namespace salesbook.Maui.Helpers;
public class QlPreviewItemBundle(string fileName, string filePath) : QLPreviewItem
{
public override string PreviewItemTitle => fileName;
public override NSUrl PreviewItemUrl
{
get
{
var documents = NSBundle.MainBundle.BundlePath;
var lib = Path.Combine(documents, filePath);
var url = NSUrl.FromFilename(lib);
return url;
}
}
}

View File

@@ -0,0 +1,12 @@
using Foundation;
using QuickLook;
namespace salesbook.Maui.Helpers;
public class QlPreviewItemFileSystem(string fileName, string filePath) : QLPreviewItem
{
public override string PreviewItemTitle => fileName;
public override NSUrl PreviewItemUrl => NSUrl.FromString(filePath);
}

View File

@@ -156,7 +156,7 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="12.2.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="IntegryApiClient.MAUI" Version="1.2.2" />
<PackageReference Include="IntegryApiClient.MAUI" Version="1.2.3" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.120" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.120" />

View File

@@ -121,6 +121,7 @@
background: var(--light-card-background);
border-radius: 16px;
overflow: clip;
min-height: 45px;
margin-bottom: 1rem;
}

View File

@@ -274,9 +274,9 @@ else
</div>
</div>
<MudScrollToTop Selector="#topPage" VisibleCssClass="visible absolute" TopOffset="100" HiddenCssClass="invisible">
<MudFab Size="Size.Small" Color="Color.Primary" StartIcon="@Icons.Material.Rounded.KeyboardArrowUp"/>
</MudScrollToTop>
@* <MudScrollToTop Selector="#topPage" VisibleCssClass="visible absolute" TopOffset="100" HiddenCssClass="invisible"> *@
@* <MudFab Size="Size.Small" Color="Color.Primary" StartIcon="@Icons.Material.Rounded.KeyboardArrowUp"/> *@
@* </MudScrollToTop> *@
</div>
</div>
}

View File

@@ -170,6 +170,7 @@
var matchesText =
(!string.IsNullOrEmpty(user.RagSoc) && user.RagSoc.Contains(filter, StringComparison.OrdinalIgnoreCase)) ||
(!string.IsNullOrEmpty(user.CodContact) && user.CodContact.Contains(filter, StringComparison.OrdinalIgnoreCase)) ||
(!string.IsNullOrEmpty(user.Indirizzo) && user.Indirizzo.Contains(filter, StringComparison.OrdinalIgnoreCase)) ||
(!string.IsNullOrEmpty(user.Telefono) && user.Telefono.Contains(filter, StringComparison.OrdinalIgnoreCase)) ||
(!string.IsNullOrEmpty(user.EMail) && user.EMail.Contains(filter, StringComparison.OrdinalIgnoreCase)) ||

View File

@@ -1,3 +1,4 @@
@using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Core.Dto
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.IntegryApi
@@ -34,12 +35,24 @@
</div>
</div>
<OverlayLayout Visible="VisibleOverlay" />
@code {
[Parameter] public CRMAttachedResponseDTO Attached { get; set; } = new();
private bool VisibleOverlay { get; set; }
private async Task OpenAttached()
{
var bytes = await IntegryApiService.DownloadFileFromRefUuid(Attached.RefUuid, Attached.FileName);
await AttachedService.OpenFile(bytes, Attached.FileName);
VisibleOverlay = true;
StateHasChanged();
await using var file = await IntegryApiService.DownloadFileFromRefUuid(Attached.RefUuid, Attached.FileName);
var path = await AttachedService.SaveToTempStorage(file, Attached.FileName);
VisibleOverlay = false;
StateHasChanged();
await AttachedService.OpenFile(Attached.FileName, path);
}
}

View File

@@ -2,6 +2,7 @@
@using CommunityToolkit.Mvvm.Messaging
@using salesbook.Shared.Components.Layout
@using salesbook.Shared.Components.Layout.Overlay
@using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Components.SingleElements.BottomSheet
@using salesbook.Shared.Core.Dto
@using salesbook.Shared.Core.Dto.Activity
@@ -235,7 +236,7 @@
{
foreach (var file in ActivityFileList)
{
<MudChip T="string" OnClick="@(() => OpenAttached(file.Id, file.FileName))"
<MudChip T="string" OnClick="@(() => OpenAttached(file.FileName))"
OnClose="@(() => DeleteAttach(file))" Color="Color.Default">
@file.FileName
</MudChip>
@@ -304,6 +305,8 @@
<SaveOverlay VisibleOverlay="VisibleOverlay" SuccessAnimation="SuccessAnimation"/>
<OverlayLayout Visible="VisibleLoadingOverlay"/>
<SelectEsito @bind-IsSheetVisible="OpenEsito" @bind-ActivityModel="ActivityModel"
@bind-ActivityModel:after="OnAfterChangeEsito"/>
@@ -332,8 +335,9 @@
private string? LabelSave { get; set; }
//Overlay for save
//Overlay
private bool VisibleOverlay { get; set; }
private bool VisibleLoadingOverlay { get; set; }
private bool SuccessAnimation { get; set; }
private bool OpenEsito { get; set; }
@@ -770,15 +774,29 @@
StateHasChanged();
}
private async Task OpenAttached(string idAttached, string fileName)
private async Task OpenAttached(string fileName)
{
try
{
var bytes = await IntegryApiService.DownloadFile(ActivityModel.ActivityId!, fileName);
await AttachedService.OpenFile(bytes, fileName);
VisibleOverlay = true;
StateHasChanged();
await using var file = await IntegryApiService.DownloadFile(ActivityModel.ActivityId!, fileName);
var path = await AttachedService.SaveToTempStorage(file, fileName);
VisibleOverlay = false;
StateHasChanged();
await AttachedService.OpenFile(fileName, path);
}
catch (Exception ex)
{
if (VisibleOverlay)
{
VisibleOverlay = false;
StateHasChanged();
}
Snackbar.Clear();
Snackbar.Add("Impossibile aprire il file", Severity.Error);
Console.WriteLine($"Errore durante l'apertura del file: {ex.Message}");
@@ -789,7 +807,15 @@
{
if (attached is { FileContent: not null, MimeType: not null })
{
await AttachedService.OpenFile(attached.FileContent!, attached.Name);
VisibleOverlay = true;
StateHasChanged();
var path = await AttachedService.SaveToTempStorage(attached.FileContent!, attached.Name);
VisibleOverlay = false;
StateHasChanged();
await AttachedService.OpenFile(attached.Name, path);
}
else
{

View File

@@ -8,5 +8,7 @@ public interface IAttachedService
Task<AttachedDTO?> SelectImageFromGallery();
Task<AttachedDTO?> SelectFile();
Task<AttachedDTO?> SelectPosition();
Task OpenFile(Stream file, string fileName);
Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default);
Task OpenFile(string fileName, string filePath);
}

View File

@@ -24,7 +24,7 @@
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="8.2.4" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="IntegryApiClient.Core" Version="1.2.2" />
<PackageReference Include="IntegryApiClient.Core" Version="1.2.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="9.0.10" />
<PackageReference Include="Microsoft.Maui.Essentials" Version="9.0.120" />
<PackageReference Include="SourceGear.sqlite3" Version="3.50.4.2" />

View File

@@ -16,7 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="IntegryApiClient.Blazor" Version="1.2.2" />
<PackageReference Include="IntegryApiClient.Blazor" Version="1.2.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.10" />