Added support for images (#609)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2025-12-30 18:30:32 +01:00
1 parent ed4c7d215a
commit e9485ca8ea
80 files changed
+1300 -495

No files matched your search

@@ -6,7 +6,7 @@
@T("See how we load your file. Review the content before we process it further.")
</MudJustifiedText>
@if (string.IsNullOrWhiteSpace(this.FilePath))
@if (this.Document is null)
{
<ReadFileContent Text="@T("Load file")" @bind-FileContent="@this.FileContent"/>
}
@@ -14,7 +14,7 @@
{
<MudTextField
T="string"
@bind-Text="@this.FilePath"
Text="@this.Document.FilePath"
AdornmentIcon="@Icons.Material.Filled.FileOpen"
Adornment="Adornment.Start"
Immediate="@true"
@@ -27,43 +27,60 @@
/>
}
<MudTabs Elevation="0" Rounded="true" ApplyEffectsToContainer="true" Outlined="true" PanelClass="pa-2" Class="mb-2">
<MudTabPanel Text="@T("Markdown View")" Icon="@Icons.Material.Filled.TextSnippet">
<MudField
Variant="Variant.Outlined"
AdornmentIcon="@Icons.Material.Filled.Article"
Adornment="Adornment.Start"
Label="@T("Loaded Content")"
FullWidth="true"
Class="ma-2 pe-4"
HelperText="@T("This is the content we loaded from your file — including headings, lists, and formatting. Use this to verify your file loads as expected.")"
>
<div style="max-height: 40vh; overflow-y: auto;">
<MudMarkdown Value="@this.FileContent" Props="Markdown.DefaultConfig" Styling="@this.MarkdownStyling"/>
</div>
</MudField>
</MudTabPanel>
<MudTabPanel Text="@T("Simple View")" Icon="@Icons.Material.Filled.Terminal">
<MudTextField
T="string"
@bind-Text="@this.FileContent"
AdornmentIcon="@Icons.Material.Filled.Article"
Adornment="Adornment.Start"
Immediate="@true"
Label="@T("Loaded Content")"
Variant="Variant.Outlined"
Lines="6"
AutoGrow="@true"
MaxLines="25"
ReadOnly="true"
Class="ma-2"
HelperText="@T("This is the content we loaded from your file — including headings, lists, and formatting. Use this to verify your file loads as expected.")"/>
</MudTabPanel>
</MudTabs>
@if (!this.Document?.Exists ?? false)
{
<MudAlert Severity="Severity.Error" Variant="Variant.Filled" Class="my-2">
@T("The specified file could not be found. The file have been moved, deleted, renamed, or is otherwise inaccessible.")
</MudAlert>
}
else
{
<MudTabs Elevation="0" Rounded="true" ApplyEffectsToContainer="true" Outlined="true" PanelClass="pa-2" Class="mb-2">
@if (this.Document?.IsImage ?? false)
{
<MudTabPanel Text="@T("Image View")" Icon="@Icons.Material.Filled.Image">
<MudImage ObjectFit="ObjectFit.ScaleDown" Style="width: 100%;" Src="@this.Document.FilePathAsUrl"/>
</MudTabPanel>
}
else
{
<MudTabPanel Text="@T("Markdown View")" Icon="@Icons.Material.Filled.TextSnippet">
<MudField
Variant="Variant.Outlined"
AdornmentIcon="@Icons.Material.Filled.Article"
Adornment="Adornment.Start"
Label="@T("Loaded Content")"
FullWidth="true"
Class="ma-2 pe-4"
HelperText="@T("This is the content we loaded from your file — including headings, lists, and formatting. Use this to verify your file loads as expected.")">
<div style="max-height: 40vh; overflow-y: auto;">
<MudMarkdown Value="@this.FileContent" Props="Markdown.DefaultConfig" Styling="@this.MarkdownStyling"/>
</div>
</MudField>
</MudTabPanel>
<MudTabPanel Text="@T("Simple View")" Icon="@Icons.Material.Filled.Terminal">
<MudTextField
T="string"
@bind-Text="@this.FileContent"
AdornmentIcon="@Icons.Material.Filled.Article"
Adornment="Adornment.Start"
Immediate="@true"
Label="@T("Loaded Content")"
Variant="Variant.Outlined"
Lines="6"
AutoGrow="@true"
MaxLines="25"
ReadOnly="true"
Class="ma-2"
HelperText="@T("This is the content we loaded from your file — including headings, lists, and formatting. Use this to verify your file loads as expected.")"/>
</MudTabPanel>
}
</MudTabs>
}
</DialogContent>
<DialogActions>
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
<MudButton OnClick="@this.Close" Variant="Variant.Filled" Color="Color.Primary">
@T("Close")
</MudButton>
</DialogActions>
@@ -1,4 +1,5 @@
using AIStudio.Components;
using AIStudio.Chat;
using AIStudio.Components;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components;
@@ -13,7 +14,7 @@ public partial class DocumentCheckDialog : MSGComponentBase
private IMudDialogInstance MudDialog { get; set; } = null!;
[Parameter]
public string FilePath { get; set; } = string.Empty;
public FileAttachment? Document { get; set; }
private void Close() => this.MudDialog.Cancel();
@@ -27,27 +28,30 @@ public partial class DocumentCheckDialog : MSGComponentBase
private IDialogService DialogService { get; init; } = null!;
[Inject]
private ILogger<ReadFileContent> Logger { get; init; } = null!;
private ILogger<DocumentCheckDialog> Logger { get; init; } = null!;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && !string.IsNullOrWhiteSpace(this.FilePath))
if (firstRender && this.Document is not null)
{
try
{
var fileContent = await UserFile.LoadFileData(this.FilePath, this.RustService, this.DialogService);
this.FileContent = fileContent;
this.StateHasChanged();
if (!this.Document.IsImage)
{
var fileContent = await UserFile.LoadFileData(this.Document.FilePath, this.RustService, this.DialogService);
this.FileContent = fileContent;
}
}
catch (Exception ex)
{
this.Logger.LogError(ex, "Failed to load file content from '{FilePath}'", this.FilePath);
this.Logger.LogError(ex, "Failed to load file content from '{FilePath}'", this.Document);
this.FileContent = string.Empty;
this.StateHasChanged();
}
this.StateHasChanged();
}
else if (firstRender)
this.Logger.LogWarning("Document check dialog opened without a valid file path");
this.Logger.LogWarning("Document check dialog opened without a valid file path.");
}
private CodeBlockTheme CodeColorPalette => this.SettingsManager.IsDarkMode ? CodeBlockTheme.Dark : CodeBlockTheme.Default;
@@ -46,19 +46,24 @@
</MudTooltip>
</div>
<MudTooltip Text="@T("Remove this attachment.")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Delete"
Color="Color.Error"
Class="ml-2"
Style="flex-shrink: 0;"
OnClick="@(() => this.DeleteAttachment(fileAttachment))"/>
</MudTooltip>
<MudToolBar WrapContent="true" Gutters="false" Class="ml-2" Style="flex-shrink: 0; min-height: 1em;">
<MudTooltip Text="@T("Preview what we send to the AI.")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Search"
Color="Color.Primary"
OnClick="@(() => this.InvestigateFile(fileAttachment))"/>
</MudTooltip>
<MudTooltip Text="@T("Remove this attachment.")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Delete"
Color="Color.Error"
OnClick="@(() => this.DeleteAttachment(fileAttachment))"/>
</MudTooltip>
</MudToolBar>
</MudStack>
}
else
{
<MudStack Row Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Class="ms-3 mb-2">
<MudStack Row Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Class="ms-3">
<div style="min-width: 0; flex: 1; overflow: hidden;">
<MudTooltip Text="@T("The file was deleted, renamed, or moved.")" Placement="Placement.Bottom">
<span class="d-inline-flex align-items-center" style="overflow: hidden; width: 100%;">
@@ -70,13 +75,17 @@
</MudTooltip>
</div>
<MudTooltip Text="@T("Remove this attachment.")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Delete"
Color="Color.Error"
Class="ml-2"
Style="flex-shrink: 0;"
OnClick="@(() => this.DeleteAttachment(fileAttachment))"/>
</MudTooltip>
<MudToolBar WrapContent="true" Gutters="false" Class="ml-2" Style="flex-shrink: 0; min-height: 1em;">
<MudIconButton Icon="@Icons.Material.Filled.Search"
Color="Color.Primary"
Disabled="true"/>
<MudTooltip Text="@T("Remove this attachment.")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Delete"
Color="Color.Error"
OnClick="@(() => this.DeleteAttachment(fileAttachment))"/>
</MudTooltip>
</MudToolBar>
</MudStack>
}
}
@@ -85,7 +94,7 @@
</DialogContent>
<DialogActions>
<MudButton OnClick="@this.Close" Variant="Variant.Filled" Color="Color.Primary">
Close
@T("Close")
</MudButton>
</DialogActions>
</MudDialog>
@@ -46,4 +46,18 @@ public partial class ReviewAttachmentsDialog : MSGComponentBase
this.StateHasChanged();
}
}
/// <summary>
/// The user might want to check what we actually extract from his file and therefore give the LLM as an input.
/// </summary>
/// <param name="fileAttachment">The file to check.</param>
private async Task InvestigateFile(FileAttachment fileAttachment)
{
var dialogParameters = new DialogParameters<DocumentCheckDialog>
{
{ x => x.Document, fileAttachment },
};
await this.DialogService.ShowAsync<DocumentCheckDialog>(T("Document Preview"), dialogParameters, DialogOptions.FULLSCREEN);
}
}