@naviedu/room-platform-react 0.0.1 → 0.0.4
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.
- package/README.md +258 -0
- package/index.d.ts +1042 -32
- package/index.esm.js +11479 -1235
- package/package.json +4 -7
- package/styles.css +584 -0
- package/extensions/room-platform-extensions.d.ts +0 -8
- package/room-action-button.d.ts +0 -11
- package/room-participant-actions.d.ts +0 -9
- package/room-participant-list.d.ts +0 -7
- package/room-participant-tab.d.ts +0 -6
- package/room-platform-active-speaker.d.ts +0 -4
- package/room-platform-background-settings.d.ts +0 -15
- package/room-platform-camera-background-presets.d.ts +0 -8
- package/room-platform-camera-background-storage.d.ts +0 -38
- package/room-platform-control-anchor.d.ts +0 -10
- package/room-platform-control-bar.d.ts +0 -11
- package/room-platform-control-state.d.ts +0 -12
- package/room-platform-current-operation-strip.d.ts +0 -13
- package/room-platform-device-selection.d.ts +0 -7
- package/room-platform-device-settings.d.ts +0 -8
- package/room-platform-local-preview.d.ts +0 -6
- package/room-platform-media-controls.d.ts +0 -1
- package/room-platform-media-runtime.d.ts +0 -2
- package/room-platform-monitor-stage.d.ts +0 -7
- package/room-platform-monitor-video-tile.d.ts +0 -20
- package/room-platform-monitor-viewer.d.ts +0 -8
- package/room-platform-private-room-connection.d.ts +0 -11
- package/room-platform-private-room-context.d.ts +0 -8
- package/room-platform-private-room-control-bar.d.ts +0 -12
- package/room-platform-private-room-experience.d.ts +0 -14
- package/room-platform-private-room-overlay.d.ts +0 -7
- package/room-platform-private-room-stage.d.ts +0 -9
- package/room-platform-private-room-status-banner.d.ts +0 -8
- package/room-platform-provider.d.ts +0 -35
- package/room-platform-room.d.ts +0 -2
- package/room-platform-screen-share-whiteboard-frame.d.ts +0 -11
- package/room-platform-shell.d.ts +0 -17
- package/room-platform-speak-queue.d.ts +0 -16
- package/room-platform-stage-selection.d.ts +0 -14
- package/room-platform-stage.d.ts +0 -13
- package/room-platform-surface-boundary.d.ts +0 -13
- package/room-platform-top-bar.d.ts +0 -7
- package/room-platform-types.d.ts +0 -154
- package/room-platform-ui-primitives.d.ts +0 -60
- package/room-platform-video-tile.d.ts +0 -13
- package/room-platform-video-tracks.d.ts +0 -6
- package/use-room-platform-camera-background.d.ts +0 -34
- package/use-room-platform-private-room-control-actions.d.ts +0 -21
- package/use-room-platform-private-room.d.ts +0 -43
- package/use-room-platform-stage.d.ts +0 -2
- package/use-room-presence.d.ts +0 -2
package/README.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# @naviedu/room-platform-react
|
|
2
|
+
|
|
3
|
+
Embeddable React UI and runtime for NaviEdu Room Platform rooms. The package
|
|
4
|
+
owns the default room experience, LiveKit connection, media controls, speaker
|
|
5
|
+
requests, private rooms, responsive layout, and optional chat and whiteboard
|
|
6
|
+
surfaces.
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- React 18 or 19
|
|
11
|
+
- A Room Platform launch ticket issued by the host backend
|
|
12
|
+
- A public Room Platform API base URL
|
|
13
|
+
- A browser running in a secure context when camera, microphone, or screen
|
|
14
|
+
sharing is required
|
|
15
|
+
|
|
16
|
+
The launch ticket is short-lived and must be obtained server-side. Do not put
|
|
17
|
+
backend credentials or long-lived signing secrets in the browser bundle.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @naviedu/room-platform-react
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`react` and `react-dom` are peer dependencies. Room Platform's published
|
|
26
|
+
runtime dependencies are installed automatically with the package.
|
|
27
|
+
|
|
28
|
+
## Basic usage
|
|
29
|
+
|
|
30
|
+
Import the package stylesheet once, then render `RoomPlatformRoom` with the
|
|
31
|
+
launch ticket returned by your backend:
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
'use client'
|
|
35
|
+
|
|
36
|
+
import { type RoomLaunchTicketRenewalReason, RoomPlatformRoom } from '@naviedu/room-platform-react'
|
|
37
|
+
import '@naviedu/room-platform-react/styles.css'
|
|
38
|
+
|
|
39
|
+
type RoomTicketResponse = { launchToken: string }
|
|
40
|
+
|
|
41
|
+
export function Room({ launchToken }: { launchToken: string }) {
|
|
42
|
+
async function renewLaunchTicket(_reason: RoomLaunchTicketRenewalReason): Promise<RoomTicketResponse> {
|
|
43
|
+
const response = await fetch('/api/room-platform/launch-ticket', {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
credentials: 'include',
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
if (!response.ok) throw new Error('Unable to renew the Room Platform launch ticket')
|
|
49
|
+
|
|
50
|
+
return (await response.json()) as RoomTicketResponse
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<RoomPlatformRoom
|
|
55
|
+
apiBaseUrl="https://api.example.com/room-platform"
|
|
56
|
+
launchToken={launchToken}
|
|
57
|
+
onLaunchTicketRequired={renewLaunchTicket}
|
|
58
|
+
onExit={() => window.history.back()}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`apiBaseUrl` is the URL prefix before `/rooms`. The package calls these routes
|
|
65
|
+
relative to it:
|
|
66
|
+
|
|
67
|
+
- `POST /rooms/exchange`
|
|
68
|
+
- `GET /rooms/:roomId/control-state`
|
|
69
|
+
- `POST /rooms/:roomId/actions`
|
|
70
|
+
|
|
71
|
+
For example, with `apiBaseUrl="https://api.example.com/room-platform"`, the
|
|
72
|
+
exchange request is sent to
|
|
73
|
+
`https://api.example.com/room-platform/rooms/exchange`.
|
|
74
|
+
|
|
75
|
+
The package renders a full viewport room (`100dvh`). Mount it in a page or
|
|
76
|
+
layout that allows the room to occupy the viewport.
|
|
77
|
+
|
|
78
|
+
## `RoomPlatformRoom` props
|
|
79
|
+
|
|
80
|
+
| Prop | Required | Description |
|
|
81
|
+
| ------------------------ | -------- | ------------------------------------------------------------------------------------ |
|
|
82
|
+
| `apiBaseUrl` | Yes | Room Platform API prefix. Do not append `/rooms`. |
|
|
83
|
+
| `launchToken` | Yes | Initial server-issued launch ticket. |
|
|
84
|
+
| `onLaunchTicketRequired` | Yes | Returns `{ launchToken }` when the current ticket or access session must be renewed. |
|
|
85
|
+
| `extensions` | No | Host-provided top-bar, workspace, sidebar, monitor, and participant extensions. |
|
|
86
|
+
| `integrations` | No | Chat and whiteboard configuration. |
|
|
87
|
+
| `isPracticeMode` | No | Enables practice-room presentation behavior. |
|
|
88
|
+
| `showLocalPreview` | No | Shows the local preview in the sidebar. Defaults to `true`. |
|
|
89
|
+
| `primaryCameraSelector` | No | Selects the primary camera track when the default selection is not suitable. |
|
|
90
|
+
| `onError` | No | Receives connection, media, and action errors. |
|
|
91
|
+
| `onLifecycleEvent` | No | Receives exchange, renewal, and reconnect lifecycle events. |
|
|
92
|
+
| `onExit` | No | Called when the user chooses to leave the room. |
|
|
93
|
+
| `children` | No | Replaces the default workspace while keeping the provider and room runtime. |
|
|
94
|
+
|
|
95
|
+
### Error and lifecycle callbacks
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<RoomPlatformRoom
|
|
99
|
+
// ...required props
|
|
100
|
+
onError={({ error, recoverable, scope }) => {
|
|
101
|
+
console.error(`[room-platform:${scope}]`, error)
|
|
102
|
+
if (!recoverable) {
|
|
103
|
+
// Show the host application's unavailable-room state.
|
|
104
|
+
}
|
|
105
|
+
}}
|
|
106
|
+
onLifecycleEvent={(event) => {
|
|
107
|
+
// Send telemetry to the host backend if needed.
|
|
108
|
+
console.info('Room Platform lifecycle:', event)
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Lifecycle events are `exchange.succeeded`, `exchange.failed`,
|
|
114
|
+
`renewal.succeeded`, `renewal.failed`, `reconnect.succeeded`, and
|
|
115
|
+
`reconnect.failed`.
|
|
116
|
+
|
|
117
|
+
## Chat and whiteboard integrations
|
|
118
|
+
|
|
119
|
+
Integrations are optional. The host supplies already-authorized configuration;
|
|
120
|
+
the room package does not issue chat or whiteboard credentials.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
<RoomPlatformRoom
|
|
124
|
+
// ...required props
|
|
125
|
+
integrations={{
|
|
126
|
+
chat: {
|
|
127
|
+
endpoint: 'https://api.example.com/chat',
|
|
128
|
+
realtimeEndpoint: 'wss://realtime.example.com/chat',
|
|
129
|
+
token: chatToken,
|
|
130
|
+
tokenExpiresAt: chatTokenExpiresAt,
|
|
131
|
+
refreshToken: refreshChatToken,
|
|
132
|
+
refreshTokenExpiresAt: refreshChatTokenExpiresAt,
|
|
133
|
+
rooms: chatRooms,
|
|
134
|
+
currentRoomId: roomId,
|
|
135
|
+
},
|
|
136
|
+
whiteboard: {
|
|
137
|
+
joinState: whiteboardJoinState,
|
|
138
|
+
runtime: {
|
|
139
|
+
realtimeEndpoint: whiteboardRealtimeEndpoint,
|
|
140
|
+
recoveryPort: whiteboardRecoveryPort,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
}}
|
|
144
|
+
/>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
When chat is configured, the default sidebar includes the chat tab and unread
|
|
148
|
+
badge. When whiteboard access is available, a shared screen can display the
|
|
149
|
+
whiteboard surface. Omit either integration when the host does not use it.
|
|
150
|
+
|
|
151
|
+
## Extensions
|
|
152
|
+
|
|
153
|
+
Extensions keep host-specific UI outside the shared room implementation. Every
|
|
154
|
+
extension receives `RoomPlatformExtensionProps`:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import type { RoomPlatformExtensionProps } from '@naviedu/room-platform-react'
|
|
158
|
+
|
|
159
|
+
function HostToolbar({ actions, capabilities, connectionStatus, roomId }: RoomPlatformExtensionProps) {
|
|
160
|
+
const canModerate = capabilities.includes('room:moderate')
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<div>
|
|
164
|
+
<span>{connectionStatus}</span>
|
|
165
|
+
<span>{roomId}</span>
|
|
166
|
+
{canModerate ? (
|
|
167
|
+
<button type="button" onClick={() => void actions.perform('speak.request')}>
|
|
168
|
+
Request to speak
|
|
169
|
+
</button>
|
|
170
|
+
) : null}
|
|
171
|
+
</div>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
;<RoomPlatformRoom
|
|
176
|
+
// ...required props
|
|
177
|
+
extensions={{
|
|
178
|
+
topBarTrailing: HostToolbar,
|
|
179
|
+
sidebarTabs: [{ id: 'materials', title: 'Materials', component: HostMaterialsTab }],
|
|
180
|
+
mainWorkspace: {
|
|
181
|
+
placement: 'alongside-stage',
|
|
182
|
+
component: HostWorkspace,
|
|
183
|
+
},
|
|
184
|
+
}}
|
|
185
|
+
/>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Available extension slots are:
|
|
189
|
+
|
|
190
|
+
- `topBarLeading` and `topBarTrailing`
|
|
191
|
+
- `mainWorkspace` with `overlay` or `alongside-stage` placement
|
|
192
|
+
- `sidebarTabs`
|
|
193
|
+
- `participantTab` in `default` or `replace` mode
|
|
194
|
+
- `monitor` with a host-provided participant roster and eligibility flag
|
|
195
|
+
|
|
196
|
+
`actions.perform` sends a Room Platform action and accepts an optional string
|
|
197
|
+
payload. Check `actions.hasCapability(...)` before rendering privileged
|
|
198
|
+
controls, and use `actions.isPending(...)` to disable controls during an
|
|
199
|
+
in-flight action.
|
|
200
|
+
|
|
201
|
+
## Advanced composition
|
|
202
|
+
|
|
203
|
+
Use `RoomPlatformProvider` and `useRoomPlatform` when the host needs to render
|
|
204
|
+
a custom room surface instead of `RoomPlatformRoom`'s default workspace:
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
import { RoomPlatformProvider, type RoomPlatformProviderProps, useRoomPlatform } from '@naviedu/room-platform-react'
|
|
208
|
+
|
|
209
|
+
function CustomRoomSurface() {
|
|
210
|
+
const { localMedia, setLocalMediaEnabled, status } = useRoomPlatform()
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<button
|
|
214
|
+
type="button"
|
|
215
|
+
disabled={status !== 'connected'}
|
|
216
|
+
onClick={() => void setLocalMediaEnabled('camera', !localMedia.camera)}
|
|
217
|
+
>
|
|
218
|
+
{localMedia.camera ? 'Turn camera off' : 'Turn camera on'}
|
|
219
|
+
</button>
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function CustomRoom(props: {
|
|
224
|
+
apiBaseUrl: string
|
|
225
|
+
launchToken: string
|
|
226
|
+
onLaunchTicketRequired: RoomPlatformProviderProps['onLaunchTicketRequired']
|
|
227
|
+
}) {
|
|
228
|
+
return (
|
|
229
|
+
<RoomPlatformProvider {...props}>
|
|
230
|
+
<CustomRoomSurface />
|
|
231
|
+
</RoomPlatformProvider>
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Use `RoomPlatformRoom` unless a custom surface is required. It composes the
|
|
237
|
+
provider, LiveKit media runtime, private-room runtime, default stage, controls,
|
|
238
|
+
and sidebar for you.
|
|
239
|
+
|
|
240
|
+
## Publishing and local verification
|
|
241
|
+
|
|
242
|
+
From the repository root:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
yarn nx run @naviedu/room-platform-react:build
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The publishable package is written to
|
|
249
|
+
`dist/libs/features/room-platform-react`. Inspect it before publishing:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
cd dist/libs/features/room-platform-react
|
|
253
|
+
npm pack --dry-run
|
|
254
|
+
npm publish --access public
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The package embeds the required shared UI source during bundling, so consumers
|
|
258
|
+
do not need private workspace aliases such as `@navi/ui` or `@navi/utils`.
|