From 07ca137bdf1cc6fd7c3f4244ec97cef7d9b23b24 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 20 Jan 2024 00:24:28 +0530 Subject: [PATCH] Convert chat input into a text area in the Obsidian client This allows for better readability of multi-line messages by users. The chat input is a text area in the other clients as well. --- src/interface/obsidian/src/chat_modal.ts | 38 ++++++++++++++++++++---- src/interface/obsidian/styles.css | 5 +++- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/interface/obsidian/src/chat_modal.ts b/src/interface/obsidian/src/chat_modal.ts index 2ee2fa1a..97b08620 100644 --- a/src/interface/obsidian/src/chat_modal.ts +++ b/src/interface/obsidian/src/chat_modal.ts @@ -22,11 +22,12 @@ export class KhojChatModal extends Modal { async chat() { // Get text in chat input element - let input_el = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; + let input_el = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; // Clear text after extracting message to send let user_message = input_el.value.trim(); input_el.value = ""; + this.autoResize(); // Get and render chat response to user message await this.getChatResponse(user_message); @@ -57,9 +58,8 @@ export class KhojChatModal extends Modal { clearChat.addEventListener('click', async (_) => { await this.clearConversationHistory() }); setIcon(clearChat, "trash"); - let chatInput = inputRow.createEl("input", { + let chatInput = inputRow.createEl("textarea", { attr: { - type: "text", id: "khoj-chat-input", autofocus: "autofocus", placeholder: placeholderText, @@ -67,12 +67,14 @@ export class KhojChatModal extends Modal { disabled: !getChatHistorySucessfully ? "disabled" : null }, }) + chatInput.addEventListener('input', (_) => { this.onChatInput() }); + chatInput.addEventListener('keydown', (event) => { this.incrementalChat(event) }); let transcribe = inputRow.createEl("button", { text: "Transcribe", attr: { id: "khoj-transcribe", - class: "khoj-input-row-button clickable-icon ", + class: "khoj-transcribe khoj-input-row-button clickable-icon ", }, }) transcribe.addEventListener('click', async (_) => { await this.speechToText() }); @@ -382,7 +384,7 @@ export class KhojChatModal extends Modal { flashStatusInChatInput(message: string) { // Get chat input element and original placeholder - let chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; + let chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; let originalPlaceholder = chatInput.placeholder; // Set placeholder to message chatInput.placeholder = message; @@ -420,7 +422,7 @@ export class KhojChatModal extends Modal { mediaRecorder: MediaRecorder | undefined; async speechToText() { const transcribeButton = this.contentEl.getElementsByClassName("khoj-transcribe")[0]; - const chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; + const chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; const generateRequestBody = async (audioBlob: Blob, boundary_string: string) => { const boundary = `------${boundary_string}`; @@ -494,4 +496,28 @@ export class KhojChatModal extends Modal { setIcon(transcribeButton, "mic"); } } + + incrementalChat(event: KeyboardEvent) { + if (!event.shiftKey && event.key === 'Enter') { + event.preventDefault(); + this.chat(); + } + } + + onChatInput() { + const chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; + chatInput.value = chatInput.value.trimStart(); + + this.autoResize(); + } + + autoResize() { + const chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; + const scrollTop = chatInput.scrollTop; + chatInput.style.height = '0'; + const scrollHeight = chatInput.scrollHeight + 8; // +8 accounts for padding + chatInput.style.height = Math.min(scrollHeight, 200) + 'px'; + chatInput.scrollTop = scrollTop; + this.modalEl.scrollTop = this.modalEl.scrollHeight; + } } diff --git a/src/interface/obsidian/styles.css b/src/interface/obsidian/styles.css index 87325d61..4029ecc7 100644 --- a/src/interface/obsidian/styles.css +++ b/src/interface/obsidian/styles.css @@ -241,14 +241,17 @@ img { } #khoj-chat-input { font-size: var(--font-ui-medium); - padding: 0 0 0 12px; + padding: 4px 0 0 12px; border-radius: 16px; height: 32px; + resize: none; } .khoj-input-row-button { border-radius: 50%; padding: 4px; --icon-size: var(--icon-size); + height: 32px; + width: 32px; } #khoj-chat-send .svg-icon { background: var(--khoj-sun);