feat(ui): support multilineand style ul (#2226)

* feat(ui/chat): handle multiline in the input field

Signed-off-by: mudler <mudler@localai.io>

* feat(ui/chat): correctly display multiline messages

Signed-off-by: mudler <mudler@localai.io>

* feat(ui/chat): add list style

Signed-off-by: mudler <mudler@localai.io>

---------

Signed-off-by: mudler <mudler@localai.io>
This commit is contained in:
Ettore Di Giacinto 2024-05-03 00:43:02 +02:00 committed by GitHub
parent a31d00d904
commit b58274b8a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 21 deletions

View File

@ -40,11 +40,7 @@ function submitPrompt(event) {
document.getElementById("input").value = "";
const key = localStorage.getItem("key");
if (input.startsWith("!img")) {
promptDallE(key, input.slice(4));
} else {
promptGPT(key, input);
}
promptGPT(key, input);
}

View File

@ -71,3 +71,23 @@ body {
flex-grow: 1;
margin: 0.5rem;
}
ul {
list-style-type: disc; /* Adds bullet points */
padding-left: 1.25rem; /* Indents the list from the left margin */
margin-top: 1rem; /* Space above the list */
}
li {
font-size: 0.875rem; /* Small text size */
color: #4a5568; /* Dark gray text */
background-color: #f7fafc; /* Very light gray background */
border-radius: 0.375rem; /* Rounded corners */
padding: 0.5rem; /* Padding inside each list item */
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); /* Subtle shadow */
margin-bottom: 0.5rem; /* Vertical space between list items */
}
li:last-child {
margin-bottom: 0; /* Removes bottom margin from the last item */
}

View File

@ -106,7 +106,7 @@ SOFTWARE.
<div class="flex flex-col flex-1">
<span class="text-xs font-semibold text-gray-600" x-text="message.role === 'user' ? 'User' : 'Assistant ({{.Model}})'"></span>
<template x-if="message.role === 'user'">
<div class="p-2 flex-1 rounded" :class="message.role" x-text="message.content"></div>
<div class="p-2 flex-1 rounded" :class="message.role" x-html="message.html"></div>
</template>
<template x-if="message.role === 'assistant'">
<div class="p-2 flex-1 rounded" :class="message.role" x-html="message.html"></div>
@ -117,22 +117,27 @@ SOFTWARE.
</div>
</div>
<div class="p-4 border-t border-gray-700">
<div id="loader" class="my-2 loader" style="display: none;" ></div>
<div class="p-4 border-t border-gray-700" x-data="{ inputValue: '', shiftPressed: false }">
<div id="loader" class="my-2 loader" style="display: none;"></div>
<input id="chat-model" type="hidden" value="{{.Model}}">
<form id="prompt" action="/chat/{{.Model}}" method="get">
<input
type="text"
id="input"
name="input"
placeholder="Prompt…"
autocomplete="off"
class="p-2 border rounded w-full bg-gray-600 text-white placeholder-gray-300"
required
/>
<form id="prompt" action="/chat/{{.Model}}" method="get" @submit.prevent="submitPrompt">
<div class="relative w-full">
<textarea
id="input"
name="input"
x-model="inputValue"
placeholder="Send a message..."
class="p-2 pl-2 border rounded w-full bg-gray-600 text-white placeholder-gray-300"
required
@keydown.shift="shiftPressed = true"
@keyup.shift="shiftPressed = false"
@keydown.enter="if (!shiftPressed) { submitPrompt($event); }"
style="padding-right: 4rem;"
></textarea>
<button type=submit><i class="fa-solid fa-circle-up text-gray-300 absolute right-2 top-3 text-lg p-2 ml-2"></i></button>
</div>
</form>
</div>
</div>
<script>
document.addEventListener("alpine:init", () => {
Alpine.store("chat", {
@ -150,10 +155,18 @@ SOFTWARE.
marked.parse(this.history[N].content),
);
} else {
c = ""
// split content newlines in content
const lines = content.split("\n");
// for each line, do DOMPurify.sanitize(marked.parse(line)) and add it to c
lines.forEach((line) => {
c += DOMPurify.sanitize(marked.parse(line));
});
this.history.push({
role: role,
content: content,
html: DOMPurify.sanitize(marked.parse(content)),
html: c,
});
}