Spaces:
Running
Running
Added enter to insert new line on mobile instead of default. (#1475)
Browse files* Added enter to insert new line on mobile instead of default.
* fix: lint
* Removed unnecessary if statement
* feat: use virtual keyboard detection instead of viewport width
---------
Co-authored-by: Nathan Sarrazin <[email protected]>
src/lib/components/chat/ChatInput.svelte
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<script lang="ts">
|
2 |
-
import {
|
3 |
import { createEventDispatcher, onMount } from "svelte";
|
4 |
|
5 |
export let value = "";
|
@@ -13,25 +13,41 @@
|
|
13 |
|
14 |
const dispatch = createEventDispatcher<{ submit: void }>();
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
$: minHeight = `${1 + minRows * 1.5}em`;
|
17 |
$: maxHeight = maxRows ? `${1 + maxRows * 1.5}em` : `auto`;
|
18 |
|
19 |
function handleKeydown(event: KeyboardEvent) {
|
20 |
-
// submit on enter
|
21 |
if (event.key === "Enter" && !event.shiftKey && !isCompositionOn) {
|
22 |
event.preventDefault();
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
28 |
}
|
29 |
-
dispatch("submit"); // use a custom event instead of `event.target.form.requestSubmit()` as it does not work on Safari 14
|
30 |
}
|
31 |
}
|
32 |
|
33 |
onMount(() => {
|
34 |
-
if (
|
35 |
textareaElement.focus();
|
36 |
}
|
37 |
});
|
@@ -44,7 +60,7 @@
|
|
44 |
style="min-height: {minHeight}; max-height: {maxHeight}">{(value || " ") + "\n"}</pre>
|
45 |
|
46 |
<textarea
|
47 |
-
enterkeyhint="send"
|
48 |
tabindex="0"
|
49 |
rows="1"
|
50 |
class="scrollbar-custom absolute top-0 m-0 h-full w-full resize-none scroll-p-3 overflow-x-hidden overflow-y-scroll border-0 bg-transparent p-3 outline-none focus:ring-0 focus-visible:ring-0"
|
|
|
1 |
<script lang="ts">
|
2 |
+
import { browser } from "$app/environment";
|
3 |
import { createEventDispatcher, onMount } from "svelte";
|
4 |
|
5 |
export let value = "";
|
|
|
13 |
|
14 |
const dispatch = createEventDispatcher<{ submit: void }>();
|
15 |
|
16 |
+
function isVirtualKeyboard(): boolean {
|
17 |
+
if (!browser) return false;
|
18 |
+
|
19 |
+
// Check for touch capability
|
20 |
+
if (navigator.maxTouchPoints > 0) return true;
|
21 |
+
|
22 |
+
// Check for touch events
|
23 |
+
if ("ontouchstart" in window) return true;
|
24 |
+
|
25 |
+
// Fallback to user agent string check
|
26 |
+
const userAgent = navigator.userAgent.toLowerCase();
|
27 |
+
|
28 |
+
return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
|
29 |
+
}
|
30 |
+
|
31 |
$: minHeight = `${1 + minRows * 1.5}em`;
|
32 |
$: maxHeight = maxRows ? `${1 + maxRows * 1.5}em` : `auto`;
|
33 |
|
34 |
function handleKeydown(event: KeyboardEvent) {
|
|
|
35 |
if (event.key === "Enter" && !event.shiftKey && !isCompositionOn) {
|
36 |
event.preventDefault();
|
37 |
+
if (isVirtualKeyboard()) {
|
38 |
+
// Insert a newline at the cursor position
|
39 |
+
const start = textareaElement.selectionStart;
|
40 |
+
const end = textareaElement.selectionEnd;
|
41 |
+
value = value.substring(0, start) + "\n" + value.substring(end);
|
42 |
+
textareaElement.selectionStart = textareaElement.selectionEnd = start + 1;
|
43 |
+
} else {
|
44 |
+
dispatch("submit");
|
45 |
}
|
|
|
46 |
}
|
47 |
}
|
48 |
|
49 |
onMount(() => {
|
50 |
+
if (!isVirtualKeyboard()) {
|
51 |
textareaElement.focus();
|
52 |
}
|
53 |
});
|
|
|
60 |
style="min-height: {minHeight}; max-height: {maxHeight}">{(value || " ") + "\n"}</pre>
|
61 |
|
62 |
<textarea
|
63 |
+
enterkeyhint={!isVirtualKeyboard() ? "enter" : "send"}
|
64 |
tabindex="0"
|
65 |
rows="1"
|
66 |
class="scrollbar-custom absolute top-0 m-0 h-full w-full resize-none scroll-p-3 overflow-x-hidden overflow-y-scroll border-0 bg-transparent p-3 outline-none focus:ring-0 focus-visible:ring-0"
|