* feat: [#22] implement message backfilling * feat: scroll to latest backfilled message * feat: document transcript backfilling
This commit is contained in:
parent
bd6f1d5090
commit
10b061e36a
@ -30,6 +30,7 @@ Open https://chitchatter.im/ and join a room to start chatting with anyone else
|
||||
- The number displayed at the top-right of the screen shows how many peers you are connected to. Your peers are the only ones who can see your message.
|
||||
- Markdown support via [`react-markdown`](https://github.com/remarkjs/react-markdown).
|
||||
- Includes support for syntax highlighting of code.
|
||||
- Conversation backfilling from peers when a new participant joins
|
||||
- Multiline message support (hold Shift and press Enter).
|
||||
- Dark and light themes
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { HTMLAttributes, useRef, useEffect } from 'react'
|
||||
import { HTMLAttributes, useRef, useEffect, useState } from 'react'
|
||||
import cx from 'classnames'
|
||||
import Box from '@mui/material/Box'
|
||||
|
||||
@ -16,6 +16,7 @@ export const ChatTranscript = ({
|
||||
userId,
|
||||
}: ChatTranscriptProps) => {
|
||||
const boxRef = useRef<HTMLDivElement>(null)
|
||||
const [previousMessageLogLength, setPreviousMessageLogLength] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const { current: boxEl } = boxRef
|
||||
@ -29,14 +30,23 @@ export const ChatTranscript = ({
|
||||
const lastChild = children[children.length - 1]
|
||||
const lastChildHeight = lastChild.clientHeight
|
||||
const previousScrollTopMax = scrollTopMax - lastChildHeight
|
||||
const wasPreviouslyScrolledToBottom =
|
||||
Math.ceil(scrollTop) >= Math.ceil(previousScrollTopMax)
|
||||
const wasMessageLogPreviouslyEmpty = previousMessageLogLength === 0
|
||||
const shouldScrollToLatestMessage =
|
||||
wasPreviouslyScrolledToBottom || wasMessageLogPreviouslyEmpty
|
||||
|
||||
if (
|
||||
Math.ceil(scrollTop) >= Math.ceil(previousScrollTopMax) &&
|
||||
shouldScrollToLatestMessage &&
|
||||
// scrollTo is not defined in the unit test environment
|
||||
'scrollTo' in boxEl
|
||||
) {
|
||||
boxEl.scrollTo({ top: scrollTopMax })
|
||||
}
|
||||
}, [messageLog.length, previousMessageLogLength])
|
||||
|
||||
useEffect(() => {
|
||||
setPreviousMessageLogLength(messageLog.length)
|
||||
}, [messageLog.length])
|
||||
|
||||
return (
|
||||
|
@ -6,7 +6,7 @@ import { v4 as uuid } from 'uuid'
|
||||
import { ShellContext } from 'contexts/ShellContext'
|
||||
import { SettingsContext } from 'contexts/SettingsContext'
|
||||
import { PeerActions } from 'models/network'
|
||||
import { ReceivedMessage, UnsentMessage, Message } from 'models/chat'
|
||||
import { Message, ReceivedMessage, UnsentMessage, isMessageReceived } from 'models/chat'
|
||||
import { funAnimalName } from 'fun-animal-names'
|
||||
import { getPeerName } from 'components/PeerNameDisplay'
|
||||
import { NotificationService } from 'services/Notification'
|
||||
@ -62,6 +62,10 @@ export function useRoom(
|
||||
PeerActions.PEER_NAME
|
||||
)
|
||||
|
||||
const [sendMessageTranscript, receiveMessageTranscript] = usePeerRoomAction<
|
||||
ReceivedMessage[]
|
||||
>(peerRoom, PeerActions.MESSAGE_TRANSCRIPT)
|
||||
|
||||
const [sendPeerMessage, receivePeerMessage] =
|
||||
usePeerRoomAction<UnsentMessage>(peerRoom, PeerActions.MESSAGE)
|
||||
|
||||
@ -102,6 +106,12 @@ export function useRoom(
|
||||
}
|
||||
})
|
||||
|
||||
receiveMessageTranscript(transcript => {
|
||||
if (messageLog.length) return
|
||||
|
||||
setMessageLog(transcript)
|
||||
})
|
||||
|
||||
receivePeerMessage(message => {
|
||||
const userSettings = settingsContext.getUserSettings()
|
||||
|
||||
@ -130,7 +140,10 @@ export function useRoom(
|
||||
shellContext.setNumberOfPeers(newNumberOfPeers)
|
||||
;(async () => {
|
||||
try {
|
||||
await sendPeerId(userId, peerId)
|
||||
await Promise.all([
|
||||
sendPeerId(userId, peerId),
|
||||
sendMessageTranscript(messageLog.filter(isMessageReceived), peerId),
|
||||
])
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
// NOTE: Action names are limited to 12 characters, otherwise Trystero breaks.
|
||||
export enum PeerActions {
|
||||
MESSAGE = 'MESSAGE',
|
||||
MESSAGE_TRANSCRIPT = 'MSG_XSCRIPT',
|
||||
PEER_NAME = 'PEER_NAME',
|
||||
}
|
||||
|
@ -28,7 +28,11 @@ Public rooms can be joined by **anyone** with the room URL. By default, rooms ar
|
||||
|
||||
To connect to others, share the room URL with a secure tool such as [Burner Note](https://burnernote.com/) or [Yopass](https://yopass.se/). You will be notified when others join the room.
|
||||
|
||||
Chat message transcripts are erased as soon as you close the page or navigate away from the room.
|
||||
##### Conversation backfilling
|
||||
|
||||
Conversation transcripts are erased from local memory as soon as you close the page or navigate away from the room. Conversations are only ever held in volatile memory and never persisted to any disk by Chitchatter.
|
||||
|
||||
When a peer joins a public room with participants already in it, the new peer will automatically request the transcript of the conversation that has already taken place from the other peers. Once all peers leave the room, the conversation is completely erased.
|
||||
|
||||
#### Message Authoring
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user