mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
Update the chat panel theme some
This commit is contained in:
parent
08626c7a2d
commit
c386e34c33
@ -4,6 +4,12 @@ import server from "../services/server.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import utils from "../services/utils.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import libraryLoader from "../services/library_loader.js";
|
||||
|
||||
// Import the LLM Chat CSS
|
||||
(async function() {
|
||||
await libraryLoader.requireCss('stylesheets/llm_chat.css');
|
||||
})();
|
||||
|
||||
interface ChatResponse {
|
||||
id: string;
|
||||
@ -42,33 +48,33 @@ export default class LlmChatPanel extends BasicWidget {
|
||||
</div>
|
||||
|
||||
<div class="sources-container p-2 border-top" style="display: none;">
|
||||
<h6 class="m-0 p-1">
|
||||
<i class="bx bx-link-alt"></i> ${t('ai.sources')}
|
||||
<span class="badge bg-secondary rounded-pill ms-2 sources-count"></span>
|
||||
<h6 class="m-0 p-1 d-flex align-items-center">
|
||||
<i class="bx bx-link-alt me-1"></i> ${t('ai.sources')}
|
||||
<span class="badge bg-primary rounded-pill ms-2 sources-count"></span>
|
||||
</h6>
|
||||
<div class="sources-list mt-2"></div>
|
||||
</div>
|
||||
|
||||
<form class="note-context-chat-form d-flex flex-column border-top p-2">
|
||||
<div class="d-flex mb-2 align-items-center">
|
||||
<div class="d-flex mb-2 align-items-center context-option-container">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input use-advanced-context-checkbox" type="checkbox" id="useAdvancedContext" checked>
|
||||
<label class="form-check-label" for="useAdvancedContext">
|
||||
${t('ai.use_advanced_context')}
|
||||
<input class="form-check-input use-advanced-context-checkbox" type="checkbox" id="useEnhancedContext" checked>
|
||||
<label class="form-check-label" for="useEnhancedContext">
|
||||
${t('ai.use_enhanced_context')}
|
||||
</label>
|
||||
</div>
|
||||
<div class="ms-2 small text-muted">
|
||||
<i class="bx bx-info-circle"></i>
|
||||
<span>${t('ai.advanced_context_helps')}</span>
|
||||
<span>${t('ai.enhanced_context_description')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<div class="d-flex chat-input-container">
|
||||
<textarea
|
||||
class="form-control note-context-chat-input"
|
||||
placeholder="${t('ai.enter_message')}"
|
||||
rows="3"
|
||||
rows="2"
|
||||
></textarea>
|
||||
<button type="submit" class="btn btn-primary note-context-chat-send-button ms-2">
|
||||
<button type="submit" class="btn btn-primary note-context-chat-send-button ms-2 d-flex align-items-center justify-content-center">
|
||||
<i class="bx bx-send"></i>
|
||||
</button>
|
||||
</div>
|
||||
@ -256,26 +262,30 @@ export default class LlmChatPanel extends BasicWidget {
|
||||
|
||||
private addMessageToChat(role: 'user' | 'assistant', content: string) {
|
||||
const messageElement = document.createElement('div');
|
||||
messageElement.className = `chat-message ${role}-message mb-3`;
|
||||
messageElement.className = `chat-message ${role}-message mb-3 d-flex`;
|
||||
|
||||
const avatarElement = document.createElement('div');
|
||||
avatarElement.className = 'message-avatar';
|
||||
avatarElement.innerHTML = role === 'user'
|
||||
? '<i class="bx bx-user"></i>'
|
||||
: '<i class="bx bx-bot"></i>';
|
||||
avatarElement.className = 'message-avatar d-flex align-items-center justify-content-center me-2';
|
||||
|
||||
if (role === 'user') {
|
||||
avatarElement.innerHTML = '<i class="bx bx-user"></i>';
|
||||
avatarElement.classList.add('user-avatar');
|
||||
} else {
|
||||
avatarElement.innerHTML = '<i class="bx bx-bot"></i>';
|
||||
avatarElement.classList.add('assistant-avatar');
|
||||
}
|
||||
|
||||
const contentElement = document.createElement('div');
|
||||
contentElement.className = 'message-content p-3';
|
||||
contentElement.className = 'message-content p-3 rounded flex-grow-1';
|
||||
|
||||
// Use a simple markdown formatter if utils.formatMarkdown is not available
|
||||
let formattedContent = content
|
||||
.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>')
|
||||
.replace(/`([^`]+)`/g, '<code>$1</code>')
|
||||
.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
|
||||
.replace(/\*([^*]+)\*/g, '<em>$1</em>')
|
||||
.replace(/\n/g, '<br>');
|
||||
if (role === 'user') {
|
||||
contentElement.classList.add('user-content', 'bg-light');
|
||||
} else {
|
||||
contentElement.classList.add('assistant-content');
|
||||
}
|
||||
|
||||
contentElement.innerHTML = formattedContent;
|
||||
// Format the content with markdown
|
||||
contentElement.innerHTML = this.formatMarkdown(content);
|
||||
|
||||
messageElement.appendChild(avatarElement);
|
||||
messageElement.appendChild(contentElement);
|
||||
@ -297,16 +307,17 @@ export default class LlmChatPanel extends BasicWidget {
|
||||
|
||||
sources.forEach(source => {
|
||||
const sourceElement = document.createElement('div');
|
||||
sourceElement.className = 'source-item p-2 mb-1 border rounded';
|
||||
sourceElement.className = 'source-item p-2 mb-1 border rounded d-flex align-items-center';
|
||||
|
||||
// Create the direct link to the note
|
||||
sourceElement.innerHTML = `
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center w-100">
|
||||
<a href="#root/${source.noteId}"
|
||||
data-note-id="${source.noteId}"
|
||||
class="source-link text-truncate"
|
||||
class="source-link text-truncate d-flex align-items-center"
|
||||
title="Open note: ${source.title}">
|
||||
<i class="bx bx-file"></i> ${source.title}
|
||||
<i class="bx bx-file-blank me-1"></i>
|
||||
<span class="source-title">${source.title}</span>
|
||||
</a>
|
||||
</div>`;
|
||||
|
||||
|
119
src/public/stylesheets/llm_chat.css
Normal file
119
src/public/stylesheets/llm_chat.css
Normal file
@ -0,0 +1,119 @@
|
||||
/* LLM Chat Panel Styles */
|
||||
.note-context-chat {
|
||||
background-color: var(--main-background-color);
|
||||
}
|
||||
|
||||
/* Message Styling */
|
||||
.chat-message {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.message-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
font-size: 1.25rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
background-color: var(--input-background-color);
|
||||
color: var(--cmd-button-icon-color);
|
||||
}
|
||||
|
||||
.assistant-avatar {
|
||||
background-color: var(--subtle-border-color, var(--main-border-color));
|
||||
color: var(--hover-item-text-color);
|
||||
}
|
||||
|
||||
.message-content {
|
||||
max-width: calc(100% - 50px);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
color: var(--main-text-color);
|
||||
}
|
||||
|
||||
.user-content {
|
||||
border-radius: 0.5rem 0.5rem 0 0.5rem !important;
|
||||
background-color: var(--input-background-color) !important;
|
||||
}
|
||||
|
||||
.assistant-content {
|
||||
border-radius: 0.5rem 0.5rem 0.5rem 0 !important;
|
||||
background-color: var(--main-background-color);
|
||||
border: 1px solid var(--subtle-border-color, var(--main-border-color));
|
||||
}
|
||||
|
||||
/* Sources Styling */
|
||||
.sources-container {
|
||||
background-color: var(--accented-background-color, var(--main-background-color));
|
||||
border-top: 1px solid var(--main-border-color);
|
||||
color: var(--main-text-color);
|
||||
}
|
||||
|
||||
.source-item {
|
||||
transition: all 0.2s ease;
|
||||
background-color: var(--main-background-color);
|
||||
border-color: var(--subtle-border-color, var(--main-border-color)) !important;
|
||||
}
|
||||
|
||||
.source-item:hover {
|
||||
background-color: var(--link-hover-background, var(--hover-item-background-color));
|
||||
}
|
||||
|
||||
.source-link {
|
||||
color: var(--link-color, var(--hover-item-text-color));
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.source-link:hover {
|
||||
color: var(--link-hover-color, var(--hover-item-text-color));
|
||||
}
|
||||
|
||||
/* Input Area Styling */
|
||||
.note-context-chat-form {
|
||||
background-color: var(--main-background-color);
|
||||
border-top: 1px solid var(--main-border-color);
|
||||
}
|
||||
|
||||
.context-option-container {
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--subtle-border-color, var(--main-border-color));
|
||||
color: var(--main-text-color);
|
||||
}
|
||||
|
||||
.chat-input-container {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
.note-context-chat-input {
|
||||
border-color: var(--subtle-border-color, var(--main-border-color));
|
||||
background-color: var(--input-background-color) !important;
|
||||
color: var(--input-text-color) !important;
|
||||
resize: none;
|
||||
transition: all 0.2s ease;
|
||||
min-height: 50px;
|
||||
max-height: 150px;
|
||||
}
|
||||
|
||||
.note-context-chat-input:focus {
|
||||
border-color: var(--input-focus-outline-color, var(--main-border-color));
|
||||
box-shadow: 0 0 0 0.25rem var(--input-focus-outline-color, rgba(13, 110, 253, 0.25));
|
||||
}
|
||||
|
||||
.note-context-chat-send-button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
align-self: flex-end;
|
||||
background-color: var(--cmd-button-background-color) !important;
|
||||
color: var(--cmd-button-text-color) !important;
|
||||
}
|
||||
|
||||
/* Loading Indicator */
|
||||
.loading-indicator {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
color: var(--muted-text-color);
|
||||
}
|
@ -1759,7 +1759,9 @@
|
||||
"ai": {
|
||||
"sources": "Sources",
|
||||
"enter_message": "Enter your message...",
|
||||
"use_advanced_context": "Use Advanced Context",
|
||||
"advanced_context_helps": "Helps with large knowledge bases and limited context windows"
|
||||
"use_advanced_context": "Use Enhanced Note Context",
|
||||
"advanced_context_helps": "Helps with large knowledge bases and limited context windows",
|
||||
"use_enhanced_context": "Use Enhanced Note Context",
|
||||
"enhanced_context_description": "Improves answers by including more relevant note content"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user