diff --git a/src/Open.Blazor.Core/Components/Chat/Chat.razor.css b/src/Open.Blazor.Core/Components/Chat/Chat.razor.css deleted file mode 100644 index 5f250d5..0000000 --- a/src/Open.Blazor.Core/Components/Chat/Chat.razor.css +++ /dev/null @@ -1,40 +0,0 @@ - -#chat-window { - width: 100%; - height: 90%; - margin: 0 auto; - overflow-y: auto; - padding: 10px; - overflow-x: hidden; -} - -.chat-box-container { - max-width: 700px; - width: 100%; - margin: 0 auto; - display: flex; - justify-content: center; - align-items: center; - padding: 10px; - box-sizing: border-box; - position: fixed; - bottom: 0; - left: 50%; - transform: translateX(-50%); -} - - -.settings { - display: block; - margin-right: 60px; - position: fixed; - right: 0; - top: 60px; - width: 300px; -} - -@media (max-width: 1400px) { - .settings { - display: none; - } -} \ No newline at end of file diff --git a/src/Open.Blazor.Core/Open.Blazor.Core.csproj b/src/Open.Blazor.Core/Open.Blazor.Core.csproj index c65f4f5..6ca1c3b 100644 --- a/src/Open.Blazor.Core/Open.Blazor.Core.csproj +++ b/src/Open.Blazor.Core/Open.Blazor.Core.csproj @@ -7,8 +7,7 @@ SKEXP0010 SKEXP0070 - - + @@ -26,22 +25,9 @@ - - - - - - - - - - - - - - + diff --git a/src/Open.Blazor.Core/_Imports.razor b/src/Open.Blazor.Core/_Imports.razor deleted file mode 100644 index b4df76f..0000000 --- a/src/Open.Blazor.Core/_Imports.razor +++ /dev/null @@ -1,2 +0,0 @@ -@using Microsoft.AspNetCore.Components.Web -@using Microsoft.JSInterop diff --git a/src/Open.Blazor.Ui/Components/App.razor b/src/Open.Blazor.Ui/Components/App.razor index 90aa160..e3dd18d 100644 --- a/src/Open.Blazor.Ui/Components/App.razor +++ b/src/Open.Blazor.Ui/Components/App.razor @@ -13,7 +13,7 @@ - + diff --git a/src/Open.Blazor.Core/Components/Chat/Chat.razor b/src/Open.Blazor.Ui/Components/Chat/Chat.razor similarity index 60% rename from src/Open.Blazor.Core/Components/Chat/Chat.razor rename to src/Open.Blazor.Ui/Components/Chat/Chat.razor index 640fbe3..f6cc46b 100644 --- a/src/Open.Blazor.Core/Components/Chat/Chat.razor +++ b/src/Open.Blazor.Ui/Components/Chat/Chat.razor @@ -1,14 +1,15 @@ @using Open.Blazor.Core.Models.Enums + @if (OllamaHostMode == OllamaHostMode.Local && _activeOllamaModels is not null) {
-
Chat Settings

-
- @* Temperature Slider *@
- + -

Think of it as a measure of creativity. Lower values are more predictable, higher values are more diverse.

+ class="w-full h-2 bg-gray-600 rounded-lg cursor-pointer accent-blue-500" @bind="_temperature"/> +

Think of it as a measure of creativity. Lower values are more + predictable, higher values are more diverse.

- @* Max Tokens Slider *@
- + -

Limits the response length by setting the maximum number of words or tokens.

+ class="w-full h-2 bg-gray-600 rounded-lg cursor-pointer accent-blue-500" @bind="_maxTokens"/> +

Limits the response length by setting the maximum number of words or + tokens.

- @* Other sliders omitted for brevity but follow the same pattern *@ -
-

Personalizes responses based on identity or preferences.

} -
+
@foreach (var message in _discourse.ChatMessages) { - + }
-
+
@if (!_isListening) { } @@ -72,27 +67,33 @@ } - + @if (!_isChatOngoing) { } else { } diff --git a/src/Open.Blazor.Core/Components/Chat/Chat.razor.cs b/src/Open.Blazor.Ui/Components/Chat/Chat.razor.cs similarity index 98% rename from src/Open.Blazor.Core/Components/Chat/Chat.razor.cs rename to src/Open.Blazor.Ui/Components/Chat/Chat.razor.cs index 41038a5..b5ac55a 100644 --- a/src/Open.Blazor.Core/Components/Chat/Chat.razor.cs +++ b/src/Open.Blazor.Ui/Components/Chat/Chat.razor.cs @@ -7,7 +7,7 @@ using Open.Blazor.Core.Services; using Toolbelt.Blazor.SpeechRecognition; -namespace Open.Blazor.Core.Components.Chat; +namespace Open.Blazor.Ui.Components.Chat; public partial class Chat : ComponentBase, IDisposable { @@ -109,6 +109,7 @@ private async Task SendMessage() { try { + Console.WriteLine($"Sending message: {_userMessage}"); if (string.IsNullOrWhiteSpace(_userMessage)) return; _isChatOngoing = true; diff --git a/src/Open.Blazor.Core/Components/Chat/ChatContent.razor b/src/Open.Blazor.Ui/Components/Chat/ChatContent.razor similarity index 83% rename from src/Open.Blazor.Core/Components/Chat/ChatContent.razor rename to src/Open.Blazor.Ui/Components/Chat/ChatContent.razor index 690cfee..f849b56 100644 --- a/src/Open.Blazor.Core/Components/Chat/ChatContent.razor +++ b/src/Open.Blazor.Ui/Components/Chat/ChatContent.razor @@ -4,7 +4,7 @@ @if (Message is not null) { -
+
@if (Message.Role == MessageRole.User) {
@@ -29,7 +29,8 @@ } else { -
+ // todo: fix overlapping width +
@((MarkupString)Markdown.ToHtml(Message.Content ?? string.Empty))
} @@ -39,8 +40,10 @@
@@ -56,7 +59,7 @@ [Parameter] public MessageContent? Message { get; set; } [Parameter] public IJSRuntime? JsRuntime { get; set; } - + private string _alignment = string.Empty; @@ -73,4 +76,5 @@ // else // // ToastService!.ShowError("Clipboard's empty"); } + } diff --git a/src/Open.Blazor.Core/Components/Chat/ChatContent.razor.css b/src/Open.Blazor.Ui/Components/Chat/ChatContent.razor.css similarity index 87% rename from src/Open.Blazor.Core/Components/Chat/ChatContent.razor.css rename to src/Open.Blazor.Ui/Components/Chat/ChatContent.razor.css index 07f9469..a08fa2a 100644 --- a/src/Open.Blazor.Core/Components/Chat/ChatContent.razor.css +++ b/src/Open.Blazor.Ui/Components/Chat/ChatContent.razor.css @@ -1,4 +1,4 @@ -::deep .markdown-content { +.markdown-content { padding: 10px; border: 1px solid #444; border-radius: 5px; @@ -6,7 +6,7 @@ color: #dcdcdc; } -::deep pre { +pre { background-color: #0D0D0D; padding: 10px; border-radius: 5px; @@ -15,7 +15,7 @@ max-width: 700px; } -::deep code { +code { background-color: #0D0D0D; padding: 2px 4px; border-radius: 3px; @@ -23,20 +23,20 @@ max-width: 700px; } -::deep strong { +strong { color: #ffffff; } -::deep a { +a { color: #66d9ef; text-decoration: none; } -::deep a:hover { +a:hover { text-decoration: underline; } -::deep blockquote { +blockquote { color: #888; border-left: 3px solid #444; padding-left: 10px; @@ -44,20 +44,20 @@ margin-right: 0; } -::deep ul, ol { +ul, ol { padding-left: 20px; } -::deep li { +li { margin-bottom: 5px; } -::deep .card-container { +.card-container { display: flex; justify-content: flex-end; } -::deep .card { +.card { border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 10px; diff --git a/src/Open.Blazor.Ui/Components/Home.razor b/src/Open.Blazor.Ui/Components/Home.razor index eec8f6c..c7dc1a7 100644 --- a/src/Open.Blazor.Ui/Components/Home.razor +++ b/src/Open.Blazor.Ui/Components/Home.razor @@ -1,7 +1,4 @@ @page "/" -@using Open.Blazor.Core.Components.Chat +@using Open.Blazor.Ui.Components.Chat -@code { - -} \ No newline at end of file diff --git a/src/Open.Blazor.Ui/Components/Layout/MainLayout.razor b/src/Open.Blazor.Ui/Components/Layout/MainLayout.razor index f2d982d..7e89e2c 100644 --- a/src/Open.Blazor.Ui/Components/Layout/MainLayout.razor +++ b/src/Open.Blazor.Ui/Components/Layout/MainLayout.razor @@ -8,10 +8,14 @@
- @Body + + + @Body + +
- Error Type: @Exception.GetType()
+ Error Type: @Exception.GetType()
Message: @Exception.Message

Nothing to see here right now. Sorry!

@@ -26,8 +30,9 @@
@code + { - OllamaHostMode _hostMode; + OllamaHostMode _hostMode = OllamaHostMode.Aspire; + - } \ No newline at end of file diff --git a/src/Open.Blazor.Ui/Open.Blazor.Ui.csproj b/src/Open.Blazor.Ui/Open.Blazor.Ui.csproj index 34f12a9..89c8748 100644 --- a/src/Open.Blazor.Ui/Open.Blazor.Ui.csproj +++ b/src/Open.Blazor.Ui/Open.Blazor.Ui.csproj @@ -20,5 +20,10 @@ + + + + + diff --git a/src/Open.Blazor.Ui/wwwroot/css/app.out.css b/src/Open.Blazor.Ui/wwwroot/css/app.out.css index a9794c6..f8d5b65 100644 --- a/src/Open.Blazor.Ui/wwwroot/css/app.out.css +++ b/src/Open.Blazor.Ui/wwwroot/css/app.out.css @@ -548,48 +548,231 @@ video { position: static; } +.fixed { + position: fixed; +} + +.bottom-0 { + bottom: 0px; +} + +.left-1\/2 { + left: 50%; +} + +.m-1 { + margin: 0.25rem; +} + .mx-auto { margin-left: auto; margin-right: auto; } +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.mt-1 { + margin-top: 0.25rem; +} + +.mt-2 { + margin-top: 0.5rem; +} + .mt-4 { margin-top: 1rem; } +.block { + display: block; +} + .flex { display: flex; } +.contents { + display: contents; +} + +.h-10 { + height: 2.5rem; +} + +.h-2 { + height: 0.5rem; +} + +.h-6 { + height: 1.5rem; +} + +.h-\[calc\(100vh-10rem\)\] { + height: calc(100vh - 10rem); +} + .min-h-screen { min-height: 100vh; } +.w-10 { + width: 2.5rem; +} + +.w-52 { + width: 13rem; +} + +.w-6 { + width: 1.5rem; +} + +.w-full { + width: 100%; +} + .max-w-3xl { max-width: 48rem; } +.max-w-md { + max-width: 28rem; +} + .flex-grow { flex-grow: 1; } +.-translate-x-1\/2 { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.animate-spin { + animation: spin 1s linear infinite; +} + +.cursor-pointer { + cursor: pointer; +} + +.resize-none { + resize: none; +} + .flex-col { flex-direction: column; } +.items-start { + align-items: flex-start; +} + +.items-end { + align-items: flex-end; +} + +.items-center { + align-items: center; +} + +.justify-center { + justify-content: center; +} + +.space-x-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} + +.overflow-auto { + overflow: auto; +} + +.break-words { + overflow-wrap: break-word; +} + .rounded { border-radius: 0.25rem; } +.rounded-full { + border-radius: 9999px; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-md { + border-radius: 0.375rem; +} + .border { border-width: 1px; } +.border-4 { + border-width: 4px; +} + +.border-none { + border-style: none; +} + .border-\[\#f85149\] { --tw-border-opacity: 1; border-color: rgb(248 81 73 / var(--tw-border-opacity)); } +.border-gray-300 { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.border-gray-600 { + --tw-border-opacity: 1; + border-color: rgb(75 85 99 / var(--tw-border-opacity)); +} + +.border-gray-700 { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); +} + +.border-red-700 { + --tw-border-opacity: 1; + border-color: rgb(185 28 28 / var(--tw-border-opacity)); +} + +.border-t-blue-500 { + --tw-border-opacity: 1; + border-top-color: rgb(59 130 246 / var(--tw-border-opacity)); +} + .bg-\[\#0d1117\] { --tw-bg-opacity: 1; background-color: rgb(13 17 23 / var(--tw-bg-opacity)); @@ -600,10 +783,43 @@ video { background-color: rgb(22 27 34 / var(--tw-bg-opacity)); } +.bg-blue-500 { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); +} + +.bg-gray-600 { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + +.bg-gray-700 { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.bg-gray-800 { + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); +} + +.bg-red-800 { + --tw-bg-opacity: 1; + background-color: rgb(153 27 27 / var(--tw-bg-opacity)); +} + +.p-2 { + padding: 0.5rem; +} + .p-4 { padding: 1rem; } +.p-6 { + padding: 1.5rem; +} + .px-4 { padding-left: 1rem; padding-right: 1rem; @@ -623,10 +839,29 @@ video { text-align: center; } +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + .font-bold { font-weight: 700; } +.font-medium { + font-weight: 500; +} + .text-\[\#8b949e\] { --tw-text-opacity: 1; color: rgb(139 148 158 / var(--tw-text-opacity)); @@ -637,6 +872,47 @@ video { color: rgb(248 81 73 / var(--tw-text-opacity)); } +.text-blue-500 { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity)); +} + +.text-gray-300 { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.text-gray-400 { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.text-red-500 { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.accent-blue-500 { + accent-color: #3b82f6; +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + /* inter-200 - latin */ @font-face { @@ -777,4 +1053,19 @@ h1:focus { .blazor-error-boundary::after { content: "An error has occurred." +} + +.hover\:bg-gray-600:hover { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + +.hover\:bg-gray-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.hover\:bg-red-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(185 28 28 / var(--tw-bg-opacity)); } \ No newline at end of file