feat: send a message to peers

This commit is contained in:
Jeremy Kahn 2022-08-14 21:26:50 -05:00
parent 9c3e96a804
commit 33b25e204d
4 changed files with 71 additions and 29 deletions

View File

@ -1,14 +1,45 @@
import { useMemo } from 'react'
import { useParams } from 'react-router-dom' import { useParams } from 'react-router-dom'
import Button from '@mui/material/Button'
import Typography from '@mui/material/Typography'
import { usePeerRoom } from '../../hooks/usePeerRoom' import { usePeerRoom } from '../../hooks/usePeerRoom'
enum PeerActions {
MESSAGE = 'MESSAGE',
}
export function Room() { export function Room() {
const { roomId = '' } = useParams() const { roomId = '' } = useParams()
usePeerRoom({ const { makeAction } = usePeerRoom({
appId: process.env.REACT_APP_NAME || '', appId: `${window.location.origin}_${process.env.REACT_APP_NAME}`,
roomId, roomId,
}) })
return <>Room ID: {roomId}</> const [sendMessage, receiveMessage] = useMemo(
() => makeAction<string>(PeerActions.MESSAGE),
[makeAction]
)
receiveMessage(message => {
console.log(message)
})
return (
<div>
<Typography>Room ID: {roomId}</Typography>
<Typography>
Open this page in another tab and open the console.
</Typography>
<Button
onClick={() => {
sendMessage('Hello!')
}}
variant="contained"
>
Say hi
</Button>
</div>
)
} }

View File

@ -9,18 +9,21 @@ interface PeerRoomProps {
export function usePeerRoom({ appId, roomId }: PeerRoomProps) { export function usePeerRoom({ appId, roomId }: PeerRoomProps) {
const peerRoom = useMemo(() => { const peerRoom = useMemo(() => {
return new PeerRoom({ appId }) const peerRoom = new PeerRoom({ appId })
}, [appId])
useEffect(() => {
peerRoom.joinRoom(roomId) peerRoom.joinRoom(roomId)
return peerRoom
}, [appId, roomId])
useEffect(() => {
return () => { return () => {
peerRoom.leaveRoom() peerRoom.leaveRoom()
} }
}, [appId, peerRoom, roomId]) }, [appId, peerRoom, roomId])
const { makeAction } = peerRoom
return { return {
peerRoom, makeAction,
} }
} }

View File

@ -1,6 +1,6 @@
/// <reference types="react-scripts" /> /// <reference types="react-scripts" />
// TODO: Contribute this to DefinitelyTyped // TODO: Contribute this to Trystero
declare module 'trystero' { declare module 'trystero' {
interface BitTorrentRoomConfig { interface BitTorrentRoomConfig {
trackerUrls?: string[] trackerUrls?: string[]
@ -25,24 +25,28 @@ declare module 'trystero' {
export type RoomConfig = BaseRoomConfig & export type RoomConfig = BaseRoomConfig &
(BitTorrentRoomConfig | FirebaseRoomConfig | IpfsRoomConfig) (BitTorrentRoomConfig | FirebaseRoomConfig | IpfsRoomConfig)
export type ActionSender = <T>( export interface ActionSender<T> {
data: T, (
targetPeers?: string[], data: T,
metadata?: Record, targetPeers?: string[],
progress: (percent: number, peerId: string) => void metadata?: Record,
) => void progress?: (percent: number, peerId: string) => void
): void
}
export type ActionReceiver = <T>( export interface ActionReceiver<T> {
data: T, (receiver: (data: T, peerId?: string, metadata?: Record) => void): void
peerId: string, }
metadata?: Record
) => void
export type ActionProgress = ( export interface ActionProgress {
percent: number, (
peerId: string, progressHandler: (
metadata?: Record percent: number,
) => void peerId: string,
metadata?: Record
) => void
): void
}
export interface Room { export interface Room {
makeAction: <T>( makeAction: <T>(

View File

@ -9,17 +9,21 @@ export class PeerRoom {
this.roomConfig = config this.roomConfig = config
} }
joinRoom(roomId: string) { joinRoom = (roomId: string) => {
this.room = joinRoom(this.roomConfig, roomId) this.room = joinRoom(this.roomConfig, roomId)
} }
leaveRoom() { leaveRoom = () => {
if (this.room) { if (this.room) {
this.room.leave() this.room.leave()
} }
} }
makeAction<T>(namespace: string) { makeAction = <T>(namespace: string) => {
return this.room?.makeAction<T>(namespace) if (!this.room) {
throw new Error('PeerRoom: Called makeAction before joinRoom')
}
return this.room.makeAction<T>(namespace)
} }
} }