summaryrefslogtreecommitdiff
path: root/ui/lib/components
diff options
context:
space:
mode:
Diffstat (limited to 'ui/lib/components')
-rw-r--r--ui/lib/components/MessageInput.svelte40
1 files changed, 37 insertions, 3 deletions
diff --git a/ui/lib/components/MessageInput.svelte b/ui/lib/components/MessageInput.svelte
index 69a8298..cdb855e 100644
--- a/ui/lib/components/MessageInput.svelte
+++ b/ui/lib/components/MessageInput.svelte
@@ -4,27 +4,61 @@
let value = $state('');
let disabled = $state(false);
+ // Entering and removing text from the input area leaves a stray line break behind. This effect
+ // looks for that scenario and removes it, restoring the "empty" state (and bringing the
+ // placeholder back again in the process).
+ $effect(() => {
+ const trimmed = value.trim();
+ if (trimmed !== value && trimmed === '') {
+ value = trimmed;
+ }
+ });
+
async function onsubmit(event) {
event.preventDefault();
disabled = true;
try {
await sendMessage(value);
- event.target.reset();
+ event.target.closest('form')?.reset();
} finally {
disabled = false;
}
}
function onkeydown(event) {
+ if (disabled) {
+ event.preventDefault();
+ return;
+ }
+
let modifier = event.shiftKey || event.altKey || event.ctrlKey || event.metaKey;
if (!modifier && event.key === 'Enter') {
event.preventDefault();
- event.target.form.requestSubmit();
+ event.target.closest('form')?.requestSubmit();
+ }
+ }
+
+ function onpaste(event) {
+ if (disabled) {
+ event.preventDefault();
}
}
</script>
<form {onsubmit}>
- <textarea {onkeydown} bind:value {disabled} placeholder="Say something..."></textarea>
+ <textarea bind:value class="hidden" {disabled}></textarea>
+ <div
+ role="textbox"
+ tabindex="0"
+ contenteditable="plaintext-only"
+ class={{
+ textarea: true,
+ disabled
+ }}
+ bind:innerText={value}
+ {onkeydown}
+ {onpaste}
+ data-placeholder="Say something..."
+ ></div>
<button type="submit">&raquo;</button>
</form>