The dialog for file attachments will only open once.

This commit is contained in:
hart_s3 2026-04-14 14:35:17 +02:00
parent 09258c7548
commit 3d03d36f0c
8 changed files with 146 additions and 78 deletions

View File

@ -21,6 +21,7 @@
<MudTooltip Text="@T("Number of attachments")" Placement="Placement.Bottom">
<MudBadge Content="@this.Content.FileAttachments.Count" Color="Color.Primary" Overlap="true" BadgeClass="sources-card-header">
<MudIconButton Icon="@Icons.Material.Filled.AttachFile"
Disabled="@this.isOpeningAttachmentsDialog"
OnClick="@this.OpenAttachmentsDialog"/>
</MudBadge>
</MudTooltip>

View File

@ -102,6 +102,7 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
private ElementReference mathContentContainer;
private string lastMathRenderSignature = string.Empty;
private bool hasActiveMathContainer;
private bool isOpeningAttachmentsDialog;
private bool isDisposed;
#region Overrides of ComponentBase
@ -599,10 +600,22 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
}
private async Task OpenAttachmentsDialog()
{
if (this.isOpeningAttachmentsDialog)
return;
this.isOpeningAttachmentsDialog = true;
try
{
var result = await ReviewAttachmentsDialog.OpenDialogAsync(this.DialogService, this.Content.FileAttachments.ToHashSet());
this.Content.FileAttachments = result.ToList();
}
finally
{
this.isOpeningAttachmentsDialog = false;
}
}
public async ValueTask DisposeAsync()
{

View File

@ -19,6 +19,7 @@
Typo="Typo.body2"
Variant="Variant.Outlined"
ReadOnly="true"
Disabled="@(this.isOpeningFileDialog || this.isOpeningAttachmentsDialog)"
/>
</MudLink>
</MudBadge>
@ -35,6 +36,7 @@
<MudIconButton
Icon="@Icons.Material.Filled.AttachFile"
Color="Color.Default"
Disabled="@(this.isOpeningFileDialog || this.isOpeningAttachmentsDialog)"
OnClick="@this.AddFilesManually"/>
</MudBadge>
</MudTooltip>
@ -45,6 +47,7 @@
<MudIconButton
Icon="@Icons.Material.Filled.AttachFile"
Color="Color.Default"
Disabled="@(this.isOpeningFileDialog || this.isOpeningAttachmentsDialog)"
OnClick="@this.AddFilesManually"/>
</MudTooltip>
}
@ -60,6 +63,7 @@ else
Variant="Variant.Filled"
StartIcon="@Icons.Material.Filled.Add"
Color="Color.Primary"
Disabled="@(this.isOpeningFileDialog || this.isOpeningAttachmentsDialog)"
OnClick="@(() => this.AddFilesManually())"
Style="vertical-align: top; margin-top: -2px;"
Size="Size.Small">

View File

@ -78,6 +78,8 @@ public partial class AttachDocuments : MSGComponentBase
private uint numDropAreasAboveThis;
private bool isComponentHovered;
private bool isDraggingOver;
private bool isOpeningFileDialog;
private bool isOpeningAttachmentsDialog;
#region Overrides of MSGComponentBase
@ -201,6 +203,13 @@ public partial class AttachDocuments : MSGComponentBase
private string dragClass = DEFAULT_DRAG_CLASS;
private async Task AddFilesManually()
{
if (this.isOpeningFileDialog)
return;
this.isOpeningFileDialog = true;
try
{
// Ensure that Pandoc is installed and ready:
var pandocState = await this.PandocAvailabilityService.EnsureAvailabilityAsync(
@ -232,11 +241,28 @@ public partial class AttachDocuments : MSGComponentBase
await this.DocumentPathsChanged.InvokeAsync(this.DocumentPaths);
await this.OnChange(this.DocumentPaths);
}
finally
{
this.isOpeningFileDialog = false;
}
}
private async Task OpenAttachmentsDialog()
{
if (this.isOpeningAttachmentsDialog)
return;
this.isOpeningAttachmentsDialog = true;
try
{
this.DocumentPaths = await ReviewAttachmentsDialog.OpenDialogAsync(this.DialogService, this.DocumentPaths);
}
finally
{
this.isOpeningAttachmentsDialog = false;
}
}
private async Task ClearAllFiles()
{

View File

@ -1,5 +1,5 @@
@inherits MSGComponentBase
<MudButton StartIcon="@Icons.Material.Filled.Description" OnClick="@(async () => await this.SelectFile())" Variant="Variant.Filled" Class="mb-3" Disabled="@this.Disabled">
<MudButton StartIcon="@Icons.Material.Filled.Description" OnClick="@(async () => await this.SelectFile())" Variant="Variant.Filled" Class="mb-3" Disabled="@(this.Disabled || this.isSelectingFile)">
@if (string.IsNullOrWhiteSpace(this.Text))
{
@T("Use file content as input")

View File

@ -31,11 +31,17 @@ public partial class ReadFileContent : MSGComponentBase
[Inject]
private PandocAvailabilityService PandocAvailabilityService { get; init; } = null!;
private bool isSelectingFile;
private async Task SelectFile()
{
if (this.Disabled)
if (this.Disabled || this.isSelectingFile)
return;
this.isSelectingFile = true;
try
{
// Ensure that Pandoc is installed and ready:
var pandocState = await this.PandocAvailabilityService.EnsureAvailabilityAsync(
showSuccessMessage: false,
@ -79,4 +85,9 @@ public partial class ReadFileContent : MSGComponentBase
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Error, T("Failed to load file content")));
}
}
finally
{
this.isSelectingFile = false;
}
}
}

View File

@ -13,7 +13,7 @@
Variant="Variant.Outlined"
/>
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen" Variant="Variant.Outlined" Color="Color.Primary" Disabled="this.Disabled" OnClick="@this.OpenFileDialog">
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen" Variant="Variant.Outlined" Color="Color.Primary" Disabled="@(this.Disabled || this.isOpeningFileDialog)" OnClick="@this.OpenFileDialog">
@T("Choose File")
</MudButton>
</MudStack>

View File

@ -35,6 +35,7 @@ public partial class SelectFile : MSGComponentBase
protected ILogger<SelectFile> Logger { get; init; } = null!;
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
private bool isOpeningFileDialog;
#region Overrides of ComponentBase
@ -54,6 +55,13 @@ public partial class SelectFile : MSGComponentBase
}
private async Task OpenFileDialog()
{
if (this.Disabled || this.isOpeningFileDialog)
return;
this.isOpeningFileDialog = true;
try
{
var response = await this.RustService.SelectFile(this.FileDialogTitle, this.Filter, string.IsNullOrWhiteSpace(this.File) ? null : this.File);
this.Logger.LogInformation($"The user selected the file '{response.SelectedFilePath}'.");
@ -61,4 +69,9 @@ public partial class SelectFile : MSGComponentBase
if (!response.UserCancelled)
this.InternalFileChanged(response.SelectedFilePath);
}
finally
{
this.isOpeningFileDialog = false;
}
}
}