fix: prevent large transcripts from affecting input performance

This commit is contained in:
Jeremy Kahn 2022-09-08 21:35:50 -05:00
parent 5b69f48229
commit cebb8dc93a
3 changed files with 91 additions and 66 deletions

View File

@ -0,0 +1,77 @@
import { KeyboardEvent, SyntheticEvent, useState } from 'react'
import FormControl from '@mui/material/FormControl'
import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Fab from '@mui/material/Fab'
import ArrowUpward from '@mui/icons-material/ArrowUpward'
interface MessageFormProps {
onMessageSubmit: (message: string) => void
isMessageSending: boolean
}
export const MessageForm = ({
onMessageSubmit,
isMessageSending,
}: MessageFormProps) => {
const [textMessage, setTextMessage] = useState('')
const canMessageBeSent = () => {
return textMessage.trim().length > 0 && !isMessageSending
}
const handleMessageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value } = event.target
setTextMessage(value)
}
const submitMessage = () => {
onMessageSubmit(textMessage)
setTextMessage('')
}
const handleMessageKeyPress = (event: KeyboardEvent<HTMLInputElement>) => {
const { key, shiftKey } = event
if (key === 'Enter' && shiftKey === false) {
event.preventDefault()
submitMessage()
}
}
const handleMessageSubmit = (event: SyntheticEvent<HTMLFormElement>) => {
event.preventDefault()
submitMessage()
}
return (
<form onSubmit={handleMessageSubmit} className="p-4">
<Stack direction="row" spacing={2}>
<FormControl fullWidth>
<TextField
variant="outlined"
value={textMessage}
onChange={handleMessageChange}
onKeyPress={handleMessageKeyPress}
size="medium"
placeholder="Your message"
multiline
/>
</FormControl>
<Fab
sx={{
flexShrink: 0,
// The !important is needed to override a Stack style
marginTop: 'auto!important',
}}
aria-label="Send"
type="submit"
disabled={!canMessageBeSent()}
color="primary"
>
<ArrowUpward />
</Fab>
</Stack>
</form>
)
}

View File

@ -0,0 +1 @@
export * from './MessageForm'

View File

@ -1,17 +1,13 @@
import React, { useContext, useEffect, useState } from 'react'
import { useContext, useEffect, useState } from 'react'
import { v4 as uuid } from 'uuid'
import Box from '@mui/material/Box'
import FormControl from '@mui/material/FormControl'
import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Fab from '@mui/material/Fab'
import Divider from '@mui/material/Divider'
import ArrowUpward from '@mui/icons-material/ArrowUpward'
import { ShellContext } from 'contexts/ShellContext'
import { usePeerRoom, usePeerRoomAction } from 'hooks/usePeerRoom'
import { PeerActions } from 'models/network'
import { UnsentMessage, ReceivedMessage } from 'models/chat'
import { MessageForm } from 'components/MessageForm'
import { ChatTranscript } from 'components/ChatTranscript'
export interface RoomProps {
@ -30,7 +26,6 @@ export function Room({
const [numberOfPeers, setNumberOfPeers] = useState(1) // Includes this peer
const shellContext = useContext(ShellContext)
const [isMessageSending, setIsMessageSending] = useState(false)
const [textMessage, setTextMessage] = useState('')
const [messageLog, setMessageLog] = useState<
Array<ReceivedMessage | UnsentMessage>
>([])
@ -100,26 +95,16 @@ export function Room({
PeerActions.MESSAGE
)
const handleMessageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value } = event.target
setTextMessage(value)
}
const canMessageBeSent = () => {
return textMessage.trim().length > 0 && !isMessageSending
}
const performMessageSend = async () => {
if (!canMessageBeSent()) return
const performMessageSend = async (message: string) => {
if (isMessageSending) return
const unsentMessage: UnsentMessage = {
authorId: userId,
text: textMessage,
text: message,
timeSent: Date.now(),
id: getUuid(),
}
setTextMessage('')
setIsMessageSending(true)
setMessageLog([...messageLog, unsentMessage])
await sendMessage(unsentMessage)
@ -131,28 +116,14 @@ export function Room({
setIsMessageSending(false)
}
const handleMessageKeyPress = async (
event: React.KeyboardEvent<HTMLInputElement>
) => {
const { key, shiftKey } = event
if (key === 'Enter' && shiftKey === false) {
event.preventDefault()
await performMessageSend()
}
}
const handleMessageSubmit = async (
event: React.SyntheticEvent<HTMLFormElement>
) => {
event.preventDefault()
await performMessageSend()
}
receiveMessage(message => {
setMessageLog([...messageLog, { ...message, timeReceived: Date.now() }])
})
const handleMessageSubmit = async (message: string) => {
await performMessageSend(message)
}
return (
<Box
className="Room"
@ -168,34 +139,10 @@ export function Room({
className="grow overflow-auto px-4"
/>
<Divider />
<form onSubmit={handleMessageSubmit} className="p-4">
<Stack direction="row" spacing={2}>
<FormControl fullWidth>
<TextField
variant="outlined"
value={textMessage}
onChange={handleMessageChange}
onKeyPress={handleMessageKeyPress}
size="medium"
placeholder="Your message"
multiline
/>
</FormControl>
<Fab
sx={{
flexShrink: 0,
// The !important is needed to override a Stack style
marginTop: 'auto!important',
}}
aria-label="Send"
type="submit"
disabled={!canMessageBeSent()}
color="primary"
>
<ArrowUpward />
</Fab>
</Stack>
</form>
<MessageForm
onMessageSubmit={handleMessageSubmit}
isMessageSending={isMessageSending}
/>
</Box>
)
}