aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx')
-rw-r--r--src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx106
1 files changed, 92 insertions, 14 deletions
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
index ba30cb42b..490739be6 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
@@ -40,7 +40,6 @@ import { ASSISTANT_ROLE, AssistantMessage, CHUNK_TYPE, Citation, ProcessingInfo,
import { Vectorstore } from '../vectorstore/Vectorstore';
import './ChatBox.scss';
import MessageComponentBox from './MessageComponent';
-import { ProgressBar } from './ProgressBar';
import { OpenWhere } from '../../OpenWhere';
import { Upload } from '../../../../../server/SharedMediaTypes';
import { DocumentMetadataTool } from '../tools/DocumentMetadataTool';
@@ -76,6 +75,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@observable private _linked_csv_files: { filename: string; id: string; text: string }[] = [];
@observable private _isUploadingDocs: boolean = false;
@observable private _citationPopup: { text: string; visible: boolean } = { text: '', visible: false };
+ @observable private _isFontSizeModalOpen: boolean = false;
+ @observable private _fontSize: 'small' | 'normal' | 'large' | 'xlarge' = 'normal';
// Private properties for managing OpenAI API, vector store, agent, and UI elements
private openai!: OpenAI; // Using definite assignment assertion
@@ -147,6 +148,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
this.dataDoc.data = JSON.stringify(serializableHistory);
}
);
+
+ // Initialize font size from saved preference
+ this.initFontSize();
}
/**
@@ -1074,12 +1078,61 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
};
_dictation: DictationButton | null = null;
+
+ /**
+ * Toggles the font size modal visibility
+ */
+ @action
+ toggleFontSizeModal = () => {
+ this._isFontSizeModalOpen = !this._isFontSizeModalOpen;
+ };
+
+ /**
+ * Changes the font size and applies it to the chat interface
+ * @param size The new font size to apply
+ */
+ @action
+ changeFontSize = (size: 'small' | 'normal' | 'large' | 'xlarge') => {
+ this._fontSize = size;
+ this._isFontSizeModalOpen = false;
+
+ // Save preference to localStorage if needed
+ if (typeof window !== 'undefined') {
+ localStorage.setItem('chatbox-font-size', size);
+ }
+ };
+
+ /**
+ * Initializes font size from saved preference
+ */
+ initFontSize = () => {
+ if (typeof window !== 'undefined') {
+ const savedSize = localStorage.getItem('chatbox-font-size');
+ if (savedSize && ['small', 'normal', 'large', 'xlarge'].includes(savedSize)) {
+ this._fontSize = savedSize as 'small' | 'normal' | 'large' | 'xlarge';
+ }
+ }
+ };
+
+ /**
+ * Renders a font size icon SVG
+ */
+ renderFontSizeIcon = () => (
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
+ <polyline points="4 7 4 4 20 4 20 7"></polyline>
+ <line x1="9" y1="20" x2="15" y2="20"></line>
+ <line x1="12" y1="4" x2="12" y2="20"></line>
+ </svg>
+ );
+
/**
* Renders the chat interface, including the message list, input field, and other UI elements.
*/
render() {
+ const fontSizeClass = `font-size-${this._fontSize}`;
+
return (
- <div className="chat-box">
+ <div className={`chat-box ${fontSizeClass}`}>
{this._isUploadingDocs && (
<div className="uploading-overlay">
<div className="progress-container">
@@ -1095,6 +1148,29 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
)}
<div className="chat-header">
<h2>{this.userName()}&apos;s AI Assistant</h2>
+ <div className="font-size-control" onClick={this.toggleFontSizeModal}>
+ {this.renderFontSizeIcon()}
+ </div>
+ {this._isFontSizeModalOpen && (
+ <div className="font-size-modal">
+ <div className={`font-size-option ${this._fontSize === 'small' ? 'active' : ''}`} onClick={() => this.changeFontSize('small')}>
+ <span className="option-label">Small</span>
+ <span className="size-preview small">Aa</span>
+ </div>
+ <div className={`font-size-option ${this._fontSize === 'normal' ? 'active' : ''}`} onClick={() => this.changeFontSize('normal')}>
+ <span className="option-label">Normal</span>
+ <span className="size-preview normal">Aa</span>
+ </div>
+ <div className={`font-size-option ${this._fontSize === 'large' ? 'active' : ''}`} onClick={() => this.changeFontSize('large')}>
+ <span className="option-label">Large</span>
+ <span className="size-preview large">Aa</span>
+ </div>
+ <div className={`font-size-option ${this._fontSize === 'xlarge' ? 'active' : ''}`} onClick={() => this.changeFontSize('xlarge')}>
+ <span className="option-label">Extra Large</span>
+ <span className="size-preview xlarge">Aa</span>
+ </div>
+ </div>
+ )}
</div>
<div className="chat-messages" ref={this.messagesRef}>
{this._history.map((message, index) => (
@@ -1106,18 +1182,20 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
</div>
<form onSubmit={this.askGPT} className="chat-input">
- <input
- ref={r => {
- this._textInputRef = r;
- }}
- type="text"
- name="messageInput"
- autoComplete="off"
- placeholder="Type your message here..."
- value={this._inputValue}
- onChange={action(e => (this._inputValue = e.target.value))}
- disabled={this._isLoading}
- />
+ <div className="input-container">
+ <input
+ ref={r => {
+ this._textInputRef = r;
+ }}
+ type="text"
+ name="messageInput"
+ autoComplete="off"
+ placeholder="Type your message here..."
+ value={this._inputValue}
+ onChange={action(e => (this._inputValue = e.target.value))}
+ disabled={this._isLoading}
+ />
+ </div>
<button className="submit-button" onClick={() => this._dictation?.stopDictation()} type="submit" disabled={this._isLoading || !this._inputValue.trim()}>
{this._isLoading ? (
<div className="spinner"></div>