This commit is contained in:
Thorsten Sommer 2025-04-23 13:11:43 +02:00 committed by GitHub
commit 40a0b19d91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 81 additions and 37 deletions

View File

@ -8,51 +8,23 @@
<PreviewExperimental ApplyInnerScrollingFix="true"/>
<ProviderSelection @bind-ProviderSettings="@this.providerSettings"/>
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Download" OnClick="@(() => this.LoadTextFile())" Color="Color.Primary" Class="mb-2">
Load a text file
</MudButton>
<InnerScrolling>
<ChildContent>
<MudTextField
@ref="@this.textField"
T="string"
Label="Write your text"
@bind-Text="@this.userInput"
Immediate="@true"
Lines="16"
MaxLines="16"
Typo="Typo.body1"
Variant="Variant.Outlined"
InputMode="InputMode.text"
FullWidth="@true"
OnKeyDown="@this.InputKeyEvent"
UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField
T="string"
Label="Your stage directions"
@bind-Text="@this.userDirection"
Immediate="@true"
Lines="4"
MaxLines="4"
Typo="Typo.body1"
Variant="Variant.Outlined"
InputMode="InputMode.text"
FullWidth="@true"
UserAttributes="@USER_INPUT_ATTRIBUTES"/>
@foreach (var chunk in this.chunks)
{
<MudJustifiedText Typo="Typo.body1" Class="ma-3 write-mode-chunk">
@chunk.Content
</MudJustifiedText>
}
</ChildContent>
<FooterContent>
@if (this.isStreaming)
{
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="mb-6" />
}
<MudTextField
T="string"
Label="Suggestion"
@bind-Text="@this.suggestion"
ReadOnly="@true"
Lines="3"
Typo="Typo.body1"
Variant="Variant.Outlined"
FullWidth="@true"
UserAttributes="@USER_INPUT_ATTRIBUTES"/>
</FooterContent>
</InnerScrolling>
</div>

View File

@ -1,6 +1,9 @@
using System.Text;
using AIStudio.Chat;
using AIStudio.Components;
using AIStudio.Provider;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
@ -14,6 +17,9 @@ public partial class Writer : MSGComponentBase, IAsyncDisposable
[Inject]
private ILogger<Chat> Logger { get; init; } = null!;
[Inject]
private RustService RustService { get; init; } = null!;
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
private readonly Timer typeTimer = new(TimeSpan.FromMilliseconds(1_500));
@ -22,6 +28,7 @@ public partial class Writer : MSGComponentBase, IAsyncDisposable
private ChatThread? chatThread;
private bool isStreaming;
private string userInput = string.Empty;
private List<WriterChunk> chunks = new();
private string userDirection = string.Empty;
private string suggestion = string.Empty;
@ -46,6 +53,39 @@ public partial class Writer : MSGComponentBase, IAsyncDisposable
#endregion
private bool IsProviderSelected => this.providerSettings.UsedLLMProvider != LLMProviders.NONE;
private async Task LoadTextFile()
{
var result = await this.RustService.SelectFile("Load a text file");
if(result.UserCancelled)
return;
if(!File.Exists(result.SelectedFilePath))
return;
var text = await File.ReadAllTextAsync(result.SelectedFilePath, Encoding.UTF8);
this.userInput = text;
this.ChunkText();
}
private void ChunkText()
{
this.chunks.Clear();
var startIndex = 0;
var contentSpan = this.userInput.AsSpan();
for (var index = 0; index < contentSpan.Length; index++)
{
if (contentSpan[index] is '\n')
{
var endIndex = index;
var lineMemory = this.userInput.AsMemory(startIndex..endIndex);
this.chunks.Add(new WriterChunk(lineMemory, false, false));
startIndex = endIndex + 1;
}
}
this.StateHasChanged();
}
private async Task InputKeyEvent(KeyboardEventArgs keyEvent)
{

View File

@ -0,0 +1,10 @@
namespace AIStudio.Tools;
public sealed class WriterChunk(ReadOnlyMemory<char> content, bool isSelected, bool isProcessing)
{
public ReadOnlyMemory<char> Content = content;
public bool IsSelected = isSelected;
public bool IsProcessing = isProcessing;
}

View File

@ -38,6 +38,28 @@
margin-top: 4px;
}
.write-mode-chunk {
font-size: large;
padding-left: 1.5em;
position: relative;
}
.write-mode-chunk::before {
content: "";
position: absolute;
left: 0;
top: 10%;
height: 80%;
width: 0.8em;
background-color: transparent;
border-radius: 0.4em;
transition: background-color 0.5s ease;
}
.write-mode-chunk:hover::before {
background-color: #5894f3; /* Balkenfarbe im hover-Zustand */
}
.plugin-icon-container {
width: var(--mud-icon-size-large);
height: var(--mud-icon-size-large);