forked from livekit/components-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcustomize.tsx
136 lines (127 loc) · 4.5 KB
/
customize.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import {
LiveKitRoom,
ParticipantName,
TrackMutedIndicator,
RoomAudioRenderer,
isTrackReference,
useConnectionQualityIndicator,
VideoTrack,
useToken,
ControlBar,
GridLayout,
useTracks,
TrackRefContext,
} from '@livekit/components-react';
import { ConnectionQuality, Room, Track } from 'livekit-client';
import styles from '../styles/Simple.module.css';
import myStyles from '../styles/Customize.module.css';
import type { NextPage } from 'next';
import { HTMLAttributes, useState } from 'react';
import { generateRandomUserId } from '../lib/helper';
const CustomizeExample: NextPage = () => {
const params = typeof window !== 'undefined' ? new URLSearchParams(location.search) : null;
const roomName = params?.get('room') ?? 'test-room';
const userIdentity = params?.get('user') ?? generateRandomUserId();
const token = useToken(process.env.NEXT_PUBLIC_LK_TOKEN_ENDPOINT, roomName, {
userInfo: {
identity: userIdentity,
name: userIdentity,
},
});
const [room] = useState(new Room());
const [connect, setConnect] = useState(false);
const [isConnected, setIsConnected] = useState(false);
const handleDisconnect = () => {
setConnect(false);
setIsConnected(false);
};
return (
<div className={styles.container} data-lk-theme="default">
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://livekit.io">LiveKit</a>
</h1>
{!isConnected && (
<button className="lk-button" onClick={() => setConnect(!connect)}>
{connect ? 'Disconnect' : 'Connect'}
</button>
)}
<LiveKitRoom
room={room}
token={token}
serverUrl={process.env.NEXT_PUBLIC_LK_SERVER_URL}
connect={connect}
onConnected={() => setIsConnected(true)}
onDisconnected={handleDisconnect}
audio={true}
video={true}
>
<RoomAudioRenderer />
{/* Render a custom Stage component once connected */}
{isConnected && <Stage />}
<ControlBar />
</LiveKitRoom>
</main>
</div>
);
};
export function Stage() {
const tracks = useTracks([
{ source: Track.Source.Camera, withPlaceholder: true },
{ source: Track.Source.ScreenShare, withPlaceholder: false },
]);
return (
<>
<div className={styles.participantGrid}>
<GridLayout tracks={tracks}>
<TrackRefContext.Consumer>
{(track) =>
track && (
<div className="my-tile">
{isTrackReference(track) ? <VideoTrack {...track} /> : <p>Camera placeholder</p>}
<div className={myStyles['participant-indicators']}>
<div style={{ display: 'flex' }}>
<TrackMutedIndicator source={Track.Source.Microphone} />
<TrackMutedIndicator source={track.source} />
</div>
{/* Overwrite styles: By passing class names, we can easily overwrite/extend the existing styles. */}
{/* In addition, we can still specify a style attribute and further customize the styles. */}
<ParticipantName
className={myStyles['my-participant-name']}
// style={{ color: 'blue' }}
/>
{/* Custom components: Here we replace the provided <ConnectionQualityIndicator /> with our own implementation. */}
<UserDefinedConnectionQualityIndicator />
</div>
</div>
)
}
</TrackRefContext.Consumer>
</GridLayout>
</div>
</>
);
}
export function UserDefinedConnectionQualityIndicator(props: HTMLAttributes<HTMLSpanElement>) {
/**
* We use the same React hook that is used internally to build our own component.
* By using this hook, we inherit all the state management and logic and can focus on our implementation.
*/
const { quality } = useConnectionQualityIndicator();
function qualityToText(quality: ConnectionQuality): string {
switch (quality) {
case ConnectionQuality.Poor:
return 'Poor';
case ConnectionQuality.Good:
return 'Good';
case ConnectionQuality.Excellent:
return 'Excellent';
case ConnectionQuality.Lost:
return 'Reconnecting';
default:
return 'No idea';
}
}
return <span {...props}> {qualityToText(quality)} </span>;
}
export default CustomizeExample;