Better console now usable

This commit is contained in:
BOTAlex 2024-07-15 04:08:10 +02:00
parent 78bf114130
commit 50c30e3a7e
7 changed files with 120 additions and 39 deletions

View File

@ -1,4 +1,5 @@
@page "/" @page "/"
@inject OpenBirchConsole console
@inject IJSRuntime jsRuntime @inject IJSRuntime jsRuntime
@inject NavigationManager nav @inject NavigationManager nav
@ -10,13 +11,13 @@
<div style="height: 200px; display: grid; place-items: end center;"> <div style="height: 200px; display: grid; place-items: end center;">
<MudPaper Style="background-color: #191724; height: 200px;" Elevation="4" Class="input-field pt-0 console-container"> <MudPaper Style="background-color: #191724; height: 200px;" Elevation="4" Class="input-field pt-0 console-container">
<div style="height: 100%;" class="reverse-stack-direction overflow-hidden"> <div style="height: 100%;" class="reverse-stack-direction overflow-hidden">
@for (int i = 0; i < consoleHistory.Count; i++) @for (int i = 0; i < console.history.Count; i++)
{ {
int temp = i; int temp = i;
<MudText Align="Align.Start"> @((consoleHistory[temp].source == ConsoleSource.User) ? ">" : "#") @consoleHistory[temp].text</MudText> <MudText Align="Align.Start"> @((console.history[temp].source == ConsoleSource.User) ? ">" : "#") @console.history[temp].text</MudText>
} }
</div> </div>
<MudTextField Class="" Style="color: #e0def4;" @bind-Value="inputField" OnKeyDown="OnKeyDown" Variant="Variant.Outlined" @onclick='()=>nav.NavigateTo("openbirch")'></MudTextField> <MudTextField Class="" Style="color: #e0def4;" @bind-Value="inputField" OnKeyDown="OnKeyDown" Variant="Variant.Outlined" @onclick='OnInputClicked'></MudTextField>
</MudPaper> </MudPaper>
</div> </div>
</div> </div>
@ -24,6 +25,7 @@
@code { @code {
public string inputField = " "; public string inputField = " ";
public bool hasInteracted = false; // Has the user interacted with the input field? public bool hasInteracted = false; // Has the user interacted with the input field?
private Task AutoTypingTask;
readonly string[] exampleInputs = { readonly string[] exampleInputs = {
"2+2;", "2+2;",
@ -50,17 +52,16 @@
Console.WriteLine(e); Console.WriteLine(e);
} }
public struct consoleLine
{
public ConsoleSource source;
public string text;
}
public List<consoleLine> consoleHistory = new();
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
StartAutoTyping(); AutoTypingTask = StartAutoTyping();
}
private async void OnInputClicked()
{
hasInteracted = true;
await AutoTypingTask;
nav.NavigateTo("openbirch");
} }
async void OnKeyDown(KeyboardEventArgs args) async void OnKeyDown(KeyboardEventArgs args)
@ -68,28 +69,21 @@
if (args.Key == "Enter") if (args.Key == "Enter")
{ {
await Task.Delay(100); await Task.Delay(100);
pushCommand(inputField); sendCommand(inputField);
inputField = "";
StateHasChanged(); StateHasChanged();
} }
} }
private void pushCommand(string command) private async void sendCommand(string command)
{ {
inputField = ""; // Clear input field inputField = "";
consoleHistory.Add(new consoleLine() { source = ConsoleSource.User, text = command }); await console.pushCommand(command);
InvokeAsync(StateHasChanged);
ExecuteCommand(command);
}
private async Task ExecuteCommand(string command)
{
string result = await jsRuntime.InvokeAsync<string>("runEval", command);
consoleHistory.Add(new consoleLine() { source = ConsoleSource.OpenBirch, text = result });
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }
private async void StartAutoTyping() int typingDelay = 200;
private async Task StartAutoTyping()
{ {
await Task.Delay(1000); await Task.Delay(1000);
@ -101,21 +95,25 @@
await InvokeAsync(StateHasChanged); // Trigger UI update await InvokeAsync(StateHasChanged); // Trigger UI update
await Task.Delay(200); // Non-blocking delay await Task.Delay(200); // Non-blocking delay
if (!hasInteracted) continue; // Makes it check if user inputted while waiting
const int waitTime = 10;
int waitedTime = 0;
while (waitedTime < typingDelay)
{
await Task.Delay(waitTime);
waitedTime += waitTime;
if (!hasInteracted) goto earlyExit;
}
inputField = ""; // Clear input and let user input inputField = ""; // Clear input and let user input
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
return; return;
earlyExit:;
} }
pushCommand(inputField); sendCommand(inputField);
await Task.Delay(500); await Task.Delay(500);
} }
} }
public enum ConsoleSource
{
User, // From the user
OpenBirch, // Guess
}
} }

View File

@ -1,20 +1,50 @@
@page "/openbirch" @page "/openbirch"
@inject OpenBirchConsole console
@inject IJSRuntime js
<div class="console-container reverse-stack-direction pa-4"> <div class="console-container reverse-stack-direction pa-4">
<div class="px-2 reverse-scroll-start overflow-auto"> <div class="px-2 h-100 reverse-scroll-start overflow-auto">
<div> <div>
@for (int i = 0; i < 100; i++) @for (int i = 0; i < console.history.Count; i++)
{ {
int temp = i; int temp = i;
<MudText>test @temp</MudText> ConsoleLine line = console.history[temp];
<MudText Align="Align.Start"> @((line.source == ConsoleSource.User) ? ">" : "") @line.text</MudText>
@if (line.source == ConsoleSource.OpenBirch)
{
<br/>
}
} }
</div> </div>
</div> </div>
<div> <div>
<MudTextField @bind-Value="test" Variant="Variant.Outlined"></MudTextField> <MudTextField id="console-input" AutoFocus="true" @bind-Value="inputField" Variant="Variant.Outlined" OnKeyDown="OnKeyDown" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ArrowForwardIos"></MudTextField>
</div> </div>
</div> </div>
@code { @code {
public string test = ""; public string inputField = "";
async void OnKeyDown(KeyboardEventArgs args)
{
if (args.Key == "Enter")
{
await Task.Delay(100);
sendCommand(inputField);
StateHasChanged();
}
}
private async void sendCommand(string command)
{
inputField = "";
await console.pushCommand(command);
await InvokeAsync(StateHasChanged);
}
protected override async Task OnInitializedAsync()
{
}
} }

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services; using MudBlazor.Services;
using OpenBirchWebsite.Services;
namespace OpenBirchWebsite namespace OpenBirchWebsite
{ {
@ -13,6 +14,8 @@ namespace OpenBirchWebsite
builder.RootComponents.Add<HeadOutlet>("head::after"); builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<OpenBirchConsole>();
builder.Services.AddMudServices(); builder.Services.AddMudServices();

View File

@ -0,0 +1,41 @@
using Microsoft.JSInterop;
namespace OpenBirchWebsite.Services
{
public class OpenBirchConsole(IJSRuntime js) : IDisposable
{
public List<ConsoleLine> history = new();
private readonly IJSRuntime js = js;
public Task pushCommand(string command)
{
history.Add(new ConsoleLine() { source = ConsoleSource.User, text = command });
return ExecuteCommand(command);
}
private async Task ExecuteCommand(string command)
{
string result = await js.InvokeAsync<string>("runEval", command);
history.Add(new ConsoleLine() { source = ConsoleSource.OpenBirch, text = result });
}
public void Dispose()
{
// The following prevents derived types that introduce a
// finalizer from needing to re-implement IDisposable.
GC.SuppressFinalize(this);
}
}
public struct ConsoleLine
{
public ConsoleSource source;
public string text;
}
public enum ConsoleSource
{
User, // From the user
OpenBirch, // Guess
}
}

View File

@ -0,0 +1,7 @@
namespace OpenBirchWebsite.Services
{
public class StateContainer
{
public readonly Dictionary<int, object> ObjectTunnel = new();
}
}

View File

@ -9,3 +9,4 @@
@using OpenBirchWebsite @using OpenBirchWebsite
@using OpenBirchWebsite.Layout @using OpenBirchWebsite.Layout
@using MudBlazor @using MudBlazor
@using OpenBirchWebsite.Services

View File

@ -0,0 +1 @@
clickElement = (elementId) => document.getElementById(elementId).click();