Skip to content

Rework writer mode #376

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 9 additions & 37 deletions app/MindWork AI Studio/Pages/Writer.razor
Original file line number Diff line number Diff line change
Expand Up @@ -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>
40 changes: 40 additions & 0 deletions app/MindWork AI Studio/Pages/Writer.razor.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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));

Expand All @@ -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;

Expand Down Expand Up @@ -56,6 +63,39 @@ protected override async Task OnInitializedAsync()
#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)
{
Expand Down
10 changes: 10 additions & 0 deletions app/MindWork AI Studio/Tools/WriterChunk.cs
Original file line number Diff line number Diff line change
@@ -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;
}
22 changes: 22 additions & 0 deletions app/MindWork AI Studio/wwwroot/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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);
Expand Down