From 579ff199219661b47ddf25063f2be1f4fd79105d Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Sun, 7 Aug 2022 03:00:14 +0300 Subject: [PATCH] add typing indicators --- frontend/public/global.css | 8 +- frontend/src/components/MessageInput.svelte | 98 +++++++++++++++++---- frontend/src/gateway.js | 2 + frontend/src/stores.js | 76 +++++++++++++++- src/gateway/gatewaypayloadtype.ts | 4 +- src/routes/api/v1/users.ts | 22 +++++ 6 files changed, 188 insertions(+), 22 deletions(-) diff --git a/frontend/public/global.css b/frontend/public/global.css index 3e5d976..1131c0e 100644 --- a/frontend/public/global.css +++ b/frontend/public/global.css @@ -6,7 +6,7 @@ font-weight: 400; font-stretch: normal; font-style: normal; - src: url('assets/woff2/iosevka-waffle-regular.woff2') format('woff2'); + src: url("assets/woff2/iosevka-waffle-regular.woff2") format("woff2"); } /* top-level */ @@ -296,7 +296,7 @@ b, strong { } code, kbd, samp, pre { - font-family: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace; + font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; font-size: 1em; } @@ -317,11 +317,11 @@ button, select { } /* Correct the inability to style clickable types in iOS and Safari. */ -button, [type='button'], [type='reset'], [type='submit'] { +button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } -/* Remove the additional ':invalid' styles in Firefox. */ +/* Remove the additional ":invalid" styles in Firefox. */ /* See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737 */ :-moz-ui-invalid { box-shadow: none; diff --git a/frontend/src/components/MessageInput.svelte b/frontend/src/components/MessageInput.svelte index e11ff8a..1115bd8 100644 --- a/frontend/src/components/MessageInput.svelte +++ b/frontend/src/components/MessageInput.svelte @@ -2,13 +2,42 @@ import { SendIcon } from "svelte-feather-icons"; import request from "../request"; import { apiRoute } from "../storage"; - import { messagesStoreProvider, overlayStore, smallViewport, userInfoStore } from "../stores"; + import { messagesStoreProvider, overlayStore, smallViewport, typingStore, userInfoStore } from "../stores"; export let channel; let messageInput = ""; let messageTextarea; + let typingList = "?no one?"; + let typingMessage = "is typing..."; $: messages = messagesStoreProvider.getStore(channel.id); + $: { + const typing = [ ...$typingStore ]; + const ownIndex = typing.findIndex(a => a.id === $userInfoStore.id); + if (ownIndex !== -1) { + typing.splice(ownIndex, 1); + } + + if (typing.length === 0) { + typingList = "?no one?"; + typingMessage = "is typing..."; + } else if (typing.length === 1) { + typingList = `${typing[0].username}`; + typingMessage = "is typing..."; + } else if (typing.length > 1) { + typingList = ""; + for (let i = 0; i < typing.length; i++) { + const item = typing[i]; + if (i == (typing.length - 1)) { + // we are at the end + typingList += `and ${item.username} `; + } else { + typingList += `${item.username}, `; + } + } + typingMessage = "are typing..."; + } + } const sendMessage = async () => { messageTextarea.focus(); @@ -56,15 +85,20 @@ } } }; + + const onInput = () => { + typingStore.didInputKey(); + };
-