Skip to content

Commit

Permalink
fixup! fixup! refactor(#141): [wip] enable multiple action receivers
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyckahn committed Nov 24, 2024
1 parent 5bd794c commit a93b924
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 263 deletions.
122 changes: 58 additions & 64 deletions src/components/Room/usePeerVerification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,64 @@ export const usePeerVerification = ({

const { getDisplayUsername } = usePeerNameDisplay()

const [sendVerificationTokenEncrypted, receiveVerificationTokenEncrypted] =
usePeerAction<ArrayBuffer>({
peerAction: PeerAction.VERIFICATION_TOKEN_ENCRYPTED,
peerRoom,
})

const [sendVerificationTokenRaw, receiveVerificationTokenRaw] =
usePeerAction<string>({
peerAction: PeerAction.VERIFICATION_TOKEN_RAW,
peerRoom,
})
const [sendVerificationTokenEncrypted] = usePeerAction<ArrayBuffer>({
peerAction: PeerAction.VERIFICATION_TOKEN_ENCRYPTED,
peerRoom,
onReceive: async (encryptedVerificationToken, peerId) => {
try {
const decryptedVerificationToken =
await encryptionService.decryptString(
privateKey,
encryptedVerificationToken
)

await sendVerificationTokenRaw(decryptedVerificationToken, [peerId])
} catch (e) {
console.error(e)
}
},
})

const [sendVerificationTokenRaw] = usePeerAction<string>({
peerAction: PeerAction.VERIFICATION_TOKEN_RAW,
peerRoom,
onReceive: (decryptedVerificationToken, peerId) => {
const matchingPeer = peerList.find(peer => peer.peerId === peerId)

if (!matchingPeer) {
throw new Error(`peerId not found: ${peerId}`)
}

const { verificationToken, verificationTimer } = matchingPeer

if (decryptedVerificationToken !== verificationToken) {
updatePeer(peerId, {
verificationState: PeerVerificationState.UNVERIFIED,
verificationTimer: null,
})

showAlert(
`Verification for ${getDisplayUsername(matchingPeer.userId)} failed`,
{
severity: 'error',
}
)

throw new Error(
`Verification token for peerId ${peerId} does not match. [expected: ${verificationToken}] [received: ${decryptedVerificationToken}]`
)
}

if (verificationTimer) {
clearTimeout(verificationTimer)
}

updatePeer(peerId, {
verificationState: PeerVerificationState.VERIFIED,
verificationTimer: null,
})
},
})

const initPeerVerification = useCallback(
async (peer: Peer) => {
Expand Down Expand Up @@ -94,58 +141,5 @@ export const usePeerVerification = ({
setScheduledPeerToVerify(peer)
}

receiveVerificationTokenEncrypted(
async (encryptedVerificationToken, peerId) => {
try {
const decryptedVerificationToken =
await encryptionService.decryptString(
privateKey,
encryptedVerificationToken
)

await sendVerificationTokenRaw(decryptedVerificationToken, [peerId])
} catch (e) {
console.error(e)
}
}
)

receiveVerificationTokenRaw((decryptedVerificationToken, peerId) => {
const matchingPeer = peerList.find(peer => peer.peerId === peerId)

if (!matchingPeer) {
throw new Error(`peerId not found: ${peerId}`)
}

const { verificationToken, verificationTimer } = matchingPeer

if (decryptedVerificationToken !== verificationToken) {
updatePeer(peerId, {
verificationState: PeerVerificationState.UNVERIFIED,
verificationTimer: null,
})

showAlert(
`Verification for ${getDisplayUsername(matchingPeer.userId)} failed`,
{
severity: 'error',
}
)

throw new Error(
`Verification token for peerId ${peerId} does not match. [expected: ${verificationToken}] [received: ${decryptedVerificationToken}]`
)
}

if (verificationTimer) {
clearTimeout(verificationTimer)
}

updatePeer(peerId, {
verificationState: PeerVerificationState.VERIFIED,
verificationTimer: null,
})
})

return { verifyPeer }
}
202 changes: 98 additions & 104 deletions src/components/Room/useRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,14 @@ export function useRoom(
]
)

const [sendTypingStatusChange, receiveTypingStatusChange] =
usePeerAction<TypingStatus>({
peerAction: PeerAction.TYPING_STATUS_CHANGE,
peerRoom,
})
const [sendTypingStatusChange] = usePeerAction<TypingStatus>({
peerAction: PeerAction.TYPING_STATUS_CHANGE,
peerRoom,
onReceive: (typingStatus, peerId) => {
const { isTyping } = typingStatus
updatePeer(peerId, { isTyping })
},
})

const [isTyping, setIsTypingDebounced, setIsTyping] = useDebounce(
false,
Expand Down Expand Up @@ -243,62 +246,13 @@ export function useRoom(
if (isShowingMessages) setUnreadMessages(0)
}, [isShowingMessages, setUnreadMessages])

const [sendPeerMetadata, receivePeerMetadata] = usePeerAction<UserMetadata>({
const [sendPeerMetadata] = usePeerAction<UserMetadata>({
peerAction: PeerAction.PEER_METADATA,
peerRoom,
})

const [sendMessageTranscript, receiveMessageTranscript] = usePeerAction<
Array<ReceivedMessage | ReceivedInlineMedia>
>({
peerAction: PeerAction.MESSAGE_TRANSCRIPT,
peerRoom,
})

const [sendPeerMessage, receivePeerMessage] = usePeerAction<UnsentMessage>({
peerAction: PeerAction.MESSAGE,
peerRoom,
})

const [sendPeerInlineMedia, receivePeerInlineMedia] =
usePeerAction<UnsentInlineMedia>({
peerAction: PeerAction.MEDIA_MESSAGE,
peerRoom,
})

const { privateKey } = settingsContext.getUserSettings()

const { verifyPeer } = usePeerVerification({
peerRoom,
privateKey,
encryptionService,
})

const sendMessage = async (message: string) => {
if (isMessageSending) return

const unsentMessage: UnsentMessage = {
authorId: userId,
text: message,
timeSent: timeService.now(),
id: getUuid(),
}

setIsTyping(false)
setIsMessageSending(true)
setMessageLog([...messageLog, unsentMessage])

await sendPeerMessage(unsentMessage, targetPeerId)

setMessageLog([
...messageLog,
{ ...unsentMessage, timeReceived: timeService.now() },
])
setIsMessageSending(false)
}

receivePeerMetadata(
async ({ userId, customUsername, publicKeyString }, peerId: string) => {
onReceive: async (
{ userId, customUsername, publicKeyString },
peerId: string
) => {
const publicKey = await encryptionService.parseCryptoKeyString(
publicKeyString,
AllowedKeyType.PUBLIC
Expand Down Expand Up @@ -343,40 +297,106 @@ export function useRoom(
showAlert(`${oldUsername} is now ${newUsername}`)
}
}
}
)
},
})

receiveMessageTranscript(transcript => {
if (messageLog.length) return
const [sendMessageTranscript] = usePeerAction<
Array<ReceivedMessage | ReceivedInlineMedia>
>({
peerAction: PeerAction.MESSAGE_TRANSCRIPT,
peerRoom,
onReceive: transcript => {
if (messageLog.length) return

setMessageLog(transcript)
setMessageLog(transcript)
},
})

receivePeerMessage((message, peerId) => {
const userSettings = settingsContext.getUserSettings()
const [sendPeerMessage] = usePeerAction<UnsentMessage>({
peerAction: PeerAction.MESSAGE,
peerRoom,
onReceive: (message, peerId) => {
const userSettings = settingsContext.getUserSettings()

if (!isShowingMessages) {
setUnreadMessages(unreadMessages + 1)
}

if (!isShowingMessages) {
setUnreadMessages(unreadMessages + 1)
}
if (!tabHasFocus || !isShowingMessages) {
if (userSettings.playSoundOnNewMessage) {
newMessageAudio.play()
}

if (userSettings.showNotificationOnNewMessage) {
const displayUsername = getDisplayUsername(message.authorId)

if (!tabHasFocus || !isShowingMessages) {
if (userSettings.playSoundOnNewMessage) {
newMessageAudio.play()
notification.showNotification(`${displayUsername}: ${message.text}`)
}
}

if (userSettings.showNotificationOnNewMessage) {
const displayUsername = getDisplayUsername(message.authorId)
setMessageLog([
...messageLog,
{ ...message, timeReceived: timeService.now() },
])
updatePeer(peerId, { isTyping: false })
},
})

const [sendPeerInlineMedia] = usePeerAction<UnsentInlineMedia>({
peerAction: PeerAction.MEDIA_MESSAGE,
peerRoom,
onReceive: inlineMedia => {
const userSettings = settingsContext.getUserSettings()

notification.showNotification(`${displayUsername}: ${message.text}`)
if (!tabHasFocus) {
if (userSettings.playSoundOnNewMessage) {
newMessageAudio.play()
}

if (userSettings.showNotificationOnNewMessage) {
notification.showNotification(
`${getDisplayUsername(inlineMedia.authorId)} shared media`
)
}
}

setMessageLog([
...messageLog,
{ ...inlineMedia, timeReceived: timeService.now() },
])
},
})

const { privateKey } = settingsContext.getUserSettings()

const { verifyPeer } = usePeerVerification({
peerRoom,
privateKey,
encryptionService,
})

const sendMessage = async (message: string) => {
if (isMessageSending) return

const unsentMessage: UnsentMessage = {
authorId: userId,
text: message,
timeSent: timeService.now(),
id: getUuid(),
}

setIsTyping(false)
setIsMessageSending(true)
setMessageLog([...messageLog, unsentMessage])

await sendPeerMessage(unsentMessage, targetPeerId)

setMessageLog([
...messageLog,
{ ...message, timeReceived: timeService.now() },
{ ...unsentMessage, timeReceived: timeService.now() },
])
updatePeer(peerId, { isTyping: false })
})
setIsMessageSending(false)
}

peerRoom.onPeerJoin(PeerHookType.NEW_PEER, (peerId: string) => {
showAlert(`Someone has joined the room`, {
Expand Down Expand Up @@ -468,32 +488,6 @@ export function useRoom(
setIsTypingDebounced(false)
}

receivePeerInlineMedia(inlineMedia => {
const userSettings = settingsContext.getUserSettings()

if (!tabHasFocus) {
if (userSettings.playSoundOnNewMessage) {
newMessageAudio.play()
}

if (userSettings.showNotificationOnNewMessage) {
notification.showNotification(
`${getDisplayUsername(inlineMedia.authorId)} shared media`
)
}
}

setMessageLog([
...messageLog,
{ ...inlineMedia, timeReceived: timeService.now() },
])
})

receiveTypingStatusChange((typingStatus, peerId) => {
const { isTyping } = typingStatus
updatePeer(peerId, { isTyping })
})

useEffect(() => {
;(async () => {
const publicKeyString =
Expand Down
Loading

0 comments on commit a93b924

Please sign in to comment.