Radzen und ein bisschen UI

This commit is contained in:
Simon Lübeß 2023-08-02 21:33:09 +02:00
parent 4875b590a5
commit e9b9275999
6 changed files with 205 additions and 22 deletions

View File

@ -11,6 +11,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="OpenAI" Version="1.7.2" /> <PackageReference Include="OpenAI" Version="1.7.2" />
<PackageReference Include="Radzen.Blazor" Version="4.14.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,46 +1,213 @@
@page "/aiart" @page "/aiart"
@using OpenAI_API @using OpenAI_API
@using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web
@using OpenAI_API.Chat @using OpenAI_API.Chat
@using OpenAI_API.Models @using OpenAI_API.Models
@using System.Diagnostics
@inject TooltipService TooltipService
@inject DialogService DialogService
<PageTitle>AiArt</PageTitle> <PageTitle>AiArt</PageTitle>
<h1>Wunschbilder von KI nur für dich</h1> <h1>Wunschbilder von KI nur für dich</h1>
@*<EditForm Model="@exampleModel" OnSubmit="@DoStuff">
<InputText @bind-Value="exampleModel.Name" />
<button type="submit">Submit</button>
</EditForm>*@
<!-- Dies ist das Textfeld --> <!-- Dies ist das Textfeld -->
<input type="text" @bind="request" placeholder="Text eingeben..." /> @*<input type="text" @bind="request" placeholder="Text eingeben..." />
<!-- Dies ist der Button -->
<button @onclick="DoStuff">Klick mich</button>
<!-- Hier wird der Text angezeigt, den wir eingeben -->
<p>@response</p>
@*<button class="btn btn-primary" @onclick="DoStuff">Click me</button>
*@ *@
<!-- Dies ist der Button -->
@*<button @onclick="DoStuff">Klick mich</button>*@
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center">
<RadzenText TextStyle="TextStyle.H2">Nenne uns deinen Wunsch:</RadzenText>
<RadzenTextBox @bind-Value=@request Placeholder="Dein Wunsch"/>
<RadzenPanel AllowCollapse="true" Style="width: 500px;" Text="Mehr Optionen">
<ChildContent>
<RadzenCard class="rz-mt-4">
<RadzenStack Orientation="Orientation.Horizontal"
MouseEnter="@(args => ShowTemperatureTooltip(args))"
MouseLeave="TooltipService.Close"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenText>Temperature:</RadzenText>
<RadzenSlider @bind-Value=@temperature TValue="float"
Step="0.0001" Min="0.0m" Max="2.0m">
</RadzenSlider>
<RadzenText>@temperature</RadzenText>
</RadzenStack>
</RadzenCard>
</ChildContent>
</RadzenPanel>
<RadzenButton Disabled=@_progressVisible Click=@DoStuff>Generate</RadzenButton>
<RadzenProgressBarCircular Visible=@_progressVisible ProgressBarStyle="ProgressBarStyle.Secondary" Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" />
<RadzenText Visible=@_progressVisible TextStyle="TextStyle.H6" Text=@BusyMessage></RadzenText>
</RadzenStack>
@code { @code {
private string response = "Drücke du hurensohn!"; private bool _progressVisible = false;
public string BusyMessage { get; set; } = "Initial Message";
// Busy dialog from markup
async Task ShowBusyDialog()
{
await DialogService.OpenAsync("", ds =>
@<RadzenStack AlignItems="AlignItems.Center" Gap="2rem" Class="rz-p-12">
<RadzenProgressBarCircular ProgressBarStyle="ProgressBarStyle.Secondary" Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate"/>
<RadzenText TextStyle="TextStyle.H6" Text=@BusyMessage></RadzenText>
</RadzenStack>, new DialogOptions() { ShowTitle = false, Style = "min-height:auto;min-width:auto;width:auto", CloseDialogOnEsc = false });
}
// Busy dialog from string
async Task BusyDialog(string message)
{
await DialogService.OpenAsync("", ds =>
{
RenderFragment content = b =>
{
b.OpenElement(0, "RadzenRow");
b.OpenElement(1, "RadzenColumn");
b.AddAttribute(2, "Size", "12");
b.AddContent(3, message);
b.CloseElement();
b.CloseElement();
};
return content;
}, new DialogOptions() { ShowTitle = false, Style = "min-height:auto;min-width:auto;width:auto", CloseDialogOnEsc = false });
}
void ShowTooltip(ElementReference elementReference, string text, TooltipOptions? options = null) => TooltipService.Open(elementReference, text, options);
void ShowTemperatureTooltip(ElementReference elementReference) => TooltipService.Open(elementReference, ds =>
@<div>
Gibt an, wie <em>kreativ</em> ChatGPT sein soll.<br />
Ich glaube, eigentlich bedeutet es eher, wie <em>deterministisch</em> die Ausgabe ist.<br />
Bei 0.0 kommt immer fast die selbe Antwort. Bei zu hohen Werten kommt nur noch Schwachsinn.<br />
OpenAI empfielt einen Wert von ca. 0.9 für kreative Anwendungen.
</div>,
new() { Position = TooltipPosition.Bottom, Duration = null});
private string _imagePrompt = "\"Painting of a soccer match with the Hamburger SV team scoring multiple goals, vibrant colors and dynamic brushstrokes.\" Watercolor + ink on paper, Pen drawing, wet-on-wet technique, dry-on-dry technique, dabbing technique.";
private string _imageDescription = "Ich habe mich für diese Interpretation des Titels entschieden, um die Dynamik und den Erfolg des Hamburger SV Fußballvereins darzustellen. Durch die Darstellung eines Spiels, in dem der HSV viele Tore schießt, wird die Leidenschaft und das Streben nach Erfolg hervorgehoben. Die lebendigen Farben und die dynamischen Pinselstriche sollen die Energie und Aufregung des Spiels wiedergeben.";
private float temperature = 0.9f;
private string request = ""; private string request = "";
private string _basePrompt;
//protected override async Task OnInitializedAsync()
//{
// _basePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"\wwwroot\prompt.txt"}");
//}
private async Task FunnyMessageSwitcher_ImageGen(CancellationToken cancellationToken)
{
Stopwatch sw = Stopwatch.StartNew();
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Dauert noch eine Weile...");
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Gut Ding hat Weil...");
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Sach ma, was issn da l... achso, er ist auf Klo gegangen... Er ist bestimmt gleich wieder da...");
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Na, also langsam verlier ich hier die Geduld, ich dachte KI soll alles schneller machen...");
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage($"Keine Sorge, er arbeitet noch. Die Bilder werden gemalt... ({sw.Elapsed.Seconds}s)");
}
}
async Task UpdateBusyMessage(string newMessage)
{
BusyMessage = newMessage;
await InvokeAsync(StateHasChanged);
}
private async Task DoStuff() private async Task DoStuff()
{ {
var prompt = File.ReadAllText($"{Directory.GetCurrentDirectory()}{@"\wwwroot\prompt.txt"}"); // Der Dialog blokiert so lange, wie der er offen ist, deshalb dürfen wir hier nicht warten, da wir sonst nie mit der Arbeit anfangen...
//Task busyDialog = ShowBusyDialog();
_progressVisible = true;
await UpdateBusyMessage("Kirstens Assistent zerbricht sich über deine Idee den Kopf...");
_basePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"\wwwroot\prompt.txt"}");
//await Task.Delay(1000);
OpenAIAPI api = new OpenAIAPI("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"); OpenAIAPI api = new OpenAIAPI("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");
ChatRequest chatRequest = new ChatRequest
{
Temperature = temperature,
Model = Model.ChatGPTTurbo,
};
Conversation converse = api.Chat.CreateConversation(chatRequest);
converse.AppendUserInput(_basePrompt + " " + request);
Conversation converse = api.Chat.CreateConversation(); string response = await converse.GetResponseFromChatbotAsync();
converse.Model = Model.ChatGPTTurbo;
converse.AppendUserInput(prompt + " " + request);
response = await converse.GetResponseFromChatbotAsync(); // Der Propt sollte dafür sorgen, dass ChatGPT einen Absatz zwischen Bild-Promt und der Erklärung macht.
int lineBreak = response.IndexOf('\n');
//var api = new OpenAI_API.OpenAIAPI("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"); if (lineBreak == -1)
//var result = await api.Completions.GetCompletion(prompt + " Brot"); {
//var result = await api.(prompt + " Brot"); // TODO: Error
//response = result ?? "Null"; }
// should print something starting with "Three"
_imagePrompt = response.Substring(0, lineBreak);
_imageDescription = response.Substring(lineBreak);
await UpdateBusyMessage("Kirstens Assistent hat eine Idee! Er wird sie nun malen...");
// TODO: Hier bilder generieren
//Task makeImagesTask = Task.Delay(10000);
CancellationTokenSource cancelFunnyMessages = new CancellationTokenSource();
Task funnyMessagesTask = FunnyMessageSwitcher_ImageGen(cancelFunnyMessages.Token);
// Wichtig, erst Bilder awaiten, dann die lustingen Sprüche, sonst warten wir ewig...
//await makeImagesTask;
cancelFunnyMessages.Cancel();
await funnyMessagesTask;
//DialogService.Close();//
// Wir warten auf den Task des Dialogs nach dem Schließen, weil das funktioniert.
//await busyDialog;
_progressVisible = false;
await InvokeAsync(StateHasChanged);
} }
} }

View File

@ -14,6 +14,10 @@
<link href="KIKunstKirstenKlöckner.styles.css" rel="stylesheet" /> <link href="KIKunstKirstenKlöckner.styles.css" rel="stylesheet" />
<link rel="icon" type="image/png" href="favicon.png"/> <link rel="icon" type="image/png" href="favicon.png"/>
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
<!-- Radzen.Blazor -->
<link rel="stylesheet" href="_content/Radzen.Blazor/css/humanistic-base.css">
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
</head> </head>
<body> <body>
<component type="typeof(App)" render-mode="ServerPrerendered" /> <component type="typeof(App)" render-mode="ServerPrerendered" />

View File

@ -1,6 +1,7 @@
using KIKunstKirstenKlöckner.Data; using KIKunstKirstenKlöckner.Data;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Radzen;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -8,6 +9,9 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(); builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor(); builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>(); builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>();
var app = builder.Build(); var app = builder.Build();

View File

@ -17,3 +17,7 @@
</article> </article>
</main> </main>
</div> </div>
<RadzenTooltip />
<RadzenDialog />
<RadzenNotification />

View File

@ -8,3 +8,6 @@
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using KIKunstKirstenKlöckner @using KIKunstKirstenKlöckner
@using KIKunstKirstenKlöckner.Shared @using KIKunstKirstenKlöckner.Shared
@using Radzen
@using Radzen.Blazor