Jeremy Kahn 6cbfaacf1a
feat(verification): [closes #209] Verified peers (#216)
* refactor(bootstrap): add BootstrapShim
* feat(security): [#209] generate public/private keys
* refactor(encryption): move encryption utils to a service
* feat(encryption): [wip] implement convertCryptoKeyToString
* fix(user-settings): serialize crypto keys to strings
* feat(user-settings): deserialize user settings from IndexedDB
* feat(user-settings): upgrade persisted settings on boot
* feat(user-settings): automatically migrate persisted user settings
* refactor(encryption): simplify CryptoKey stringification
* refactor(encryption): DRY up EncryptionService
* feat(verification): send public key to new peers
* refactor(encryption): use class instance
* refactor(serialization): use class instance
* refactor(verification): [wip] create usePeerVerification hook
* feat(verification): encrypt verification token
* feat(verification): send encrypted token to peer
* feat(verification): verify peer
* refactor(verification): use enum for verification state
* feat(verification): expire verification requests
* fix(updatePeer): update with fresh state data
* feat(verification): display verification state
* refactor(usePeerVerification): store verification timer in Peer
* feat(verification): present tooltips explaining verification state
* feat(ui): show full page loading indicator
* feat(init): present bootup failure reasons
* refactor(init): move init to its own file
* feat(verification): show errors upon verification failure
* refactor(verification): move workaround to usePeerVerification
* feat(verification): present peer public keys
* refactor(verification): move peer public key rendering to its own component
* refactor(verification): only pass publicKey into renderer
* feat(verification): show user's own public key
* refactor(naming): rename Username to UserInfo
* refactor(loading): encapsulate height styling
* feat(verification): improve user messaging
* refactor(style): improve formatting and variable names
* feat(verification): add user info tooltip
* docs(verification): explain verification
2023-12-09 17:47:05 -06:00

92 lines
2.6 KiB
TypeScript

import { PropsWithChildren } from 'react'
import List from '@mui/material/List'
import ListItemIcon from '@mui/material/ListItemIcon'
import ListItemText from '@mui/material/ListItemText'
import Divider from '@mui/material/Divider'
import VolumeUp from '@mui/icons-material/VolumeUp'
import ListItem from '@mui/material/ListItem'
import Box from '@mui/material/Box'
import CircularProgress from '@mui/material/CircularProgress'
import { UserInfo } from 'components/UserInfo'
import { AudioState, Peer } from 'models/chat'
import { PeerConnectionType } from 'services/PeerRoom'
import { TrackerConnection } from 'services/ConnectionTest'
import { PeerListHeader } from './PeerListHeader'
import { PeerListItem } from './PeerListItem'
import { ConnectionTestResults as IConnectionTestResults } from './useConnectionTest'
export const peerListWidth = 300
export interface PeerListProps extends PropsWithChildren {
userId: string
roomId: string | undefined
onPeerListClose: () => void
peerList: Peer[]
peerConnectionTypes: Record<string, PeerConnectionType>
audioState: AudioState
peerAudios: Record<string, HTMLAudioElement>
connectionTestResults: IConnectionTestResults
}
export const PeerList = ({
userId,
roomId,
onPeerListClose,
peerList,
peerConnectionTypes,
audioState,
peerAudios,
connectionTestResults,
}: PeerListProps) => {
return (
<>
<PeerListHeader
onPeerListClose={onPeerListClose}
connectionTestResults={connectionTestResults}
/>
<Divider />
<List>
<ListItem divider={true}>
{audioState === AudioState.PLAYING && (
<ListItemIcon>
<VolumeUp />
</ListItemIcon>
)}
<ListItemText>
<UserInfo userId={userId} />
</ListItemText>
</ListItem>
{peerList.map((peer: Peer) => (
<PeerListItem
key={peer.peerId}
peer={peer}
peerConnectionTypes={peerConnectionTypes}
peerAudios={peerAudios}
/>
))}
{peerList.length === 0 &&
typeof roomId === 'string' &&
connectionTestResults.trackerConnection ===
TrackerConnection.CONNECTED &&
connectionTestResults.hasHost ? (
<>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
m: 2,
}}
>
<CircularProgress size={16} sx={{ mr: 1.5 }} />
<span>Searching for peers...</span>
</Box>
</>
) : null}
</List>
</>
)
}