(null)
+
+ const draw = (context: CanvasRenderingContext2D) => {
+ const image: HTMLImageElement = new Image()
+ let imageWidth: number
+ let imageHeight: number
+ image.src = photo
+ image.onload = () => {
+ const ratio = Math.min(288 / image.width, 288 / image.height)
+ if (image.width > 288 || image.height > 288) {
+ imageWidth = image.width * ratio
+ imageHeight = image.height * ratio
+ } else {
+ imageWidth = image.width
+ imageHeight = image.height
+ }
+ const x = context.canvas.width / 2 - imageWidth / 2
+ const y = context.canvas.height / 2 - imageHeight / 2
+ context.clearRect(0, 0, context.canvas.width, context.canvas.height)
+ context.drawImage(image, x, y, imageWidth, imageHeight)
+ }
+ }
+
+ const handleChange = (event: any) => {
+ if (event.target.files[0]) {
+ setPhoto(URL.createObjectURL(event.target.files[0]))
+ }
+ }
+
+ const removePhoto = () => {
+ setPhoto(defaultPhoto)
+ }
+
+ useEffect(() => {
+ if (!canvasRef.current) {
+ throw Error('Missing canvas element reference')
+ }
+ const canvas = canvasRef.current
+ const context = canvas.getContext('2d')
+ if (context) {
+ draw(context)
+ setStream(canvas.captureStream())
+ }
+ }, [photo])
+
+ return (
+
+
+
+ )
+}
+
+export default PhotoUploader
\ No newline at end of file
diff --git a/types/photo.tsx b/types/photo.tsx
new file mode 100644
index 0000000..ab385f8
--- /dev/null
+++ b/types/photo.tsx
@@ -0,0 +1,29 @@
+import { useEffect, useRef } from 'react'
+
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, prettier/prettier
+const Photo = () => {
+ const canvasRef = useRef(null)
+
+ const draw = (context: CanvasRenderingContext2D) => {
+ const image: HTMLImageElement = new Image()
+ image.src = '/no-video.svg'
+ image.onload = () => {
+ context.drawImage(image, 0, 0)
+ }
+ }
+
+ useEffect(() => {
+ const canvas = canvasRef.current
+ const context = canvas?.getContext('2d')
+ if (context) {
+ draw(context)
+ }
+ })
+ // w-40 h-40 md:w-56 md:h-56 xl:w-72 xl:h-72
+
+ return (
+
+ )
+}
+
+export default Photo
\ No newline at end of file
diff --git a/types/presenter.tsx b/types/presenter.tsx
index f42779b..047796d 100644
--- a/types/presenter.tsx
+++ b/types/presenter.tsx
@@ -1,14 +1,12 @@
import { useState } from 'react'
-import Disconnect from '../public/disconnect'
-import Mute from '../public/mute'
import Share from '../public/share'
import UnShare from '../public/un-share'
-import UnMute from '../public/unmute'
import Video from '../types/video'
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
-const Presenter = (props: { stream: MediaStream; disconnect: () => void }) => {
+const Presenter = (props: { stream: MediaStream | null, disconnect: () => void }) => {
const [micActivated, setMicActivated] = useState(true)
+ const [audioTrack, setAudioTrack] = useState(undefined)
const [videoActive, setVideoActive] = useState(true)
const [screenCaptureActivated, setScreenCapture] = useState(false)
@@ -21,18 +19,23 @@ const Presenter = (props: { stream: MediaStream; disconnect: () => void }) => {
const activateMicrophone = () => {
setMicActivated(true)
- const audioTracks = props.stream.getAudioTracks()
- audioTracks.forEach((track) => {
- track.enabled = true
- })
+ if (audioTrack) {
+ props.stream?.addTrack(audioTrack)
+ }
}
const deactivateMicrophone = () => {
+ if (!props.stream) {
+ return
+ }
setMicActivated(false)
- const audioTracks = props.stream.getAudioTracks()
- audioTracks.forEach((track) => {
- track.enabled = false
- })
+ if (!audioTrack) {
+ const track = props.stream.getAudioTracks()[0]
+ setAudioTrack(track)
+ props.stream.removeTrack(track)
+ } else {
+ props.stream.removeTrack(audioTrack)
+ }
}
const startVideo = () => {
@@ -85,7 +88,7 @@ const Presenter = (props: { stream: MediaStream; disconnect: () => void }) => {
{videoButton}
-
+
)
diff --git a/types/video.tsx b/types/video.tsx
index 120e03e..35ec677 100644
--- a/types/video.tsx
+++ b/types/video.tsx
@@ -1,7 +1,7 @@
import { useRef } from 'react'
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, prettier/prettier
-const Video = (props: { stream: MediaStream, muted: boolean }) => {
+const Video = (props: { stream: MediaStream | null, muted: boolean }) => {
const videoRef = useRef(null)
const handleCanPlay = () => {
diff --git a/useConnectionState.ts b/useConnectionState.ts
index 3a01773..7876adb 100644
--- a/useConnectionState.ts
+++ b/useConnectionState.ts
@@ -4,9 +4,9 @@ import { Socket } from 'socket.io-client'
import PeerCall from './types/peer-call'
const useConnectionState = (
- peer: Peer,
- socket: Socket,
- stream: MediaStream
+ peer: Peer | null,
+ socket: Socket | null,
+ stream: MediaStream | null
): [PeerCall[]] => {
const [calls, setCalls] = useState([])
@@ -33,7 +33,7 @@ const useConnectionState = (
socket.on('user-disconnected', (peerId: string) => {
removeCallFromPeersByUserId(peerId)
})
- }, [peer, stream])
+ }, [peer, socket, stream])
const addCallToPeers = (peerId: string, call: MediaConnection) => {
call.on('stream', (peerVideoStream: MediaStream) => {
diff --git a/usePeerState.ts b/usePeerState.ts
index ba9538b..73b1f0b 100644
--- a/usePeerState.ts
+++ b/usePeerState.ts
@@ -5,10 +5,10 @@ import PeerError from './types/peer-error'
// copied partially from https://github.com/madou/react-peer/blob/master/src/use-peer-state.tsx
const usePeerState = (
opts: { userId: string | undefined, stunUrl: string } = { userId: undefined, stunUrl: '' }
-): [string | undefined, Peer, PeerError | undefined] => {
- const [error, setError] = useState(undefined)
+): [Peer | null, string | undefined, PeerError | undefined] => {
const [peer, setPeer] = useState(null)
const [userId, setUserId] = useState(opts.userId)
+ const [error, setError] = useState(undefined)
useEffect(() => {
import('peerjs').then(({ default: Peer }) => {
@@ -38,27 +38,22 @@ const usePeerState = (
}
})
- localPeer?.on('open', () => {
- if (userId !== localPeer?.id) {
- setUserId(localPeer?.id)
- }
+ localPeer?.on('open', (id) => {
+ console.dir(id)
+ setUserId(id)
})
localPeer?.on('error', (err) => setError(err))
})
return function cleanup() {
- if (peer) {
- peer.destroy()
- }
+ peer?.destroy()
}
- }, [opts.userId])
+ }, [userId, error])
return [
- userId,
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
peer,
+ userId,
error
]
}
diff --git a/useUserMedia.ts b/useUserMedia.ts
index f1949c0..bd2c30b 100644
--- a/useUserMedia.ts
+++ b/useUserMedia.ts
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
-const useUserMedia = (): MediaStream => {
+const useUserMedia = (): MediaStream | null => {
const [stream, setStream] = useState(null)
useEffect(() => {
@@ -25,8 +25,6 @@ const useUserMedia = (): MediaStream => {
}
}
}, [stream])
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
return stream
}