fix(save-attachments): authoritative disk-verify + hide extension in rename UI
Two bugs reported after v1.1.2: 1. False-negative "נכשלו" toast even though the file was on disk. Root cause from the log: Polly's 15s timeout on /NetworkStorage/action/upload fires while the server is still writing larger PDFs, so the client sees TimeoutRejectedException → Outcome.Failed, while the server quietly finishes the write. The outcome is now decided by listing the target folder, not by the upload response. If the upload exception fires, the listing is retried up to 4 times with 2s delays to let the server finish. Saved if the file appears, Failed only if it never does. 2. The filename TextBox in the attachments list exposed the extension (.pdf / .docx). Users have to delete it manually when renaming and risk dropping it. AttachmentRowViewModel now splits FileName into BaseName (editable) and Extension (frozen at construction). The XAML binds the TextBox to BaseName and shows the Extension as a muted adjacent chip. The on-disk filename = BaseName + Extension always. Bump to 1.1.3.0 for the patch release. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.IO;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using MarcusLaw.OutlookAddin.Core.Models;
|
||||
|
||||
@@ -10,23 +11,42 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
[ObservableProperty]
|
||||
private bool isSelected = true;
|
||||
|
||||
public string FileName
|
||||
/// <summary>
|
||||
/// Frozen at construction from the original filename. The user
|
||||
/// edits only the base name; the extension always tags along.
|
||||
/// </summary>
|
||||
public string Extension { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Editable base name without the extension. Setting this rewrites
|
||||
/// <see cref="EspoAttachment.Name"/> as <basename><Extension>.
|
||||
/// </summary>
|
||||
public string BaseName
|
||||
{
|
||||
get => Data.Name;
|
||||
get => Path.GetFileNameWithoutExtension(Data.Name) ?? string.Empty;
|
||||
set
|
||||
{
|
||||
var newName = value ?? string.Empty;
|
||||
if (Data.Name == newName) return;
|
||||
Data.Name = newName;
|
||||
var newBase = (value ?? string.Empty).Trim();
|
||||
var newFull = newBase + Extension;
|
||||
if (Data.Name == newFull) return;
|
||||
Data.Name = newFull;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(FileName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full filename including extension — what actually goes to the
|
||||
/// server. Read-only mirror of <see cref="EspoAttachment.Name"/>.
|
||||
/// </summary>
|
||||
public string FileName => Data.Name;
|
||||
|
||||
public string SizeDisplay { get; }
|
||||
|
||||
public AttachmentRowViewModel(EspoAttachment data)
|
||||
{
|
||||
Data = data;
|
||||
Extension = Path.GetExtension(data.Name) ?? string.Empty;
|
||||
SizeDisplay = ComputeSize(data.ContentBase64);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user