feat: show animation when message is successfully sent
This commit is contained in:
parent
3be1f2e88a
commit
0d28df82c2
@ -5,7 +5,7 @@ export const joinRoom: typeof trysteroJoinRoom = (
|
||||
_roomId: string
|
||||
) => {
|
||||
const room: Room = {
|
||||
makeAction: () => [() => {}, () => {}, () => {}],
|
||||
makeAction: () => [() => Promise.resolve([]), () => {}, () => {}],
|
||||
ping: () => Promise.resolve(0),
|
||||
leave: () => {},
|
||||
getPeers: () => [],
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Typography from '@mui/material/Typography'
|
||||
|
||||
import { UnsentMessage, ReceivedMessage } from 'models/chat'
|
||||
import { isMessageReceived, UnsentMessage, ReceivedMessage } from 'models/chat'
|
||||
|
||||
export interface ChatTranscriptProps {
|
||||
messageLog: Array<UnsentMessage | ReceivedMessage>
|
||||
@ -10,24 +10,35 @@ export interface ChatTranscriptProps {
|
||||
export const ChatTranscript = ({ messageLog, userId }: ChatTranscriptProps) => {
|
||||
return (
|
||||
<div className="ChatTranscript flex flex-col">
|
||||
{messageLog.map((message, idx) => (
|
||||
<div className="block">
|
||||
<Typography
|
||||
key={`${idx}_${message}`}
|
||||
variant="body1"
|
||||
sx={{
|
||||
backgroundColor:
|
||||
message.authorId === userId ? 'primary.dark' : 'grey.700',
|
||||
margin: 0.5,
|
||||
padding: 1,
|
||||
borderRadius: 4,
|
||||
float: message.authorId === userId ? 'right' : 'left',
|
||||
}}
|
||||
>
|
||||
{message.text}
|
||||
</Typography>
|
||||
</div>
|
||||
))}
|
||||
{messageLog.map(message => {
|
||||
let backgroundColor: string
|
||||
|
||||
if (message.authorId === userId) {
|
||||
backgroundColor = isMessageReceived(message)
|
||||
? 'primary.dark'
|
||||
: 'primary.main'
|
||||
} else {
|
||||
backgroundColor = 'grey.700'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="block" key={message.id}>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
backgroundColor,
|
||||
margin: 0.5,
|
||||
padding: 1,
|
||||
borderRadius: 6,
|
||||
float: message.authorId === userId ? 'right' : 'left',
|
||||
transition: 'background-color 1s',
|
||||
}}
|
||||
>
|
||||
{message.text}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PropsWithChildren } from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { waitFor, render, screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { MemoryRouter as Router, Route, Routes } from 'react-router-dom'
|
||||
|
||||
@ -8,7 +8,9 @@ import { Room } from './'
|
||||
const stubUserId = 'user-id'
|
||||
|
||||
const mockGetUuid = jest.fn()
|
||||
const mockMessagedSender = jest.fn()
|
||||
const mockMessagedSender = jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve([]))
|
||||
|
||||
jest.mock('trystero', () => ({
|
||||
joinRoom: () => ({
|
||||
@ -73,7 +75,7 @@ describe('Room', () => {
|
||||
expect(sendButton).not.toBeDisabled()
|
||||
})
|
||||
|
||||
test('sending a message clears the text input', () => {
|
||||
test('sending a message clears the text input', async () => {
|
||||
render(
|
||||
<RouteStub>
|
||||
<Room userId={stubUserId} />
|
||||
@ -83,11 +85,15 @@ describe('Room', () => {
|
||||
const sendButton = screen.getByText('Send')
|
||||
const textInput = screen.getByPlaceholderText('Your message')
|
||||
userEvent.type(textInput, 'hello')
|
||||
userEvent.click(sendButton)
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(sendButton)
|
||||
})
|
||||
|
||||
expect(textInput).toHaveValue('')
|
||||
})
|
||||
|
||||
test('message is sent to peer', () => {
|
||||
test('message is sent to peer', async () => {
|
||||
render(
|
||||
<RouteStub>
|
||||
<Room
|
||||
@ -100,7 +106,11 @@ describe('Room', () => {
|
||||
const sendButton = screen.getByText('Send')
|
||||
const textInput = screen.getByPlaceholderText('Your message')
|
||||
userEvent.type(textInput, 'hello')
|
||||
userEvent.click(sendButton)
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(sendButton)
|
||||
})
|
||||
|
||||
expect(mockMessagedSender).toHaveBeenCalledWith({
|
||||
authorId: stubUserId,
|
||||
text: 'hello',
|
||||
|
@ -24,6 +24,7 @@ export function Room({
|
||||
}: RoomProps) {
|
||||
const { roomId = '' } = useParams()
|
||||
|
||||
const [isMessageSending, setIsMessageSending] = useState(false)
|
||||
const [textMessage, setTextMessage] = useState('')
|
||||
const [messageLog, setMessageLog] = useState<
|
||||
Array<ReceivedMessage | UnsentMessage>
|
||||
@ -46,7 +47,7 @@ export function Room({
|
||||
setTextMessage(value)
|
||||
}
|
||||
|
||||
const handleMessageSubmit = (
|
||||
const handleMessageSubmit = async (
|
||||
event: React.SyntheticEvent<HTMLFormElement>
|
||||
) => {
|
||||
event.preventDefault()
|
||||
@ -58,10 +59,16 @@ export function Room({
|
||||
id: getUuid(),
|
||||
}
|
||||
|
||||
sendMessage(unsentMessage)
|
||||
|
||||
setTextMessage('')
|
||||
setIsMessageSending(true)
|
||||
setMessageLog([...messageLog, unsentMessage])
|
||||
await sendMessage(unsentMessage)
|
||||
|
||||
setMessageLog([
|
||||
...messageLog,
|
||||
{ ...unsentMessage, timeReceived: Date.now() },
|
||||
])
|
||||
setIsMessageSending(false)
|
||||
}
|
||||
|
||||
receiveMessage(message => {
|
||||
@ -85,7 +92,7 @@ export function Room({
|
||||
<Button
|
||||
variant="contained"
|
||||
type="submit"
|
||||
disabled={textMessage.length === 0}
|
||||
disabled={textMessage.length === 0 || isMessageSending}
|
||||
sx={{
|
||||
marginTop: 2,
|
||||
}}
|
||||
|
@ -8,3 +8,7 @@ export interface UnsentMessage {
|
||||
export interface ReceivedMessage extends UnsentMessage {
|
||||
timeReceived: number
|
||||
}
|
||||
|
||||
export const isMessageReceived = (
|
||||
message: UnsentMessage
|
||||
): message is ReceivedMessage => 'timeReceived' in message
|
||||
|
4
src/react-app-env.d.ts
vendored
4
src/react-app-env.d.ts
vendored
@ -25,13 +25,13 @@ declare module 'trystero' {
|
||||
export type RoomConfig = BaseRoomConfig &
|
||||
(BitTorrentRoomConfig | FirebaseRoomConfig | IpfsRoomConfig)
|
||||
|
||||
export interface ActionSender<T> {
|
||||
export interface ActionSender<T> extends Promise {
|
||||
(
|
||||
data: T,
|
||||
targetPeers?: string[],
|
||||
metadata?: Record,
|
||||
progress?: (percent: number, peerId: string) => void
|
||||
): void
|
||||
): Promise<Array<undefined>>
|
||||
}
|
||||
|
||||
export interface ActionReceiver<T> {
|
||||
|
Loading…
Reference in New Issue
Block a user