improve message input box
This commit is contained in:
parent
17a7aaafdd
commit
97847288fc
3 changed files with 39 additions and 8 deletions
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { getItem } from "../storage";
|
||||
import { selectedChannel, sendMessageAction, setMessageInputEvent, smallViewport, typingStore, userInfoStore } from "../stores";
|
||||
import { overlayStore, selectedChannel, sendMessageAction, setMessageInputEvent, smallViewport, typingStore, userInfoStore, usesKeyboardNavigation } from "../stores";
|
||||
|
||||
export let channel;
|
||||
let messageInput = "";
|
||||
|
@ -65,14 +65,21 @@
|
|||
const unsubscribers = [];
|
||||
|
||||
|
||||
// Focus the text area when the component first loads, or when the user selects another channel
|
||||
const focusTextarea = () => {
|
||||
if (messageTextarea && getItem("ui:useragent:formFactor") !== "touch") {
|
||||
messageTextarea.focus();
|
||||
const handleDocumentKeydown = () => {
|
||||
if (document.activeElement && (["input", "textarea"]).includes(document.activeElement.tagName.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
if (overlayStore.isOverlayPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
messageTextarea.focus();
|
||||
};
|
||||
onMount(focusTextarea);
|
||||
unsubscribers.push(selectedChannel.on(focusTextarea));
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("keydown", handleDocumentKeydown);
|
||||
return () => document.removeEventListener("keydown", handleDocumentKeydown);
|
||||
});
|
||||
|
||||
// Handle the setMessageInput event
|
||||
unsubscribers.push(setMessageInputEvent.on((value) => {
|
||||
|
@ -121,7 +128,11 @@
|
|||
contain: strict;
|
||||
}
|
||||
|
||||
/* TODO: is this good? */
|
||||
.message-input:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
.message-input.keyboard-nav:focus-visible {
|
||||
outline: 2px solid var(--purple-2);
|
||||
}
|
||||
|
||||
|
@ -179,6 +190,7 @@
|
|||
bind:value={ messageInput }
|
||||
bind:this={ messageTextarea }
|
||||
class:small={ $smallViewport || getItem("ui:alwaysUseMobileChatBar") }
|
||||
class:keyboard-nav={ $usesKeyboardNavigation }
|
||||
/>
|
||||
{#if $smallViewport || getItem("ui:alwaysUseMobileChatBar")}
|
||||
<button class="icon-button send-button material-icons-outlined" on:click="{ sendMessage }">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { getItem } from "./storage";
|
||||
import { showSidebar, smallViewport, theme } from "./stores";
|
||||
import { showSidebar, smallViewport, theme, usesKeyboardNavigation } from "./stores";
|
||||
|
||||
function initViewportSizeHandler() {
|
||||
const root = document.querySelector(':root');
|
||||
|
@ -33,8 +33,22 @@ function updateTheme(themeName) {
|
|||
classes.add(`theme--${themeName}`);
|
||||
}
|
||||
|
||||
function initKeyboardNavigationDetection() {
|
||||
document.addEventListener("keydown", ({ key }) => {
|
||||
if (key === "Tab") {
|
||||
usesKeyboardNavigation.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("click", e => {
|
||||
// screenX and screenY are 0 when a user presses enter for navigation
|
||||
usesKeyboardNavigation.set(!e.screenX && !e.screenY);
|
||||
});
|
||||
}
|
||||
|
||||
export function initResponsiveHandlers() {
|
||||
initViewportSizeHandler();
|
||||
initKeyboardNavigationDetection();
|
||||
|
||||
const mediaQuery = window.matchMedia('(min-width: 768px)');
|
||||
|
||||
|
|
|
@ -410,6 +410,10 @@ class OverlayStore extends Store {
|
|||
super([], "OverlayStore");
|
||||
}
|
||||
|
||||
isOverlayPresent() {
|
||||
return !!this.value.length;
|
||||
}
|
||||
|
||||
push(type, props={}) {
|
||||
const id = Math.floor(Math.random() * 9999999);
|
||||
|
||||
|
@ -840,6 +844,7 @@ export const selectedChannel = new SelectedChannelStore();
|
|||
export const showSidebar = new Store(true, "showSidebar");
|
||||
export const showPresenceSidebar = new Store(false, "showPresenceSidebar");
|
||||
export const smallViewport = new Store(false, "smallViewport");
|
||||
export const usesKeyboardNavigation = new Store(false, "usesKeyboardNavigation");
|
||||
export const showChannelView = new Store(true, "showChannelView");
|
||||
export const theme = new StorageItemStore("ui:theme");
|
||||
export const sendTypingUpdatesItemStore = new StorageItemStore("ui:online:sendTypingUpdates");
|
||||
|
|
Loading…
Reference in a new issue