Finish v1.2.5(11)

This commit is contained in:
MarcoE committed 2026-11-04 15:53:55 +01:00
commit c57df2cbb7
6 files changed
+120 -20

No files matched your search

+7 -5
View File
@@ -16,15 +16,15 @@ public class FileManager(
private async Task<AttachedDto> ConvertToDto(FileInfo file, AttachedDto.TypeAttached type, bool isFromToUpload) private async Task<AttachedDto> ConvertToDto(FileInfo file, AttachedDto.TypeAttached type, bool isFromToUpload)
{ {
var (origUrl, thumbUrl) = await SaveAndCreateThumbAsync( var bytes = await File.ReadAllBytesAsync(file.FullName);
await File.ReadAllBytesAsync(file.FullName), var (origUrl, thumbUrl) = await SaveAndCreateThumbAsync(bytes, file.Name);
file.Name
);
return new AttachedDto return new AttachedDto
{ {
Name = file.Name, Name = file.Name,
Path = file.FullName, Path = file.FullName,
// Servono per inviare le foto rimaste in /toUpload (salvate senza rete).
FileBytes = bytes,
TempPath = origUrl, TempPath = origUrl,
ThumbPath = thumbUrl, ThumbPath = thumbUrl,
Type = type, Type = type,
@@ -101,7 +101,9 @@ public class FileManager(
foreach (var file in toUploadFiles) foreach (var file in toUploadFiles)
{ {
if (!fileNameFilter.Contains(file.Name)) // Scheda.ImageNames contiene il percorso completo restituito da SaveInspectionFile:
// confrontando solo il nome le foto salvate e non ancora inviate non comparivano mai.
if (!fileNameFilter.Contains(file.FullName) && !fileNameFilter.Contains(file.Name))
continue; continue;
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
+2 -2
View File
@@ -30,8 +30,8 @@
<ApplicationId>it.integry.SteUp</ApplicationId> <ApplicationId>it.integry.SteUp</ApplicationId>
<!-- Versions --> <!-- Versions -->
<ApplicationDisplayVersion>1.2.4</ApplicationDisplayVersion> <ApplicationDisplayVersion>1.2.5</ApplicationDisplayVersion>
<ApplicationVersion>10</ApplicationVersion> <ApplicationVersion>11</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion> <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<!-- <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">--> <!-- <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">-->
@@ -171,7 +171,10 @@
</div> </div>
} }
@if (item.p.ToUpload && !ReadOnly) @* Rimovibile anche se gia' salvata o inviata. Non mentre e'
in elaborazione: l'indice della foto serve ancora al
caricamento in background. *@
@if (!ReadOnly && !item.p.ThumbPath.IsNullOrEmpty())
{ {
<button type="button" class="attach-item__remove" <button type="button" class="attach-item__remove"
aria-label="@($"Rimuovi la foto {item.p.Name}")" aria-label="@($"Rimuovi la foto {item.p.Name}")"
@@ -336,6 +339,9 @@
// Gli allegati vivono in AttachedList finche' non si salva: li tracciamo con un flag. // Gli allegati vivono in AttachedList finche' non si salva: li tracciamo con un flag.
private bool _attachmentsDirty; private bool _attachmentsDirty;
private List<AttachedDto>? AttachedList { get; set; } private List<AttachedDto>? AttachedList { get; set; }
// Foto gia' salvate tolte dal rilevatore: si eliminano davvero solo al salvataggio,
// cosi' uscendo senza salvare restano dove sono.
private readonly List<AttachedDto> _removedAttachments = [];
private IDisposable? _backRegistration; private IDisposable? _backRegistration;
// Il tasto indietro puo' arrivare mentre il prompt di uscita e' gia' a video. // Il tasto indietro puo' arrivare mentre il prompt di uscita e' gia' a video.
@@ -505,10 +511,6 @@
} }
private async Task Update(SaveSchedaResponseDto? apiResponse, bool preserveActivityId = false) private async Task Update(SaveSchedaResponseDto? apiResponse, bool preserveActivityId = false)
{
if (!AttachedList.IsNullOrEmpty())
{
foreach (var attached in AttachedList!.Where(x => !x.SavedOnAppData))
{ {
var ispezione = new Ispezione var ispezione = new Ispezione
{ {
@@ -517,7 +519,13 @@
Rilevatore = UserSession.User.Username Rilevatore = UserSession.User.Username
}; };
if (!attached.ToRemove) // Prima di toccare l'ActivityId: le foto gia' inviate vanno tolte dall'attivita'
// su cui sono state caricate.
await RemoveDeletedAttachments(ispezione);
if (!AttachedList.IsNullOrEmpty())
{
foreach (var attached in AttachedList!.Where(x => !x.SavedOnAppData))
{ {
var fileNameAdded = await FileManager.SaveInspectionFile( var fileNameAdded = await FileManager.SaveInspectionFile(
ispezione, ispezione,
@@ -529,9 +537,6 @@
if (fileNameAdded != null) if (fileNameAdded != null)
Scheda.ImageNames.Add(fileNameAdded); Scheda.ImageNames.Add(fileNameAdded);
} }
else
_ = FileManager.RemoveInspectionFile(ispezione, attached.Name!);
}
} }
// Salvando una bozza non tocchiamo l'ActivityId: se la scheda era già sul server, // Salvando una bozza non tocchiamo l'ActivityId: se la scheda era già sul server,
@@ -549,6 +554,70 @@
} }
} }
/// <summary>
/// Elimina le foto salvate che il rilevatore ha tolto dalla scheda: dal server se
/// erano gia' state inviate, poi dal dispositivo e dall'elenco della scheda.
/// Se il server non conferma, la foto resta (sul server e sul dispositivo) invece
/// di sparire solo da qui.
/// </summary>
private async Task RemoveDeletedAttachments(Ispezione ispezione)
{
if (_removedAttachments.Count == 0) return;
var nonEliminate = 0;
foreach (var attached in _removedAttachments)
{
if (attached.Name.IsNullOrEmpty()) continue;
var giaInviata = !attached.ToUpload;
// Una foto ancora "da inviare" di norma non e' sul server, ma l'invio dalla
// card o dalla chiusura ispezione non la sposta fra le inviate: con la rete
// si prova comunque a toglierla, senza bloccare l'eliminazione se non c'e'.
if (Scheda.ActivityId.IsValorized() && (giaInviata || NetworkService.ConnectionAvailable))
{
try
{
await IntegrySteupService.RemoveFile(Scheda.ActivityId!, attached.Name!);
}
catch (Exception e)
{
if (giaInviata)
{
Logger.LogError(e, "Eliminazione della foto {FileName} dal server non riuscita", attached.Name);
nonEliminate++;
continue;
}
Logger.LogWarning(e, "Foto {FileName} non trovata sul server", attached.Name);
}
}
try
{
FileManager.RemoveInspectionFile(ispezione, attached.Name!);
}
catch (Exception e)
{
// Il file orfano non fa danni: conta che la foto esca dalla scheda.
Logger.LogError(e, "Eliminazione del file {FileName} non riuscita", attached.Name);
}
Scheda.ImageNames?.RemoveAll(x => System.IO.Path.GetFileName(x) == attached.Name);
}
_removedAttachments.Clear();
if (nonEliminate > 0)
{
Snackbar.Add(nonEliminate == 1
? "Una foto già inviata non è stata eliminata: riprova con la connessione"
: $"{nonEliminate} foto già inviate non sono state eliminate: riprova con la connessione",
Severity.Warning);
}
}
private async Task UploadFile(Scheda scheda) private async Task UploadFile(Scheda scheda)
{ {
if (AttachedList.IsNullOrEmpty()) return; if (AttachedList.IsNullOrEmpty()) return;
@@ -703,7 +772,8 @@
/// <summary> /// <summary>
/// Salva il lavoro in corso solo sul dispositivo, marcato come da completare. /// Salva il lavoro in corso solo sul dispositivo, marcato come da completare.
/// Niente chiamate al server e niente validazione: una bozza può essere incompleta. /// Niente salvataggio sul server e niente validazione: una bozza può essere incompleta.
/// Unica eccezione: le foto già inviate tolte dal rilevatore si eliminano anche dal server.
/// </summary> /// </summary>
private async Task SaveDraft() private async Task SaveDraft()
{ {
@@ -929,8 +999,22 @@
{ {
if (AttachedList is null || index < 0 || index >= AttachedList.Count) return; if (AttachedList is null || index < 0 || index >= AttachedList.Count) return;
if (AttachedList[index].SavedOnAppData) var attached = AttachedList[index];
AttachedList[index].ToRemove = true;
// Le foto appena scattate stanno solo in memoria: basta toglierle dall'elenco.
if (attached.SavedOnAppData)
{
// Una foto gia' inviata va tolta anche dal server: senza rete resterebbe
// nella scheda inviata pur sparendo dal dispositivo.
if (!attached.ToUpload && !NetworkService.ConnectionAvailable)
{
Snackbar.Clear();
Snackbar.Add("Per eliminare una foto già inviata serve la connessione", Severity.Warning);
return;
}
_removedAttachments.Add(attached);
}
AttachedList.RemoveAt(index); AttachedList.RemoveAt(index);
_attachmentsDirty = true; _attachmentsDirty = true;
-1
View File
@@ -15,7 +15,6 @@ public class AttachedDto
public string? ThumbPath { get; set; } public string? ThumbPath { get; set; }
public bool SavedOnAppData { get; set; } public bool SavedOnAppData { get; set; }
public bool ToRemove { get; set; }
public bool ToUpload { get; set; } public bool ToUpload { get; set; }
public Stream? FileContent => public Stream? FileContent =>
@@ -17,6 +17,7 @@ public interface IIntegrySteupService
Task<SaveSchedaResponseDto?> SaveMultipleSchede(List<SaveRequestDto> request); Task<SaveSchedaResponseDto?> SaveMultipleSchede(List<SaveRequestDto> request);
Task CompleteInspection(string activityId); Task CompleteInspection(string activityId);
Task UploadFile(string activityId, byte[] file, string fileName); Task UploadFile(string activityId, byte[] file, string fileName);
Task RemoveFile(string activityId, string fileName);
Task DeleteScheda(string activityId); Task DeleteScheda(string activityId);
} }
@@ -70,6 +70,20 @@ public class IntegrySteupService(IIntegryApiRestClient integryApiRestClient) : I
content.Dispose(); content.Dispose();
} }
/// <summary>
/// Toglie un allegato dalla scheda. Il server lo riconosce dal nome con cui
/// è stato caricato da <see cref="UploadFile"/>.
/// </summary>
public Task RemoveFile(string activityId, string fileName) =>
integryApiRestClient.AuthorizedGet<object>(
$"{BaseRequest}/removeAttachment",
new Dictionary<string, object?>
{
{ "activityId", activityId },
{ "fileName", fileName }
}
);
public Task DeleteScheda(string activityId) => public Task DeleteScheda(string activityId) =>
integryApiRestClient.AuthorizedGet<object>( integryApiRestClient.AuthorizedGet<object>(
$"{BaseRequest}/deleteScheda", $"{BaseRequest}/deleteScheda",