From 10c2ca9994d1eb37296f7ccb662304a09a3dff6a Mon Sep 17 00:00:00 2001 From: Logan Yang Date: Thu, 30 Mar 2023 23:48:04 -0700 Subject: [PATCH] Add autosize for input textarea and fix format for user messages --- src/ChatGPTView.ts | 43 +++++++++++++++++++++++++++++++++++-------- src/style.ts | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 src/style.ts diff --git a/src/ChatGPTView.ts b/src/ChatGPTView.ts index d0007b06..f512ceae 100644 --- a/src/ChatGPTView.ts +++ b/src/ChatGPTView.ts @@ -1,4 +1,5 @@ import { ItemView, WorkspaceLeaf } from 'obsidian'; +import { CHATGPT_VIEW_STYLE } from './style'; export default class ChatGPTView extends ItemView { constructor(leaf: WorkspaceLeaf) { @@ -28,6 +29,10 @@ export default class ChatGPTView extends ItemView { // Render the chat interface and add event listeners async onOpen() { this.containerEl.empty(); + // Add the chat interface CSS styles + this.containerEl.createEl('style', { + text: CHATGPT_VIEW_STYLE, + }); // Create the chat interface HTML const container = this.containerEl.createDiv({ cls: 'chat-container' }); @@ -35,31 +40,42 @@ export default class ChatGPTView extends ItemView { const chatMessages = container.createDiv({ cls: 'chat-messages' }); const chatInputContainer = container.createDiv({ cls: 'chat-input-container' }); - const chatInput = chatInputContainer.createEl('input', { type: 'text', placeholder: 'Type your message here...' }); + const chatInput = chatInputContainer.createEl('textarea', { placeholder: 'Type your message here...' }); const chatSendButton = chatInputContainer.createEl('button', { text: 'Send' }); // Add event listeners chatSendButton.addEventListener('click', () => { - this.handleSendMessage(chatInput as HTMLInputElement, chatMessages as HTMLDivElement); + this.handleSendMessage(chatInput as HTMLTextAreaElement, chatMessages as HTMLDivElement); }); - chatInput.addEventListener('keypress', (event) => { - if (event.key === 'Enter') { - this.handleSendMessage(chatInput as HTMLInputElement, chatMessages as HTMLDivElement); + chatInput.addEventListener('keydown', (event) => { + // Check if the 'shift' key is pressed and the 'enter' key is pressed + if (event.shiftKey && event.key === 'Enter') { + // Prevent the default behavior of 'Enter' key press + event.preventDefault(); + // Create a new line + chatInput.value += '\n'; + return; } + if (event.key === 'Enter') { + this.handleSendMessage(chatInput as HTMLTextAreaElement, chatMessages as HTMLDivElement); + } + }); + + chatInput.addEventListener('input', () => { + this.autosize(chatInput as HTMLTextAreaElement); }); } // Create a message element and append it to the chatMessages div appendMessage(chatMessages: HTMLDivElement, message: string, sender: string) { const messageEl = chatMessages.createDiv({ cls: `chat-message ${sender}` }); - messageEl.createEl('span', { text: message }); + messageEl.innerHTML = message.replace(/\n/g, '
'); } // Add a method to handle sending messages to ChatGPT - handleSendMessage(chatInput: HTMLInputElement, chatMessages: HTMLDivElement) { + handleSendMessage(chatInput: HTMLTextAreaElement, chatMessages: HTMLDivElement) { const message = chatInput.value; - chatInput.value = ''; // Append the user's message to the chat interface this.appendMessage(chatMessages, message, 'user'); @@ -71,5 +87,16 @@ export default class ChatGPTView extends ItemView { // Replace this with the actual response from the API const chatGPTResponse = 'This is a sample response from ChatGPT'; this.appendMessage(chatMessages, chatGPTResponse, 'chatgpt'); + + // Clear the textarea content after sending the message with a slight delay + setTimeout(() => { + chatInput.value = ''; + this.autosize(chatInput); // Reset the textarea height after clearing its value + }, 10); + } + + autosize(textarea: HTMLTextAreaElement) { + textarea.style.height = 'auto'; + textarea.style.height = textarea.scrollHeight + 'px'; } } \ No newline at end of file diff --git a/src/style.ts b/src/style.ts new file mode 100644 index 00000000..83e386e9 --- /dev/null +++ b/src/style.ts @@ -0,0 +1,38 @@ +export const CHATGPT_VIEW_STYLE = ` + .chat-container { + display: flex; + flex-direction: column; + height: 100%; + } + .chat-messages { + flex-grow: 1; + overflow-y: auto; + padding: 8px; + } + .chat-message.user { + background-color: #3a3a3a; + color: #ffffff; + border-radius: 5px; + padding: 8px; + margin-bottom: 8px; + } + .chat-message.chatgpt { + background-color: #e6e6e6; + color: #333333; + border-radius: 5px; + padding: 8px; + margin-bottom: 8px; + } + .chat-input-container { + display: flex; + padding: 8px; + } + .chat-input-container textarea { + flex-grow: 1; + margin-right: 8px; + margin-bottom: 32px; + max-height: 200px; /* Set a maximum height for the textarea */ + resize: vertical; /* Allow vertical resizing of the textarea */ + overflow: auto; /* Enable scrolling if the content exceeds the max-height */ + } +` \ No newline at end of file