@fraku/video 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/package.json +2 -3
  2. package/src/App.tsx +0 -7
  3. package/src/components/ZoomVideoPlugin/ZoomVideoPlugin.stories.tsx +0 -50
  4. package/src/components/ZoomVideoPlugin/ZoomVideoPlugin.tsx +0 -253
  5. package/src/components/ZoomVideoPlugin/components/ButtonsDock/ButtonsDock.tsx +0 -353
  6. package/src/components/ZoomVideoPlugin/components/ButtonsDock/DockButton.tsx +0 -90
  7. package/src/components/ZoomVideoPlugin/components/ButtonsDock/MenuItemTemplate.tsx +0 -35
  8. package/src/components/ZoomVideoPlugin/components/ButtonsDock/index.ts +0 -1
  9. package/src/components/ZoomVideoPlugin/components/MobileIconButton/MobileIconButton.tsx +0 -30
  10. package/src/components/ZoomVideoPlugin/components/MobileIconButton/index.ts +0 -1
  11. package/src/components/ZoomVideoPlugin/components/Overlay/Overlay.tsx +0 -74
  12. package/src/components/ZoomVideoPlugin/components/Overlay/index.ts +0 -1
  13. package/src/components/ZoomVideoPlugin/components/ParticipantsList.tsx +0 -52
  14. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/SettingsContent.tsx +0 -19
  15. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/SettingsMenu.tsx +0 -30
  16. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/SettingsOverlay.tsx +0 -52
  17. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/Tabs/AudioSettings.tsx +0 -191
  18. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/Tabs/BackgroundSettings.tsx +0 -47
  19. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/Tabs/DropdownItemTemplate.tsx +0 -20
  20. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/Tabs/DropdownValueTemplate.tsx +0 -12
  21. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/Tabs/VideoSettings.tsx +0 -30
  22. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/context.ts +0 -20
  23. package/src/components/ZoomVideoPlugin/components/SettingsOverlay/index.ts +0 -1
  24. package/src/components/ZoomVideoPlugin/components/Video.tsx +0 -35
  25. package/src/components/ZoomVideoPlugin/constants.ts +0 -4
  26. package/src/components/ZoomVideoPlugin/context.ts +0 -86
  27. package/src/components/ZoomVideoPlugin/hooks/useClientMessages.ts +0 -142
  28. package/src/components/ZoomVideoPlugin/hooks/useDeviceSize.ts +0 -24
  29. package/src/components/ZoomVideoPlugin/hooks/useStartVideoOptions.ts +0 -14
  30. package/src/components/ZoomVideoPlugin/hooks/useZoomVideoPlayer.tsx +0 -142
  31. package/src/components/ZoomVideoPlugin/index.ts +0 -2
  32. package/src/components/ZoomVideoPlugin/lib/platforms.ts +0 -17
  33. package/src/components/ZoomVideoPlugin/pages/AfterSession.tsx +0 -14
  34. package/src/components/ZoomVideoPlugin/pages/MainSession.tsx +0 -53
  35. package/src/components/ZoomVideoPlugin/pages/PanelistsSession.tsx +0 -97
  36. package/src/components/ZoomVideoPlugin/pages/PreSessionConfiguration.tsx +0 -154
  37. package/src/components/ZoomVideoPlugin/types.global.d.ts +0 -15
  38. package/src/components/ZoomVideoPlugin/types.ts +0 -23
  39. package/src/global.d.ts +0 -46
  40. package/src/index.css +0 -4
  41. package/src/index.ts +0 -4
  42. package/src/main.tsx +0 -10
  43. package/src/vite-env.d.ts +0 -12
@@ -1,30 +0,0 @@
1
- import { Dropdown } from 'primereact/dropdown'
2
- import { useZoomVideoContext } from '../../../context'
3
- import DropdownValueTemplate from './DropdownValueTemplate'
4
- import DropdownItemTemplate from './DropdownItemTemplate'
5
-
6
- const VideoSettings = () => {
7
- const { activeCamera, cameraList, setActiveCamera } = useZoomVideoContext()
8
-
9
- const cameraOptions = cameraList.map((camera) => ({
10
- label: camera.label || `Cámara ${camera.deviceId}`,
11
- value: camera.deviceId
12
- }))
13
-
14
- return (
15
- <div className="flex flex-col">
16
- <p className="text-s font-bold mb-8">Cámara</p>
17
- <Dropdown
18
- itemTemplate={(option) => <DropdownItemTemplate option={option} isActive={option.value === activeCamera} />}
19
- className="mb-16"
20
- onChange={(e) => setActiveCamera(e.value)}
21
- options={cameraOptions}
22
- placeholder="Selecciona una cámara"
23
- value={activeCamera ?? ''}
24
- valueTemplate={(option) => <DropdownValueTemplate option={option} icon="fa-regular fa-video" />}
25
- />
26
- </div>
27
- )
28
- }
29
-
30
- export default VideoSettings
@@ -1,20 +0,0 @@
1
- import { useContext, createContext } from 'react'
2
- import { ReactSetter } from '../../types'
3
-
4
- export enum SettingsTab {
5
- Audio = 'Audio',
6
- Video = 'Video',
7
- Background = 'Background'
8
- }
9
-
10
- export type SettingsOverlayContextProps = {
11
- selectedSettingsTab: SettingsTab
12
- setSelectedSettingsTab: ReactSetter<SettingsTab>
13
- }
14
-
15
- export const settingsOverlayContext = createContext<SettingsOverlayContextProps>({
16
- selectedSettingsTab: SettingsTab.Audio,
17
- setSelectedSettingsTab: () => {}
18
- })
19
-
20
- export const useSettingsOverlayContext = () => useContext(settingsOverlayContext)
@@ -1 +0,0 @@
1
- export { default } from './SettingsOverlay'
@@ -1,35 +0,0 @@
1
- import styled from 'styled-components'
2
-
3
- type VideoProps = {
4
- fullRef: React.RefObject<HTMLVideoElement> | null
5
- }
6
- const Video = ({ fullRef }: VideoProps) => {
7
- return (
8
- <StyledVideoContainer>
9
- <video-player-container className="video-player-container">
10
- <video-player ref={fullRef} className="video-player" />
11
- </video-player-container>
12
- </StyledVideoContainer>
13
- )
14
- }
15
-
16
- const StyledVideoContainer = styled.div`
17
- width: 100%;
18
- height: auto;
19
- aspect-ratio: 16/9;
20
-
21
- & video-player-container {
22
- margin-left: auto;
23
- margin-right: auto;
24
- width: 100%;
25
- height: auto;
26
-
27
- video-player {
28
- width: 100%;
29
- height: auto;
30
- aspect-ratio: 16/9;
31
- }
32
- }
33
- `
34
-
35
- export default Video
@@ -1,4 +0,0 @@
1
- export const VIDEO_PLACEHOLDER =
2
- '<div class="video-placeholder flex items-center justify-center bg-neutral-20 w-full h-full aspect-video text-white"><i class="fa-regular fa-video-slash fa-lg"/></div>'
3
-
4
- export const SETTINGS_OVERLAY_WIDTH = 680
@@ -1,86 +0,0 @@
1
- import { createContext, useContext } from 'react'
2
- import ZoomVideo, {
3
- ActiveSpeaker,
4
- ConnectionState,
5
- LocalAudioTrack,
6
- LocalVideoTrack,
7
- MediaDevice,
8
- Participant,
9
- Stream,
10
- VideoClient
11
- } from '@zoom/videosdk'
12
- import { Breakpoint } from './hooks/useDeviceSize'
13
-
14
- export const zmClient = ZoomVideo.createClient()
15
-
16
- export type ZoomVideoContextType = {
17
- activeAudioOutput: string | undefined
18
- activeCamera: string | undefined
19
- activeMicrophone: string | undefined
20
- activeSpeakers: ActiveSpeaker[]
21
- activeVideoId: number | null
22
- audioOutputList: MediaDevice[]
23
- breakpoint: Breakpoint
24
- cameraList: MediaDevice[]
25
- closeParentContainer: () => void
26
- connectionState: ConnectionState | null
27
- isBlurred: boolean
28
- isCamOn: boolean
29
- isMicOn: boolean
30
- localAudio: LocalAudioTrack | undefined
31
- localVideo: LocalVideoTrack | undefined
32
- mediaStream: typeof Stream | null
33
- micList: MediaDevice[]
34
- participants: Participant[]
35
- setActiveCamera: ReactSetter<string | undefined>
36
- setIsBlurred: ReactSetter<boolean>
37
- setIsCamOn: ReactSetter<boolean>
38
- setIsMicOn: ReactSetter<boolean>
39
- setLocalAudio: ReactSetter<LocalAudioTrack>
40
- setLocalVideo: ReactSetter<LocalVideoTrack>
41
- setMediaStream: ReactSetter<typeof Stream | null>
42
- setParticipants: ReactSetter<Participant[]>
43
- stopSession: () => Promise<void>
44
- switchActiveAudioOutput: (deviceId: string) => Promise<void>
45
- switchActiveMicrophone: (deviceId: string) => Promise<void>
46
- zmClient: typeof VideoClient
47
- }
48
-
49
- export const ZoomVideoContext = createContext<ZoomVideoContextType>({
50
- activeAudioOutput: undefined,
51
- activeCamera: undefined,
52
- activeMicrophone: undefined,
53
- activeSpeakers: [],
54
- activeVideoId: null,
55
- audioOutputList: [],
56
- breakpoint: Breakpoint.Mobile,
57
- cameraList: [],
58
- closeParentContainer: () => {},
59
- connectionState: null,
60
- isBlurred: false,
61
- isCamOn: false,
62
- isMicOn: false,
63
- localAudio: undefined,
64
- localVideo: undefined,
65
- mediaStream: null,
66
- micList: [],
67
- participants: [],
68
- setActiveCamera: () => {},
69
- setIsBlurred: () => {},
70
- setIsCamOn: () => {},
71
- setIsMicOn: () => {},
72
- setLocalAudio: () => {},
73
- setLocalVideo: () => {},
74
- setMediaStream: () => {},
75
- setParticipants: () => {},
76
- stopSession: async () => {},
77
- switchActiveAudioOutput: () => Promise.resolve(),
78
- switchActiveMicrophone: () => Promise.resolve(),
79
- zmClient
80
- })
81
-
82
- export const useZoomVideoContext = () => {
83
- const ctx = useContext(ZoomVideoContext)
84
- if (!ctx) throw new Error('useZoomVideo must be used within ZoomVideoProvider')
85
- return ctx
86
- }
@@ -1,142 +0,0 @@
1
- import { useEffect } from 'react'
2
- import {
3
- type ActiveSpeaker,
4
- CommandChannelMsg,
5
- ConnectionChangePayload,
6
- ConnectionState,
7
- MediaDevice,
8
- type Participant,
9
- type Stream,
10
- VideoActiveState,
11
- type VideoClient
12
- } from '@zoom/videosdk'
13
- import { isAndroidOrIOSBrowser } from '../lib/platforms'
14
-
15
- type Props = {
16
- zmClient: typeof VideoClient | null
17
- mediaStream: typeof Stream | null
18
- setActiveMicrophone: ReactSetter<string | undefined>
19
- setActiveAudioOutput: ReactSetter<string | undefined>
20
- setActiveCamera: ReactSetter<string | undefined>
21
- setMicList: ReactSetter<MediaDevice[]>
22
- setAudioOutputList: ReactSetter<MediaDevice[]>
23
- setCameraList: ReactSetter<MediaDevice[]>
24
- setConnectionState: ReactSetter<ConnectionState | null>
25
- setIsCamOn: ReactSetter<boolean>
26
- setIsMicOn: ReactSetter<boolean>
27
- setActiveSpeakers: ReactSetter<ActiveSpeaker[]>
28
- setParticipants: ReactSetter<Participant[]>
29
- setActiveVideoId: ReactSetter<number | null>
30
- setHandRaises: ReactSetter<Record<string, boolean>>
31
- }
32
-
33
- export const useClientMessages = ({
34
- zmClient,
35
- mediaStream,
36
- setActiveMicrophone,
37
- setActiveAudioOutput,
38
- setActiveCamera,
39
- setMicList,
40
- setAudioOutputList,
41
- setCameraList,
42
- setConnectionState,
43
- setIsCamOn,
44
- setIsMicOn,
45
- setActiveSpeakers,
46
- setActiveVideoId,
47
- setParticipants,
48
- setHandRaises
49
- }: Props) => {
50
- useEffect(() => {
51
- if (!mediaStream || !zmClient) return
52
-
53
- setActiveVideoId(mediaStream?.getActiveVideoId() ?? null)
54
-
55
- const onCommandChannelMessage = (payload: CommandChannelMsg) => {
56
- console.log('onCommandChannelMessage payload: ', payload)
57
- try {
58
- const data = JSON.parse(payload?.text)
59
- if (data.type === 'RAISE_HAND') {
60
- setHandRaises((prev) => ({ ...prev, [data.userId]: true }))
61
- } else if (data.type === 'LOWER_HAND') {
62
- setHandRaises((prev) => ({ ...prev, [data.userId]: false }))
63
- }
64
- } catch (e) {
65
- console.warn('Invalid command message', e)
66
- }
67
- }
68
-
69
- const onConnectionChange = (payload: ConnectionChangePayload) => {
70
- setConnectionState(payload.state)
71
- console.log(`Connection state changed to ${payload.state}, reason: ${payload.reason}`)
72
- }
73
-
74
- const onParticipantChange = () => {
75
- const allUsers = zmClient.getAllUser()
76
- setParticipants(allUsers)
77
- }
78
-
79
- const onActiveVideoChange = (payload: { state: VideoActiveState; userId: number }) => {
80
- const { state, userId } = payload
81
- if (state === 'Active') {
82
- setActiveVideoId(userId)
83
- console.log(`User ${userId} video is active`)
84
- }
85
- }
86
-
87
- const onActiveSpeakerChange = (payload: ActiveSpeaker[]) => {
88
- if (Array.isArray(payload)) {
89
- setActiveSpeakers(payload)
90
- }
91
- }
92
-
93
- const onDeviceChange = () => {
94
- if (mediaStream) {
95
- console.log('onDeviceChange: update device list')
96
- setMicList(mediaStream.getMicList())
97
- setAudioOutputList(mediaStream.getSpeakerList())
98
- if (!isAndroidOrIOSBrowser()) setCameraList(mediaStream.getCameraList())
99
- setActiveMicrophone(mediaStream.getActiveMicrophone())
100
- setActiveAudioOutput(mediaStream.getActiveSpeaker())
101
- setActiveCamera(mediaStream.getActiveCamera())
102
- }
103
- }
104
-
105
- /* https://marketplacefront.zoom.us/sdk/custom/web/modules/ZoomVideo.VideoClient.html#on */
106
- zmClient.on('active-speaker', onActiveSpeakerChange)
107
- zmClient.on('command-channel-message', onCommandChannelMessage)
108
- zmClient.on('connection-change', onConnectionChange)
109
- zmClient.on('device-change', onDeviceChange)
110
- zmClient.on('user-added', onParticipantChange)
111
- zmClient.on('user-removed', onParticipantChange)
112
- zmClient.on('user-updated', onParticipantChange)
113
- zmClient.on('video-active-change', onActiveVideoChange) // It fires when the active speaker is talking for more than one second, allowing for a smoother user experience than the Audio active-speaker event. Event fires for active speakers who have their video on or off
114
-
115
- return () => {
116
- zmClient.off('active-speaker', onActiveSpeakerChange)
117
- zmClient.off('command-channel-message', onCommandChannelMessage)
118
- zmClient.off('connection-change', onConnectionChange)
119
- zmClient.off('device-change', onDeviceChange)
120
- zmClient.off('user-added', onParticipantChange)
121
- zmClient.off('user-removed', onParticipantChange)
122
- zmClient.off('user-updated', onParticipantChange)
123
- zmClient.off('video-active-change', onActiveVideoChange)
124
- }
125
- }, [
126
- mediaStream,
127
- setActiveCamera,
128
- setActiveMicrophone,
129
- setActiveAudioOutput,
130
- setActiveSpeakers,
131
- setActiveVideoId,
132
- setCameraList,
133
- setConnectionState,
134
- setHandRaises,
135
- setIsCamOn,
136
- setIsMicOn,
137
- setMicList,
138
- setParticipants,
139
- zmClient,
140
- setAudioOutputList
141
- ])
142
- }
@@ -1,24 +0,0 @@
1
- import { useMemo } from 'react'
2
- import { useMeasure } from 'react-use'
3
-
4
- export enum Breakpoint {
5
- Mobile,
6
- Tablet,
7
- Desktop
8
- }
9
-
10
- // TODO: Use tailwind screens when created a new project with zoom video
11
- const MOBILE_MAX = 768
12
- const TABLET_MAX = 1024
13
-
14
- export const useContainerSize = () => {
15
- const [ref, { width }] = useMeasure<HTMLDivElement>()
16
-
17
- const breakpoint = useMemo(() => {
18
- if (width < MOBILE_MAX) return Breakpoint.Mobile
19
- if (width < TABLET_MAX) return Breakpoint.Tablet
20
- return Breakpoint.Desktop
21
- }, [width])
22
-
23
- return { ref, width, breakpoint }
24
- }
@@ -1,14 +0,0 @@
1
- import { Stream } from '@zoom/videosdk'
2
- import { useMemo } from 'react'
3
-
4
- export const useStartVideoOptions = ({ mediaStream }: { mediaStream: typeof Stream | null }) => {
5
- return useMemo(
6
- () => ({
7
- hd: true,
8
- fullHd: true,
9
- ptz: mediaStream?.isBrowserSupportPTZ(),
10
- originalRatio: true
11
- }),
12
- [mediaStream]
13
- )
14
- }
@@ -1,142 +0,0 @@
1
- import { useEffect, type RefObject } from 'react'
2
- import { useEffectOnce } from 'react-use'
3
- import { type VideoClient, type Participant, VideoQuality, VideoPlayer, ConnectionState } from '@zoom/videosdk'
4
- import { VIDEO_PLACEHOLDER } from './../constants'
5
- import { useZoomVideoContext } from '../context'
6
- import { useStartVideoOptions } from './useStartVideoOptions'
7
-
8
- type UseZoomVideoPlayerProps = {
9
- fullRef: RefObject<HTMLVideoElement | null>
10
- }
11
-
12
- /* Create a name tag for the video */
13
- const createNameTag = ({ name, isMicOff }: { name: string; isMicOff: boolean }): HTMLDivElement => {
14
- const container = document.createElement('div')
15
- container.className = 'absolute top-[2px] px-4 py-4 opacity-[0.6] w-full h-fit flex items-center justify-between'
16
- const nameTag = document.createElement('div')
17
- container.appendChild(nameTag)
18
- nameTag.textContent = name
19
- nameTag.className = 'bg-neutral-40 text-s font-bold text-white px-4 py-4 rounded-m max-w-[60%] truncate'
20
-
21
- const micOffSpan = document.createElement('i')
22
- micOffSpan.className = 'fa-regular fa-microphone-slash w-24 h-24 !text-white'
23
- isMicOff ? micOffSpan.classList.remove('hidden') : micOffSpan.classList.add('hidden')
24
- container.appendChild(micOffSpan)
25
-
26
- return container
27
- }
28
-
29
- /* Determine which user video to show */
30
- const getRenderTargetUserId = (
31
- zmClient: typeof VideoClient,
32
- participants: Participant[],
33
- activeVideoId: number | null
34
- ): number | null => {
35
- if (!participants?.length) return null
36
- const selfId = zmClient?.getCurrentUserInfo()?.userId ?? null
37
- if (participants.length === 1) return selfId
38
- if (participants.length === 2) {
39
- return participants.find((p) => p.userId !== selfId)?.userId ?? selfId
40
- }
41
- return activeVideoId ?? selfId
42
- }
43
-
44
- export const useZoomVideoPlayer = ({ fullRef }: UseZoomVideoPlayerProps) => {
45
- const {
46
- activeAudioOutput,
47
- activeMicrophone,
48
- activeVideoId,
49
- connectionState,
50
- isCamOn,
51
- isMicOn,
52
- mediaStream,
53
- participants,
54
- zmClient
55
- } = useZoomVideoContext()
56
-
57
- useEffect(() => {
58
- const containerEl = fullRef.current
59
- if (!mediaStream || !containerEl || !zmClient || connectionState === ConnectionState.Closed) return
60
-
61
- const userId = getRenderTargetUserId(zmClient, participants, activeVideoId)
62
- if (!userId) return
63
-
64
- let videoElement: VideoPlayer | null = null
65
- let wrapperEl: HTMLDivElement | null = null
66
-
67
- const attach = async () => {
68
- const participant = participants.find((p) => p.userId === userId)
69
- const displayName = participant?.displayName ?? ''
70
- const nameTag = createNameTag({ name: displayName, isMicOff: participant?.muted || !participant?.audio })
71
-
72
- // Clear previous content
73
- containerEl.innerHTML = ''
74
-
75
- // Create wrapper for video and name tag
76
- wrapperEl = document.createElement('div')
77
- wrapperEl.className = 'relative w-full h-full'
78
-
79
- try {
80
- // Create or reuse the video-player element
81
- const element = await mediaStream.attachVideo(userId, VideoQuality.Video_720P)
82
- videoElement = element as VideoPlayer
83
- if (!videoElement) throw new Error('No video element')
84
-
85
- // Add video
86
- wrapperEl.appendChild(videoElement)
87
- // Add name tag
88
- wrapperEl.appendChild(nameTag)
89
- // Append to container
90
- containerEl.appendChild(wrapperEl)
91
- } catch (err) {
92
- console.warn('Failed to attach video, using placeholder:', err)
93
- containerEl.innerHTML = VIDEO_PLACEHOLDER
94
- containerEl.appendChild(nameTag)
95
- }
96
- }
97
-
98
- attach()
99
-
100
- return () => {
101
- if (videoElement && userId) {
102
- try {
103
- mediaStream.detachVideo(userId)
104
- videoElement.remove()
105
- } catch (err) {
106
- console.warn('Failed to detach video:', err)
107
- }
108
- }
109
- if (wrapperEl) wrapperEl.remove()
110
- }
111
- }, [activeVideoId, connectionState, fullRef, mediaStream, participants, zmClient])
112
-
113
- // Manage local camera
114
- const startVideoOptions = useStartVideoOptions({ mediaStream })
115
- useEffect(() => {
116
- if (!mediaStream || connectionState === ConnectionState.Closed) return
117
-
118
- const toggleCam = async () => {
119
- try {
120
- const isCapturing = mediaStream.isCapturingVideo()
121
-
122
- if (isCamOn && !isCapturing) {
123
- await mediaStream.startVideo(startVideoOptions)
124
- } else if (!isCamOn && isCapturing) {
125
- await mediaStream.stopVideo()
126
- }
127
- } catch (err: any) {
128
- console.warn('Video toggle failed:', err)
129
- }
130
- }
131
-
132
- toggleCam()
133
- }, [mediaStream, isCamOn, startVideoOptions, connectionState])
134
-
135
- // Initialize microphone on join if mic is on
136
- useEffectOnce(() => {
137
- if (!mediaStream || !isMicOn) {
138
- return
139
- }
140
- mediaStream.startAudio({ microphoneId: activeMicrophone, speakerId: activeAudioOutput }).catch(console.warn)
141
- })
142
- }
@@ -1,2 +0,0 @@
1
- export { default } from './ZoomVideoPlugin'
2
- export type { ZoomVideoPluginProps } from './types'
@@ -1,17 +0,0 @@
1
- export const isIPad = (): boolean => {
2
- const { userAgent, maxTouchPoints } = navigator
3
- const isiPadClassic = /iPad/i.test(userAgent)
4
- const isiPadOS = /Macintosh/i.test(userAgent) && maxTouchPoints > 1
5
- return isiPadClassic || isiPadOS
6
- }
7
-
8
- export const isIOSMobile = (): boolean => {
9
- const { userAgent } = navigator
10
- return /iPhone|iPad|iPod/i.test(userAgent) || isIPad()
11
- }
12
-
13
- export const isAndroidBrowser = (): boolean => /Android/i.test(navigator.userAgent)
14
-
15
- export const isAndroidOrIOSBrowser = (): boolean => {
16
- return isAndroidBrowser() || isIOSMobile()
17
- }
@@ -1,14 +0,0 @@
1
- import { Button } from 'primereact/button'
2
-
3
- const AfterSession = ({ restartSession }: { restartSession: () => void }) => {
4
- return (
5
- <div className="flex flex-col gap-24 py-16 justify-center items-center w-full">
6
- <h2>After Session</h2>
7
- <Button className="w-fit" onClick={restartSession}>
8
- Restart Session
9
- </Button>
10
- </div>
11
- )
12
- }
13
-
14
- export default AfterSession
@@ -1,53 +0,0 @@
1
- import { useRef } from 'react'
2
- import { useUnmount } from 'react-use'
3
- import Video from '../components/Video'
4
- import { Button } from 'primereact/button'
5
- import { useZoomVideoContext } from '../context'
6
- import { useZoomVideoPlayer } from '../hooks/useZoomVideoPlayer'
7
- import ParticipantsList from '../components/ParticipantsList'
8
-
9
- const MainSession = () => {
10
- const { activeVideoId, zmClient, mediaStream, stopSession, setIsCamOn, setIsMicOn, participants } =
11
- useZoomVideoContext()
12
-
13
- const fullRef = useRef<HTMLVideoElement>(null)
14
-
15
- useZoomVideoPlayer({ fullRef })
16
-
17
- useUnmount(() => {
18
- if (zmClient?.getSessionInfo().isInMeeting) {
19
- if (zmClient?.getCurrentUserInfo().audio) {
20
- mediaStream?.stopAudio().catch(console.warn)
21
- }
22
- if (zmClient?.getCurrentUserInfo()?.bVideoOn) {
23
- mediaStream?.stopVideo().catch(console.warn)
24
- }
25
-
26
- mediaStream?.stopShareScreen().catch(console.warn)
27
- }
28
- })
29
-
30
- return (
31
- <div className="flex flex-col gap-24 py-16 justify-start w-full">
32
- <div className="flex flex-col gap-16 items-center justify-center w-full">
33
- <div className="flex flex-col gap-16 items-center justify-center w-full @sm:w-[640px] @md:w-[680px] mx-auto">
34
- <Video fullRef={fullRef} />
35
-
36
- <p>Active video id: {activeVideoId}</p>
37
- <ParticipantsList
38
- zmClient={zmClient}
39
- setIsCamOn={setIsCamOn}
40
- setIsMicOn={setIsMicOn}
41
- participants={participants}
42
- />
43
-
44
- <Button className="w-fit" onClick={stopSession}>
45
- Stop Session
46
- </Button>
47
- </div>
48
- </div>
49
- </div>
50
- )
51
- }
52
-
53
- export default MainSession