1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-25 19:52:31 +01:00

typing indicators seem to work correctly now

This commit is contained in:
Puyodead1 2023-09-10 14:40:38 -04:00
parent 534bc10531
commit aa7a8327e4
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
2 changed files with 46 additions and 22 deletions

View File

@ -1,12 +1,12 @@
import Channel from "../../stores/objects/Channel";
import { debounce } from "@mui/material";
import { ChannelType } from "@spacebarchat/spacebar-api-types/v9";
import { observer } from "mobx-react-lite";
import React from "react";
import styled from "styled-components";
import useLogger from "../../hooks/useLogger";
import Guild from "../../stores/objects/Guild";
import { debounce } from "../../utils/debounce";
import MessageTextArea from "./MessageTextArea";
import AttachmentUploadList from "./attachments/AttachmentUploadPreview";
import FileUpload from "./attachments/FileUpload";
@ -68,32 +68,39 @@ function MessageInput({ channel }: Props) {
type: UploadStateType.NONE,
files: [],
});
const [typing, setTyping] = React.useState<number | null>(null);
const [typing, setTyping] = React.useState<number | boolean>();
/**
* Starts typing for client user and triggers gateway event
*/
const startTyping = React.useCallback(() => {
if (typing && typing > Date.now()) return;
if (typeof typing === "number" && typing > +new Date()) return;
logger.debug("ShouldStartTyping");
// TODO: send typing request
setTyping(+Date.now() + 10000);
setTyping(+new Date() + 10_000);
}, [typing, setTyping]);
/**
* Stops typing for client user
*/
const stopTyping = React.useCallback(() => {
if (typing) {
const stopTyping = React.useCallback(
(force?: boolean) => {
if (force || typing) {
logger.debug("ShouldStopTyping");
setTyping(null);
setTyping(false);
}
}, [typing, setTyping]);
},
[typing, setTyping],
);
/**
* Debounced version of stopTyping
*/
const debouncedStopTyping = React.useCallback(debounce(stopTyping, 10000), [stopTyping]);
const debouncedStopTyping = React.useCallback(debounce(stopTyping as (...args: unknown[]) => void, 10_000), [
channel,
stopTyping,
]);
/**
* @returns Whether or not a message can be sent given the current state
@ -111,20 +118,15 @@ function MessageInput({ channel }: Props) {
logger.debug("ShouldSendMessage");
}, [content, uploadState, channel, canSendMessage]);
/**
* Handles the change event of the textarea
*/
const onChange = React.useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
setContent(e.target.value);
}, []);
const onKeyDown = React.useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {
const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
// TODO:
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
send();
}
}, []);
debouncedStopTyping(true);
};
return (
<Container>
@ -177,8 +179,13 @@ function MessageInput({ channel }: Props) {
uploadState.type === UploadStateType.UPLOADING ||
uploadState.type === UploadStateType.SENDING
}
onChange={onChange}
onKeyDown={onKeyDown}
onChange={(e) => {
setContent(e.target.value);
startTyping();
}}
onKeyDown={() => {
debouncedStopTyping();
}}
/>
<ButtonWrapper>
{/* <IconButton>

17
src/utils/debounce.ts Normal file
View File

@ -0,0 +1,17 @@
// https://github.com/revoltchat/revite/blob/master/src/lib/debounce.ts#L5
export function debounce(cb: (...args: unknown[]) => void, duration: number) {
// Store the timer variable.
let timer: NodeJS.Timeout;
// This function is given to React.
return (...args: unknown[]) => {
// Get rid of the old timer.
clearTimeout(timer);
// Set a new timer.
timer = setTimeout(() => {
// Instead calling the new function.
// (with the newer data)
cb(...args);
}, duration);
};
}