streemo-video-call-sdk 0.2.11 → 0.2.12
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/dist/index.d.ts +4 -2
- package/dist/index.js +58 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -216,8 +216,9 @@ type ParticipantTileProps = {
|
|
|
216
216
|
userId: string;
|
|
217
217
|
stream?: MediaStream;
|
|
218
218
|
subtitle?: string;
|
|
219
|
+
videoActive?: boolean;
|
|
219
220
|
};
|
|
220
|
-
declare function ParticipantTile({ userId, stream, subtitle }: ParticipantTileProps): react_jsx_runtime.JSX.Element;
|
|
221
|
+
declare function ParticipantTile({ userId, stream, subtitle, videoActive }: ParticipantTileProps): react_jsx_runtime.JSX.Element;
|
|
221
222
|
|
|
222
223
|
declare function CallControls(): react_jsx_runtime.JSX.Element;
|
|
223
224
|
|
|
@@ -334,13 +335,14 @@ type Props = {
|
|
|
334
335
|
mirrored?: boolean;
|
|
335
336
|
label: string;
|
|
336
337
|
subtitle?: string;
|
|
338
|
+
videoActive?: boolean;
|
|
337
339
|
i18n?: {
|
|
338
340
|
resumePlayback?: string;
|
|
339
341
|
audioOnlyMuted?: string;
|
|
340
342
|
audioOnlyConnected?: string;
|
|
341
343
|
};
|
|
342
344
|
};
|
|
343
|
-
declare function VideoTile({ stream, muted, mirrored, label, subtitle, i18n }: Props): react_jsx_runtime.JSX.Element;
|
|
345
|
+
declare function VideoTile({ stream, muted, mirrored, label, subtitle, videoActive, i18n }: Props): react_jsx_runtime.JSX.Element;
|
|
344
346
|
|
|
345
347
|
type ChatPanelProps = {
|
|
346
348
|
messages: ChatMessage[];
|
package/dist/index.js
CHANGED
|
@@ -995,6 +995,29 @@ function useWebRTCCall(params) {
|
|
|
995
995
|
})
|
|
996
996
|
);
|
|
997
997
|
}, [roomId, userId]);
|
|
998
|
+
const getLocalMediaState = useCallback2(() => {
|
|
999
|
+
const stream = localStreamRef.current;
|
|
1000
|
+
if (!stream) {
|
|
1001
|
+
return {
|
|
1002
|
+
audioEnabled: false,
|
|
1003
|
+
videoEnabled: false,
|
|
1004
|
+
screenSharing: false
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
const audioEnabled = stream.getAudioTracks().some((track) => track.readyState === "live" && track.enabled && !track.muted);
|
|
1008
|
+
const videoEnabled = stream.getVideoTracks().some((track) => track.readyState === "live" && track.enabled && !track.muted);
|
|
1009
|
+
return {
|
|
1010
|
+
audioEnabled,
|
|
1011
|
+
videoEnabled,
|
|
1012
|
+
screenSharing: Boolean(screenTrackRef.current)
|
|
1013
|
+
};
|
|
1014
|
+
}, []);
|
|
1015
|
+
const broadcastLocalMediaState = useCallback2(() => {
|
|
1016
|
+
send({
|
|
1017
|
+
type: "media_state",
|
|
1018
|
+
payload: getLocalMediaState()
|
|
1019
|
+
});
|
|
1020
|
+
}, [getLocalMediaState, send]);
|
|
998
1021
|
const gracefulLeave = useCallback2(() => {
|
|
999
1022
|
const ws = wsRef.current;
|
|
1000
1023
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
@@ -1345,7 +1368,22 @@ function useWebRTCCall(params) {
|
|
|
1345
1368
|
setParticipants((prev) => Array.from(/* @__PURE__ */ new Set([...prev, message.userId])));
|
|
1346
1369
|
await createOffer(message.userId);
|
|
1347
1370
|
scheduleRenegotiationRetry(message.userId);
|
|
1371
|
+
broadcastLocalMediaState();
|
|
1348
1372
|
break;
|
|
1373
|
+
case "media_state": {
|
|
1374
|
+
const payload = message.payload ?? {};
|
|
1375
|
+
const peer = peersRef.current.get(message.userId);
|
|
1376
|
+
setParticipants((prev) => Array.from(/* @__PURE__ */ new Set([...prev, message.userId])));
|
|
1377
|
+
setRemoteTrackStates((prev) => ({
|
|
1378
|
+
...prev,
|
|
1379
|
+
[message.userId]: {
|
|
1380
|
+
audio: Boolean(payload.audioEnabled),
|
|
1381
|
+
video: Boolean(payload.videoEnabled),
|
|
1382
|
+
connectionState: prev[message.userId]?.connectionState ?? peer?.connectionState ?? "connected"
|
|
1383
|
+
}
|
|
1384
|
+
}));
|
|
1385
|
+
break;
|
|
1386
|
+
}
|
|
1349
1387
|
case "participant_left":
|
|
1350
1388
|
removePeer(message.userId, true);
|
|
1351
1389
|
break;
|
|
@@ -1416,6 +1454,7 @@ function useWebRTCCall(params) {
|
|
|
1416
1454
|
pushChatMessage,
|
|
1417
1455
|
removePeer,
|
|
1418
1456
|
scheduleRenegotiationRetry,
|
|
1457
|
+
broadcastLocalMediaState,
|
|
1419
1458
|
send,
|
|
1420
1459
|
setTypingState,
|
|
1421
1460
|
userId
|
|
@@ -1485,6 +1524,7 @@ function useWebRTCCall(params) {
|
|
|
1485
1524
|
setConnected(true);
|
|
1486
1525
|
send({ type: "join", payload: { joinedAt: (/* @__PURE__ */ new Date()).toISOString() } });
|
|
1487
1526
|
send({ type: "chat_history_request", payload: { limit: 30 } });
|
|
1527
|
+
broadcastLocalMediaState();
|
|
1488
1528
|
};
|
|
1489
1529
|
ws.onclose = () => {
|
|
1490
1530
|
setConnected(false);
|
|
@@ -1550,6 +1590,7 @@ function useWebRTCCall(params) {
|
|
|
1550
1590
|
}, [
|
|
1551
1591
|
apiBaseUrl,
|
|
1552
1592
|
auth,
|
|
1593
|
+
broadcastLocalMediaState,
|
|
1553
1594
|
enabled,
|
|
1554
1595
|
removePeer,
|
|
1555
1596
|
resolvedTokenProvider,
|
|
@@ -1585,7 +1626,8 @@ function useWebRTCCall(params) {
|
|
|
1585
1626
|
track.enabled = nextEnabled;
|
|
1586
1627
|
});
|
|
1587
1628
|
setMicEnabled(nextEnabled);
|
|
1588
|
-
|
|
1629
|
+
broadcastLocalMediaState();
|
|
1630
|
+
}, [broadcastLocalMediaState, micEnabled]);
|
|
1589
1631
|
const toggleCamera = useCallback2(() => {
|
|
1590
1632
|
const stream = localStreamRef.current;
|
|
1591
1633
|
if (!stream) return;
|
|
@@ -1596,7 +1638,8 @@ function useWebRTCCall(params) {
|
|
|
1596
1638
|
track.enabled = nextEnabled;
|
|
1597
1639
|
});
|
|
1598
1640
|
setCameraEnabled(nextEnabled);
|
|
1599
|
-
|
|
1641
|
+
broadcastLocalMediaState();
|
|
1642
|
+
}, [broadcastLocalMediaState, cameraEnabled]);
|
|
1600
1643
|
const syncVideoTrackToPeers = useCallback2(
|
|
1601
1644
|
async (nextVideoTrack, options) => {
|
|
1602
1645
|
const renegotiationTargets = /* @__PURE__ */ new Set();
|
|
@@ -1691,7 +1734,8 @@ function useWebRTCCall(params) {
|
|
|
1691
1734
|
setScreenSharing(false);
|
|
1692
1735
|
setLocalStream(new MediaStream(stream.getTracks()));
|
|
1693
1736
|
syncLocalTrackFlags();
|
|
1694
|
-
|
|
1737
|
+
broadcastLocalMediaState();
|
|
1738
|
+
}, [broadcastLocalMediaState, syncLocalTrackFlags, syncVideoTrackToPeers]);
|
|
1695
1739
|
const toggleScreenShare = useCallback2(async () => {
|
|
1696
1740
|
const stream = localStreamRef.current;
|
|
1697
1741
|
if (!stream) return;
|
|
@@ -1720,12 +1764,14 @@ function useWebRTCCall(params) {
|
|
|
1720
1764
|
setLocalStream(new MediaStream(stream.getTracks()));
|
|
1721
1765
|
syncLocalTrackFlags();
|
|
1722
1766
|
await syncVideoTrackToPeers(screenTrack, { forceRenegotiation: true });
|
|
1767
|
+
broadcastLocalMediaState();
|
|
1723
1768
|
screenStream.getTracks().filter((t) => t !== screenTrack).forEach((t) => t.stop());
|
|
1724
1769
|
} catch {
|
|
1725
1770
|
setScreenSharing(false);
|
|
1726
1771
|
screenTrackRef.current = null;
|
|
1772
|
+
broadcastLocalMediaState();
|
|
1727
1773
|
}
|
|
1728
|
-
}, [screenSharing, stopScreenShare, syncLocalTrackFlags, syncVideoTrackToPeers]);
|
|
1774
|
+
}, [broadcastLocalMediaState, screenSharing, stopScreenShare, syncLocalTrackFlags, syncVideoTrackToPeers]);
|
|
1729
1775
|
const sendChatMessage = useCallback2(
|
|
1730
1776
|
(text, senderName = "\u0413\u043E\u0441\u0442\u044C") => {
|
|
1731
1777
|
const normalizedText = text.trim();
|
|
@@ -2124,7 +2170,7 @@ function useCallRoomContext() {
|
|
|
2124
2170
|
// src/VideoTile.tsx
|
|
2125
2171
|
import { useEffect as useEffect8, useMemo as useMemo10, useRef as useRef3, useState as useState11 } from "react";
|
|
2126
2172
|
import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2127
|
-
function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, i18n }) {
|
|
2173
|
+
function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, videoActive, i18n }) {
|
|
2128
2174
|
const ref = useRef3(null);
|
|
2129
2175
|
const [hasVideoTrack, setHasVideoTrack] = useState11(false);
|
|
2130
2176
|
const [needsInteraction, setNeedsInteraction] = useState11(false);
|
|
@@ -2206,7 +2252,8 @@ function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, i
|
|
|
2206
2252
|
setNeedsInteraction(true);
|
|
2207
2253
|
}
|
|
2208
2254
|
};
|
|
2209
|
-
|
|
2255
|
+
const resolvedHasVideoTrack = videoActive ?? hasVideoTrack;
|
|
2256
|
+
return /* @__PURE__ */ jsxs7("div", { className: `vc-video-tile ${resolvedHasVideoTrack ? "" : "audio-only"}`, children: [
|
|
2210
2257
|
/* @__PURE__ */ jsx16(
|
|
2211
2258
|
"video",
|
|
2212
2259
|
{
|
|
@@ -2215,11 +2262,11 @@ function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, i
|
|
|
2215
2262
|
playsInline: true,
|
|
2216
2263
|
muted,
|
|
2217
2264
|
className: mirrored ? "vc-video-mirrored" : "",
|
|
2218
|
-
style: { display:
|
|
2265
|
+
style: { display: resolvedHasVideoTrack ? "block" : "none" }
|
|
2219
2266
|
}
|
|
2220
2267
|
),
|
|
2221
2268
|
needsInteraction && /* @__PURE__ */ jsx16("button", { className: "vc-video-play-button", onClick: handleResumePlayback, children: texts.resumePlayback }),
|
|
2222
|
-
!
|
|
2269
|
+
!resolvedHasVideoTrack && /* @__PURE__ */ jsxs7("div", { className: "vc-video-placeholder", children: [
|
|
2223
2270
|
/* @__PURE__ */ jsx16("div", { className: "vc-avatar-circle", children: initials }),
|
|
2224
2271
|
/* @__PURE__ */ jsx16("span", { className: "vc-muted", children: muted ? texts.audioOnlyMuted : texts.audioOnlyConnected })
|
|
2225
2272
|
] }),
|
|
@@ -2230,8 +2277,8 @@ function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, i
|
|
|
2230
2277
|
|
|
2231
2278
|
// src/components/video/ParticipantTile.tsx
|
|
2232
2279
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
2233
|
-
function ParticipantTile({ userId, stream, subtitle }) {
|
|
2234
|
-
return /* @__PURE__ */ jsx17(VideoTile, { stream: stream ?? null, label: userId, subtitle });
|
|
2280
|
+
function ParticipantTile({ userId, stream, subtitle, videoActive }) {
|
|
2281
|
+
return /* @__PURE__ */ jsx17(VideoTile, { stream: stream ?? null, label: userId, subtitle, videoActive });
|
|
2235
2282
|
}
|
|
2236
2283
|
|
|
2237
2284
|
// src/components/video/ParticipantGrid.tsx
|
|
@@ -2245,6 +2292,7 @@ function ParticipantGrid() {
|
|
|
2245
2292
|
{
|
|
2246
2293
|
userId,
|
|
2247
2294
|
stream: call.remoteStreams[userId],
|
|
2295
|
+
videoActive: call.remoteTrackStates[userId]?.video,
|
|
2248
2296
|
subtitle: call.remoteTrackStates[userId]?.connectionState
|
|
2249
2297
|
},
|
|
2250
2298
|
userId
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/StreemoClient.ts","../src/client/createStreemoClient.ts","../src/provider/StreemoProvider.tsx","../src/theme/StreemoTheme.tsx","../src/index.ts","../src/hooks/useChat.ts","../src/hooks/useChannel.ts","../src/hooks/useMessages.ts","../src/hooks/useTyping.ts","../src/hooks/usePresence.ts","../src/hooks/useCall.ts","../src/useWebRTCCall.ts","../src/auth.ts","../src/sdkErrors.ts","../src/tokenProvider.ts","../src/sdkConfig.ts","../src/hooks/useParticipants.ts","../src/hooks/useEntitlements.ts","../src/components/chat/Chat.tsx","../src/components/chat/ChannelPreview.tsx","../src/components/ui/LoadingSpinner.tsx","../src/components/chat/ChannelList.tsx","../src/components/chat/Channel.tsx","../src/components/chat/MessageList.tsx","../src/components/chat/AttachmentPreview.tsx","../src/components/chat/ReactionPicker.tsx","../src/components/chat/Message.tsx","../src/components/chat/Thread.tsx","../src/components/chat/MessageInput.tsx","../src/components/chat/TypingIndicator.tsx","../src/components/video/CallRoom.tsx","../src/VideoTile.tsx","../src/components/video/ParticipantTile.tsx","../src/components/video/ParticipantGrid.tsx","../src/components/video/CameraToggle.tsx","../src/components/video/JoinCallButton.tsx","../src/components/video/LeaveCallButton.tsx","../src/components/video/MuteButton.tsx","../src/components/video/ScreenShareButton.tsx","../src/components/video/CallControls.tsx","../src/components/ui/Avatar.tsx","../src/components/ui/PresenceBadge.tsx","../src/components/ui/UserStatus.tsx","../src/components/ui/ErrorBoundary.tsx","../src/ChatPanel.tsx","../src/VideoCallWidget.tsx"],"sourcesContent":["import type {\r\n PresenceState,\r\n StreemoAttachment,\r\n StreemoChannel,\r\n StreemoMessage,\r\n StreemoReaction,\r\n StreemoUser,\r\n TypingState,\r\n} from '../types/models'\r\n\r\ntype Listener<T> = (event: T) => void\r\n\r\ntype RealtimeEventMap = {\r\n connected: { connected: boolean }\r\n message_new: StreemoMessage\r\n message_updated: StreemoMessage\r\n typing: TypingState\r\n presence: PresenceState\r\n reaction_new: { channelId: string; messageId: string; reaction: StreemoReaction }\r\n}\r\n\r\ntype QueryParams = Record<string, string | number | undefined>\r\n\r\n/** Internal storage uses a generic listener to avoid DTS inference issues with mapped types */\r\ntype AnyListener = Listener<RealtimeEventMap[keyof RealtimeEventMap]>\r\n\r\nexport type StreemoClientOptions = {\r\n apiKey: string\r\n userToken: string\r\n user: StreemoUser\r\n baseUrl?: string\r\n wsUrl?: string\r\n reconnect?: boolean\r\n}\r\n\r\nexport class StreemoClient {\r\n public readonly apiKey: string\r\n public readonly userToken: string\r\n public readonly user: StreemoUser\r\n public readonly baseUrl: string\r\n public readonly wsUrl: string\r\n private readonly reconnect: boolean\r\n\r\n private ws: WebSocket | null = null\r\n private manuallyClosed = false\r\n private reconnectAttempt = 0\r\n private listeners: Partial<Record<keyof RealtimeEventMap, Set<AnyListener>>> = {}\r\n\r\n constructor(options: StreemoClientOptions) {\r\n this.apiKey = options.apiKey\r\n this.userToken = options.userToken\r\n this.user = options.user\r\n this.baseUrl = (options.baseUrl ?? 'https://api.streemo.ru').replace(/\\/+$/, '')\r\n const defaultWs = this.baseUrl.replace(/^http/, 'ws')\r\n this.wsUrl = (options.wsUrl ?? defaultWs).replace(/\\/+$/, '')\r\n this.reconnect = options.reconnect ?? true\r\n }\r\n\r\n on<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): () => void {\r\n if (!this.listeners[event]) this.listeners[event] = new Set()\r\n this.listeners[event]?.add(listener as Listener<RealtimeEventMap[keyof RealtimeEventMap]>)\r\n return () => this.off(event, listener)\r\n }\r\n\r\n off<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): void {\r\n this.listeners[event]?.delete(listener as Listener<RealtimeEventMap[keyof RealtimeEventMap]>)\r\n }\r\n\r\n private emit<K extends keyof RealtimeEventMap>(event: K, payload: RealtimeEventMap[K]): void {\r\n this.listeners[event]?.forEach((listener) => {\r\n listener(payload)\r\n })\r\n }\r\n\r\n async connect(): Promise<void> {\r\n if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) return\r\n this.manuallyClosed = false\r\n await this.openSocket()\r\n }\r\n\r\n disconnect(): void {\r\n this.manuallyClosed = true\r\n this.ws?.close()\r\n this.ws = null\r\n this.emit('connected', { connected: false })\r\n }\r\n\r\n private async openSocket(): Promise<void> {\r\n await new Promise<void>((resolve, reject) => {\r\n const url = `${this.wsUrl}/v1/ws?token=${encodeURIComponent(this.userToken)}&userId=${encodeURIComponent(this.user.id)}`\r\n const ws = new WebSocket(url)\r\n this.ws = ws\r\n\r\n ws.onopen = () => {\r\n this.reconnectAttempt = 0\r\n this.emit('connected', { connected: true })\r\n resolve()\r\n }\r\n\r\n ws.onmessage = (event) => {\r\n const parsed = JSON.parse(event.data) as { type: keyof RealtimeEventMap } & Record<string, unknown>\r\n switch (parsed.type) {\r\n case 'message_new':\r\n case 'message_updated':\r\n this.emit(parsed.type, parsed as unknown as StreemoMessage)\r\n break\r\n case 'typing':\r\n this.emit('typing', parsed as unknown as TypingState)\r\n break\r\n case 'presence':\r\n this.emit('presence', parsed as unknown as PresenceState)\r\n break\r\n case 'reaction_new':\r\n this.emit('reaction_new', parsed as unknown as { channelId: string; messageId: string; reaction: StreemoReaction })\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n ws.onerror = () => {\r\n reject(new Error('WebSocket connection failed'))\r\n }\r\n\r\n ws.onclose = () => {\r\n this.emit('connected', { connected: false })\r\n if (!this.manuallyClosed && this.reconnect) {\r\n const backoffMs = Math.min(1000 * 2 ** this.reconnectAttempt, 15000)\r\n this.reconnectAttempt += 1\r\n setTimeout(() => {\r\n void this.openSocket()\r\n }, backoffMs)\r\n }\r\n }\r\n })\r\n }\r\n\r\n private buildUrl(path: string, query?: QueryParams): string {\r\n const url = new URL(`${this.baseUrl}${path}`)\r\n if (query) {\r\n Object.entries(query).forEach(([key, value]) => {\r\n if (value !== undefined) url.searchParams.set(key, String(value))\r\n })\r\n }\r\n return url.toString()\r\n }\r\n\r\n private async request<T>(path: string, init?: RequestInit, query?: QueryParams): Promise<T> {\r\n const response = await fetch(this.buildUrl(path, query), {\r\n ...init,\r\n headers: {\r\n Authorization: `Bearer ${this.userToken}`,\r\n 'X-App-Id': this.apiKey,\r\n 'Content-Type': 'application/json',\r\n ...(init?.headers ?? {}),\r\n },\r\n })\r\n const data = await response.json().catch(() => ({}))\r\n if (!response.ok) {\r\n throw new Error((data as { error?: string }).error || `HTTP ${response.status}`)\r\n }\r\n return data as T\r\n }\r\n\r\n listChannels(): Promise<{ items: StreemoChannel[] }> {\r\n return this.request<{ items: StreemoChannel[] }>('/v1/channels')\r\n }\r\n\r\n listMessages(channelId: string, cursor?: string, limit = 30): Promise<{ items: StreemoMessage[]; nextCursor?: string; hasMore?: boolean }> {\r\n return this.request<{ items: StreemoMessage[]; nextCursor?: string; hasMore?: boolean }>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages`,\r\n undefined,\r\n { cursor, limit },\r\n )\r\n }\r\n\r\n sendMessage(input: {\r\n channelId: string\r\n text: string\r\n parentId?: string\r\n attachments?: StreemoAttachment[]\r\n }): Promise<StreemoMessage> {\r\n return this.request<StreemoMessage>(`/v1/channels/${encodeURIComponent(input.channelId)}/messages`, {\r\n method: 'POST',\r\n body: JSON.stringify(input),\r\n })\r\n }\r\n\r\n updateMessage(channelId: string, messageId: string, text: string): Promise<StreemoMessage> {\r\n return this.request<StreemoMessage>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,\r\n {\r\n method: 'PATCH',\r\n body: JSON.stringify({ text }),\r\n },\r\n )\r\n }\r\n\r\n deleteMessage(channelId: string, messageId: string): Promise<{ ok: true }> {\r\n return this.request<{ ok: true }>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,\r\n { method: 'DELETE' },\r\n )\r\n }\r\n\r\n sendTyping(channelId: string, isTyping: boolean): Promise<{ ok: true }> {\r\n return this.request<{ ok: true }>(`/v1/channels/${encodeURIComponent(channelId)}/typing`, {\r\n method: 'POST',\r\n body: JSON.stringify({ isTyping }),\r\n })\r\n }\r\n}\r\n","import { StreemoClient, type StreemoClientOptions } from './StreemoClient'\n\n/**\n * Stable factory for app-level client creation.\n * Keeps construction centralized and allows future non-breaking extensions.\n */\nexport function createStreemoClient(options: StreemoClientOptions): StreemoClient {\n return new StreemoClient(options)\n}\n","import { createContext, useContext, useEffect, useMemo, useState, type PropsWithChildren } from 'react'\r\nimport { StreemoClient } from '../client/StreemoClient'\r\n\r\ntype StreemoContextValue = {\r\n client: StreemoClient\r\n connected: boolean\r\n activeChannelId: string | null\r\n setActiveChannelId: (channelId: string | null) => void\r\n}\r\n\r\nconst StreemoContext = createContext<StreemoContextValue | null>(null)\r\n\r\nexport type StreemoProviderProps = PropsWithChildren<{\r\n client: StreemoClient\r\n}>\r\n\r\nexport function StreemoProvider({ client, children }: StreemoProviderProps) {\r\n const [connected, setConnected] = useState(false)\r\n const [activeChannelId, setActiveChannelId] = useState<string | null>(null)\r\n\r\n useEffect(() => {\r\n let mounted = true\r\n void client.connect().catch(() => {\r\n if (mounted) setConnected(false)\r\n })\r\n const unsub = client.on('connected', ({ connected: isConnected }) => {\r\n if (mounted) setConnected(isConnected)\r\n })\r\n return () => {\r\n mounted = false\r\n unsub()\r\n client.disconnect()\r\n }\r\n }, [client])\r\n\r\n const value = useMemo<StreemoContextValue>(\r\n () => ({\r\n client,\r\n connected,\r\n activeChannelId,\r\n setActiveChannelId,\r\n }),\r\n [activeChannelId, client, connected],\r\n )\r\n\r\n return <StreemoContext.Provider value={value}>{children}</StreemoContext.Provider>\r\n}\r\n\r\nexport function useStreemoContext(): StreemoContextValue {\r\n const value = useContext(StreemoContext)\r\n if (!value) {\r\n throw new Error('useStreemoContext must be used within StreemoProvider')\r\n }\r\n return value\r\n}\r\n","import type { CSSProperties, PropsWithChildren } from 'react'\r\nimport { createTheme, themeToCssVars } from 'streemo-ui-kit-web/theme'\r\n\r\nexport type StreemoThemeTokens = {\r\n primary?: string\r\n background?: string\r\n text?: string\r\n radius?: string\r\n}\r\n\r\nexport type StreemoThemeProps = PropsWithChildren<{\r\n theme?: StreemoThemeTokens\r\n mode?: 'light' | 'dark'\r\n}>\r\n\r\nexport function StreemoTheme({ theme, mode = 'light', children }: StreemoThemeProps) {\r\n const themeConfig = createTheme({\r\n mode,\r\n tokens: theme\r\n ? {\r\n colors: {\r\n primary: theme.primary,\r\n background: theme.background,\r\n text: theme.text,\r\n },\r\n radius: theme.radius ? { md: parseInt(theme.radius, 10) || 10, lg: 12 } : undefined,\r\n }\r\n : undefined,\r\n })\r\n const style: CSSProperties = themeToCssVars(themeConfig) as unknown as CSSProperties\r\n\r\n return (\r\n <div className={`st-theme st-theme--${mode}`} style={style}>\r\n {children}\r\n </div>\r\n )\r\n}\r\n","export { StreemoClient } from './client/StreemoClient'\nexport type { StreemoClientOptions } from './client/StreemoClient'\nexport { createStreemoClient } from './client/createStreemoClient'\nexport { StreemoProvider, useStreemoContext } from './provider/StreemoProvider'\nexport { StreemoTheme } from './theme/StreemoTheme'\nexport type { StreemoThemeTokens } from './theme/StreemoTheme'\nexport { createTheme, StreemoThemeProvider, useTheme } from 'streemo-ui-kit-web/theme'\nexport type { Theme, ThemeTokens, ThemeMode } from 'streemo-ui-kit-web/theme'\n\nexport { useChat } from './hooks/useChat'\nexport { useChannel } from './hooks/useChannel'\nexport { useMessages } from './hooks/useMessages'\nexport { useTyping } from './hooks/useTyping'\nexport { usePresence } from './hooks/usePresence'\nexport { useCall } from './hooks/useCall'\nexport { useParticipants } from './hooks/useParticipants'\nexport { useEntitlements } from './hooks/useEntitlements'\nexport type { StreemoEntitlements } from './hooks/useEntitlements'\n\nexport { Chat } from './components/chat/Chat'\nexport { ChannelList } from './components/chat/ChannelList'\nexport { ChannelPreview } from './components/chat/ChannelPreview'\nexport { Channel } from './components/chat/Channel'\nexport { MessageList } from './components/chat/MessageList'\nexport { Message } from './components/chat/Message'\nexport { MessageInput } from './components/chat/MessageInput'\nexport { Thread } from './components/chat/Thread'\nexport { TypingIndicator } from './components/chat/TypingIndicator'\nexport { AttachmentPreview } from './components/chat/AttachmentPreview'\nexport { ReactionPicker } from './components/chat/ReactionPicker'\n\nexport { CallRoom, useCallRoomContext } from './components/video/CallRoom'\nexport { ParticipantGrid } from './components/video/ParticipantGrid'\nexport { ParticipantTile } from './components/video/ParticipantTile'\nexport { CallControls } from './components/video/CallControls'\nexport { JoinCallButton } from './components/video/JoinCallButton'\nexport { LeaveCallButton } from './components/video/LeaveCallButton'\nexport { MuteButton } from './components/video/MuteButton'\nexport { CameraToggle } from './components/video/CameraToggle'\nexport { ScreenShareButton } from './components/video/ScreenShareButton'\n\nexport { Avatar } from './components/ui/Avatar'\nexport { UserStatus } from './components/ui/UserStatus'\nexport { PresenceBadge } from './components/ui/PresenceBadge'\nexport { LoadingSpinner } from './components/ui/LoadingSpinner'\nexport { ErrorBoundary } from './components/ui/ErrorBoundary'\n\nexport type {\n StreemoAttachment,\n StreemoChannel,\n StreemoMessage,\n StreemoReaction,\n StreemoUser,\n PresenceState,\n TypingState,\n Participant,\n} from './types/models'\n\nexport { useWebRTCCall } from './useWebRTCCall'\nexport type { UseWebRTCCallParams, RemoteTrackState, ChatMessage, TypingParticipant } from './useWebRTCCall'\nexport { VideoTile } from './VideoTile'\nexport { ChatPanel } from './ChatPanel'\nexport type { ChatPanelProps } from './ChatPanel'\nexport { VideoCallWidget } from './VideoCallWidget'\nexport type { VideoCallWidgetProps } from './VideoCallWidget'\nexport { createServerTokenProvider, defaultWsBaseUrlFromApi, defaultApiBaseUrl } from './tokenProvider'\nexport type { TokenProvider, TokenProviderContext, ServerTokenProviderOptions } from './tokenProvider'\nexport type { ServerAuthConfig } from './auth'\nexport { SDKError, mapSDKErrorToUIMessage } from './sdkErrors'\nexport type { SDKErrorCode } from './sdkErrors'\nexport { initVideoSDK, getVideoSDKConfig } from './sdkConfig'\nexport type { VideoSDKConfig } from './sdkConfig'\n","import { useEffect, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { StreemoChannel } from '../types/models'\r\n\r\nexport function useChat() {\r\n const { client, activeChannelId, setActiveChannelId, connected } = useStreemoContext()\r\n const [channels, setChannels] = useState<StreemoChannel[]>([])\r\n const [loading, setLoading] = useState(false)\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n const refreshChannels = async () => {\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const result = await client.listChannels()\r\n setChannels(result.items)\r\n if (!activeChannelId && result.items[0]) {\r\n setActiveChannelId(result.items[0].id)\r\n }\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load channels')\r\n } finally {\r\n setLoading(false)\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n void refreshChannels()\r\n }, [client])\r\n\r\n return {\r\n channels,\r\n loading,\r\n error,\r\n connected,\r\n activeChannelId,\r\n setActiveChannelId,\r\n refreshChannels,\r\n }\r\n}\r\n","import { useMemo } from 'react'\r\nimport { useChat } from './useChat'\r\nimport { useMessages } from './useMessages'\r\nimport { useTyping } from './useTyping'\r\n\r\nexport function useChannel(channelId?: string) {\r\n const chat = useChat()\r\n const resolvedChannelId = channelId ?? chat.activeChannelId ?? ''\r\n const messages = useMessages(resolvedChannelId)\r\n const typing = useTyping(resolvedChannelId)\r\n\r\n return useMemo(\r\n () => ({\r\n channelId: resolvedChannelId,\r\n ...messages,\r\n ...typing,\r\n activeChannelId: chat.activeChannelId,\r\n setActiveChannelId: chat.setActiveChannelId,\r\n }),\r\n [chat.activeChannelId, chat.setActiveChannelId, messages, resolvedChannelId, typing],\r\n )\r\n}\r\n","import { useCallback, useEffect, useMemo, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { StreemoAttachment, StreemoMessage } from '../types/models'\r\n\r\nfunction upsert(messages: StreemoMessage[], next: StreemoMessage): StreemoMessage[] {\r\n const idx = messages.findIndex((item) => item.id === next.id)\r\n if (idx === -1) return [...messages, next]\r\n const copy = [...messages]\r\n copy[idx] = next\r\n return copy\r\n}\r\n\r\nexport function useMessages(channelId: string) {\r\n const { client } = useStreemoContext()\r\n const [messages, setMessages] = useState<StreemoMessage[]>([])\r\n const [loading, setLoading] = useState(false)\r\n const [loadingMore, setLoadingMore] = useState(false)\r\n const [error, setError] = useState<string | null>(null)\r\n const [cursor, setCursor] = useState<string | undefined>(undefined)\r\n const [hasMore, setHasMore] = useState(false)\r\n\r\n const reload = useCallback(async () => {\r\n if (!channelId) return\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const result = await client.listMessages(channelId)\r\n setMessages(result.items)\r\n setCursor(result.nextCursor)\r\n setHasMore(Boolean(result.hasMore))\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load messages')\r\n } finally {\r\n setLoading(false)\r\n }\r\n }, [channelId, client])\r\n\r\n useEffect(() => {\r\n if (!channelId) return\r\n void reload()\r\n }, [channelId, reload])\r\n\r\n useEffect(() => {\r\n if (!channelId) return\r\n const unsubNew = client.on('message_new', (event) => {\r\n if (event.channelId !== channelId) return\r\n setMessages((prev) => upsert(prev, { ...event, deliveryStatus: 'sent' }))\r\n })\r\n const unsubUpdated = client.on('message_updated', (event) => {\r\n if (event.channelId !== channelId) return\r\n setMessages((prev) => upsert(prev, { ...event, deliveryStatus: 'sent' }))\r\n })\r\n return () => {\r\n unsubNew()\r\n unsubUpdated()\r\n }\r\n }, [channelId, client])\r\n\r\n const sendMessage = useCallback(\r\n async (text: string, options?: { parentId?: string; attachments?: StreemoAttachment[] }) => {\r\n if (!channelId || !text.trim()) return\r\n const optimisticId = `optimistic-${crypto.randomUUID()}`\r\n const optimisticMessage: StreemoMessage = {\r\n id: optimisticId,\r\n channelId,\r\n text: text.trim(),\r\n userId: client.user.id,\r\n createdAt: new Date().toISOString(),\r\n parentId: options?.parentId,\r\n attachments: options?.attachments,\r\n reactions: [],\r\n deliveryStatus: 'sending',\r\n }\r\n setMessages((prev) => [...prev, optimisticMessage])\r\n try {\r\n const saved = await client.sendMessage({\r\n channelId,\r\n text: text.trim(),\r\n parentId: options?.parentId,\r\n attachments: options?.attachments,\r\n })\r\n setMessages((prev) =>\r\n prev.map((item) => (item.id === optimisticId ? { ...saved, deliveryStatus: 'sent' } : item)),\r\n )\r\n } catch (err) {\r\n setMessages((prev) =>\r\n prev.map((item) => (item.id === optimisticId ? { ...item, deliveryStatus: 'failed' } : item)),\r\n )\r\n throw err\r\n }\r\n },\r\n [channelId, client],\r\n )\r\n\r\n const loadMore = useCallback(async () => {\r\n if (!channelId || !cursor || !hasMore || loadingMore) return\r\n setLoadingMore(true)\r\n try {\r\n const result = await client.listMessages(channelId, cursor)\r\n setMessages((prev) => [...result.items, ...prev])\r\n setCursor(result.nextCursor)\r\n setHasMore(Boolean(result.hasMore))\r\n } finally {\r\n setLoadingMore(false)\r\n }\r\n }, [channelId, client, cursor, hasMore, loadingMore])\r\n\r\n return useMemo(\r\n () => ({\r\n messages,\r\n loading,\r\n error,\r\n hasMore,\r\n loadingMore,\r\n sendMessage,\r\n loadMore,\r\n reload,\r\n }),\r\n [error, hasMore, loadMore, loading, loadingMore, messages, reload, sendMessage],\r\n )\r\n}\r\n","import { useEffect, useMemo, useRef, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { TypingState } from '../types/models'\r\n\r\nexport function useTyping(channelId: string) {\r\n const { client } = useStreemoContext()\r\n const [typing, setTyping] = useState<Record<string, TypingState>>({})\r\n const timeoutRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map())\r\n\r\n useEffect(() => {\r\n if (!channelId) return\r\n const unsub = client.on('typing', (event) => {\r\n if (event.channelId !== channelId || event.userId === client.user.id) return\r\n if (!event.isTyping) {\r\n setTyping((prev) => {\r\n const copy = { ...prev }\r\n delete copy[event.userId]\r\n return copy\r\n })\r\n return\r\n }\r\n setTyping((prev) => ({ ...prev, [event.userId]: event }))\r\n const prevTimer = timeoutRef.current.get(event.userId)\r\n if (prevTimer) clearTimeout(prevTimer)\r\n const timer = setTimeout(() => {\r\n setTyping((prev) => {\r\n const copy = { ...prev }\r\n delete copy[event.userId]\r\n return copy\r\n })\r\n timeoutRef.current.delete(event.userId)\r\n }, 3500)\r\n timeoutRef.current.set(event.userId, timer)\r\n })\r\n return () => {\r\n unsub()\r\n timeoutRef.current.forEach((timer) => clearTimeout(timer))\r\n timeoutRef.current.clear()\r\n }\r\n }, [channelId, client])\r\n\r\n const sendTyping = async (isTyping: boolean) => {\r\n if (!channelId) return\r\n await client.sendTyping(channelId, isTyping)\r\n }\r\n\r\n return useMemo(\r\n () => ({\r\n typingUsers: Object.values(typing),\r\n sendTyping,\r\n }),\r\n [typing],\r\n )\r\n}\r\n","import { useEffect, useMemo, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { PresenceState } from '../types/models'\r\n\r\nexport function usePresence() {\r\n const { client } = useStreemoContext()\r\n const [presence, setPresence] = useState<Record<string, PresenceState>>({})\r\n\r\n useEffect(() => {\r\n const unsub = client.on('presence', (event) => {\r\n setPresence((prev) => ({ ...prev, [event.userId]: event }))\r\n })\r\n return () => unsub()\r\n }, [client])\r\n\r\n return useMemo(\r\n () => ({\r\n presenceMap: presence,\r\n getUserPresence: (userId: string) =>\r\n presence[userId] ?? { userId, status: 'offline', lastSeenAt: undefined },\r\n findUserPresence: (userId: string) => presence[userId],\r\n }),\r\n [presence],\r\n )\r\n}\r\n","import { useMemo, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport { useWebRTCCall } from '../useWebRTCCall'\r\n\r\nexport type UseCallParams = {\r\n roomId: string\r\n enabled?: boolean\r\n}\r\n\r\nexport function useCall({ roomId, enabled = true }: UseCallParams) {\r\n const { client } = useStreemoContext()\r\n const [joined, setJoined] = useState(enabled)\r\n const auth = useMemo(\r\n () => ({ appId: client.apiKey, authToken: client.userToken }),\r\n [client.apiKey, client.userToken],\r\n )\r\n\r\n const call = useWebRTCCall({\r\n roomId,\r\n userId: client.user.id,\r\n enabled: joined,\r\n apiBaseUrl: client.baseUrl,\r\n auth,\r\n })\r\n\r\n return useMemo(\r\n () => ({\r\n ...call,\r\n joined,\r\n joinCall: () => setJoined(true),\r\n leaveCall: () => setJoined(false),\r\n }),\r\n [call, joined],\r\n )\r\n}\r\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ServerAuthConfig } from './auth'\nimport {\n createServerTokenProvider,\n defaultApiBaseUrl,\n defaultWsBaseUrlFromApi,\n type TokenProvider,\n type TokenProviderContext,\n} from './tokenProvider'\nimport { mapSDKErrorToUIMessage } from './sdkErrors'\nimport { getVideoSDKConfig } from './sdkConfig'\n\ntype SignalMessage = {\n type: string\n roomId: string\n userId: string\n targetUserId?: string\n payload?: unknown\n}\n\nexport type UseWebRTCCallParams = {\n roomId: string\n userId: string\n roomToken?: string\n wsBaseUrl?: string\n tokenProvider?: TokenProvider\n apiBaseUrl?: string\n auth?: ServerAuthConfig\n enabled: boolean\n}\n\nexport type RemoteTrackState = {\n audio: boolean\n video: boolean\n connectionState: RTCPeerConnectionState\n}\n\nexport type ChatMessage = {\n id: string\n userId: string\n text: string\n senderName: string\n sentAt: string\n editedAt?: string\n deletedAt?: string\n deliveryStatus?: 'sending' | 'sent' | 'failed'\n clientMessageId?: string\n}\n\nexport type TypingParticipant = {\n userId: string\n senderName: string\n updatedAt: string\n}\n\n/** RTCRtpTransceiver has `kind` at runtime; DOM types omit it */\ntype TransceiverWithKind = RTCRtpTransceiver & { kind: 'audio' | 'video' }\n\nconst RENEGOTIATION_RETRY_DELAY_MS = 6000\nconst RENEGOTIATION_MAX_RETRIES = 3\nconst DISCONNECTED_CLEANUP_DELAY_MS = 10000\nconst NETWORK_STATS_POLL_MS = 5000\n\ntype QualityLevel = 'low' | 'medium' | 'high'\n\n/** RTCRtpTransceiver has `kind` at runtime but TypeScript DOM types omit it */\nfunction isVideoTransceiver(t: RTCRtpTransceiver): boolean {\n return (t as RTCRtpTransceiver & { kind?: string }).kind === 'video'\n}\n\nconst AUDIO_CONSTRAINTS: MediaTrackConstraints = {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n channelCount: 1,\n}\nconst VIDEO_CONSTRAINTS: MediaTrackConstraints = {\n width: { ideal: 1280, max: 1920 },\n height: { ideal: 720, max: 1080 },\n frameRate: { ideal: 24, max: 30 },\n facingMode: 'user',\n}\n\nasync function tuneLocalStream(stream: MediaStream): Promise<void> {\n const audioTrack = stream.getAudioTracks()[0]\n const videoTrack = stream.getVideoTracks()[0]\n\n if (audioTrack) {\n audioTrack.contentHint = 'speech'\n try {\n await audioTrack.applyConstraints(AUDIO_CONSTRAINTS)\n } catch {\n // Browser may ignore unsupported audio processing constraints.\n }\n }\n if (videoTrack) {\n videoTrack.contentHint = 'motion'\n try {\n await videoTrack.applyConstraints(VIDEO_CONSTRAINTS)\n } catch {\n // Browser may ignore unsupported video quality constraints.\n }\n }\n}\n\nasync function tuneSenderEncodings(peer: RTCPeerConnection): Promise<void> {\n const tasks = peer.getSenders().map(async (sender) => {\n const track = sender.track\n if (!track) return\n const params = sender.getParameters()\n if (!params.encodings || params.encodings.length === 0) {\n params.encodings = [{}]\n }\n const encoding = params.encodings[0]\n\n if (track.kind === 'audio') {\n encoding.maxBitrate = 64000\n }\n if (track.kind === 'video') {\n encoding.maxBitrate = 1200000\n encoding.maxFramerate = 24\n encoding.scaleResolutionDownBy = 1\n }\n\n try {\n await sender.setParameters(params)\n } catch {\n // Some browsers can reject runtime encoding changes.\n }\n })\n\n await Promise.all(tasks)\n}\n\nfunction getVideoProfile(level: QualityLevel): {\n maxBitrate: number\n maxFramerate: number\n scaleResolutionDownBy: number\n} {\n switch (level) {\n case 'low':\n return {\n maxBitrate: 350_000,\n maxFramerate: 15,\n scaleResolutionDownBy: 2,\n }\n case 'medium':\n return {\n maxBitrate: 700_000,\n maxFramerate: 20,\n scaleResolutionDownBy: 1.5,\n }\n case 'high':\n default:\n return {\n maxBitrate: 1_200_000,\n maxFramerate: 24,\n scaleResolutionDownBy: 1,\n }\n }\n}\n\nasync function applyVideoQualityProfile(peer: RTCPeerConnection, level: QualityLevel): Promise<void> {\n const profile = getVideoProfile(level)\n const tasks = peer.getSenders().map(async (sender) => {\n if (sender.track?.kind !== 'video') return\n const params = sender.getParameters()\n if (!params.encodings || params.encodings.length === 0) {\n params.encodings = [{}]\n }\n const encoding = params.encodings[0]\n encoding.maxBitrate = profile.maxBitrate\n encoding.maxFramerate = profile.maxFramerate\n encoding.scaleResolutionDownBy = profile.scaleResolutionDownBy\n try {\n await sender.setParameters(params)\n } catch {\n // Some browsers reject runtime adaptation for sender parameters.\n }\n })\n await Promise.all(tasks)\n}\n\nfunction nextQualityLevel(current: QualityLevel, target: QualityLevel): QualityLevel {\n const levels: QualityLevel[] = ['low', 'medium', 'high']\n const currentIdx = levels.indexOf(current)\n const targetIdx = levels.indexOf(target)\n if (currentIdx === targetIdx) return current\n if (currentIdx < targetIdx) return levels[currentIdx + 1]\n return levels[currentIdx - 1]\n}\n\nfunction resolveTokenProvider(params: UseWebRTCCallParams): TokenProvider | null {\n if (params.tokenProvider) return params.tokenProvider\n if (params.auth) {\n return createServerTokenProvider({\n apiBaseUrl: params.apiBaseUrl || defaultApiBaseUrl(),\n auth: params.auth,\n })\n }\n return null\n}\n\nfunction resolveWsBaseUrl(params: UseWebRTCCallParams): string {\n if (params.wsBaseUrl) return params.wsBaseUrl.replace(/\\/+$/, '')\n const apiBase = params.apiBaseUrl || defaultApiBaseUrl()\n if (apiBase) return defaultWsBaseUrlFromApi(apiBase)\n return ''\n}\n\nasync function resolveRoomToken(params: UseWebRTCCallParams): Promise<string> {\n if (params.roomToken) return params.roomToken\n const provider = resolveTokenProvider(params)\n if (!provider) {\n throw new Error('roomToken or tokenProvider/apiBaseUrl+auth is required')\n }\n const ctx: TokenProviderContext = {\n roomId: params.roomId,\n userId: params.userId,\n }\n return provider(ctx)\n}\n\nexport function useWebRTCCall(params: UseWebRTCCallParams) {\n const sdkConfig = getVideoSDKConfig()\n const mergedParams: UseWebRTCCallParams = {\n ...params,\n apiBaseUrl: params.apiBaseUrl ?? sdkConfig.apiBaseUrl,\n wsBaseUrl: params.wsBaseUrl ?? sdkConfig.wsBaseUrl,\n auth: params.auth ?? sdkConfig.auth,\n }\n\n const { roomId, userId, enabled } = mergedParams\n const { roomToken, wsBaseUrl, tokenProvider, apiBaseUrl, auth } = mergedParams\n\n const resolvedTokenProvider = useMemo<TokenProvider | null>(() => {\n if (tokenProvider) return tokenProvider\n if (auth) {\n return createServerTokenProvider({\n apiBaseUrl: apiBaseUrl || defaultApiBaseUrl(),\n auth,\n })\n }\n return null\n }, [tokenProvider, auth?.authToken, auth?.appId, apiBaseUrl])\n\n const wsRef = useRef<WebSocket | null>(null)\n const setupGenerationRef = useRef(0)\n const peersRef = useRef(new Map<string, RTCPeerConnection>())\n const localStreamRef = useRef<MediaStream | null>(null)\n const remoteStreamsRef = useRef<Record<string, MediaStream>>({})\n const localParticipantIdRef = useRef<string | null>(null)\n const renegotiationTimersRef = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n const renegotiationAttemptsRef = useRef(new Map<string, number>())\n const disconnectedCleanupTimersRef = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n const remoteStreamCleanupRef = useRef(new Map<string, () => void>())\n const networkStatsTimersRef = useRef(new Map<string, ReturnType<typeof setInterval>>())\n const qualityLevelRef = useRef(new Map<string, QualityLevel>())\n const makingOfferRef = useRef(new Map<string, boolean>())\n const ignoreOfferRef = useRef(new Map<string, boolean>())\n const isSettingRemoteAnswerPendingRef = useRef(new Map<string, boolean>())\n const politeRef = useRef(new Map<string, boolean>())\n const pendingChatPatchesRef = useRef(new Map<string, { text?: string; editedAt?: string; deletedAt?: string }>())\n const typingTimersRef = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n const isChatFocusedRef = useRef(false)\n const handleSignalMessageRef = useRef<(m: SignalMessage) => void>(() => {})\n const [localStream, setLocalStream] = useState<MediaStream | null>(null)\n const [remoteStreams, setRemoteStreams] = useState<Record<string, MediaStream>>({})\n const [participants, setParticipants] = useState<string[]>([])\n const [connected, setConnected] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [remoteTrackStates, setRemoteTrackStates] = useState<Record<string, RemoteTrackState>>({})\n const [chatMessages, setChatMessages] = useState<ChatMessage[]>([])\n const [typingParticipants, setTypingParticipants] = useState<TypingParticipant[]>([])\n const [chatUnreadCount, setChatUnreadCount] = useState(0)\n const [chatNextCursor, setChatNextCursor] = useState<string | null>(null)\n const [chatHasMore, setChatHasMore] = useState(false)\n const [chatLoadingHistory, setChatLoadingHistory] = useState(false)\n const [micEnabled, setMicEnabled] = useState(true)\n const [cameraEnabled, setCameraEnabled] = useState(true)\n const [hasMicTrack, setHasMicTrack] = useState(false)\n const [hasCameraTrack, setHasCameraTrack] = useState(false)\n const [screenSharing, setScreenSharing] = useState(false)\n const screenTrackRef = useRef<MediaStreamTrack | null>(null)\n const previousCameraTrackRef = useRef<MediaStreamTrack | null>(null)\n\n const clearRenegotiationRetry = useCallback((targetUserId: string) => {\n const timer = renegotiationTimersRef.current.get(targetUserId)\n if (timer) {\n clearTimeout(timer)\n renegotiationTimersRef.current.delete(targetUserId)\n }\n renegotiationAttemptsRef.current.delete(targetUserId)\n }, [])\n\n const clearDisconnectedCleanup = useCallback((targetUserId: string) => {\n const timer = disconnectedCleanupTimersRef.current.get(targetUserId)\n if (timer) {\n clearTimeout(timer)\n disconnectedCleanupTimersRef.current.delete(targetUserId)\n }\n }, [])\n\n const clearRemoteStreamObservers = useCallback((targetUserId: string) => {\n const cleanup = remoteStreamCleanupRef.current.get(targetUserId)\n if (cleanup) {\n cleanup()\n remoteStreamCleanupRef.current.delete(targetUserId)\n }\n }, [])\n\n const clearNetworkAdaptation = useCallback((targetUserId: string) => {\n const timer = networkStatsTimersRef.current.get(targetUserId)\n if (timer) {\n clearInterval(timer)\n networkStatsTimersRef.current.delete(targetUserId)\n }\n qualityLevelRef.current.delete(targetUserId)\n }, [])\n\n const computeTargetQualityLevel = useCallback(async (peer: RTCPeerConnection): Promise<QualityLevel> => {\n const stats = await peer.getStats()\n let rttSeconds: number | null = null\n let packetLossPercent: number | null = null\n\n stats.forEach((report) => {\n const stat = report as RTCStats & Record<string, unknown>\n\n if (stat.type === 'candidate-pair' && stat.state === 'succeeded') {\n const currentRTT = stat.currentRoundTripTime\n if (typeof currentRTT === 'number') {\n rttSeconds = rttSeconds === null ? currentRTT : Math.max(rttSeconds, currentRTT)\n }\n }\n\n if (stat.type === 'remote-inbound-rtp' && stat.kind === 'video') {\n const fractionLost = stat.fractionLost\n if (typeof fractionLost === 'number') {\n packetLossPercent = Math.max(0, fractionLost * 100)\n }\n }\n })\n\n if ((rttSeconds ?? 0) > 0.35 || (packetLossPercent ?? 0) > 8) {\n return 'low'\n }\n if ((rttSeconds ?? 0) > 0.2 || (packetLossPercent ?? 0) > 3) {\n return 'medium'\n }\n return 'high'\n }, [])\n\n const startNetworkAdaptation = useCallback(\n (targetUserId: string, peer: RTCPeerConnection) => {\n clearNetworkAdaptation(targetUserId)\n qualityLevelRef.current.set(targetUserId, 'high')\n const timer = setInterval(() => {\n void (async () => {\n if (peer.connectionState === 'closed' || peer.connectionState === 'failed') {\n clearNetworkAdaptation(targetUserId)\n return\n }\n const hasVideoSender = peer.getSenders().some((sender) => sender.track?.kind === 'video')\n if (!hasVideoSender) return\n\n let targetLevel: QualityLevel\n try {\n targetLevel = await computeTargetQualityLevel(peer)\n } catch {\n return\n }\n\n const currentLevel = qualityLevelRef.current.get(targetUserId) ?? 'high'\n const nextLevel = nextQualityLevel(currentLevel, targetLevel)\n if (nextLevel === currentLevel) return\n\n qualityLevelRef.current.set(targetUserId, nextLevel)\n await applyVideoQualityProfile(peer, nextLevel)\n })()\n }, NETWORK_STATS_POLL_MS)\n\n networkStatsTimersRef.current.set(targetUserId, timer)\n },\n [clearNetworkAdaptation, computeTargetQualityLevel],\n )\n\n const removePeer = useCallback(\n (targetUserId: string, removeParticipant = false) => {\n clearRenegotiationRetry(targetUserId)\n clearDisconnectedCleanup(targetUserId)\n clearRemoteStreamObservers(targetUserId)\n clearNetworkAdaptation(targetUserId)\n makingOfferRef.current.delete(targetUserId)\n ignoreOfferRef.current.delete(targetUserId)\n isSettingRemoteAnswerPendingRef.current.delete(targetUserId)\n politeRef.current.delete(targetUserId)\n\n const peer = peersRef.current.get(targetUserId)\n if (peer) {\n peer.ontrack = null\n peer.onicecandidate = null\n peer.onconnectionstatechange = null\n peer.close()\n }\n peersRef.current.delete(targetUserId)\n\n setRemoteStreams((prev) => {\n const copy = { ...prev }\n delete copy[targetUserId]\n remoteStreamsRef.current = copy\n return copy\n })\n setRemoteTrackStates((prev) => {\n const copy = { ...prev }\n delete copy[targetUserId]\n return copy\n })\n if (removeParticipant) {\n setParticipants((prev) => prev.filter((id) => id !== targetUserId))\n }\n },\n [clearDisconnectedCleanup, clearNetworkAdaptation, clearRemoteStreamObservers, clearRenegotiationRetry],\n )\n\n const hasRemoteVideoTrack = useCallback((targetUserId: string) => {\n const stream = remoteStreamsRef.current[targetUserId]\n if (!stream) return false\n return stream\n .getVideoTracks()\n .some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n }, [])\n\n const syncLocalTrackFlags = useCallback(() => {\n const stream = localStreamRef.current\n if (!stream) {\n setHasMicTrack(false)\n setHasCameraTrack(false)\n setMicEnabled(false)\n setCameraEnabled(false)\n return\n }\n\n const audioTrack = stream.getAudioTracks()[0]\n const videoTrack = stream.getVideoTracks()[0]\n\n setHasMicTrack(Boolean(audioTrack))\n setHasCameraTrack(Boolean(videoTrack))\n setMicEnabled(Boolean(audioTrack?.enabled))\n setCameraEnabled(Boolean(videoTrack?.enabled))\n }, [])\n\n const send = useCallback((message: Omit<SignalMessage, 'roomId' | 'userId'>) => {\n const ws = wsRef.current\n if (!ws || ws.readyState !== WebSocket.OPEN) return\n ws.send(\n JSON.stringify({\n roomId,\n userId,\n ...message,\n }),\n )\n }, [roomId, userId])\n\n const gracefulLeave = useCallback(() => {\n const ws = wsRef.current\n if (!ws || ws.readyState !== WebSocket.OPEN) return\n try {\n ws.send(\n JSON.stringify({\n roomId,\n userId,\n type: 'participant_left',\n payload: { source: 'page_unload', leftAt: new Date().toISOString() },\n }),\n )\n } catch {\n // Ignore unload-time send errors.\n }\n ws.close()\n }, [roomId, userId])\n\n const updateRemoteTrackState = useCallback((targetUserId: string, stream: MediaStream, peer: RTCPeerConnection) => {\n const audio = stream.getAudioTracks().some((track) => track.readyState === 'live' && track.enabled)\n const video = stream.getVideoTracks().some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n setRemoteTrackStates((prev) => ({\n ...prev,\n [targetUserId]: {\n audio,\n video,\n connectionState: peer.connectionState,\n },\n }))\n }, [])\n\n const pushChatMessage = useCallback((message: ChatMessage) => {\n setChatMessages((prev) => {\n const existingIdx = prev.findIndex((item) => item.id === message.id)\n if (existingIdx >= 0) {\n const copy = [...prev]\n copy[existingIdx] = {\n ...copy[existingIdx],\n ...message,\n deliveryStatus: message.deliveryStatus ?? copy[existingIdx].deliveryStatus ?? 'sent',\n }\n return copy\n }\n const patch = pendingChatPatchesRef.current.get(message.id)\n const withPatch: ChatMessage = patch\n ? {\n ...message,\n text: patch.deletedAt ? '' : (patch.text ?? message.text),\n editedAt: patch.editedAt ?? message.editedAt,\n deletedAt: patch.deletedAt ?? message.deletedAt,\n }\n : message\n const next = [...prev, withPatch]\n next.sort((a, b) => new Date(a.sentAt).getTime() - new Date(b.sentAt).getTime())\n if (next.length > 200) {\n return next.slice(next.length - 200)\n }\n return next\n })\n }, [])\n\n const prependChatMessages = useCallback((messages: ChatMessage[]) => {\n if (messages.length === 0) return\n setChatMessages((prev) => {\n const byID = new Map(prev.map((item) => [item.id, item]))\n messages.forEach((item) => {\n const patch = pendingChatPatchesRef.current.get(item.id)\n byID.set(item.id, {\n ...item,\n text: patch?.deletedAt ? '' : (patch?.text ?? item.text),\n editedAt: patch?.editedAt ?? item.editedAt,\n deletedAt: patch?.deletedAt ?? item.deletedAt,\n deliveryStatus: item.deliveryStatus ?? 'sent',\n })\n })\n const next = Array.from(byID.values())\n next.sort((a, b) => new Date(a.sentAt).getTime() - new Date(b.sentAt).getTime())\n return next.slice(Math.max(0, next.length - 400))\n })\n }, [])\n\n const patchChatMessage = useCallback((id: string, patch: { text?: string; editedAt?: string; deletedAt?: string }) => {\n let applied = false\n setChatMessages((prev) => {\n const idx = prev.findIndex((item) => item.id === id)\n if (idx < 0) return prev\n applied = true\n const next = [...prev]\n next[idx] = {\n ...next[idx],\n ...(patch.text !== undefined ? { text: patch.text } : {}),\n ...(patch.editedAt ? { editedAt: patch.editedAt } : {}),\n ...(patch.deletedAt ? { deletedAt: patch.deletedAt, text: '' } : {}),\n }\n return next\n })\n if (!applied) {\n const existing = pendingChatPatchesRef.current.get(id) ?? {}\n pendingChatPatchesRef.current.set(id, { ...existing, ...patch })\n }\n }, [])\n\n const setTypingState = useCallback((userIdValue: string, senderName: string, isTyping: boolean) => {\n const timer = typingTimersRef.current.get(userIdValue)\n if (timer) {\n clearTimeout(timer)\n typingTimersRef.current.delete(userIdValue)\n }\n if (!isTyping) {\n setTypingParticipants((prev) => prev.filter((item) => item.userId !== userIdValue))\n return\n }\n const now = new Date().toISOString()\n setTypingParticipants((prev) => {\n const filtered = prev.filter((item) => item.userId !== userIdValue)\n return [...filtered, { userId: userIdValue, senderName, updatedAt: now }]\n })\n const cleanupTimer = setTimeout(() => {\n setTypingParticipants((prev) => prev.filter((item) => item.userId !== userIdValue))\n typingTimersRef.current.delete(userIdValue)\n }, 3000)\n typingTimersRef.current.set(userIdValue, cleanupTimer)\n }, [])\n\n const ensurePeer = useCallback<(targetUserId: string) => RTCPeerConnection>(\n (targetUserId: string) => {\n const existing = peersRef.current.get(targetUserId)\n if (existing) return existing\n\n const peer = new RTCPeerConnection({\n iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],\n })\n const localParticipantID = localParticipantIdRef.current\n politeRef.current.set(targetUserId, localParticipantID ? localParticipantID > targetUserId : true)\n\n const localStream = localStreamRef.current\n const hasLocalAudio = Boolean(localStream?.getAudioTracks().length)\n const hasLocalVideo = Boolean(localStream?.getVideoTracks().length)\n\n if (!hasLocalAudio) {\n peer.addTransceiver('audio', { direction: 'recvonly' })\n }\n if (!hasLocalVideo) {\n peer.addTransceiver('video', { direction: 'recvonly' })\n }\n\n localStreamRef.current?.getTracks().forEach((track) => {\n peer.addTrack(track, localStreamRef.current as MediaStream)\n })\n void tuneSenderEncodings(peer)\n startNetworkAdaptation(targetUserId, peer)\n\n peer.onicecandidate = (event) => {\n if (!event.candidate) return\n send({\n type: 'ice_candidate',\n targetUserId,\n payload: event.candidate.toJSON(),\n })\n }\n\n peer.ontrack = (event) => {\n const [stream] = event.streams\n clearRemoteStreamObservers(targetUserId)\n setRemoteStreams((prev) => {\n const next = { ...prev, [targetUserId]: stream }\n remoteStreamsRef.current = next\n return next\n })\n updateRemoteTrackState(targetUserId, stream, peer)\n const update = () => updateRemoteTrackState(targetUserId, stream, peer)\n stream.getTracks().forEach((track) => {\n track.addEventListener('mute', update)\n track.addEventListener('unmute', update)\n track.addEventListener('ended', update)\n })\n stream.addEventListener('addtrack', update)\n stream.addEventListener('removetrack', update)\n remoteStreamCleanupRef.current.set(targetUserId, () => {\n stream.getTracks().forEach((track) => {\n track.removeEventListener('mute', update)\n track.removeEventListener('unmute', update)\n track.removeEventListener('ended', update)\n })\n stream.removeEventListener('addtrack', update)\n stream.removeEventListener('removetrack', update)\n })\n if (stream.getVideoTracks().some((track) => track.readyState === 'live' && track.enabled)) {\n clearRenegotiationRetry(targetUserId)\n }\n }\n\n peer.onconnectionstatechange = () => {\n const stream = remoteStreamsRef.current[targetUserId]\n if (stream) {\n updateRemoteTrackState(targetUserId, stream, peer)\n } else {\n setRemoteTrackStates((prev) => ({\n ...prev,\n [targetUserId]: {\n audio: false,\n video: false,\n connectionState: peer.connectionState,\n },\n }))\n }\n\n if (peer.connectionState === 'failed' || peer.connectionState === 'closed') {\n removePeer(targetUserId, true)\n return\n }\n if (peer.connectionState === 'disconnected') {\n clearDisconnectedCleanup(targetUserId)\n const timer = setTimeout(() => {\n const current = peersRef.current.get(targetUserId)\n if (!current) return\n if (current.connectionState === 'disconnected') {\n removePeer(targetUserId, true)\n }\n }, DISCONNECTED_CLEANUP_DELAY_MS)\n disconnectedCleanupTimersRef.current.set(targetUserId, timer)\n return\n }\n clearDisconnectedCleanup(targetUserId)\n }\n\n peersRef.current.set(targetUserId, peer)\n return peer\n },\n [clearDisconnectedCleanup, clearRemoteStreamObservers, clearRenegotiationRetry, removePeer, send, startNetworkAdaptation, updateRemoteTrackState],\n )\n\n const createOffer = useCallback(\n async (targetUserId: string) => {\n const peer = ensurePeer(targetUserId)\n if (peer.signalingState !== 'stable') {\n return\n }\n makingOfferRef.current.set(targetUserId, true)\n try {\n const offer = await peer.createOffer()\n await peer.setLocalDescription(offer)\n send({\n type: 'offer',\n targetUserId,\n payload: offer,\n })\n } finally {\n makingOfferRef.current.set(targetUserId, false)\n }\n },\n [ensurePeer, send],\n )\n\n const scheduleRenegotiationRetry = useCallback(\n (targetUserId: string) => {\n const existingTimer = renegotiationTimersRef.current.get(targetUserId)\n if (existingTimer) {\n clearTimeout(existingTimer)\n }\n\n const timer = setTimeout(async () => {\n const peer = peersRef.current.get(targetUserId)\n if (!peer) {\n clearRenegotiationRetry(targetUserId)\n return\n }\n if (hasRemoteVideoTrack(targetUserId)) {\n clearRenegotiationRetry(targetUserId)\n return\n }\n\n const attempts = renegotiationAttemptsRef.current.get(targetUserId) ?? 0\n if (attempts >= RENEGOTIATION_MAX_RETRIES) {\n clearRenegotiationRetry(targetUserId)\n return\n }\n\n renegotiationAttemptsRef.current.set(targetUserId, attempts + 1)\n await createOffer(targetUserId)\n scheduleRenegotiationRetry(targetUserId)\n }, RENEGOTIATION_RETRY_DELAY_MS)\n\n renegotiationTimersRef.current.set(targetUserId, timer)\n },\n [clearRenegotiationRetry, createOffer, hasRemoteVideoTrack],\n )\n\n const handleSignalMessage = useCallback(\n async (message: SignalMessage) => {\n if (message.userId === userId) return\n\n switch (message.type) {\n case 'welcome':\n localParticipantIdRef.current = message.userId\n break\n case 'chat_history':\n case 'chat_history_page': {\n const payload = (message.payload as {\n items?: Array<Omit<ChatMessage, 'userId'> & { userId?: string; senderUserId?: string }>\n nextCursor?: string\n hasMore?: boolean\n }) ?? {}\n const items = payload.items ?? []\n const normalized = items\n .filter((item) => item.id)\n .map((item) => ({\n id: item.id,\n userId: item.senderUserId ?? item.userId ?? '',\n text: item.text ?? '',\n senderName: item.senderName || 'Гость',\n sentAt: item.sentAt || new Date().toISOString(),\n editedAt: item.editedAt,\n deletedAt: item.deletedAt,\n clientMessageId: item.clientMessageId,\n deliveryStatus: 'sent' as const,\n }))\n prependChatMessages(normalized)\n setChatNextCursor(payload.nextCursor || null)\n setChatHasMore(Boolean(payload.hasMore))\n setChatLoadingHistory(false)\n break\n }\n case 'chat_error': {\n const payload = (message.payload as { code?: string }) ?? {}\n if (payload.code === 'rate_limited') {\n setError('Слишком много сообщений. Подождите немного.')\n }\n break\n }\n case 'chat_typing': {\n const payload = (message.payload as { isTyping?: boolean; senderName?: string; senderUserId?: string }) ?? {}\n const typingUserID = payload.senderUserId || message.userId\n if (!typingUserID || typingUserID === userId) break\n setTypingState(typingUserID, payload.senderName || 'Гость', Boolean(payload.isTyping))\n break\n }\n case 'chat_message_edited': {\n const payload = (message.payload as { id?: string; text?: string; editedAt?: string }) ?? {}\n if (!payload.id) break\n patchChatMessage(payload.id, { text: payload.text ?? '', editedAt: payload.editedAt || new Date().toISOString() })\n break\n }\n case 'chat_message_deleted': {\n const payload = (message.payload as { id?: string; deletedAt?: string }) ?? {}\n if (!payload.id) break\n patchChatMessage(payload.id, { deletedAt: payload.deletedAt || new Date().toISOString() })\n break\n }\n case 'chat_message': {\n const payload = (message.payload as Partial<ChatMessage> & { senderUserId?: string }) ?? {}\n if (!payload.id) break\n const senderID = payload.senderUserId || message.userId\n const normalized: ChatMessage = {\n id: payload.id,\n userId: senderID,\n text: payload.text ?? '',\n senderName: payload.senderName || 'Гость',\n sentAt: payload.sentAt || new Date().toISOString(),\n editedAt: payload.editedAt,\n deletedAt: payload.deletedAt,\n clientMessageId: payload.clientMessageId,\n deliveryStatus: 'sent',\n }\n if (payload.clientMessageId) {\n setChatMessages((prev) =>\n prev.map((item) =>\n item.clientMessageId === payload.clientMessageId\n ? { ...item, id: normalized.id, sentAt: normalized.sentAt, deliveryStatus: 'sent' }\n : item,\n ),\n )\n }\n pushChatMessage(normalized)\n if (senderID !== userId && !isChatFocusedRef.current) {\n setChatUnreadCount((prev) => prev + 1)\n }\n break\n }\n case 'join':\n case 'participant_joined':\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n await createOffer(message.userId)\n scheduleRenegotiationRetry(message.userId)\n break\n case 'participant_left':\n removePeer(message.userId, true)\n break\n case 'offer': {\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n let peer = ensurePeer(message.userId)\n const makingOffer = makingOfferRef.current.get(message.userId) ?? false\n const isSettingRemoteAnswerPending = isSettingRemoteAnswerPendingRef.current.get(message.userId) ?? false\n const polite = politeRef.current.get(message.userId) ?? true\n const offerCollision = makingOffer || (peer.signalingState !== 'stable' && !isSettingRemoteAnswerPending)\n const ignoreOffer = !polite && offerCollision\n ignoreOfferRef.current.set(message.userId, ignoreOffer)\n if (ignoreOffer) {\n return\n }\n if (offerCollision) {\n try {\n await peer.setLocalDescription({ type: 'rollback' })\n } catch {\n removePeer(message.userId)\n peer = ensurePeer(message.userId)\n }\n }\n await peer.setRemoteDescription(new RTCSessionDescription(message.payload as RTCSessionDescriptionInit))\n const answer = await peer.createAnswer()\n await peer.setLocalDescription(answer)\n send({\n type: 'answer',\n targetUserId: message.userId,\n payload: answer,\n })\n break\n }\n case 'answer': {\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n const peer = peersRef.current.get(message.userId)\n if (!peer) return\n if (ignoreOfferRef.current.get(message.userId)) {\n return\n }\n if (peer.signalingState !== 'have-local-offer') {\n return\n }\n isSettingRemoteAnswerPendingRef.current.set(message.userId, true)\n try {\n await peer.setRemoteDescription(new RTCSessionDescription(message.payload as RTCSessionDescriptionInit))\n } finally {\n isSettingRemoteAnswerPendingRef.current.set(message.userId, false)\n }\n scheduleRenegotiationRetry(message.userId)\n break\n }\n case 'ice_candidate': {\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n const peer = ensurePeer(message.userId)\n await peer.addIceCandidate(new RTCIceCandidate(message.payload as RTCIceCandidateInit))\n break\n }\n default:\n break\n }\n },\n [\n createOffer,\n ensurePeer,\n patchChatMessage,\n prependChatMessages,\n pushChatMessage,\n removePeer,\n scheduleRenegotiationRetry,\n send,\n setTypingState,\n userId,\n ],\n )\n\n useEffect(() => {\n handleSignalMessageRef.current = handleSignalMessage\n }, [handleSignalMessage])\n\n useEffect(() => {\n if (!enabled || !roomId || !userId) return\n const peers = peersRef.current\n const currentParams: UseWebRTCCallParams = {\n roomId,\n userId,\n enabled,\n roomToken,\n wsBaseUrl,\n tokenProvider: resolvedTokenProvider ?? undefined,\n apiBaseUrl,\n auth,\n }\n\n const setup = async () => {\n const myGen = ++setupGenerationRef.current\n try {\n const resolvedRoomToken = await resolveRoomToken(currentParams)\n if (myGen !== setupGenerationRef.current) return\n const resolvedWsBaseUrl = resolveWsBaseUrl(currentParams)\n if (!resolvedWsBaseUrl) {\n setError('wsBaseUrl or apiBaseUrl is required')\n return\n }\n\n if (!window.isSecureContext) {\n setError('getUserMedia requires HTTPS (or localhost).')\n return\n }\n if (!navigator.mediaDevices?.getUserMedia) {\n setError('Browser does not support mediaDevices/getUserMedia.')\n return\n }\n\n let acquiredLocalStream: MediaStream\n try {\n acquiredLocalStream = await navigator.mediaDevices.getUserMedia({\n audio: AUDIO_CONSTRAINTS,\n video: VIDEO_CONSTRAINTS,\n })\n } catch (err) {\n if (err instanceof DOMException && ['NotFoundError', 'OverconstrainedError'].includes(err.name)) {\n acquiredLocalStream = await navigator.mediaDevices.getUserMedia({\n audio: AUDIO_CONSTRAINTS,\n video: false,\n })\n setError('Camera is unavailable. Joined in audio-only mode.')\n } else {\n throw err\n }\n }\n if (myGen !== setupGenerationRef.current) return\n await tuneLocalStream(acquiredLocalStream)\n if (myGen !== setupGenerationRef.current) return\n localStreamRef.current = acquiredLocalStream\n setLocalStream(acquiredLocalStream)\n syncLocalTrackFlags()\n\n const wsURL = `${resolvedWsBaseUrl}/v1/ws?roomId=${encodeURIComponent(roomId)}&token=${encodeURIComponent(resolvedRoomToken)}`\n const ws = new WebSocket(wsURL)\n wsRef.current = ws\n\n ws.onopen = () => {\n setConnected(true)\n send({ type: 'join', payload: { joinedAt: new Date().toISOString() } })\n send({ type: 'chat_history_request', payload: { limit: 30 } })\n }\n ws.onclose = () => {\n setConnected(false)\n }\n ws.onerror = () => {\n setError('WebSocket connection error')\n }\n ws.onmessage = (event) => {\n const message = JSON.parse(event.data) as SignalMessage\n void handleSignalMessageRef.current(message)\n }\n } catch (err) {\n const mappedMessage = mapSDKErrorToUIMessage(err)\n if (mappedMessage !== 'Unexpected error while connecting to call server.') {\n setError(mappedMessage)\n return\n }\n if (err instanceof DOMException && err.name === 'NotAllowedError') {\n setError('No camera/microphone access. Please allow permissions in browser settings.')\n return\n }\n setError(err instanceof Error ? err.message : 'Call initialization failed')\n }\n }\n\n void setup()\n\n return () => {\n wsRef.current?.close()\n peers.forEach((_, peerID) => removePeer(peerID))\n peers.clear()\n renegotiationTimersRef.current.forEach((timer) => clearTimeout(timer))\n renegotiationTimersRef.current.clear()\n renegotiationAttemptsRef.current.clear()\n disconnectedCleanupTimersRef.current.forEach((timer) => clearTimeout(timer))\n disconnectedCleanupTimersRef.current.clear()\n remoteStreamCleanupRef.current.forEach((cleanup) => cleanup())\n remoteStreamCleanupRef.current.clear()\n networkStatsTimersRef.current.forEach((timer) => clearInterval(timer))\n networkStatsTimersRef.current.clear()\n qualityLevelRef.current.clear()\n makingOfferRef.current.clear()\n ignoreOfferRef.current.clear()\n isSettingRemoteAnswerPendingRef.current.clear()\n politeRef.current.clear()\n localParticipantIdRef.current = null\n remoteStreamsRef.current = {}\n setChatMessages([])\n setTypingParticipants([])\n setChatUnreadCount(0)\n setChatNextCursor(null)\n setChatHasMore(false)\n setChatLoadingHistory(false)\n pendingChatPatchesRef.current.clear()\n typingTimersRef.current.forEach((timer) => clearTimeout(timer))\n typingTimersRef.current.clear()\n isChatFocusedRef.current = false\n localStreamRef.current?.getTracks().forEach((track) => track.stop())\n localStreamRef.current = null\n previousCameraTrackRef.current?.stop()\n previousCameraTrackRef.current = null\n screenTrackRef.current = null\n syncLocalTrackFlags()\n }\n }, [\n apiBaseUrl,\n auth,\n enabled,\n removePeer,\n resolvedTokenProvider,\n roomId,\n roomToken,\n send,\n syncLocalTrackFlags,\n userId,\n wsBaseUrl,\n ])\n\n useEffect(() => {\n if (!enabled) return\n\n const onPageHide = () => {\n gracefulLeave()\n }\n const onBeforeUnload = () => {\n gracefulLeave()\n }\n\n window.addEventListener('pagehide', onPageHide)\n window.addEventListener('beforeunload', onBeforeUnload)\n\n return () => {\n window.removeEventListener('pagehide', onPageHide)\n window.removeEventListener('beforeunload', onBeforeUnload)\n }\n }, [enabled, gracefulLeave])\n\n const toggleMic = useCallback(() => {\n const stream = localStreamRef.current\n if (!stream) return\n const audioTracks = stream.getAudioTracks()\n if (audioTracks.length === 0) return\n const nextEnabled = !micEnabled\n audioTracks.forEach((track) => {\n track.enabled = nextEnabled\n })\n setMicEnabled(nextEnabled)\n }, [micEnabled])\n\n const toggleCamera = useCallback(() => {\n const stream = localStreamRef.current\n if (!stream) return\n const videoTracks = stream.getVideoTracks()\n if (videoTracks.length === 0) return\n const nextEnabled = !cameraEnabled\n videoTracks.forEach((track) => {\n track.enabled = nextEnabled\n })\n setCameraEnabled(nextEnabled)\n }, [cameraEnabled])\n\n const syncVideoTrackToPeers = useCallback(\n async (nextVideoTrack: MediaStreamTrack | null, options?: { forceRenegotiation?: boolean }) => {\n const renegotiationTargets = new Set<string>()\n const replaceTasks: Array<Promise<void>> = []\n const forceRenegotiation = Boolean(options?.forceRenegotiation)\n\n peersRef.current.forEach((peer, targetUserId) => {\n if (forceRenegotiation) {\n renegotiationTargets.add(targetUserId)\n }\n\n const videoTransceiver = peer.getTransceivers().find(isVideoTransceiver)\n if (videoTransceiver) {\n const currentDirection = videoTransceiver.direction\n if (nextVideoTrack) {\n if (currentDirection === 'recvonly') {\n videoTransceiver.direction = 'sendrecv'\n renegotiationTargets.add(targetUserId)\n } else if (currentDirection === 'inactive') {\n videoTransceiver.direction = 'sendonly'\n renegotiationTargets.add(targetUserId)\n }\n } else {\n if (currentDirection === 'sendrecv') {\n videoTransceiver.direction = 'recvonly'\n renegotiationTargets.add(targetUserId)\n } else if (currentDirection === 'sendonly') {\n videoTransceiver.direction = 'inactive'\n renegotiationTargets.add(targetUserId)\n }\n }\n\n replaceTasks.push(\n Promise.resolve(videoTransceiver.sender.replaceTrack(nextVideoTrack)).catch(() => {\n renegotiationTargets.add(targetUserId)\n }),\n )\n return\n }\n\n const videoSender = peer.getSenders().find((sender) => sender.track?.kind === 'video')\n if (videoSender) {\n replaceTasks.push(\n Promise.resolve(videoSender.replaceTrack(nextVideoTrack)).catch(() => {\n renegotiationTargets.add(targetUserId)\n }),\n )\n return\n }\n\n if (nextVideoTrack && localStreamRef.current) {\n peer.addTrack(nextVideoTrack, localStreamRef.current)\n renegotiationTargets.add(targetUserId)\n }\n })\n\n await Promise.all(replaceTasks)\n\n for (const targetUserId of renegotiationTargets) {\n await createOffer(targetUserId)\n scheduleRenegotiationRetry(targetUserId)\n }\n },\n [createOffer, scheduleRenegotiationRetry],\n )\n\n const stopScreenShare = useCallback(async () => {\n const stream = localStreamRef.current\n const activeScreenTrack = screenTrackRef.current\n if (!stream || !activeScreenTrack) {\n setScreenSharing(false)\n return\n }\n\n activeScreenTrack.onended = null\n stream.getVideoTracks().forEach((track) => {\n if (track === activeScreenTrack) {\n stream.removeTrack(track)\n }\n })\n activeScreenTrack.stop()\n screenTrackRef.current = null\n\n let cameraTrack = previousCameraTrackRef.current\n if (!cameraTrack || cameraTrack.readyState !== 'live') {\n cameraTrack = null\n try {\n const cameraStream = await navigator.mediaDevices.getUserMedia({ audio: false, video: VIDEO_CONSTRAINTS })\n cameraTrack = cameraStream.getVideoTracks()[0] ?? null\n cameraStream.getTracks().forEach((track) => {\n if (track !== cameraTrack) track.stop()\n })\n } catch {\n cameraTrack = null\n }\n }\n\n if (cameraTrack) {\n stream.addTrack(cameraTrack)\n }\n\n await syncVideoTrackToPeers(cameraTrack ?? null, { forceRenegotiation: true })\n\n previousCameraTrackRef.current = cameraTrack\n setScreenSharing(false)\n setLocalStream(new MediaStream(stream.getTracks()))\n syncLocalTrackFlags()\n }, [syncLocalTrackFlags, syncVideoTrackToPeers])\n\n const toggleScreenShare = useCallback(async () => {\n const stream = localStreamRef.current\n if (!stream) return\n if (screenSharing) {\n stopScreenShare()\n return\n }\n try {\n const screenStream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: false,\n })\n const screenTrack = screenStream.getVideoTracks()[0]\n if (!screenTrack) return\n screenTrackRef.current = screenTrack\n screenTrack.onended = () => stopScreenShare()\n const oldVideoTrack = stream.getVideoTracks().find((track) => track !== screenTrack)\n if (oldVideoTrack) {\n previousCameraTrackRef.current = oldVideoTrack\n stream.removeTrack(oldVideoTrack)\n } else {\n previousCameraTrackRef.current = null\n }\n stream.addTrack(screenTrack)\n setScreenSharing(true)\n setLocalStream(new MediaStream(stream.getTracks()))\n syncLocalTrackFlags()\n await syncVideoTrackToPeers(screenTrack, { forceRenegotiation: true })\n screenStream.getTracks().filter((t) => t !== screenTrack).forEach((t) => t.stop())\n } catch {\n setScreenSharing(false)\n screenTrackRef.current = null\n }\n }, [screenSharing, stopScreenShare, syncLocalTrackFlags, syncVideoTrackToPeers])\n\n const sendChatMessage = useCallback(\n (text: string, senderName = 'Гость') => {\n const normalizedText = text.trim()\n if (!normalizedText) return\n const clientMessageId = crypto.randomUUID()\n pushChatMessage({\n id: `local-${clientMessageId}`,\n userId,\n text: normalizedText,\n senderName: senderName.trim() || 'Гость',\n sentAt: new Date().toISOString(),\n clientMessageId,\n deliveryStatus: 'sending',\n })\n send({\n type: 'chat_message',\n payload: {\n text: normalizedText,\n senderName: senderName.trim() || 'Гость',\n clientMessageId,\n },\n })\n },\n [pushChatMessage, send, userId],\n )\n\n const editChatMessage = useCallback(\n (id: string, text: string) => {\n const normalized = text.trim()\n if (!id || !normalized) return\n patchChatMessage(id, { text: normalized, editedAt: new Date().toISOString() })\n send({ type: 'chat_message_edited', payload: { id, text: normalized } })\n },\n [patchChatMessage, send],\n )\n\n const deleteChatMessage = useCallback(\n (id: string) => {\n if (!id) return\n patchChatMessage(id, { deletedAt: new Date().toISOString() })\n send({ type: 'chat_message_deleted', payload: { id } })\n },\n [patchChatMessage, send],\n )\n\n const sendTyping = useCallback(\n (isTyping: boolean, senderName = 'Гость') => {\n send({\n type: 'chat_typing',\n payload: {\n isTyping,\n senderName: senderName.trim() || 'Гость',\n },\n })\n },\n [send],\n )\n\n const markChatRead = useCallback(() => {\n isChatFocusedRef.current = true\n setChatUnreadCount(0)\n }, [])\n\n const setChatFocused = useCallback((focused: boolean) => {\n isChatFocusedRef.current = focused\n if (focused) {\n setChatUnreadCount(0)\n }\n }, [])\n\n const loadMoreChatMessages = useCallback(() => {\n if (!chatHasMore || chatLoadingHistory) return\n setChatLoadingHistory(true)\n send({\n type: 'chat_history_request',\n payload: {\n cursor: chatNextCursor,\n limit: 30,\n },\n })\n }, [chatHasMore, chatLoadingHistory, chatNextCursor, send])\n\n return {\n localStream,\n remoteStreams,\n participants,\n remoteTrackStates,\n chatMessages,\n typingParticipants,\n chatUnreadCount,\n chatHasMore,\n chatLoadingHistory,\n connected,\n error,\n micEnabled,\n cameraEnabled,\n hasMicTrack,\n hasCameraTrack,\n toggleMic,\n toggleCamera,\n screenSharing,\n toggleScreenShare,\n sendChatMessage,\n editChatMessage,\n deleteChatMessage,\n sendTyping,\n loadMoreChatMessages,\n markChatRead,\n setChatFocused,\n }\n}\n","export type ServerAuthConfig = {\n authToken: string\n clientId?: string\n appId: string\n authHeader?: string\n clientIdHeader?: string\n appIdHeader?: string\n}\n\nexport function buildAuthHeaders(auth: ServerAuthConfig): Record<string, string> {\n const headers: Record<string, string> = {\n [auth.appIdHeader ?? 'X-App-Id']: auth.appId,\n [auth.authHeader ?? 'Authorization']: `Bearer ${auth.authToken}`,\n }\n if (auth.clientId) {\n headers[auth.clientIdHeader ?? 'X-Client-Id'] = auth.clientId\n }\n return headers\n}\n","export type SDKErrorCode =\n | 'invalid_app'\n | 'invalid_client'\n | 'expired_token'\n | 'unauthorized'\n | 'forbidden'\n | 'rate_limited'\n | 'network_error'\n | 'unknown_error'\n\nexport class SDKError extends Error {\n code: SDKErrorCode\n status?: number\n\n constructor(code: SDKErrorCode, message: string, status?: number) {\n super(message)\n this.code = code\n this.status = status\n this.name = 'SDKError'\n }\n}\n\nexport function mapSDKErrorToUIMessage(err: unknown): string {\n if (!(err instanceof SDKError)) {\n return 'Unexpected error while connecting to call server.'\n }\n\n switch (err.code) {\n case 'invalid_app':\n return 'Application is not allowed to use this video service.'\n case 'invalid_client':\n return 'Client is not recognized by video service.'\n case 'expired_token':\n return 'Authorization token is expired. Please sign in again.'\n case 'unauthorized':\n return 'Authorization failed. Please check your credentials.'\n case 'forbidden':\n return 'Access is forbidden for this application/client.'\n case 'rate_limited':\n return 'Organization rate limit exceeded. Please retry later.'\n case 'network_error':\n return 'Network error while connecting to video service.'\n default:\n return err.message || 'Unknown video service error.'\n }\n}\n","import { buildAuthHeaders, type ServerAuthConfig } from './auth'\nimport { SDKError } from './sdkErrors'\n\nexport type TokenProviderContext = {\n roomId: string\n userId: string\n}\n\nexport type TokenProvider = (ctx: TokenProviderContext) => Promise<string>\n\nexport type ServerTokenProviderOptions = {\n apiBaseUrl?: string\n auth: ServerAuthConfig\n externalUserRegisterPath?: string\n joinPathBuilder?: (roomId: string) => string\n tokenPathBuilder?: (roomId: string) => string\n}\n\ntype ServerErrorPayload = {\n error?: string\n message?: string\n}\n\nfunction mapServerError(status: number, serverMessage: string): SDKError {\n const message = serverMessage.toLowerCase()\n if (status === 403 && message.includes('app id')) {\n return new SDKError('invalid_app', 'invalid_app', status)\n }\n if (status === 403 && message.includes('auth token')) {\n return new SDKError('unauthorized', 'invalid_auth_token', status)\n }\n if (status === 403 && message.includes('client id')) {\n return new SDKError('invalid_client', 'invalid_client', status)\n }\n if (status === 401 && message.includes('expired token')) {\n return new SDKError('expired_token', 'expired_token', status)\n }\n if (status === 401) {\n return new SDKError('unauthorized', 'unauthorized', status)\n }\n if (status === 403) {\n return new SDKError('forbidden', 'forbidden', status)\n }\n if (status === 429) {\n return new SDKError('rate_limited', 'rate_limited', status)\n }\n return new SDKError('unknown_error', serverMessage || 'unknown_error', status)\n}\n\nasync function fetchJson<T>(input: RequestInfo | URL, init: RequestInit): Promise<T> {\n let response: Response\n try {\n response = await fetch(input, init)\n } catch {\n throw new SDKError('network_error', 'network_error')\n }\n if (!response.ok) {\n let serverMessage = response.statusText\n try {\n const payload = (await response.json()) as ServerErrorPayload\n serverMessage = payload.error || payload.message || serverMessage\n } catch {\n const text = await response.text()\n if (text) serverMessage = text\n }\n throw mapServerError(response.status, serverMessage)\n }\n return response.json() as Promise<T>\n}\n\nexport function defaultWsBaseUrlFromApi(apiBaseUrl: string): string {\n const normalized = apiBaseUrl.replace(/\\/+$/, '')\n if (normalized.startsWith('https://')) {\n return normalized.replace(/^https:\\/\\//, 'wss://')\n }\n if (normalized.startsWith('http://')) {\n return normalized.replace(/^http:\\/\\//, 'ws://')\n }\n return normalized\n}\n\nexport function defaultApiBaseUrl(): string {\n if (typeof window !== 'undefined' && window.location?.origin) {\n return window.location.origin\n }\n return ''\n}\n\nexport function createServerTokenProvider(options: ServerTokenProviderOptions): TokenProvider {\n const externalUserRegisterPath = options.externalUserRegisterPath ?? '/v1/external-users/register'\n const joinPathBuilder = options.joinPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/join`)\n const tokenPathBuilder = options.tokenPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/token`)\n const externalUserMap = new Map<string, string>()\n\n return async ({ roomId, userId }) => {\n const base = (options.apiBaseUrl || defaultApiBaseUrl()).replace(/\\/+$/, '')\n if (!base) {\n throw new SDKError('unknown_error', 'api_base_url_required')\n }\n const headers = {\n 'Content-Type': 'application/json',\n ...buildAuthHeaders(options.auth),\n }\n\n let internalUserID = externalUserMap.get(userId)\n if (!internalUserID) {\n const registration = await fetchJson<{ userId: string }>(`${base}${externalUserRegisterPath}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n externalId: userId,\n }),\n })\n if (!registration.userId) {\n throw new SDKError('unknown_error', 'external_user_registration_failed')\n }\n internalUserID = registration.userId\n externalUserMap.set(userId, internalUserID)\n }\n const roomHeaders = {\n ...headers,\n 'X-Guest-Id': internalUserID,\n }\n\n await fetchJson<{ ok?: boolean }>(`${base}${joinPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n body: '{}',\n })\n\n const tokenResponse = await fetchJson<{ token: string }>(`${base}${tokenPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n })\n\n if (!tokenResponse.token) {\n throw new Error('Room token is empty')\n }\n return tokenResponse.token\n }\n}\n","import type { ServerAuthConfig } from './auth'\n\nexport type VideoSDKConfig = {\n apiBaseUrl?: string\n wsBaseUrl?: string\n auth?: ServerAuthConfig\n}\n\nconst DEFAULT_API_BASE_URL = 'https://api.streemo.ru'\nconst DEFAULT_WS_BASE_URL = 'wss://api.streemo.ru'\n\nlet globalConfig: VideoSDKConfig = {\n apiBaseUrl: DEFAULT_API_BASE_URL,\n wsBaseUrl: DEFAULT_WS_BASE_URL,\n}\n\nexport function initVideoSDK(config: VideoSDKConfig): void {\n globalConfig = {\n ...globalConfig,\n ...config,\n auth: config.auth ? { ...(globalConfig.auth ?? {}), ...config.auth } : globalConfig.auth,\n }\n}\n\nexport function getVideoSDKConfig(): VideoSDKConfig {\n return globalConfig\n}\n\n","import { useMemo } from 'react'\r\nimport { useCall, type UseCallParams } from './useCall'\r\n\r\nexport function useParticipants(params: UseCallParams) {\r\n const call = useCall(params)\r\n\r\n return useMemo(\r\n () => ({\r\n participants: call.participants.map((userId) => ({\r\n userId,\r\n stream: call.remoteStreams[userId],\r\n trackState: call.remoteTrackStates[userId],\r\n })),\r\n localStream: call.localStream,\r\n joined: call.joined,\r\n joinCall: call.joinCall,\r\n leaveCall: call.leaveCall,\r\n }),\r\n [call],\r\n )\r\n}\r\n","import { useCallback, useEffect, useState } from 'react'\nimport { useStreemoContext } from '../provider/StreemoProvider'\nimport { getVideoSDKConfig } from '../sdkConfig'\n\nexport type StreemoEntitlements = {\n operations: {\n createRoom: boolean\n chatWrite: boolean\n }\n}\n\ntype UseEntitlementsResult = {\n entitlements: StreemoEntitlements | null\n loading: boolean\n error: string | null\n refresh: () => Promise<StreemoEntitlements | null>\n}\n\nconst EMPTY_ENTITLEMENTS: StreemoEntitlements = {\n operations: {\n createRoom: false,\n chatWrite: false,\n },\n}\n\nexport function useEntitlements(enabled = true): UseEntitlementsResult {\n const { client } = useStreemoContext()\n const [entitlements, setEntitlements] = useState<StreemoEntitlements | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const refresh = useCallback(async () => {\n if (!enabled) {\n setEntitlements(null)\n setError(null)\n return null\n }\n\n setLoading(true)\n setError(null)\n try {\n const sdkConfig = getVideoSDKConfig()\n const response = await fetch(`${client.baseUrl}/v1/me/entitlements`, {\n headers: {\n Authorization: `Bearer ${client.userToken}`,\n 'X-App-Id': client.apiKey,\n ...(sdkConfig.auth?.authToken ? { 'X-Org-Auth-Token': sdkConfig.auth.authToken } : {}),\n 'Content-Type': 'application/json',\n },\n })\n const payload = (await response.json().catch(() => ({}))) as Partial<StreemoEntitlements> & { error?: string }\n if (!response.ok) {\n throw new Error(payload.error ?? `HTTP ${response.status}`)\n }\n\n const normalized: StreemoEntitlements = {\n operations: {\n createRoom: Boolean(payload.operations?.createRoom),\n chatWrite: Boolean(payload.operations?.chatWrite),\n },\n }\n setEntitlements(normalized)\n return normalized\n } catch (requestError) {\n const nextError = requestError instanceof Error ? requestError.message : 'Failed to fetch entitlements'\n setError(nextError)\n setEntitlements(EMPTY_ENTITLEMENTS)\n return EMPTY_ENTITLEMENTS\n } finally {\n setLoading(false)\n }\n }, [client.apiKey, client.baseUrl, client.userToken, enabled])\n\n useEffect(() => {\n void refresh()\n }, [refresh])\n\n return { entitlements, loading, error, refresh }\n}\n","import type { PropsWithChildren } from 'react'\r\n\r\nexport function Chat({ children }: PropsWithChildren) {\r\n return <section className=\"st-chat\">{children}</section>\r\n}\r\n","import type { StreemoChannel } from '../../types/models'\r\n\r\nexport type ChannelPreviewProps = {\r\n channel: StreemoChannel\r\n active?: boolean\r\n onSelect?: (channelId: string) => void\r\n}\r\n\r\nexport function ChannelPreview({ channel, active, onSelect }: ChannelPreviewProps) {\r\n return (\r\n <button className={`st-channel-preview ${active ? 'is-active' : ''}`} onClick={() => onSelect?.(channel.id)}>\r\n <span className=\"st-channel-preview__name\">{channel.name}</span>\r\n {channel.unreadCount ? <span className=\"st-channel-preview__unread\">{channel.unreadCount}</span> : null}\r\n </button>\r\n )\r\n}\r\n","import { Spinner } from 'streemo-ui-kit-web'\r\n\r\nexport type LoadingSpinnerProps = {\r\n label?: string\r\n}\r\n\r\nexport function LoadingSpinner({ label = 'Loading...' }: LoadingSpinnerProps) {\r\n return (\r\n <div className=\"st-spinner\" role=\"status\" aria-live=\"polite\">\r\n <Spinner size={20} />\r\n {label != null && <span>{label}</span>}\r\n </div>\r\n )\r\n}\r\n","import { useChat } from '../../hooks/useChat'\r\nimport { ChannelPreview } from './ChannelPreview'\r\nimport { LoadingSpinner } from '../ui/LoadingSpinner'\r\n\r\nexport function ChannelList() {\r\n const { channels, loading, error, activeChannelId, setActiveChannelId } = useChat()\r\n\r\n if (loading) return <LoadingSpinner label=\"Loading channels...\" />\r\n if (error) return <p className=\"st-error\">{error}</p>\r\n\r\n return (\r\n <aside className=\"st-channel-list\">\r\n {channels.map((channel) => (\r\n <ChannelPreview\r\n key={channel.id}\r\n channel={channel}\r\n active={activeChannelId === channel.id}\r\n onSelect={setActiveChannelId}\r\n />\r\n ))}\r\n </aside>\r\n )\r\n}\r\n","import type { PropsWithChildren } from 'react'\r\nimport { useChannel } from '../../hooks/useChannel'\r\n\r\nexport type ChannelProps = PropsWithChildren<{\r\n channelId?: string\r\n}>\r\n\r\nexport function Channel({ channelId, children }: ChannelProps) {\r\n const { channelId: resolved } = useChannel(channelId)\r\n if (!resolved) {\r\n return <section className=\"st-channel st-empty\">Select a channel</section>\r\n }\r\n return <section className=\"st-channel\">{children}</section>\r\n}\r\n","import { useMemo, useState } from 'react'\r\nimport { useChannel } from '../../hooks/useChannel'\r\nimport type { StreemoMessage } from '../../types/models'\r\nimport { Message } from './Message'\r\nimport { LoadingSpinner } from '../ui/LoadingSpinner'\r\nimport { Thread } from './Thread'\r\n\r\nexport type MessageListProps = {\r\n channelId?: string\r\n}\r\n\r\nexport function MessageList({ channelId }: MessageListProps) {\r\n const { channelId: resolvedChannelId, messages, loading, hasMore, loadingMore, loadMore } = useChannel(channelId)\r\n const [threadParent, setThreadParent] = useState<StreemoMessage | null>(null)\r\n const threadMessages = useMemo(\r\n () => messages.filter((message) => message.parentId === threadParent?.id),\r\n [messages, threadParent?.id],\r\n )\r\n\r\n if (!resolvedChannelId) return null\r\n if (loading) return <LoadingSpinner label=\"Loading messages...\" />\r\n\r\n return (\r\n <section className=\"st-message-list\">\r\n {hasMore && (\r\n <button onClick={() => void loadMore()} disabled={loadingMore}>\r\n {loadingMore ? 'Loading...' : 'Load more'}\r\n </button>\r\n )}\r\n {messages\r\n .filter((item) => !item.parentId)\r\n .map((message) => (\r\n <Message key={message.id} message={message} onThread={setThreadParent} />\r\n ))}\r\n {threadParent && (\r\n <Thread parent={threadParent} messages={threadMessages} onClose={() => setThreadParent(null)} />\r\n )}\r\n </section>\r\n )\r\n}\r\n","import type { StreemoAttachment } from '../../types/models'\r\n\r\nexport type AttachmentPreviewProps = {\r\n attachment: StreemoAttachment\r\n}\r\n\r\nexport function AttachmentPreview({ attachment }: AttachmentPreviewProps) {\r\n if (attachment.type === 'image') {\r\n return <img className=\"st-attachment st-attachment--image\" src={attachment.url} alt={attachment.name ?? 'attachment'} />\r\n }\r\n return (\r\n <a className=\"st-attachment st-attachment--file\" href={attachment.url} target=\"_blank\" rel=\"noreferrer\">\r\n {attachment.name ?? attachment.url}\r\n </a>\r\n )\r\n}\r\n","const DEFAULT_REACTIONS = ['👍', '❤️', '😂', '🎉', '🔥']\r\n\r\nexport type ReactionPickerProps = {\r\n onPick: (reaction: string) => void\r\n}\r\n\r\nexport function ReactionPicker({ onPick }: ReactionPickerProps) {\r\n return (\r\n <div className=\"st-reaction-picker\" role=\"toolbar\" aria-label=\"Reactions\">\r\n {DEFAULT_REACTIONS.map((reaction) => (\r\n <button key={reaction} onClick={() => onPick(reaction)} aria-label={`Add reaction ${reaction}`}>\r\n {reaction}\r\n </button>\r\n ))}\r\n </div>\r\n )\r\n}\r\n","import type { StreemoMessage } from '../../types/models'\r\nimport { AttachmentPreview } from './AttachmentPreview'\r\nimport { ReactionPicker } from './ReactionPicker'\r\n\r\nexport type MessageProps = {\r\n message: StreemoMessage\r\n isOwn?: boolean\r\n onThread?: (message: StreemoMessage) => void\r\n}\r\n\r\nexport function Message({ message, isOwn, onThread }: MessageProps) {\r\n return (\r\n <article className={`st-message ${isOwn ? 'is-own' : ''}`}>\r\n <header className=\"st-message__meta\">\r\n <span>{message.userId}</span>\r\n <time>{new Date(message.createdAt).toLocaleTimeString()}</time>\r\n {message.deliveryStatus && <small>{message.deliveryStatus}</small>}\r\n </header>\r\n <p>{message.text}</p>\r\n {!!message.attachments?.length && (\r\n <div className=\"st-message__attachments\">\r\n {message.attachments.map((attachment) => (\r\n <AttachmentPreview key={attachment.id} attachment={attachment} />\r\n ))}\r\n </div>\r\n )}\r\n <div className=\"st-message__actions\">\r\n <button onClick={() => onThread?.(message)}>Thread</button>\r\n <ReactionPicker onPick={() => undefined} />\r\n </div>\r\n </article>\r\n )\r\n}\r\n","import type { StreemoMessage } from '../../types/models'\r\nimport { Message } from './Message'\r\n\r\nexport type ThreadProps = {\r\n parent: StreemoMessage\r\n messages: StreemoMessage[]\r\n onClose: () => void\r\n}\r\n\r\nexport function Thread({ parent, messages, onClose }: ThreadProps) {\r\n return (\r\n <aside className=\"st-thread\">\r\n <header className=\"st-thread__header\">\r\n <strong>Thread</strong>\r\n <button onClick={onClose}>Close</button>\r\n </header>\r\n <Message message={parent} />\r\n {messages.map((item) => (\r\n <Message key={item.id} message={item} />\r\n ))}\r\n </aside>\r\n )\r\n}\r\n","import { useState } from 'react'\r\nimport { useChannel } from '../../hooks/useChannel'\r\n\r\nexport type MessageInputProps = {\r\n channelId?: string\r\n parentId?: string\r\n placeholder?: string\r\n}\r\n\r\nexport function MessageInput({ channelId, parentId, placeholder = 'Write a message...' }: MessageInputProps) {\r\n const { sendMessage, sendTyping } = useChannel(channelId)\r\n const [value, setValue] = useState('')\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n const submit = async () => {\r\n const text = value.trim()\r\n if (!text) return\r\n setError(null)\r\n try {\r\n await sendMessage(text, { parentId })\r\n setValue('')\r\n await sendTyping(false)\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Message send failed')\r\n }\r\n }\r\n\r\n return (\r\n <div className=\"st-message-input\">\r\n <input\r\n value={value}\r\n placeholder={placeholder}\r\n onChange={(event) => {\r\n setValue(event.target.value)\r\n void sendTyping(true)\r\n }}\r\n onBlur={() => void sendTyping(false)}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n event.preventDefault()\r\n void submit()\r\n }\r\n }}\r\n />\r\n <button onClick={() => void submit()} disabled={!value.trim()}>\r\n Send\r\n </button>\r\n {error ? <small className=\"st-error\">{error}</small> : null}\r\n </div>\r\n )\r\n}\r\n","import { useChannel } from '../../hooks/useChannel'\r\n\r\nexport type TypingIndicatorProps = {\r\n channelId?: string\r\n}\r\n\r\nexport function TypingIndicator({ channelId }: TypingIndicatorProps) {\r\n const { typingUsers } = useChannel(channelId)\r\n if (!typingUsers.length) return null\r\n const text =\r\n typingUsers.length === 1\r\n ? `${typingUsers[0].userId} is typing...`\r\n : `${typingUsers[0].userId} and ${typingUsers.length - 1} others are typing...`\r\n return <p className=\"st-typing-indicator\">{text}</p>\r\n}\r\n","import { createContext, useContext, type PropsWithChildren } from 'react'\r\nimport { useCall } from '../../hooks/useCall'\r\n\r\ntype CallRoomContextValue = ReturnType<typeof useCall>\r\n\r\nconst CallRoomContext = createContext<CallRoomContextValue | null>(null)\r\n\r\nexport type CallRoomProps = PropsWithChildren<{\r\n roomId: string\r\n autoJoin?: boolean\r\n}>\r\n\r\nexport function CallRoom({ roomId, autoJoin = true, children }: CallRoomProps) {\r\n const value = useCall({ roomId, enabled: autoJoin })\r\n return <CallRoomContext.Provider value={value}>{children}</CallRoomContext.Provider>\r\n}\r\n\r\nexport function useCallRoomContext(): CallRoomContextValue {\r\n const value = useContext(CallRoomContext)\r\n if (!value) throw new Error('Call components must be used within <CallRoom>')\r\n return value\r\n}\r\n","import { useEffect, useMemo, useRef, useState } from 'react'\n\ntype Props = {\n stream: MediaStream | null\n muted?: boolean\n mirrored?: boolean\n label: string\n subtitle?: string\n i18n?: {\n resumePlayback?: string\n audioOnlyMuted?: string\n audioOnlyConnected?: string\n }\n}\n\nexport function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, i18n }: Props) {\n const ref = useRef<HTMLVideoElement | null>(null)\n const [hasVideoTrack, setHasVideoTrack] = useState(false)\n const [needsInteraction, setNeedsInteraction] = useState(false)\n\n const texts = {\n resumePlayback: i18n?.resumePlayback ?? 'Enable video/audio',\n audioOnlyMuted: i18n?.audioOnlyMuted ?? 'Microphone only',\n audioOnlyConnected: i18n?.audioOnlyConnected ?? 'Audio connected',\n }\n\n const initials = useMemo(() => {\n const parts = label\n .replace(/\\(.*\\)/g, '')\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n if (parts.length === 0) return 'U'\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase()\n return `${parts[0][0] ?? ''}${parts[1][0] ?? ''}`.toUpperCase()\n }, [label])\n\n useEffect(() => {\n if (!ref.current) return\n ref.current.srcObject = stream\n ref.current.muted = muted\n void ref.current.play()\n .then(() => setNeedsInteraction(false))\n .catch(() => setNeedsInteraction(true))\n }, [stream, muted])\n\n useEffect(() => {\n if (!stream) {\n setHasVideoTrack(false)\n return\n }\n\n const trackCleanups = new Map<MediaStreamTrack, () => void>()\n\n const evaluateHasVideo = () => {\n const hasVideo = stream\n .getVideoTracks()\n .some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n setHasVideoTrack(hasVideo)\n }\n\n const bindTrack = (track: MediaStreamTrack) => {\n const update = () => evaluateHasVideo()\n track.addEventListener('mute', update)\n track.addEventListener('unmute', update)\n track.addEventListener('ended', update)\n trackCleanups.set(track, () => {\n track.removeEventListener('mute', update)\n track.removeEventListener('unmute', update)\n track.removeEventListener('ended', update)\n })\n }\n\n const unbindTrack = (track: MediaStreamTrack) => {\n const cleanup = trackCleanups.get(track)\n if (cleanup) {\n cleanup()\n trackCleanups.delete(track)\n }\n }\n\n stream.getVideoTracks().forEach((track) => bindTrack(track))\n\n const onAddTrack = (event: MediaStreamTrackEvent) => {\n if (event.track.kind === 'video') {\n bindTrack(event.track)\n }\n evaluateHasVideo()\n }\n\n const onRemoveTrack = (event: MediaStreamTrackEvent) => {\n if (event.track.kind === 'video') {\n unbindTrack(event.track)\n }\n evaluateHasVideo()\n }\n\n evaluateHasVideo()\n\n stream.addEventListener('addtrack', onAddTrack)\n stream.addEventListener('removetrack', onRemoveTrack)\n\n return () => {\n stream.removeEventListener('addtrack', onAddTrack)\n stream.removeEventListener('removetrack', onRemoveTrack)\n trackCleanups.forEach((cleanup) => cleanup())\n trackCleanups.clear()\n }\n }, [stream])\n\n const handleResumePlayback = async () => {\n if (!ref.current) return\n try {\n ref.current.muted = muted\n await ref.current.play()\n setNeedsInteraction(false)\n } catch {\n setNeedsInteraction(true)\n }\n }\n\n return (\n <div className={`vc-video-tile ${hasVideoTrack ? '' : 'audio-only'}`}>\n <video\n ref={ref}\n autoPlay\n playsInline\n muted={muted}\n className={mirrored ? 'vc-video-mirrored' : ''}\n style={{ display: hasVideoTrack ? 'block' : 'none' }}\n />\n {needsInteraction && (\n <button className=\"vc-video-play-button\" onClick={handleResumePlayback}>\n {texts.resumePlayback}\n </button>\n )}\n {!hasVideoTrack && (\n <div className=\"vc-video-placeholder\">\n <div className=\"vc-avatar-circle\">{initials}</div>\n <span className=\"vc-muted\">{muted ? texts.audioOnlyMuted : texts.audioOnlyConnected}</span>\n </div>\n )}\n <p>{label}</p>\n {subtitle && <p className=\"vc-video-subtitle\">{subtitle}</p>}\n </div>\n )\n}\n","import { VideoTile } from '../../VideoTile'\r\n\r\nexport type ParticipantTileProps = {\r\n userId: string\r\n stream?: MediaStream\r\n subtitle?: string\r\n}\r\n\r\nexport function ParticipantTile({ userId, stream, subtitle }: ParticipantTileProps) {\r\n return <VideoTile stream={stream ?? null} label={userId} subtitle={subtitle} />\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\nimport { ParticipantTile } from './ParticipantTile'\r\nimport { VideoTile } from '../../VideoTile'\r\n\r\nexport function ParticipantGrid() {\r\n const call = useCallRoomContext()\r\n return (\r\n <section className=\"st-participant-grid\">\r\n <VideoTile stream={call.localStream} label=\"You\" muted mirrored />\r\n {call.participants.map((userId) => (\r\n <ParticipantTile\r\n key={userId}\r\n userId={userId}\r\n stream={call.remoteStreams[userId]}\r\n subtitle={call.remoteTrackStates[userId]?.connectionState}\r\n />\r\n ))}\r\n </section>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function CameraToggle() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.toggleCamera} disabled={!call.hasCameraTrack}>\r\n {call.cameraEnabled ? 'Camera off' : 'Camera on'}\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function JoinCallButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.joinCall} disabled={call.joined}>\r\n Join call\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function LeaveCallButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.leaveCall} disabled={!call.joined}>\r\n Leave call\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function MuteButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.toggleMic} disabled={!call.hasMicTrack}>\r\n {call.micEnabled ? 'Mute' : 'Unmute'}\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function ScreenShareButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={() => void call.toggleScreenShare()}>\r\n {call.screenSharing ? 'Stop share' : 'Share screen'}\r\n </button>\r\n )\r\n}\r\n","import { CameraToggle } from './CameraToggle'\r\nimport { JoinCallButton } from './JoinCallButton'\r\nimport { LeaveCallButton } from './LeaveCallButton'\r\nimport { MuteButton } from './MuteButton'\r\nimport { ScreenShareButton } from './ScreenShareButton'\r\n\r\nexport function CallControls() {\r\n return (\r\n <div className=\"st-call-controls\">\r\n <JoinCallButton />\r\n <LeaveCallButton />\r\n <MuteButton />\r\n <CameraToggle />\r\n <ScreenShareButton />\r\n </div>\r\n )\r\n}\r\n","import { Avatar as StreemoAvatar } from 'streemo-ui-kit-web'\r\n\r\nexport type AvatarProps = {\r\n name: string\r\n image?: string\r\n size?: number\r\n}\r\n\r\nexport function Avatar({ name, image, size = 32 }: AvatarProps) {\r\n return <StreemoAvatar name={name} src={image ?? undefined} size={size} />\r\n}\r\n","export type PresenceBadgeProps = {\r\n status: 'online' | 'offline' | 'away'\r\n}\r\n\r\nexport function PresenceBadge({ status }: PresenceBadgeProps) {\r\n return <span className={`st-presence st-presence--${status}`} aria-label={status} />\r\n}\r\n","import { PresenceBadge } from './PresenceBadge'\r\n\r\nexport type UserStatusProps = {\r\n name: string\r\n status: 'online' | 'offline' | 'away'\r\n}\r\n\r\nexport function UserStatus({ name, status }: UserStatusProps) {\r\n return (\r\n <div className=\"st-user-status\">\r\n <PresenceBadge status={status} />\r\n <span>{name}</span>\r\n </div>\r\n )\r\n}\r\n","import { Component, type ErrorInfo, type ReactNode } from 'react'\r\n\r\ntype ErrorBoundaryProps = {\r\n children: ReactNode\r\n fallback?: ReactNode\r\n}\r\n\r\ntype ErrorBoundaryState = {\r\n hasError: boolean\r\n}\r\n\r\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\r\n state: ErrorBoundaryState = { hasError: false }\r\n\r\n static getDerivedStateFromError(): ErrorBoundaryState {\r\n return { hasError: true }\r\n }\r\n\r\n componentDidCatch(error: Error, info: ErrorInfo): void {\r\n console.error('Streemo ErrorBoundary caught error', error, info)\r\n }\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n return this.props.fallback ?? <div className=\"st-error\">Something went wrong in Streemo UI.</div>\r\n }\r\n return this.props.children\r\n }\r\n}\r\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport type { ChatMessage, TypingParticipant } from './useWebRTCCall'\n\nexport type ChatPanelProps = {\n messages: ChatMessage[]\n typingParticipants: TypingParticipant[]\n unreadCount: number\n hasMore: boolean\n loadingHistory: boolean\n currentUserId: string\n onSend: (text: string) => void\n onEdit: (id: string, text: string) => void\n onDelete: (id: string) => void\n onTyping: (isTyping: boolean) => void\n onLoadMore: () => void\n onMarkRead: () => void\n onFocusChange?: (focused: boolean) => void\n placeholder?: string\n}\n\nexport function ChatPanel({\n messages,\n typingParticipants,\n unreadCount,\n hasMore,\n loadingHistory,\n currentUserId,\n onSend,\n onEdit,\n onDelete,\n onTyping,\n onLoadMore,\n onMarkRead,\n onFocusChange,\n placeholder = 'Write a message...',\n}: ChatPanelProps) {\n const [draft, setDraft] = useState('')\n const [editingId, setEditingId] = useState<string | null>(null)\n const [editingText, setEditingText] = useState('')\n const listRef = useRef<HTMLDivElement | null>(null)\n const typingTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const typingLine = useMemo(() => {\n if (typingParticipants.length === 0) return ''\n const names = typingParticipants.map((item) => item.senderName || 'Guest')\n if (names.length === 1) return `${names[0]} is typing...`\n if (names.length === 2) return `${names[0]} and ${names[1]} are typing...`\n return `${names[0]} and ${names.length - 1} others are typing...`\n }, [typingParticipants])\n\n useEffect(() => {\n if (!listRef.current) return\n const el = listRef.current\n const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 60\n if (nearBottom) {\n el.scrollTop = el.scrollHeight\n onMarkRead()\n }\n }, [messages, onMarkRead])\n\n const handleScroll = () => {\n const el = listRef.current\n if (!el) return\n if (el.scrollTop < 40 && hasMore && !loadingHistory) {\n onLoadMore()\n }\n const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 60\n if (nearBottom) {\n onMarkRead()\n }\n }\n\n const notifyTyping = () => {\n onTyping(true)\n if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current)\n typingTimeoutRef.current = setTimeout(() => onTyping(false), 1200)\n }\n\n return (\n <section className=\"vc-chat-panel\">\n <div className=\"vc-chat-header\">\n <h3>Chat</h3>\n {unreadCount > 0 && <span className=\"vc-chat-unread\">Unread: {unreadCount}</span>}\n </div>\n <div\n ref={listRef}\n className=\"vc-chat-list\"\n onScroll={handleScroll}\n onFocus={() => onFocusChange?.(true)}\n onBlur={() => onFocusChange?.(false)}\n tabIndex={0}\n >\n {hasMore && <p className=\"vc-chat-muted\">{loadingHistory ? 'Loading...' : 'Scroll up to load more'}</p>}\n {messages.map((message) => {\n const isOwn = message.userId === currentUserId\n return (\n <div key={message.id} className={`vc-chat-item ${isOwn ? 'own' : ''}`}>\n <p className=\"vc-chat-meta\">\n <strong>{message.senderName || 'Guest'}</strong>\n <span>{new Date(message.sentAt).toLocaleTimeString()}</span>\n {message.editedAt && <span>(edited)</span>}\n {message.deliveryStatus === 'sending' && <span>(sending)</span>}\n {message.deliveryStatus === 'failed' && <span>(failed)</span>}\n </p>\n {message.deletedAt ? (\n <p className=\"vc-chat-deleted\">Message deleted</p>\n ) : editingId === message.id ? (\n <div className=\"vc-chat-edit-row\">\n <input value={editingText} onChange={(e) => setEditingText(e.target.value)} />\n <button\n onClick={() => {\n onEdit(message.id, editingText)\n setEditingId(null)\n }}\n >\n Save\n </button>\n <button onClick={() => setEditingId(null)}>Cancel</button>\n </div>\n ) : (\n <p>{message.text}</p>\n )}\n {isOwn && !message.deletedAt && editingId !== message.id && (\n <div className=\"vc-chat-actions\">\n <button\n onClick={() => {\n setEditingId(message.id)\n setEditingText(message.text)\n }}\n >\n Edit\n </button>\n <button onClick={() => onDelete(message.id)}>Delete</button>\n </div>\n )}\n </div>\n )\n })}\n </div>\n {typingLine && <p className=\"vc-chat-muted\">{typingLine}</p>}\n <div className=\"vc-chat-input-row\">\n <input\n value={draft}\n placeholder={placeholder}\n onChange={(e) => {\n setDraft(e.target.value)\n notifyTyping()\n }}\n onFocus={() => onFocusChange?.(true)}\n onBlur={() => onFocusChange?.(false)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n const value = draft.trim()\n if (!value) return\n onSend(value)\n setDraft('')\n onTyping(false)\n }\n }}\n />\n <button\n onClick={() => {\n const value = draft.trim()\n if (!value) return\n onSend(value)\n setDraft('')\n onTyping(false)\n }}\n disabled={!draft.trim()}\n >\n Send\n </button>\n </div>\n </section>\n )\n}\n","import { useMemo } from 'react'\nimport { useWebRTCCall } from './useWebRTCCall'\nimport { VideoTile } from './VideoTile'\nimport { ChatPanel } from './ChatPanel'\nimport type { ServerAuthConfig } from './auth'\nimport type { TokenProvider } from './tokenProvider'\n\nexport type VideoCallWidgetProps = {\n roomId: string\n userId: string\n userName: string\n roomToken?: string\n wsBaseUrl?: string\n tokenProvider?: TokenProvider\n apiBaseUrl?: string\n auth?: ServerAuthConfig\n enabled: boolean\n localLabelSuffix?: string\n showChat?: boolean\n}\n\nexport function VideoCallWidget({\n roomId,\n userId,\n userName,\n roomToken,\n wsBaseUrl,\n tokenProvider,\n apiBaseUrl,\n auth,\n enabled,\n localLabelSuffix = '(you)',\n showChat = true,\n}: VideoCallWidgetProps) {\n const call = useWebRTCCall({\n roomId,\n userId,\n roomToken,\n wsBaseUrl,\n tokenProvider,\n apiBaseUrl,\n auth,\n enabled,\n })\n\n const remotes = useMemo(() => Object.entries(call.remoteStreams), [call.remoteStreams])\n\n return (\n <div className=\"vc-root\">\n <div className=\"vc-toolbar\">\n <span className=\"vc-muted\">\n WS: {call.connected ? 'connected' : 'disconnected'} | participants: {call.participants.length + 1}\n </span>\n <div className=\"vc-row vc-wrap\">\n <button onClick={call.toggleMic} disabled={!call.hasMicTrack}>\n {call.micEnabled ? 'Mute mic' : 'Unmute mic'}\n </button>\n <button onClick={call.toggleCamera} disabled={!call.hasCameraTrack}>\n {call.cameraEnabled ? 'Disable camera' : 'Enable camera'}\n </button>\n </div>\n </div>\n\n {call.error && <p className=\"vc-error\">{call.error}</p>}\n\n <section className=\"vc-video-grid\">\n <VideoTile stream={call.localStream} muted mirrored label={`${userName} ${localLabelSuffix}`.trim()} />\n {remotes.map(([peerUserId, stream]) => (\n <VideoTile\n key={peerUserId}\n stream={stream}\n label={`peer: ${peerUserId.slice(0, 8)}`}\n subtitle={`remote video: ${call.remoteTrackStates[peerUserId]?.video ? 'on' : 'off'} | remote audio: ${call.remoteTrackStates[peerUserId]?.audio ? 'on' : 'off'} | pc: ${call.remoteTrackStates[peerUserId]?.connectionState ?? 'new'}`}\n />\n ))}\n </section>\n {showChat && (\n <ChatPanel\n messages={call.chatMessages}\n typingParticipants={call.typingParticipants}\n unreadCount={call.chatUnreadCount}\n hasMore={call.chatHasMore}\n loadingHistory={call.chatLoadingHistory}\n currentUserId={userId}\n onSend={(text) => call.sendChatMessage(text, userName)}\n onEdit={call.editChatMessage}\n onDelete={call.deleteChatMessage}\n onTyping={(isTyping) => call.sendTyping(isTyping, userName)}\n onLoadMore={call.loadMoreChatMessages}\n onMarkRead={call.markChatRead}\n onFocusChange={call.setChatFocused}\n />\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","createTheme","useEffect","useState","useState","useEffect","useMemo","useEffect","useMemo","useState","useState","useEffect","useMemo","useEffect","useMemo","useState","useState","useEffect","useMemo","useMemo","useEffect","useMemo","useState","useState","useEffect","useMemo","useMemo","useState","useCallback","useEffect","useMemo","useRef","useState","useMemo","useRef","useState","useCallback","localStream","useEffect","useState","useMemo","useMemo","useMemo","useCallback","useEffect","useState","useState","useCallback","useEffect","jsx","jsx","jsx","jsxs","jsx","jsx","useMemo","useState","jsx","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useMemo","useState","jsx","jsxs","useState","jsx","createContext","useContext","jsx","createContext","useContext","useEffect","useMemo","useRef","useState","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","jsx","jsx","jsx","jsx","jsxs","jsx","jsx","jsx","jsxs","jsx","useEffect","useMemo","useRef","useState","jsx","jsxs","useMemo","jsx","jsxs","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/StreemoClient.ts","../src/client/createStreemoClient.ts","../src/provider/StreemoProvider.tsx","../src/theme/StreemoTheme.tsx","../src/index.ts","../src/hooks/useChat.ts","../src/hooks/useChannel.ts","../src/hooks/useMessages.ts","../src/hooks/useTyping.ts","../src/hooks/usePresence.ts","../src/hooks/useCall.ts","../src/useWebRTCCall.ts","../src/auth.ts","../src/sdkErrors.ts","../src/tokenProvider.ts","../src/sdkConfig.ts","../src/hooks/useParticipants.ts","../src/hooks/useEntitlements.ts","../src/components/chat/Chat.tsx","../src/components/chat/ChannelPreview.tsx","../src/components/ui/LoadingSpinner.tsx","../src/components/chat/ChannelList.tsx","../src/components/chat/Channel.tsx","../src/components/chat/MessageList.tsx","../src/components/chat/AttachmentPreview.tsx","../src/components/chat/ReactionPicker.tsx","../src/components/chat/Message.tsx","../src/components/chat/Thread.tsx","../src/components/chat/MessageInput.tsx","../src/components/chat/TypingIndicator.tsx","../src/components/video/CallRoom.tsx","../src/VideoTile.tsx","../src/components/video/ParticipantTile.tsx","../src/components/video/ParticipantGrid.tsx","../src/components/video/CameraToggle.tsx","../src/components/video/JoinCallButton.tsx","../src/components/video/LeaveCallButton.tsx","../src/components/video/MuteButton.tsx","../src/components/video/ScreenShareButton.tsx","../src/components/video/CallControls.tsx","../src/components/ui/Avatar.tsx","../src/components/ui/PresenceBadge.tsx","../src/components/ui/UserStatus.tsx","../src/components/ui/ErrorBoundary.tsx","../src/ChatPanel.tsx","../src/VideoCallWidget.tsx"],"sourcesContent":["import type {\r\n PresenceState,\r\n StreemoAttachment,\r\n StreemoChannel,\r\n StreemoMessage,\r\n StreemoReaction,\r\n StreemoUser,\r\n TypingState,\r\n} from '../types/models'\r\n\r\ntype Listener<T> = (event: T) => void\r\n\r\ntype RealtimeEventMap = {\r\n connected: { connected: boolean }\r\n message_new: StreemoMessage\r\n message_updated: StreemoMessage\r\n typing: TypingState\r\n presence: PresenceState\r\n reaction_new: { channelId: string; messageId: string; reaction: StreemoReaction }\r\n}\r\n\r\ntype QueryParams = Record<string, string | number | undefined>\r\n\r\n/** Internal storage uses a generic listener to avoid DTS inference issues with mapped types */\r\ntype AnyListener = Listener<RealtimeEventMap[keyof RealtimeEventMap]>\r\n\r\nexport type StreemoClientOptions = {\r\n apiKey: string\r\n userToken: string\r\n user: StreemoUser\r\n baseUrl?: string\r\n wsUrl?: string\r\n reconnect?: boolean\r\n}\r\n\r\nexport class StreemoClient {\r\n public readonly apiKey: string\r\n public readonly userToken: string\r\n public readonly user: StreemoUser\r\n public readonly baseUrl: string\r\n public readonly wsUrl: string\r\n private readonly reconnect: boolean\r\n\r\n private ws: WebSocket | null = null\r\n private manuallyClosed = false\r\n private reconnectAttempt = 0\r\n private listeners: Partial<Record<keyof RealtimeEventMap, Set<AnyListener>>> = {}\r\n\r\n constructor(options: StreemoClientOptions) {\r\n this.apiKey = options.apiKey\r\n this.userToken = options.userToken\r\n this.user = options.user\r\n this.baseUrl = (options.baseUrl ?? 'https://api.streemo.ru').replace(/\\/+$/, '')\r\n const defaultWs = this.baseUrl.replace(/^http/, 'ws')\r\n this.wsUrl = (options.wsUrl ?? defaultWs).replace(/\\/+$/, '')\r\n this.reconnect = options.reconnect ?? true\r\n }\r\n\r\n on<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): () => void {\r\n if (!this.listeners[event]) this.listeners[event] = new Set()\r\n this.listeners[event]?.add(listener as Listener<RealtimeEventMap[keyof RealtimeEventMap]>)\r\n return () => this.off(event, listener)\r\n }\r\n\r\n off<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): void {\r\n this.listeners[event]?.delete(listener as Listener<RealtimeEventMap[keyof RealtimeEventMap]>)\r\n }\r\n\r\n private emit<K extends keyof RealtimeEventMap>(event: K, payload: RealtimeEventMap[K]): void {\r\n this.listeners[event]?.forEach((listener) => {\r\n listener(payload)\r\n })\r\n }\r\n\r\n async connect(): Promise<void> {\r\n if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) return\r\n this.manuallyClosed = false\r\n await this.openSocket()\r\n }\r\n\r\n disconnect(): void {\r\n this.manuallyClosed = true\r\n this.ws?.close()\r\n this.ws = null\r\n this.emit('connected', { connected: false })\r\n }\r\n\r\n private async openSocket(): Promise<void> {\r\n await new Promise<void>((resolve, reject) => {\r\n const url = `${this.wsUrl}/v1/ws?token=${encodeURIComponent(this.userToken)}&userId=${encodeURIComponent(this.user.id)}`\r\n const ws = new WebSocket(url)\r\n this.ws = ws\r\n\r\n ws.onopen = () => {\r\n this.reconnectAttempt = 0\r\n this.emit('connected', { connected: true })\r\n resolve()\r\n }\r\n\r\n ws.onmessage = (event) => {\r\n const parsed = JSON.parse(event.data) as { type: keyof RealtimeEventMap } & Record<string, unknown>\r\n switch (parsed.type) {\r\n case 'message_new':\r\n case 'message_updated':\r\n this.emit(parsed.type, parsed as unknown as StreemoMessage)\r\n break\r\n case 'typing':\r\n this.emit('typing', parsed as unknown as TypingState)\r\n break\r\n case 'presence':\r\n this.emit('presence', parsed as unknown as PresenceState)\r\n break\r\n case 'reaction_new':\r\n this.emit('reaction_new', parsed as unknown as { channelId: string; messageId: string; reaction: StreemoReaction })\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n ws.onerror = () => {\r\n reject(new Error('WebSocket connection failed'))\r\n }\r\n\r\n ws.onclose = () => {\r\n this.emit('connected', { connected: false })\r\n if (!this.manuallyClosed && this.reconnect) {\r\n const backoffMs = Math.min(1000 * 2 ** this.reconnectAttempt, 15000)\r\n this.reconnectAttempt += 1\r\n setTimeout(() => {\r\n void this.openSocket()\r\n }, backoffMs)\r\n }\r\n }\r\n })\r\n }\r\n\r\n private buildUrl(path: string, query?: QueryParams): string {\r\n const url = new URL(`${this.baseUrl}${path}`)\r\n if (query) {\r\n Object.entries(query).forEach(([key, value]) => {\r\n if (value !== undefined) url.searchParams.set(key, String(value))\r\n })\r\n }\r\n return url.toString()\r\n }\r\n\r\n private async request<T>(path: string, init?: RequestInit, query?: QueryParams): Promise<T> {\r\n const response = await fetch(this.buildUrl(path, query), {\r\n ...init,\r\n headers: {\r\n Authorization: `Bearer ${this.userToken}`,\r\n 'X-App-Id': this.apiKey,\r\n 'Content-Type': 'application/json',\r\n ...(init?.headers ?? {}),\r\n },\r\n })\r\n const data = await response.json().catch(() => ({}))\r\n if (!response.ok) {\r\n throw new Error((data as { error?: string }).error || `HTTP ${response.status}`)\r\n }\r\n return data as T\r\n }\r\n\r\n listChannels(): Promise<{ items: StreemoChannel[] }> {\r\n return this.request<{ items: StreemoChannel[] }>('/v1/channels')\r\n }\r\n\r\n listMessages(channelId: string, cursor?: string, limit = 30): Promise<{ items: StreemoMessage[]; nextCursor?: string; hasMore?: boolean }> {\r\n return this.request<{ items: StreemoMessage[]; nextCursor?: string; hasMore?: boolean }>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages`,\r\n undefined,\r\n { cursor, limit },\r\n )\r\n }\r\n\r\n sendMessage(input: {\r\n channelId: string\r\n text: string\r\n parentId?: string\r\n attachments?: StreemoAttachment[]\r\n }): Promise<StreemoMessage> {\r\n return this.request<StreemoMessage>(`/v1/channels/${encodeURIComponent(input.channelId)}/messages`, {\r\n method: 'POST',\r\n body: JSON.stringify(input),\r\n })\r\n }\r\n\r\n updateMessage(channelId: string, messageId: string, text: string): Promise<StreemoMessage> {\r\n return this.request<StreemoMessage>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,\r\n {\r\n method: 'PATCH',\r\n body: JSON.stringify({ text }),\r\n },\r\n )\r\n }\r\n\r\n deleteMessage(channelId: string, messageId: string): Promise<{ ok: true }> {\r\n return this.request<{ ok: true }>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,\r\n { method: 'DELETE' },\r\n )\r\n }\r\n\r\n sendTyping(channelId: string, isTyping: boolean): Promise<{ ok: true }> {\r\n return this.request<{ ok: true }>(`/v1/channels/${encodeURIComponent(channelId)}/typing`, {\r\n method: 'POST',\r\n body: JSON.stringify({ isTyping }),\r\n })\r\n }\r\n}\r\n","import { StreemoClient, type StreemoClientOptions } from './StreemoClient'\n\n/**\n * Stable factory for app-level client creation.\n * Keeps construction centralized and allows future non-breaking extensions.\n */\nexport function createStreemoClient(options: StreemoClientOptions): StreemoClient {\n return new StreemoClient(options)\n}\n","import { createContext, useContext, useEffect, useMemo, useState, type PropsWithChildren } from 'react'\r\nimport { StreemoClient } from '../client/StreemoClient'\r\n\r\ntype StreemoContextValue = {\r\n client: StreemoClient\r\n connected: boolean\r\n activeChannelId: string | null\r\n setActiveChannelId: (channelId: string | null) => void\r\n}\r\n\r\nconst StreemoContext = createContext<StreemoContextValue | null>(null)\r\n\r\nexport type StreemoProviderProps = PropsWithChildren<{\r\n client: StreemoClient\r\n}>\r\n\r\nexport function StreemoProvider({ client, children }: StreemoProviderProps) {\r\n const [connected, setConnected] = useState(false)\r\n const [activeChannelId, setActiveChannelId] = useState<string | null>(null)\r\n\r\n useEffect(() => {\r\n let mounted = true\r\n void client.connect().catch(() => {\r\n if (mounted) setConnected(false)\r\n })\r\n const unsub = client.on('connected', ({ connected: isConnected }) => {\r\n if (mounted) setConnected(isConnected)\r\n })\r\n return () => {\r\n mounted = false\r\n unsub()\r\n client.disconnect()\r\n }\r\n }, [client])\r\n\r\n const value = useMemo<StreemoContextValue>(\r\n () => ({\r\n client,\r\n connected,\r\n activeChannelId,\r\n setActiveChannelId,\r\n }),\r\n [activeChannelId, client, connected],\r\n )\r\n\r\n return <StreemoContext.Provider value={value}>{children}</StreemoContext.Provider>\r\n}\r\n\r\nexport function useStreemoContext(): StreemoContextValue {\r\n const value = useContext(StreemoContext)\r\n if (!value) {\r\n throw new Error('useStreemoContext must be used within StreemoProvider')\r\n }\r\n return value\r\n}\r\n","import type { CSSProperties, PropsWithChildren } from 'react'\r\nimport { createTheme, themeToCssVars } from 'streemo-ui-kit-web/theme'\r\n\r\nexport type StreemoThemeTokens = {\r\n primary?: string\r\n background?: string\r\n text?: string\r\n radius?: string\r\n}\r\n\r\nexport type StreemoThemeProps = PropsWithChildren<{\r\n theme?: StreemoThemeTokens\r\n mode?: 'light' | 'dark'\r\n}>\r\n\r\nexport function StreemoTheme({ theme, mode = 'light', children }: StreemoThemeProps) {\r\n const themeConfig = createTheme({\r\n mode,\r\n tokens: theme\r\n ? {\r\n colors: {\r\n primary: theme.primary,\r\n background: theme.background,\r\n text: theme.text,\r\n },\r\n radius: theme.radius ? { md: parseInt(theme.radius, 10) || 10, lg: 12 } : undefined,\r\n }\r\n : undefined,\r\n })\r\n const style: CSSProperties = themeToCssVars(themeConfig) as unknown as CSSProperties\r\n\r\n return (\r\n <div className={`st-theme st-theme--${mode}`} style={style}>\r\n {children}\r\n </div>\r\n )\r\n}\r\n","export { StreemoClient } from './client/StreemoClient'\nexport type { StreemoClientOptions } from './client/StreemoClient'\nexport { createStreemoClient } from './client/createStreemoClient'\nexport { StreemoProvider, useStreemoContext } from './provider/StreemoProvider'\nexport { StreemoTheme } from './theme/StreemoTheme'\nexport type { StreemoThemeTokens } from './theme/StreemoTheme'\nexport { createTheme, StreemoThemeProvider, useTheme } from 'streemo-ui-kit-web/theme'\nexport type { Theme, ThemeTokens, ThemeMode } from 'streemo-ui-kit-web/theme'\n\nexport { useChat } from './hooks/useChat'\nexport { useChannel } from './hooks/useChannel'\nexport { useMessages } from './hooks/useMessages'\nexport { useTyping } from './hooks/useTyping'\nexport { usePresence } from './hooks/usePresence'\nexport { useCall } from './hooks/useCall'\nexport { useParticipants } from './hooks/useParticipants'\nexport { useEntitlements } from './hooks/useEntitlements'\nexport type { StreemoEntitlements } from './hooks/useEntitlements'\n\nexport { Chat } from './components/chat/Chat'\nexport { ChannelList } from './components/chat/ChannelList'\nexport { ChannelPreview } from './components/chat/ChannelPreview'\nexport { Channel } from './components/chat/Channel'\nexport { MessageList } from './components/chat/MessageList'\nexport { Message } from './components/chat/Message'\nexport { MessageInput } from './components/chat/MessageInput'\nexport { Thread } from './components/chat/Thread'\nexport { TypingIndicator } from './components/chat/TypingIndicator'\nexport { AttachmentPreview } from './components/chat/AttachmentPreview'\nexport { ReactionPicker } from './components/chat/ReactionPicker'\n\nexport { CallRoom, useCallRoomContext } from './components/video/CallRoom'\nexport { ParticipantGrid } from './components/video/ParticipantGrid'\nexport { ParticipantTile } from './components/video/ParticipantTile'\nexport { CallControls } from './components/video/CallControls'\nexport { JoinCallButton } from './components/video/JoinCallButton'\nexport { LeaveCallButton } from './components/video/LeaveCallButton'\nexport { MuteButton } from './components/video/MuteButton'\nexport { CameraToggle } from './components/video/CameraToggle'\nexport { ScreenShareButton } from './components/video/ScreenShareButton'\n\nexport { Avatar } from './components/ui/Avatar'\nexport { UserStatus } from './components/ui/UserStatus'\nexport { PresenceBadge } from './components/ui/PresenceBadge'\nexport { LoadingSpinner } from './components/ui/LoadingSpinner'\nexport { ErrorBoundary } from './components/ui/ErrorBoundary'\n\nexport type {\n StreemoAttachment,\n StreemoChannel,\n StreemoMessage,\n StreemoReaction,\n StreemoUser,\n PresenceState,\n TypingState,\n Participant,\n} from './types/models'\n\nexport { useWebRTCCall } from './useWebRTCCall'\nexport type { UseWebRTCCallParams, RemoteTrackState, ChatMessage, TypingParticipant } from './useWebRTCCall'\nexport { VideoTile } from './VideoTile'\nexport { ChatPanel } from './ChatPanel'\nexport type { ChatPanelProps } from './ChatPanel'\nexport { VideoCallWidget } from './VideoCallWidget'\nexport type { VideoCallWidgetProps } from './VideoCallWidget'\nexport { createServerTokenProvider, defaultWsBaseUrlFromApi, defaultApiBaseUrl } from './tokenProvider'\nexport type { TokenProvider, TokenProviderContext, ServerTokenProviderOptions } from './tokenProvider'\nexport type { ServerAuthConfig } from './auth'\nexport { SDKError, mapSDKErrorToUIMessage } from './sdkErrors'\nexport type { SDKErrorCode } from './sdkErrors'\nexport { initVideoSDK, getVideoSDKConfig } from './sdkConfig'\nexport type { VideoSDKConfig } from './sdkConfig'\n","import { useEffect, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { StreemoChannel } from '../types/models'\r\n\r\nexport function useChat() {\r\n const { client, activeChannelId, setActiveChannelId, connected } = useStreemoContext()\r\n const [channels, setChannels] = useState<StreemoChannel[]>([])\r\n const [loading, setLoading] = useState(false)\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n const refreshChannels = async () => {\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const result = await client.listChannels()\r\n setChannels(result.items)\r\n if (!activeChannelId && result.items[0]) {\r\n setActiveChannelId(result.items[0].id)\r\n }\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load channels')\r\n } finally {\r\n setLoading(false)\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n void refreshChannels()\r\n }, [client])\r\n\r\n return {\r\n channels,\r\n loading,\r\n error,\r\n connected,\r\n activeChannelId,\r\n setActiveChannelId,\r\n refreshChannels,\r\n }\r\n}\r\n","import { useMemo } from 'react'\r\nimport { useChat } from './useChat'\r\nimport { useMessages } from './useMessages'\r\nimport { useTyping } from './useTyping'\r\n\r\nexport function useChannel(channelId?: string) {\r\n const chat = useChat()\r\n const resolvedChannelId = channelId ?? chat.activeChannelId ?? ''\r\n const messages = useMessages(resolvedChannelId)\r\n const typing = useTyping(resolvedChannelId)\r\n\r\n return useMemo(\r\n () => ({\r\n channelId: resolvedChannelId,\r\n ...messages,\r\n ...typing,\r\n activeChannelId: chat.activeChannelId,\r\n setActiveChannelId: chat.setActiveChannelId,\r\n }),\r\n [chat.activeChannelId, chat.setActiveChannelId, messages, resolvedChannelId, typing],\r\n )\r\n}\r\n","import { useCallback, useEffect, useMemo, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { StreemoAttachment, StreemoMessage } from '../types/models'\r\n\r\nfunction upsert(messages: StreemoMessage[], next: StreemoMessage): StreemoMessage[] {\r\n const idx = messages.findIndex((item) => item.id === next.id)\r\n if (idx === -1) return [...messages, next]\r\n const copy = [...messages]\r\n copy[idx] = next\r\n return copy\r\n}\r\n\r\nexport function useMessages(channelId: string) {\r\n const { client } = useStreemoContext()\r\n const [messages, setMessages] = useState<StreemoMessage[]>([])\r\n const [loading, setLoading] = useState(false)\r\n const [loadingMore, setLoadingMore] = useState(false)\r\n const [error, setError] = useState<string | null>(null)\r\n const [cursor, setCursor] = useState<string | undefined>(undefined)\r\n const [hasMore, setHasMore] = useState(false)\r\n\r\n const reload = useCallback(async () => {\r\n if (!channelId) return\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const result = await client.listMessages(channelId)\r\n setMessages(result.items)\r\n setCursor(result.nextCursor)\r\n setHasMore(Boolean(result.hasMore))\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load messages')\r\n } finally {\r\n setLoading(false)\r\n }\r\n }, [channelId, client])\r\n\r\n useEffect(() => {\r\n if (!channelId) return\r\n void reload()\r\n }, [channelId, reload])\r\n\r\n useEffect(() => {\r\n if (!channelId) return\r\n const unsubNew = client.on('message_new', (event) => {\r\n if (event.channelId !== channelId) return\r\n setMessages((prev) => upsert(prev, { ...event, deliveryStatus: 'sent' }))\r\n })\r\n const unsubUpdated = client.on('message_updated', (event) => {\r\n if (event.channelId !== channelId) return\r\n setMessages((prev) => upsert(prev, { ...event, deliveryStatus: 'sent' }))\r\n })\r\n return () => {\r\n unsubNew()\r\n unsubUpdated()\r\n }\r\n }, [channelId, client])\r\n\r\n const sendMessage = useCallback(\r\n async (text: string, options?: { parentId?: string; attachments?: StreemoAttachment[] }) => {\r\n if (!channelId || !text.trim()) return\r\n const optimisticId = `optimistic-${crypto.randomUUID()}`\r\n const optimisticMessage: StreemoMessage = {\r\n id: optimisticId,\r\n channelId,\r\n text: text.trim(),\r\n userId: client.user.id,\r\n createdAt: new Date().toISOString(),\r\n parentId: options?.parentId,\r\n attachments: options?.attachments,\r\n reactions: [],\r\n deliveryStatus: 'sending',\r\n }\r\n setMessages((prev) => [...prev, optimisticMessage])\r\n try {\r\n const saved = await client.sendMessage({\r\n channelId,\r\n text: text.trim(),\r\n parentId: options?.parentId,\r\n attachments: options?.attachments,\r\n })\r\n setMessages((prev) =>\r\n prev.map((item) => (item.id === optimisticId ? { ...saved, deliveryStatus: 'sent' } : item)),\r\n )\r\n } catch (err) {\r\n setMessages((prev) =>\r\n prev.map((item) => (item.id === optimisticId ? { ...item, deliveryStatus: 'failed' } : item)),\r\n )\r\n throw err\r\n }\r\n },\r\n [channelId, client],\r\n )\r\n\r\n const loadMore = useCallback(async () => {\r\n if (!channelId || !cursor || !hasMore || loadingMore) return\r\n setLoadingMore(true)\r\n try {\r\n const result = await client.listMessages(channelId, cursor)\r\n setMessages((prev) => [...result.items, ...prev])\r\n setCursor(result.nextCursor)\r\n setHasMore(Boolean(result.hasMore))\r\n } finally {\r\n setLoadingMore(false)\r\n }\r\n }, [channelId, client, cursor, hasMore, loadingMore])\r\n\r\n return useMemo(\r\n () => ({\r\n messages,\r\n loading,\r\n error,\r\n hasMore,\r\n loadingMore,\r\n sendMessage,\r\n loadMore,\r\n reload,\r\n }),\r\n [error, hasMore, loadMore, loading, loadingMore, messages, reload, sendMessage],\r\n )\r\n}\r\n","import { useEffect, useMemo, useRef, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { TypingState } from '../types/models'\r\n\r\nexport function useTyping(channelId: string) {\r\n const { client } = useStreemoContext()\r\n const [typing, setTyping] = useState<Record<string, TypingState>>({})\r\n const timeoutRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map())\r\n\r\n useEffect(() => {\r\n if (!channelId) return\r\n const unsub = client.on('typing', (event) => {\r\n if (event.channelId !== channelId || event.userId === client.user.id) return\r\n if (!event.isTyping) {\r\n setTyping((prev) => {\r\n const copy = { ...prev }\r\n delete copy[event.userId]\r\n return copy\r\n })\r\n return\r\n }\r\n setTyping((prev) => ({ ...prev, [event.userId]: event }))\r\n const prevTimer = timeoutRef.current.get(event.userId)\r\n if (prevTimer) clearTimeout(prevTimer)\r\n const timer = setTimeout(() => {\r\n setTyping((prev) => {\r\n const copy = { ...prev }\r\n delete copy[event.userId]\r\n return copy\r\n })\r\n timeoutRef.current.delete(event.userId)\r\n }, 3500)\r\n timeoutRef.current.set(event.userId, timer)\r\n })\r\n return () => {\r\n unsub()\r\n timeoutRef.current.forEach((timer) => clearTimeout(timer))\r\n timeoutRef.current.clear()\r\n }\r\n }, [channelId, client])\r\n\r\n const sendTyping = async (isTyping: boolean) => {\r\n if (!channelId) return\r\n await client.sendTyping(channelId, isTyping)\r\n }\r\n\r\n return useMemo(\r\n () => ({\r\n typingUsers: Object.values(typing),\r\n sendTyping,\r\n }),\r\n [typing],\r\n )\r\n}\r\n","import { useEffect, useMemo, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport type { PresenceState } from '../types/models'\r\n\r\nexport function usePresence() {\r\n const { client } = useStreemoContext()\r\n const [presence, setPresence] = useState<Record<string, PresenceState>>({})\r\n\r\n useEffect(() => {\r\n const unsub = client.on('presence', (event) => {\r\n setPresence((prev) => ({ ...prev, [event.userId]: event }))\r\n })\r\n return () => unsub()\r\n }, [client])\r\n\r\n return useMemo(\r\n () => ({\r\n presenceMap: presence,\r\n getUserPresence: (userId: string) =>\r\n presence[userId] ?? { userId, status: 'offline', lastSeenAt: undefined },\r\n findUserPresence: (userId: string) => presence[userId],\r\n }),\r\n [presence],\r\n )\r\n}\r\n","import { useMemo, useState } from 'react'\r\nimport { useStreemoContext } from '../provider/StreemoProvider'\r\nimport { useWebRTCCall } from '../useWebRTCCall'\r\n\r\nexport type UseCallParams = {\r\n roomId: string\r\n enabled?: boolean\r\n}\r\n\r\nexport function useCall({ roomId, enabled = true }: UseCallParams) {\r\n const { client } = useStreemoContext()\r\n const [joined, setJoined] = useState(enabled)\r\n const auth = useMemo(\r\n () => ({ appId: client.apiKey, authToken: client.userToken }),\r\n [client.apiKey, client.userToken],\r\n )\r\n\r\n const call = useWebRTCCall({\r\n roomId,\r\n userId: client.user.id,\r\n enabled: joined,\r\n apiBaseUrl: client.baseUrl,\r\n auth,\r\n })\r\n\r\n return useMemo(\r\n () => ({\r\n ...call,\r\n joined,\r\n joinCall: () => setJoined(true),\r\n leaveCall: () => setJoined(false),\r\n }),\r\n [call, joined],\r\n )\r\n}\r\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ServerAuthConfig } from './auth'\nimport {\n createServerTokenProvider,\n defaultApiBaseUrl,\n defaultWsBaseUrlFromApi,\n type TokenProvider,\n type TokenProviderContext,\n} from './tokenProvider'\nimport { mapSDKErrorToUIMessage } from './sdkErrors'\nimport { getVideoSDKConfig } from './sdkConfig'\n\ntype SignalMessage = {\n type: string\n roomId: string\n userId: string\n targetUserId?: string\n payload?: unknown\n}\n\nexport type UseWebRTCCallParams = {\n roomId: string\n userId: string\n roomToken?: string\n wsBaseUrl?: string\n tokenProvider?: TokenProvider\n apiBaseUrl?: string\n auth?: ServerAuthConfig\n enabled: boolean\n}\n\nexport type RemoteTrackState = {\n audio: boolean\n video: boolean\n connectionState: RTCPeerConnectionState\n}\n\nexport type ChatMessage = {\n id: string\n userId: string\n text: string\n senderName: string\n sentAt: string\n editedAt?: string\n deletedAt?: string\n deliveryStatus?: 'sending' | 'sent' | 'failed'\n clientMessageId?: string\n}\n\nexport type TypingParticipant = {\n userId: string\n senderName: string\n updatedAt: string\n}\n\n/** RTCRtpTransceiver has `kind` at runtime; DOM types omit it */\ntype TransceiverWithKind = RTCRtpTransceiver & { kind: 'audio' | 'video' }\n\nconst RENEGOTIATION_RETRY_DELAY_MS = 6000\nconst RENEGOTIATION_MAX_RETRIES = 3\nconst DISCONNECTED_CLEANUP_DELAY_MS = 10000\nconst NETWORK_STATS_POLL_MS = 5000\n\ntype QualityLevel = 'low' | 'medium' | 'high'\n\n/** RTCRtpTransceiver has `kind` at runtime but TypeScript DOM types omit it */\nfunction isVideoTransceiver(t: RTCRtpTransceiver): boolean {\n return (t as RTCRtpTransceiver & { kind?: string }).kind === 'video'\n}\n\nconst AUDIO_CONSTRAINTS: MediaTrackConstraints = {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n channelCount: 1,\n}\nconst VIDEO_CONSTRAINTS: MediaTrackConstraints = {\n width: { ideal: 1280, max: 1920 },\n height: { ideal: 720, max: 1080 },\n frameRate: { ideal: 24, max: 30 },\n facingMode: 'user',\n}\n\nasync function tuneLocalStream(stream: MediaStream): Promise<void> {\n const audioTrack = stream.getAudioTracks()[0]\n const videoTrack = stream.getVideoTracks()[0]\n\n if (audioTrack) {\n audioTrack.contentHint = 'speech'\n try {\n await audioTrack.applyConstraints(AUDIO_CONSTRAINTS)\n } catch {\n // Browser may ignore unsupported audio processing constraints.\n }\n }\n if (videoTrack) {\n videoTrack.contentHint = 'motion'\n try {\n await videoTrack.applyConstraints(VIDEO_CONSTRAINTS)\n } catch {\n // Browser may ignore unsupported video quality constraints.\n }\n }\n}\n\nasync function tuneSenderEncodings(peer: RTCPeerConnection): Promise<void> {\n const tasks = peer.getSenders().map(async (sender) => {\n const track = sender.track\n if (!track) return\n const params = sender.getParameters()\n if (!params.encodings || params.encodings.length === 0) {\n params.encodings = [{}]\n }\n const encoding = params.encodings[0]\n\n if (track.kind === 'audio') {\n encoding.maxBitrate = 64000\n }\n if (track.kind === 'video') {\n encoding.maxBitrate = 1200000\n encoding.maxFramerate = 24\n encoding.scaleResolutionDownBy = 1\n }\n\n try {\n await sender.setParameters(params)\n } catch {\n // Some browsers can reject runtime encoding changes.\n }\n })\n\n await Promise.all(tasks)\n}\n\nfunction getVideoProfile(level: QualityLevel): {\n maxBitrate: number\n maxFramerate: number\n scaleResolutionDownBy: number\n} {\n switch (level) {\n case 'low':\n return {\n maxBitrate: 350_000,\n maxFramerate: 15,\n scaleResolutionDownBy: 2,\n }\n case 'medium':\n return {\n maxBitrate: 700_000,\n maxFramerate: 20,\n scaleResolutionDownBy: 1.5,\n }\n case 'high':\n default:\n return {\n maxBitrate: 1_200_000,\n maxFramerate: 24,\n scaleResolutionDownBy: 1,\n }\n }\n}\n\nasync function applyVideoQualityProfile(peer: RTCPeerConnection, level: QualityLevel): Promise<void> {\n const profile = getVideoProfile(level)\n const tasks = peer.getSenders().map(async (sender) => {\n if (sender.track?.kind !== 'video') return\n const params = sender.getParameters()\n if (!params.encodings || params.encodings.length === 0) {\n params.encodings = [{}]\n }\n const encoding = params.encodings[0]\n encoding.maxBitrate = profile.maxBitrate\n encoding.maxFramerate = profile.maxFramerate\n encoding.scaleResolutionDownBy = profile.scaleResolutionDownBy\n try {\n await sender.setParameters(params)\n } catch {\n // Some browsers reject runtime adaptation for sender parameters.\n }\n })\n await Promise.all(tasks)\n}\n\nfunction nextQualityLevel(current: QualityLevel, target: QualityLevel): QualityLevel {\n const levels: QualityLevel[] = ['low', 'medium', 'high']\n const currentIdx = levels.indexOf(current)\n const targetIdx = levels.indexOf(target)\n if (currentIdx === targetIdx) return current\n if (currentIdx < targetIdx) return levels[currentIdx + 1]\n return levels[currentIdx - 1]\n}\n\nfunction resolveTokenProvider(params: UseWebRTCCallParams): TokenProvider | null {\n if (params.tokenProvider) return params.tokenProvider\n if (params.auth) {\n return createServerTokenProvider({\n apiBaseUrl: params.apiBaseUrl || defaultApiBaseUrl(),\n auth: params.auth,\n })\n }\n return null\n}\n\nfunction resolveWsBaseUrl(params: UseWebRTCCallParams): string {\n if (params.wsBaseUrl) return params.wsBaseUrl.replace(/\\/+$/, '')\n const apiBase = params.apiBaseUrl || defaultApiBaseUrl()\n if (apiBase) return defaultWsBaseUrlFromApi(apiBase)\n return ''\n}\n\nasync function resolveRoomToken(params: UseWebRTCCallParams): Promise<string> {\n if (params.roomToken) return params.roomToken\n const provider = resolveTokenProvider(params)\n if (!provider) {\n throw new Error('roomToken or tokenProvider/apiBaseUrl+auth is required')\n }\n const ctx: TokenProviderContext = {\n roomId: params.roomId,\n userId: params.userId,\n }\n return provider(ctx)\n}\n\nexport function useWebRTCCall(params: UseWebRTCCallParams) {\n const sdkConfig = getVideoSDKConfig()\n const mergedParams: UseWebRTCCallParams = {\n ...params,\n apiBaseUrl: params.apiBaseUrl ?? sdkConfig.apiBaseUrl,\n wsBaseUrl: params.wsBaseUrl ?? sdkConfig.wsBaseUrl,\n auth: params.auth ?? sdkConfig.auth,\n }\n\n const { roomId, userId, enabled } = mergedParams\n const { roomToken, wsBaseUrl, tokenProvider, apiBaseUrl, auth } = mergedParams\n\n const resolvedTokenProvider = useMemo<TokenProvider | null>(() => {\n if (tokenProvider) return tokenProvider\n if (auth) {\n return createServerTokenProvider({\n apiBaseUrl: apiBaseUrl || defaultApiBaseUrl(),\n auth,\n })\n }\n return null\n }, [tokenProvider, auth?.authToken, auth?.appId, apiBaseUrl])\n\n const wsRef = useRef<WebSocket | null>(null)\n const setupGenerationRef = useRef(0)\n const peersRef = useRef(new Map<string, RTCPeerConnection>())\n const localStreamRef = useRef<MediaStream | null>(null)\n const remoteStreamsRef = useRef<Record<string, MediaStream>>({})\n const localParticipantIdRef = useRef<string | null>(null)\n const renegotiationTimersRef = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n const renegotiationAttemptsRef = useRef(new Map<string, number>())\n const disconnectedCleanupTimersRef = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n const remoteStreamCleanupRef = useRef(new Map<string, () => void>())\n const networkStatsTimersRef = useRef(new Map<string, ReturnType<typeof setInterval>>())\n const qualityLevelRef = useRef(new Map<string, QualityLevel>())\n const makingOfferRef = useRef(new Map<string, boolean>())\n const ignoreOfferRef = useRef(new Map<string, boolean>())\n const isSettingRemoteAnswerPendingRef = useRef(new Map<string, boolean>())\n const politeRef = useRef(new Map<string, boolean>())\n const pendingChatPatchesRef = useRef(new Map<string, { text?: string; editedAt?: string; deletedAt?: string }>())\n const typingTimersRef = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n const isChatFocusedRef = useRef(false)\n const handleSignalMessageRef = useRef<(m: SignalMessage) => void>(() => {})\n const [localStream, setLocalStream] = useState<MediaStream | null>(null)\n const [remoteStreams, setRemoteStreams] = useState<Record<string, MediaStream>>({})\n const [participants, setParticipants] = useState<string[]>([])\n const [connected, setConnected] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [remoteTrackStates, setRemoteTrackStates] = useState<Record<string, RemoteTrackState>>({})\n const [chatMessages, setChatMessages] = useState<ChatMessage[]>([])\n const [typingParticipants, setTypingParticipants] = useState<TypingParticipant[]>([])\n const [chatUnreadCount, setChatUnreadCount] = useState(0)\n const [chatNextCursor, setChatNextCursor] = useState<string | null>(null)\n const [chatHasMore, setChatHasMore] = useState(false)\n const [chatLoadingHistory, setChatLoadingHistory] = useState(false)\n const [micEnabled, setMicEnabled] = useState(true)\n const [cameraEnabled, setCameraEnabled] = useState(true)\n const [hasMicTrack, setHasMicTrack] = useState(false)\n const [hasCameraTrack, setHasCameraTrack] = useState(false)\n const [screenSharing, setScreenSharing] = useState(false)\n const screenTrackRef = useRef<MediaStreamTrack | null>(null)\n const previousCameraTrackRef = useRef<MediaStreamTrack | null>(null)\n\n const clearRenegotiationRetry = useCallback((targetUserId: string) => {\n const timer = renegotiationTimersRef.current.get(targetUserId)\n if (timer) {\n clearTimeout(timer)\n renegotiationTimersRef.current.delete(targetUserId)\n }\n renegotiationAttemptsRef.current.delete(targetUserId)\n }, [])\n\n const clearDisconnectedCleanup = useCallback((targetUserId: string) => {\n const timer = disconnectedCleanupTimersRef.current.get(targetUserId)\n if (timer) {\n clearTimeout(timer)\n disconnectedCleanupTimersRef.current.delete(targetUserId)\n }\n }, [])\n\n const clearRemoteStreamObservers = useCallback((targetUserId: string) => {\n const cleanup = remoteStreamCleanupRef.current.get(targetUserId)\n if (cleanup) {\n cleanup()\n remoteStreamCleanupRef.current.delete(targetUserId)\n }\n }, [])\n\n const clearNetworkAdaptation = useCallback((targetUserId: string) => {\n const timer = networkStatsTimersRef.current.get(targetUserId)\n if (timer) {\n clearInterval(timer)\n networkStatsTimersRef.current.delete(targetUserId)\n }\n qualityLevelRef.current.delete(targetUserId)\n }, [])\n\n const computeTargetQualityLevel = useCallback(async (peer: RTCPeerConnection): Promise<QualityLevel> => {\n const stats = await peer.getStats()\n let rttSeconds: number | null = null\n let packetLossPercent: number | null = null\n\n stats.forEach((report) => {\n const stat = report as RTCStats & Record<string, unknown>\n\n if (stat.type === 'candidate-pair' && stat.state === 'succeeded') {\n const currentRTT = stat.currentRoundTripTime\n if (typeof currentRTT === 'number') {\n rttSeconds = rttSeconds === null ? currentRTT : Math.max(rttSeconds, currentRTT)\n }\n }\n\n if (stat.type === 'remote-inbound-rtp' && stat.kind === 'video') {\n const fractionLost = stat.fractionLost\n if (typeof fractionLost === 'number') {\n packetLossPercent = Math.max(0, fractionLost * 100)\n }\n }\n })\n\n if ((rttSeconds ?? 0) > 0.35 || (packetLossPercent ?? 0) > 8) {\n return 'low'\n }\n if ((rttSeconds ?? 0) > 0.2 || (packetLossPercent ?? 0) > 3) {\n return 'medium'\n }\n return 'high'\n }, [])\n\n const startNetworkAdaptation = useCallback(\n (targetUserId: string, peer: RTCPeerConnection) => {\n clearNetworkAdaptation(targetUserId)\n qualityLevelRef.current.set(targetUserId, 'high')\n const timer = setInterval(() => {\n void (async () => {\n if (peer.connectionState === 'closed' || peer.connectionState === 'failed') {\n clearNetworkAdaptation(targetUserId)\n return\n }\n const hasVideoSender = peer.getSenders().some((sender) => sender.track?.kind === 'video')\n if (!hasVideoSender) return\n\n let targetLevel: QualityLevel\n try {\n targetLevel = await computeTargetQualityLevel(peer)\n } catch {\n return\n }\n\n const currentLevel = qualityLevelRef.current.get(targetUserId) ?? 'high'\n const nextLevel = nextQualityLevel(currentLevel, targetLevel)\n if (nextLevel === currentLevel) return\n\n qualityLevelRef.current.set(targetUserId, nextLevel)\n await applyVideoQualityProfile(peer, nextLevel)\n })()\n }, NETWORK_STATS_POLL_MS)\n\n networkStatsTimersRef.current.set(targetUserId, timer)\n },\n [clearNetworkAdaptation, computeTargetQualityLevel],\n )\n\n const removePeer = useCallback(\n (targetUserId: string, removeParticipant = false) => {\n clearRenegotiationRetry(targetUserId)\n clearDisconnectedCleanup(targetUserId)\n clearRemoteStreamObservers(targetUserId)\n clearNetworkAdaptation(targetUserId)\n makingOfferRef.current.delete(targetUserId)\n ignoreOfferRef.current.delete(targetUserId)\n isSettingRemoteAnswerPendingRef.current.delete(targetUserId)\n politeRef.current.delete(targetUserId)\n\n const peer = peersRef.current.get(targetUserId)\n if (peer) {\n peer.ontrack = null\n peer.onicecandidate = null\n peer.onconnectionstatechange = null\n peer.close()\n }\n peersRef.current.delete(targetUserId)\n\n setRemoteStreams((prev) => {\n const copy = { ...prev }\n delete copy[targetUserId]\n remoteStreamsRef.current = copy\n return copy\n })\n setRemoteTrackStates((prev) => {\n const copy = { ...prev }\n delete copy[targetUserId]\n return copy\n })\n if (removeParticipant) {\n setParticipants((prev) => prev.filter((id) => id !== targetUserId))\n }\n },\n [clearDisconnectedCleanup, clearNetworkAdaptation, clearRemoteStreamObservers, clearRenegotiationRetry],\n )\n\n const hasRemoteVideoTrack = useCallback((targetUserId: string) => {\n const stream = remoteStreamsRef.current[targetUserId]\n if (!stream) return false\n return stream\n .getVideoTracks()\n .some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n }, [])\n\n const syncLocalTrackFlags = useCallback(() => {\n const stream = localStreamRef.current\n if (!stream) {\n setHasMicTrack(false)\n setHasCameraTrack(false)\n setMicEnabled(false)\n setCameraEnabled(false)\n return\n }\n\n const audioTrack = stream.getAudioTracks()[0]\n const videoTrack = stream.getVideoTracks()[0]\n\n setHasMicTrack(Boolean(audioTrack))\n setHasCameraTrack(Boolean(videoTrack))\n setMicEnabled(Boolean(audioTrack?.enabled))\n setCameraEnabled(Boolean(videoTrack?.enabled))\n }, [])\n\n const send = useCallback((message: Omit<SignalMessage, 'roomId' | 'userId'>) => {\n const ws = wsRef.current\n if (!ws || ws.readyState !== WebSocket.OPEN) return\n ws.send(\n JSON.stringify({\n roomId,\n userId,\n ...message,\n }),\n )\n }, [roomId, userId])\n\n const getLocalMediaState = useCallback(() => {\n const stream = localStreamRef.current\n if (!stream) {\n return {\n audioEnabled: false,\n videoEnabled: false,\n screenSharing: false,\n }\n }\n const audioEnabled = stream\n .getAudioTracks()\n .some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n const videoEnabled = stream\n .getVideoTracks()\n .some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n return {\n audioEnabled,\n videoEnabled,\n screenSharing: Boolean(screenTrackRef.current),\n }\n }, [])\n\n const broadcastLocalMediaState = useCallback(() => {\n send({\n type: 'media_state',\n payload: getLocalMediaState(),\n })\n }, [getLocalMediaState, send])\n\n const gracefulLeave = useCallback(() => {\n const ws = wsRef.current\n if (!ws || ws.readyState !== WebSocket.OPEN) return\n try {\n ws.send(\n JSON.stringify({\n roomId,\n userId,\n type: 'participant_left',\n payload: { source: 'page_unload', leftAt: new Date().toISOString() },\n }),\n )\n } catch {\n // Ignore unload-time send errors.\n }\n ws.close()\n }, [roomId, userId])\n\n const updateRemoteTrackState = useCallback((targetUserId: string, stream: MediaStream, peer: RTCPeerConnection) => {\n const audio = stream.getAudioTracks().some((track) => track.readyState === 'live' && track.enabled)\n const video = stream.getVideoTracks().some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n setRemoteTrackStates((prev) => ({\n ...prev,\n [targetUserId]: {\n audio,\n video,\n connectionState: peer.connectionState,\n },\n }))\n }, [])\n\n const pushChatMessage = useCallback((message: ChatMessage) => {\n setChatMessages((prev) => {\n const existingIdx = prev.findIndex((item) => item.id === message.id)\n if (existingIdx >= 0) {\n const copy = [...prev]\n copy[existingIdx] = {\n ...copy[existingIdx],\n ...message,\n deliveryStatus: message.deliveryStatus ?? copy[existingIdx].deliveryStatus ?? 'sent',\n }\n return copy\n }\n const patch = pendingChatPatchesRef.current.get(message.id)\n const withPatch: ChatMessage = patch\n ? {\n ...message,\n text: patch.deletedAt ? '' : (patch.text ?? message.text),\n editedAt: patch.editedAt ?? message.editedAt,\n deletedAt: patch.deletedAt ?? message.deletedAt,\n }\n : message\n const next = [...prev, withPatch]\n next.sort((a, b) => new Date(a.sentAt).getTime() - new Date(b.sentAt).getTime())\n if (next.length > 200) {\n return next.slice(next.length - 200)\n }\n return next\n })\n }, [])\n\n const prependChatMessages = useCallback((messages: ChatMessage[]) => {\n if (messages.length === 0) return\n setChatMessages((prev) => {\n const byID = new Map(prev.map((item) => [item.id, item]))\n messages.forEach((item) => {\n const patch = pendingChatPatchesRef.current.get(item.id)\n byID.set(item.id, {\n ...item,\n text: patch?.deletedAt ? '' : (patch?.text ?? item.text),\n editedAt: patch?.editedAt ?? item.editedAt,\n deletedAt: patch?.deletedAt ?? item.deletedAt,\n deliveryStatus: item.deliveryStatus ?? 'sent',\n })\n })\n const next = Array.from(byID.values())\n next.sort((a, b) => new Date(a.sentAt).getTime() - new Date(b.sentAt).getTime())\n return next.slice(Math.max(0, next.length - 400))\n })\n }, [])\n\n const patchChatMessage = useCallback((id: string, patch: { text?: string; editedAt?: string; deletedAt?: string }) => {\n let applied = false\n setChatMessages((prev) => {\n const idx = prev.findIndex((item) => item.id === id)\n if (idx < 0) return prev\n applied = true\n const next = [...prev]\n next[idx] = {\n ...next[idx],\n ...(patch.text !== undefined ? { text: patch.text } : {}),\n ...(patch.editedAt ? { editedAt: patch.editedAt } : {}),\n ...(patch.deletedAt ? { deletedAt: patch.deletedAt, text: '' } : {}),\n }\n return next\n })\n if (!applied) {\n const existing = pendingChatPatchesRef.current.get(id) ?? {}\n pendingChatPatchesRef.current.set(id, { ...existing, ...patch })\n }\n }, [])\n\n const setTypingState = useCallback((userIdValue: string, senderName: string, isTyping: boolean) => {\n const timer = typingTimersRef.current.get(userIdValue)\n if (timer) {\n clearTimeout(timer)\n typingTimersRef.current.delete(userIdValue)\n }\n if (!isTyping) {\n setTypingParticipants((prev) => prev.filter((item) => item.userId !== userIdValue))\n return\n }\n const now = new Date().toISOString()\n setTypingParticipants((prev) => {\n const filtered = prev.filter((item) => item.userId !== userIdValue)\n return [...filtered, { userId: userIdValue, senderName, updatedAt: now }]\n })\n const cleanupTimer = setTimeout(() => {\n setTypingParticipants((prev) => prev.filter((item) => item.userId !== userIdValue))\n typingTimersRef.current.delete(userIdValue)\n }, 3000)\n typingTimersRef.current.set(userIdValue, cleanupTimer)\n }, [])\n\n const ensurePeer = useCallback<(targetUserId: string) => RTCPeerConnection>(\n (targetUserId: string) => {\n const existing = peersRef.current.get(targetUserId)\n if (existing) return existing\n\n const peer = new RTCPeerConnection({\n iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],\n })\n const localParticipantID = localParticipantIdRef.current\n politeRef.current.set(targetUserId, localParticipantID ? localParticipantID > targetUserId : true)\n\n const localStream = localStreamRef.current\n const hasLocalAudio = Boolean(localStream?.getAudioTracks().length)\n const hasLocalVideo = Boolean(localStream?.getVideoTracks().length)\n\n if (!hasLocalAudio) {\n peer.addTransceiver('audio', { direction: 'recvonly' })\n }\n if (!hasLocalVideo) {\n peer.addTransceiver('video', { direction: 'recvonly' })\n }\n\n localStreamRef.current?.getTracks().forEach((track) => {\n peer.addTrack(track, localStreamRef.current as MediaStream)\n })\n void tuneSenderEncodings(peer)\n startNetworkAdaptation(targetUserId, peer)\n\n peer.onicecandidate = (event) => {\n if (!event.candidate) return\n send({\n type: 'ice_candidate',\n targetUserId,\n payload: event.candidate.toJSON(),\n })\n }\n\n peer.ontrack = (event) => {\n const [stream] = event.streams\n clearRemoteStreamObservers(targetUserId)\n setRemoteStreams((prev) => {\n const next = { ...prev, [targetUserId]: stream }\n remoteStreamsRef.current = next\n return next\n })\n updateRemoteTrackState(targetUserId, stream, peer)\n const update = () => updateRemoteTrackState(targetUserId, stream, peer)\n stream.getTracks().forEach((track) => {\n track.addEventListener('mute', update)\n track.addEventListener('unmute', update)\n track.addEventListener('ended', update)\n })\n stream.addEventListener('addtrack', update)\n stream.addEventListener('removetrack', update)\n remoteStreamCleanupRef.current.set(targetUserId, () => {\n stream.getTracks().forEach((track) => {\n track.removeEventListener('mute', update)\n track.removeEventListener('unmute', update)\n track.removeEventListener('ended', update)\n })\n stream.removeEventListener('addtrack', update)\n stream.removeEventListener('removetrack', update)\n })\n if (stream.getVideoTracks().some((track) => track.readyState === 'live' && track.enabled)) {\n clearRenegotiationRetry(targetUserId)\n }\n }\n\n peer.onconnectionstatechange = () => {\n const stream = remoteStreamsRef.current[targetUserId]\n if (stream) {\n updateRemoteTrackState(targetUserId, stream, peer)\n } else {\n setRemoteTrackStates((prev) => ({\n ...prev,\n [targetUserId]: {\n audio: false,\n video: false,\n connectionState: peer.connectionState,\n },\n }))\n }\n\n if (peer.connectionState === 'failed' || peer.connectionState === 'closed') {\n removePeer(targetUserId, true)\n return\n }\n if (peer.connectionState === 'disconnected') {\n clearDisconnectedCleanup(targetUserId)\n const timer = setTimeout(() => {\n const current = peersRef.current.get(targetUserId)\n if (!current) return\n if (current.connectionState === 'disconnected') {\n removePeer(targetUserId, true)\n }\n }, DISCONNECTED_CLEANUP_DELAY_MS)\n disconnectedCleanupTimersRef.current.set(targetUserId, timer)\n return\n }\n clearDisconnectedCleanup(targetUserId)\n }\n\n peersRef.current.set(targetUserId, peer)\n return peer\n },\n [clearDisconnectedCleanup, clearRemoteStreamObservers, clearRenegotiationRetry, removePeer, send, startNetworkAdaptation, updateRemoteTrackState],\n )\n\n const createOffer = useCallback(\n async (targetUserId: string) => {\n const peer = ensurePeer(targetUserId)\n if (peer.signalingState !== 'stable') {\n return\n }\n makingOfferRef.current.set(targetUserId, true)\n try {\n const offer = await peer.createOffer()\n await peer.setLocalDescription(offer)\n send({\n type: 'offer',\n targetUserId,\n payload: offer,\n })\n } finally {\n makingOfferRef.current.set(targetUserId, false)\n }\n },\n [ensurePeer, send],\n )\n\n const scheduleRenegotiationRetry = useCallback(\n (targetUserId: string) => {\n const existingTimer = renegotiationTimersRef.current.get(targetUserId)\n if (existingTimer) {\n clearTimeout(existingTimer)\n }\n\n const timer = setTimeout(async () => {\n const peer = peersRef.current.get(targetUserId)\n if (!peer) {\n clearRenegotiationRetry(targetUserId)\n return\n }\n if (hasRemoteVideoTrack(targetUserId)) {\n clearRenegotiationRetry(targetUserId)\n return\n }\n\n const attempts = renegotiationAttemptsRef.current.get(targetUserId) ?? 0\n if (attempts >= RENEGOTIATION_MAX_RETRIES) {\n clearRenegotiationRetry(targetUserId)\n return\n }\n\n renegotiationAttemptsRef.current.set(targetUserId, attempts + 1)\n await createOffer(targetUserId)\n scheduleRenegotiationRetry(targetUserId)\n }, RENEGOTIATION_RETRY_DELAY_MS)\n\n renegotiationTimersRef.current.set(targetUserId, timer)\n },\n [clearRenegotiationRetry, createOffer, hasRemoteVideoTrack],\n )\n\n const handleSignalMessage = useCallback(\n async (message: SignalMessage) => {\n if (message.userId === userId) return\n\n switch (message.type) {\n case 'welcome':\n localParticipantIdRef.current = message.userId\n break\n case 'chat_history':\n case 'chat_history_page': {\n const payload = (message.payload as {\n items?: Array<Omit<ChatMessage, 'userId'> & { userId?: string; senderUserId?: string }>\n nextCursor?: string\n hasMore?: boolean\n }) ?? {}\n const items = payload.items ?? []\n const normalized = items\n .filter((item) => item.id)\n .map((item) => ({\n id: item.id,\n userId: item.senderUserId ?? item.userId ?? '',\n text: item.text ?? '',\n senderName: item.senderName || 'Гость',\n sentAt: item.sentAt || new Date().toISOString(),\n editedAt: item.editedAt,\n deletedAt: item.deletedAt,\n clientMessageId: item.clientMessageId,\n deliveryStatus: 'sent' as const,\n }))\n prependChatMessages(normalized)\n setChatNextCursor(payload.nextCursor || null)\n setChatHasMore(Boolean(payload.hasMore))\n setChatLoadingHistory(false)\n break\n }\n case 'chat_error': {\n const payload = (message.payload as { code?: string }) ?? {}\n if (payload.code === 'rate_limited') {\n setError('Слишком много сообщений. Подождите немного.')\n }\n break\n }\n case 'chat_typing': {\n const payload = (message.payload as { isTyping?: boolean; senderName?: string; senderUserId?: string }) ?? {}\n const typingUserID = payload.senderUserId || message.userId\n if (!typingUserID || typingUserID === userId) break\n setTypingState(typingUserID, payload.senderName || 'Гость', Boolean(payload.isTyping))\n break\n }\n case 'chat_message_edited': {\n const payload = (message.payload as { id?: string; text?: string; editedAt?: string }) ?? {}\n if (!payload.id) break\n patchChatMessage(payload.id, { text: payload.text ?? '', editedAt: payload.editedAt || new Date().toISOString() })\n break\n }\n case 'chat_message_deleted': {\n const payload = (message.payload as { id?: string; deletedAt?: string }) ?? {}\n if (!payload.id) break\n patchChatMessage(payload.id, { deletedAt: payload.deletedAt || new Date().toISOString() })\n break\n }\n case 'chat_message': {\n const payload = (message.payload as Partial<ChatMessage> & { senderUserId?: string }) ?? {}\n if (!payload.id) break\n const senderID = payload.senderUserId || message.userId\n const normalized: ChatMessage = {\n id: payload.id,\n userId: senderID,\n text: payload.text ?? '',\n senderName: payload.senderName || 'Гость',\n sentAt: payload.sentAt || new Date().toISOString(),\n editedAt: payload.editedAt,\n deletedAt: payload.deletedAt,\n clientMessageId: payload.clientMessageId,\n deliveryStatus: 'sent',\n }\n if (payload.clientMessageId) {\n setChatMessages((prev) =>\n prev.map((item) =>\n item.clientMessageId === payload.clientMessageId\n ? { ...item, id: normalized.id, sentAt: normalized.sentAt, deliveryStatus: 'sent' }\n : item,\n ),\n )\n }\n pushChatMessage(normalized)\n if (senderID !== userId && !isChatFocusedRef.current) {\n setChatUnreadCount((prev) => prev + 1)\n }\n break\n }\n case 'join':\n case 'participant_joined':\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n await createOffer(message.userId)\n scheduleRenegotiationRetry(message.userId)\n broadcastLocalMediaState()\n break\n case 'media_state': {\n const payload = (message.payload as {\n audioEnabled?: boolean\n videoEnabled?: boolean\n }) ?? {}\n const peer = peersRef.current.get(message.userId)\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n setRemoteTrackStates((prev) => ({\n ...prev,\n [message.userId]: {\n audio: Boolean(payload.audioEnabled),\n video: Boolean(payload.videoEnabled),\n connectionState: prev[message.userId]?.connectionState ?? peer?.connectionState ?? 'connected',\n },\n }))\n break\n }\n case 'participant_left':\n removePeer(message.userId, true)\n break\n case 'offer': {\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n let peer = ensurePeer(message.userId)\n const makingOffer = makingOfferRef.current.get(message.userId) ?? false\n const isSettingRemoteAnswerPending = isSettingRemoteAnswerPendingRef.current.get(message.userId) ?? false\n const polite = politeRef.current.get(message.userId) ?? true\n const offerCollision = makingOffer || (peer.signalingState !== 'stable' && !isSettingRemoteAnswerPending)\n const ignoreOffer = !polite && offerCollision\n ignoreOfferRef.current.set(message.userId, ignoreOffer)\n if (ignoreOffer) {\n return\n }\n if (offerCollision) {\n try {\n await peer.setLocalDescription({ type: 'rollback' })\n } catch {\n removePeer(message.userId)\n peer = ensurePeer(message.userId)\n }\n }\n await peer.setRemoteDescription(new RTCSessionDescription(message.payload as RTCSessionDescriptionInit))\n const answer = await peer.createAnswer()\n await peer.setLocalDescription(answer)\n send({\n type: 'answer',\n targetUserId: message.userId,\n payload: answer,\n })\n break\n }\n case 'answer': {\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n const peer = peersRef.current.get(message.userId)\n if (!peer) return\n if (ignoreOfferRef.current.get(message.userId)) {\n return\n }\n if (peer.signalingState !== 'have-local-offer') {\n return\n }\n isSettingRemoteAnswerPendingRef.current.set(message.userId, true)\n try {\n await peer.setRemoteDescription(new RTCSessionDescription(message.payload as RTCSessionDescriptionInit))\n } finally {\n isSettingRemoteAnswerPendingRef.current.set(message.userId, false)\n }\n scheduleRenegotiationRetry(message.userId)\n break\n }\n case 'ice_candidate': {\n setParticipants((prev) => Array.from(new Set([...prev, message.userId])))\n const peer = ensurePeer(message.userId)\n await peer.addIceCandidate(new RTCIceCandidate(message.payload as RTCIceCandidateInit))\n break\n }\n default:\n break\n }\n },\n [\n createOffer,\n ensurePeer,\n patchChatMessage,\n prependChatMessages,\n pushChatMessage,\n removePeer,\n scheduleRenegotiationRetry,\n broadcastLocalMediaState,\n send,\n setTypingState,\n userId,\n ],\n )\n\n useEffect(() => {\n handleSignalMessageRef.current = handleSignalMessage\n }, [handleSignalMessage])\n\n useEffect(() => {\n if (!enabled || !roomId || !userId) return\n const peers = peersRef.current\n const currentParams: UseWebRTCCallParams = {\n roomId,\n userId,\n enabled,\n roomToken,\n wsBaseUrl,\n tokenProvider: resolvedTokenProvider ?? undefined,\n apiBaseUrl,\n auth,\n }\n\n const setup = async () => {\n const myGen = ++setupGenerationRef.current\n try {\n const resolvedRoomToken = await resolveRoomToken(currentParams)\n if (myGen !== setupGenerationRef.current) return\n const resolvedWsBaseUrl = resolveWsBaseUrl(currentParams)\n if (!resolvedWsBaseUrl) {\n setError('wsBaseUrl or apiBaseUrl is required')\n return\n }\n\n if (!window.isSecureContext) {\n setError('getUserMedia requires HTTPS (or localhost).')\n return\n }\n if (!navigator.mediaDevices?.getUserMedia) {\n setError('Browser does not support mediaDevices/getUserMedia.')\n return\n }\n\n let acquiredLocalStream: MediaStream\n try {\n acquiredLocalStream = await navigator.mediaDevices.getUserMedia({\n audio: AUDIO_CONSTRAINTS,\n video: VIDEO_CONSTRAINTS,\n })\n } catch (err) {\n if (err instanceof DOMException && ['NotFoundError', 'OverconstrainedError'].includes(err.name)) {\n acquiredLocalStream = await navigator.mediaDevices.getUserMedia({\n audio: AUDIO_CONSTRAINTS,\n video: false,\n })\n setError('Camera is unavailable. Joined in audio-only mode.')\n } else {\n throw err\n }\n }\n if (myGen !== setupGenerationRef.current) return\n await tuneLocalStream(acquiredLocalStream)\n if (myGen !== setupGenerationRef.current) return\n localStreamRef.current = acquiredLocalStream\n setLocalStream(acquiredLocalStream)\n syncLocalTrackFlags()\n\n const wsURL = `${resolvedWsBaseUrl}/v1/ws?roomId=${encodeURIComponent(roomId)}&token=${encodeURIComponent(resolvedRoomToken)}`\n const ws = new WebSocket(wsURL)\n wsRef.current = ws\n\n ws.onopen = () => {\n setConnected(true)\n send({ type: 'join', payload: { joinedAt: new Date().toISOString() } })\n send({ type: 'chat_history_request', payload: { limit: 30 } })\n broadcastLocalMediaState()\n }\n ws.onclose = () => {\n setConnected(false)\n }\n ws.onerror = () => {\n setError('WebSocket connection error')\n }\n ws.onmessage = (event) => {\n const message = JSON.parse(event.data) as SignalMessage\n void handleSignalMessageRef.current(message)\n }\n } catch (err) {\n const mappedMessage = mapSDKErrorToUIMessage(err)\n if (mappedMessage !== 'Unexpected error while connecting to call server.') {\n setError(mappedMessage)\n return\n }\n if (err instanceof DOMException && err.name === 'NotAllowedError') {\n setError('No camera/microphone access. Please allow permissions in browser settings.')\n return\n }\n setError(err instanceof Error ? err.message : 'Call initialization failed')\n }\n }\n\n void setup()\n\n return () => {\n wsRef.current?.close()\n peers.forEach((_, peerID) => removePeer(peerID))\n peers.clear()\n renegotiationTimersRef.current.forEach((timer) => clearTimeout(timer))\n renegotiationTimersRef.current.clear()\n renegotiationAttemptsRef.current.clear()\n disconnectedCleanupTimersRef.current.forEach((timer) => clearTimeout(timer))\n disconnectedCleanupTimersRef.current.clear()\n remoteStreamCleanupRef.current.forEach((cleanup) => cleanup())\n remoteStreamCleanupRef.current.clear()\n networkStatsTimersRef.current.forEach((timer) => clearInterval(timer))\n networkStatsTimersRef.current.clear()\n qualityLevelRef.current.clear()\n makingOfferRef.current.clear()\n ignoreOfferRef.current.clear()\n isSettingRemoteAnswerPendingRef.current.clear()\n politeRef.current.clear()\n localParticipantIdRef.current = null\n remoteStreamsRef.current = {}\n setChatMessages([])\n setTypingParticipants([])\n setChatUnreadCount(0)\n setChatNextCursor(null)\n setChatHasMore(false)\n setChatLoadingHistory(false)\n pendingChatPatchesRef.current.clear()\n typingTimersRef.current.forEach((timer) => clearTimeout(timer))\n typingTimersRef.current.clear()\n isChatFocusedRef.current = false\n localStreamRef.current?.getTracks().forEach((track) => track.stop())\n localStreamRef.current = null\n previousCameraTrackRef.current?.stop()\n previousCameraTrackRef.current = null\n screenTrackRef.current = null\n syncLocalTrackFlags()\n }\n }, [\n apiBaseUrl,\n auth,\n broadcastLocalMediaState,\n enabled,\n removePeer,\n resolvedTokenProvider,\n roomId,\n roomToken,\n send,\n syncLocalTrackFlags,\n userId,\n wsBaseUrl,\n ])\n\n useEffect(() => {\n if (!enabled) return\n\n const onPageHide = () => {\n gracefulLeave()\n }\n const onBeforeUnload = () => {\n gracefulLeave()\n }\n\n window.addEventListener('pagehide', onPageHide)\n window.addEventListener('beforeunload', onBeforeUnload)\n\n return () => {\n window.removeEventListener('pagehide', onPageHide)\n window.removeEventListener('beforeunload', onBeforeUnload)\n }\n }, [enabled, gracefulLeave])\n\n const toggleMic = useCallback(() => {\n const stream = localStreamRef.current\n if (!stream) return\n const audioTracks = stream.getAudioTracks()\n if (audioTracks.length === 0) return\n const nextEnabled = !micEnabled\n audioTracks.forEach((track) => {\n track.enabled = nextEnabled\n })\n setMicEnabled(nextEnabled)\n broadcastLocalMediaState()\n }, [broadcastLocalMediaState, micEnabled])\n\n const toggleCamera = useCallback(() => {\n const stream = localStreamRef.current\n if (!stream) return\n const videoTracks = stream.getVideoTracks()\n if (videoTracks.length === 0) return\n const nextEnabled = !cameraEnabled\n videoTracks.forEach((track) => {\n track.enabled = nextEnabled\n })\n setCameraEnabled(nextEnabled)\n broadcastLocalMediaState()\n }, [broadcastLocalMediaState, cameraEnabled])\n\n const syncVideoTrackToPeers = useCallback(\n async (nextVideoTrack: MediaStreamTrack | null, options?: { forceRenegotiation?: boolean }) => {\n const renegotiationTargets = new Set<string>()\n const replaceTasks: Array<Promise<void>> = []\n const forceRenegotiation = Boolean(options?.forceRenegotiation)\n\n peersRef.current.forEach((peer, targetUserId) => {\n if (forceRenegotiation) {\n renegotiationTargets.add(targetUserId)\n }\n\n const videoTransceiver = peer.getTransceivers().find(isVideoTransceiver)\n if (videoTransceiver) {\n const currentDirection = videoTransceiver.direction\n if (nextVideoTrack) {\n if (currentDirection === 'recvonly') {\n videoTransceiver.direction = 'sendrecv'\n renegotiationTargets.add(targetUserId)\n } else if (currentDirection === 'inactive') {\n videoTransceiver.direction = 'sendonly'\n renegotiationTargets.add(targetUserId)\n }\n } else {\n if (currentDirection === 'sendrecv') {\n videoTransceiver.direction = 'recvonly'\n renegotiationTargets.add(targetUserId)\n } else if (currentDirection === 'sendonly') {\n videoTransceiver.direction = 'inactive'\n renegotiationTargets.add(targetUserId)\n }\n }\n\n replaceTasks.push(\n Promise.resolve(videoTransceiver.sender.replaceTrack(nextVideoTrack)).catch(() => {\n renegotiationTargets.add(targetUserId)\n }),\n )\n return\n }\n\n const videoSender = peer.getSenders().find((sender) => sender.track?.kind === 'video')\n if (videoSender) {\n replaceTasks.push(\n Promise.resolve(videoSender.replaceTrack(nextVideoTrack)).catch(() => {\n renegotiationTargets.add(targetUserId)\n }),\n )\n return\n }\n\n if (nextVideoTrack && localStreamRef.current) {\n peer.addTrack(nextVideoTrack, localStreamRef.current)\n renegotiationTargets.add(targetUserId)\n }\n })\n\n await Promise.all(replaceTasks)\n\n for (const targetUserId of renegotiationTargets) {\n await createOffer(targetUserId)\n scheduleRenegotiationRetry(targetUserId)\n }\n },\n [createOffer, scheduleRenegotiationRetry],\n )\n\n const stopScreenShare = useCallback(async () => {\n const stream = localStreamRef.current\n const activeScreenTrack = screenTrackRef.current\n if (!stream || !activeScreenTrack) {\n setScreenSharing(false)\n return\n }\n\n activeScreenTrack.onended = null\n stream.getVideoTracks().forEach((track) => {\n if (track === activeScreenTrack) {\n stream.removeTrack(track)\n }\n })\n activeScreenTrack.stop()\n screenTrackRef.current = null\n\n let cameraTrack = previousCameraTrackRef.current\n if (!cameraTrack || cameraTrack.readyState !== 'live') {\n cameraTrack = null\n try {\n const cameraStream = await navigator.mediaDevices.getUserMedia({ audio: false, video: VIDEO_CONSTRAINTS })\n cameraTrack = cameraStream.getVideoTracks()[0] ?? null\n cameraStream.getTracks().forEach((track) => {\n if (track !== cameraTrack) track.stop()\n })\n } catch {\n cameraTrack = null\n }\n }\n\n if (cameraTrack) {\n stream.addTrack(cameraTrack)\n }\n\n await syncVideoTrackToPeers(cameraTrack ?? null, { forceRenegotiation: true })\n\n previousCameraTrackRef.current = cameraTrack\n setScreenSharing(false)\n setLocalStream(new MediaStream(stream.getTracks()))\n syncLocalTrackFlags()\n broadcastLocalMediaState()\n }, [broadcastLocalMediaState, syncLocalTrackFlags, syncVideoTrackToPeers])\n\n const toggleScreenShare = useCallback(async () => {\n const stream = localStreamRef.current\n if (!stream) return\n if (screenSharing) {\n stopScreenShare()\n return\n }\n try {\n const screenStream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: false,\n })\n const screenTrack = screenStream.getVideoTracks()[0]\n if (!screenTrack) return\n screenTrackRef.current = screenTrack\n screenTrack.onended = () => stopScreenShare()\n const oldVideoTrack = stream.getVideoTracks().find((track) => track !== screenTrack)\n if (oldVideoTrack) {\n previousCameraTrackRef.current = oldVideoTrack\n stream.removeTrack(oldVideoTrack)\n } else {\n previousCameraTrackRef.current = null\n }\n stream.addTrack(screenTrack)\n setScreenSharing(true)\n setLocalStream(new MediaStream(stream.getTracks()))\n syncLocalTrackFlags()\n await syncVideoTrackToPeers(screenTrack, { forceRenegotiation: true })\n broadcastLocalMediaState()\n screenStream.getTracks().filter((t) => t !== screenTrack).forEach((t) => t.stop())\n } catch {\n setScreenSharing(false)\n screenTrackRef.current = null\n broadcastLocalMediaState()\n }\n }, [broadcastLocalMediaState, screenSharing, stopScreenShare, syncLocalTrackFlags, syncVideoTrackToPeers])\n\n const sendChatMessage = useCallback(\n (text: string, senderName = 'Гость') => {\n const normalizedText = text.trim()\n if (!normalizedText) return\n const clientMessageId = crypto.randomUUID()\n pushChatMessage({\n id: `local-${clientMessageId}`,\n userId,\n text: normalizedText,\n senderName: senderName.trim() || 'Гость',\n sentAt: new Date().toISOString(),\n clientMessageId,\n deliveryStatus: 'sending',\n })\n send({\n type: 'chat_message',\n payload: {\n text: normalizedText,\n senderName: senderName.trim() || 'Гость',\n clientMessageId,\n },\n })\n },\n [pushChatMessage, send, userId],\n )\n\n const editChatMessage = useCallback(\n (id: string, text: string) => {\n const normalized = text.trim()\n if (!id || !normalized) return\n patchChatMessage(id, { text: normalized, editedAt: new Date().toISOString() })\n send({ type: 'chat_message_edited', payload: { id, text: normalized } })\n },\n [patchChatMessage, send],\n )\n\n const deleteChatMessage = useCallback(\n (id: string) => {\n if (!id) return\n patchChatMessage(id, { deletedAt: new Date().toISOString() })\n send({ type: 'chat_message_deleted', payload: { id } })\n },\n [patchChatMessage, send],\n )\n\n const sendTyping = useCallback(\n (isTyping: boolean, senderName = 'Гость') => {\n send({\n type: 'chat_typing',\n payload: {\n isTyping,\n senderName: senderName.trim() || 'Гость',\n },\n })\n },\n [send],\n )\n\n const markChatRead = useCallback(() => {\n isChatFocusedRef.current = true\n setChatUnreadCount(0)\n }, [])\n\n const setChatFocused = useCallback((focused: boolean) => {\n isChatFocusedRef.current = focused\n if (focused) {\n setChatUnreadCount(0)\n }\n }, [])\n\n const loadMoreChatMessages = useCallback(() => {\n if (!chatHasMore || chatLoadingHistory) return\n setChatLoadingHistory(true)\n send({\n type: 'chat_history_request',\n payload: {\n cursor: chatNextCursor,\n limit: 30,\n },\n })\n }, [chatHasMore, chatLoadingHistory, chatNextCursor, send])\n\n return {\n localStream,\n remoteStreams,\n participants,\n remoteTrackStates,\n chatMessages,\n typingParticipants,\n chatUnreadCount,\n chatHasMore,\n chatLoadingHistory,\n connected,\n error,\n micEnabled,\n cameraEnabled,\n hasMicTrack,\n hasCameraTrack,\n toggleMic,\n toggleCamera,\n screenSharing,\n toggleScreenShare,\n sendChatMessage,\n editChatMessage,\n deleteChatMessage,\n sendTyping,\n loadMoreChatMessages,\n markChatRead,\n setChatFocused,\n }\n}\n","export type ServerAuthConfig = {\n authToken: string\n clientId?: string\n appId: string\n authHeader?: string\n clientIdHeader?: string\n appIdHeader?: string\n}\n\nexport function buildAuthHeaders(auth: ServerAuthConfig): Record<string, string> {\n const headers: Record<string, string> = {\n [auth.appIdHeader ?? 'X-App-Id']: auth.appId,\n [auth.authHeader ?? 'Authorization']: `Bearer ${auth.authToken}`,\n }\n if (auth.clientId) {\n headers[auth.clientIdHeader ?? 'X-Client-Id'] = auth.clientId\n }\n return headers\n}\n","export type SDKErrorCode =\n | 'invalid_app'\n | 'invalid_client'\n | 'expired_token'\n | 'unauthorized'\n | 'forbidden'\n | 'rate_limited'\n | 'network_error'\n | 'unknown_error'\n\nexport class SDKError extends Error {\n code: SDKErrorCode\n status?: number\n\n constructor(code: SDKErrorCode, message: string, status?: number) {\n super(message)\n this.code = code\n this.status = status\n this.name = 'SDKError'\n }\n}\n\nexport function mapSDKErrorToUIMessage(err: unknown): string {\n if (!(err instanceof SDKError)) {\n return 'Unexpected error while connecting to call server.'\n }\n\n switch (err.code) {\n case 'invalid_app':\n return 'Application is not allowed to use this video service.'\n case 'invalid_client':\n return 'Client is not recognized by video service.'\n case 'expired_token':\n return 'Authorization token is expired. Please sign in again.'\n case 'unauthorized':\n return 'Authorization failed. Please check your credentials.'\n case 'forbidden':\n return 'Access is forbidden for this application/client.'\n case 'rate_limited':\n return 'Organization rate limit exceeded. Please retry later.'\n case 'network_error':\n return 'Network error while connecting to video service.'\n default:\n return err.message || 'Unknown video service error.'\n }\n}\n","import { buildAuthHeaders, type ServerAuthConfig } from './auth'\nimport { SDKError } from './sdkErrors'\n\nexport type TokenProviderContext = {\n roomId: string\n userId: string\n}\n\nexport type TokenProvider = (ctx: TokenProviderContext) => Promise<string>\n\nexport type ServerTokenProviderOptions = {\n apiBaseUrl?: string\n auth: ServerAuthConfig\n externalUserRegisterPath?: string\n joinPathBuilder?: (roomId: string) => string\n tokenPathBuilder?: (roomId: string) => string\n}\n\ntype ServerErrorPayload = {\n error?: string\n message?: string\n}\n\nfunction mapServerError(status: number, serverMessage: string): SDKError {\n const message = serverMessage.toLowerCase()\n if (status === 403 && message.includes('app id')) {\n return new SDKError('invalid_app', 'invalid_app', status)\n }\n if (status === 403 && message.includes('auth token')) {\n return new SDKError('unauthorized', 'invalid_auth_token', status)\n }\n if (status === 403 && message.includes('client id')) {\n return new SDKError('invalid_client', 'invalid_client', status)\n }\n if (status === 401 && message.includes('expired token')) {\n return new SDKError('expired_token', 'expired_token', status)\n }\n if (status === 401) {\n return new SDKError('unauthorized', 'unauthorized', status)\n }\n if (status === 403) {\n return new SDKError('forbidden', 'forbidden', status)\n }\n if (status === 429) {\n return new SDKError('rate_limited', 'rate_limited', status)\n }\n return new SDKError('unknown_error', serverMessage || 'unknown_error', status)\n}\n\nasync function fetchJson<T>(input: RequestInfo | URL, init: RequestInit): Promise<T> {\n let response: Response\n try {\n response = await fetch(input, init)\n } catch {\n throw new SDKError('network_error', 'network_error')\n }\n if (!response.ok) {\n let serverMessage = response.statusText\n try {\n const payload = (await response.json()) as ServerErrorPayload\n serverMessage = payload.error || payload.message || serverMessage\n } catch {\n const text = await response.text()\n if (text) serverMessage = text\n }\n throw mapServerError(response.status, serverMessage)\n }\n return response.json() as Promise<T>\n}\n\nexport function defaultWsBaseUrlFromApi(apiBaseUrl: string): string {\n const normalized = apiBaseUrl.replace(/\\/+$/, '')\n if (normalized.startsWith('https://')) {\n return normalized.replace(/^https:\\/\\//, 'wss://')\n }\n if (normalized.startsWith('http://')) {\n return normalized.replace(/^http:\\/\\//, 'ws://')\n }\n return normalized\n}\n\nexport function defaultApiBaseUrl(): string {\n if (typeof window !== 'undefined' && window.location?.origin) {\n return window.location.origin\n }\n return ''\n}\n\nexport function createServerTokenProvider(options: ServerTokenProviderOptions): TokenProvider {\n const externalUserRegisterPath = options.externalUserRegisterPath ?? '/v1/external-users/register'\n const joinPathBuilder = options.joinPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/join`)\n const tokenPathBuilder = options.tokenPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/token`)\n const externalUserMap = new Map<string, string>()\n\n return async ({ roomId, userId }) => {\n const base = (options.apiBaseUrl || defaultApiBaseUrl()).replace(/\\/+$/, '')\n if (!base) {\n throw new SDKError('unknown_error', 'api_base_url_required')\n }\n const headers = {\n 'Content-Type': 'application/json',\n ...buildAuthHeaders(options.auth),\n }\n\n let internalUserID = externalUserMap.get(userId)\n if (!internalUserID) {\n const registration = await fetchJson<{ userId: string }>(`${base}${externalUserRegisterPath}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n externalId: userId,\n }),\n })\n if (!registration.userId) {\n throw new SDKError('unknown_error', 'external_user_registration_failed')\n }\n internalUserID = registration.userId\n externalUserMap.set(userId, internalUserID)\n }\n const roomHeaders = {\n ...headers,\n 'X-Guest-Id': internalUserID,\n }\n\n await fetchJson<{ ok?: boolean }>(`${base}${joinPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n body: '{}',\n })\n\n const tokenResponse = await fetchJson<{ token: string }>(`${base}${tokenPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n })\n\n if (!tokenResponse.token) {\n throw new Error('Room token is empty')\n }\n return tokenResponse.token\n }\n}\n","import type { ServerAuthConfig } from './auth'\n\nexport type VideoSDKConfig = {\n apiBaseUrl?: string\n wsBaseUrl?: string\n auth?: ServerAuthConfig\n}\n\nconst DEFAULT_API_BASE_URL = 'https://api.streemo.ru'\nconst DEFAULT_WS_BASE_URL = 'wss://api.streemo.ru'\n\nlet globalConfig: VideoSDKConfig = {\n apiBaseUrl: DEFAULT_API_BASE_URL,\n wsBaseUrl: DEFAULT_WS_BASE_URL,\n}\n\nexport function initVideoSDK(config: VideoSDKConfig): void {\n globalConfig = {\n ...globalConfig,\n ...config,\n auth: config.auth ? { ...(globalConfig.auth ?? {}), ...config.auth } : globalConfig.auth,\n }\n}\n\nexport function getVideoSDKConfig(): VideoSDKConfig {\n return globalConfig\n}\n\n","import { useMemo } from 'react'\r\nimport { useCall, type UseCallParams } from './useCall'\r\n\r\nexport function useParticipants(params: UseCallParams) {\r\n const call = useCall(params)\r\n\r\n return useMemo(\r\n () => ({\r\n participants: call.participants.map((userId) => ({\r\n userId,\r\n stream: call.remoteStreams[userId],\r\n trackState: call.remoteTrackStates[userId],\r\n })),\r\n localStream: call.localStream,\r\n joined: call.joined,\r\n joinCall: call.joinCall,\r\n leaveCall: call.leaveCall,\r\n }),\r\n [call],\r\n )\r\n}\r\n","import { useCallback, useEffect, useState } from 'react'\nimport { useStreemoContext } from '../provider/StreemoProvider'\nimport { getVideoSDKConfig } from '../sdkConfig'\n\nexport type StreemoEntitlements = {\n operations: {\n createRoom: boolean\n chatWrite: boolean\n }\n}\n\ntype UseEntitlementsResult = {\n entitlements: StreemoEntitlements | null\n loading: boolean\n error: string | null\n refresh: () => Promise<StreemoEntitlements | null>\n}\n\nconst EMPTY_ENTITLEMENTS: StreemoEntitlements = {\n operations: {\n createRoom: false,\n chatWrite: false,\n },\n}\n\nexport function useEntitlements(enabled = true): UseEntitlementsResult {\n const { client } = useStreemoContext()\n const [entitlements, setEntitlements] = useState<StreemoEntitlements | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const refresh = useCallback(async () => {\n if (!enabled) {\n setEntitlements(null)\n setError(null)\n return null\n }\n\n setLoading(true)\n setError(null)\n try {\n const sdkConfig = getVideoSDKConfig()\n const response = await fetch(`${client.baseUrl}/v1/me/entitlements`, {\n headers: {\n Authorization: `Bearer ${client.userToken}`,\n 'X-App-Id': client.apiKey,\n ...(sdkConfig.auth?.authToken ? { 'X-Org-Auth-Token': sdkConfig.auth.authToken } : {}),\n 'Content-Type': 'application/json',\n },\n })\n const payload = (await response.json().catch(() => ({}))) as Partial<StreemoEntitlements> & { error?: string }\n if (!response.ok) {\n throw new Error(payload.error ?? `HTTP ${response.status}`)\n }\n\n const normalized: StreemoEntitlements = {\n operations: {\n createRoom: Boolean(payload.operations?.createRoom),\n chatWrite: Boolean(payload.operations?.chatWrite),\n },\n }\n setEntitlements(normalized)\n return normalized\n } catch (requestError) {\n const nextError = requestError instanceof Error ? requestError.message : 'Failed to fetch entitlements'\n setError(nextError)\n setEntitlements(EMPTY_ENTITLEMENTS)\n return EMPTY_ENTITLEMENTS\n } finally {\n setLoading(false)\n }\n }, [client.apiKey, client.baseUrl, client.userToken, enabled])\n\n useEffect(() => {\n void refresh()\n }, [refresh])\n\n return { entitlements, loading, error, refresh }\n}\n","import type { PropsWithChildren } from 'react'\r\n\r\nexport function Chat({ children }: PropsWithChildren) {\r\n return <section className=\"st-chat\">{children}</section>\r\n}\r\n","import type { StreemoChannel } from '../../types/models'\r\n\r\nexport type ChannelPreviewProps = {\r\n channel: StreemoChannel\r\n active?: boolean\r\n onSelect?: (channelId: string) => void\r\n}\r\n\r\nexport function ChannelPreview({ channel, active, onSelect }: ChannelPreviewProps) {\r\n return (\r\n <button className={`st-channel-preview ${active ? 'is-active' : ''}`} onClick={() => onSelect?.(channel.id)}>\r\n <span className=\"st-channel-preview__name\">{channel.name}</span>\r\n {channel.unreadCount ? <span className=\"st-channel-preview__unread\">{channel.unreadCount}</span> : null}\r\n </button>\r\n )\r\n}\r\n","import { Spinner } from 'streemo-ui-kit-web'\r\n\r\nexport type LoadingSpinnerProps = {\r\n label?: string\r\n}\r\n\r\nexport function LoadingSpinner({ label = 'Loading...' }: LoadingSpinnerProps) {\r\n return (\r\n <div className=\"st-spinner\" role=\"status\" aria-live=\"polite\">\r\n <Spinner size={20} />\r\n {label != null && <span>{label}</span>}\r\n </div>\r\n )\r\n}\r\n","import { useChat } from '../../hooks/useChat'\r\nimport { ChannelPreview } from './ChannelPreview'\r\nimport { LoadingSpinner } from '../ui/LoadingSpinner'\r\n\r\nexport function ChannelList() {\r\n const { channels, loading, error, activeChannelId, setActiveChannelId } = useChat()\r\n\r\n if (loading) return <LoadingSpinner label=\"Loading channels...\" />\r\n if (error) return <p className=\"st-error\">{error}</p>\r\n\r\n return (\r\n <aside className=\"st-channel-list\">\r\n {channels.map((channel) => (\r\n <ChannelPreview\r\n key={channel.id}\r\n channel={channel}\r\n active={activeChannelId === channel.id}\r\n onSelect={setActiveChannelId}\r\n />\r\n ))}\r\n </aside>\r\n )\r\n}\r\n","import type { PropsWithChildren } from 'react'\r\nimport { useChannel } from '../../hooks/useChannel'\r\n\r\nexport type ChannelProps = PropsWithChildren<{\r\n channelId?: string\r\n}>\r\n\r\nexport function Channel({ channelId, children }: ChannelProps) {\r\n const { channelId: resolved } = useChannel(channelId)\r\n if (!resolved) {\r\n return <section className=\"st-channel st-empty\">Select a channel</section>\r\n }\r\n return <section className=\"st-channel\">{children}</section>\r\n}\r\n","import { useMemo, useState } from 'react'\r\nimport { useChannel } from '../../hooks/useChannel'\r\nimport type { StreemoMessage } from '../../types/models'\r\nimport { Message } from './Message'\r\nimport { LoadingSpinner } from '../ui/LoadingSpinner'\r\nimport { Thread } from './Thread'\r\n\r\nexport type MessageListProps = {\r\n channelId?: string\r\n}\r\n\r\nexport function MessageList({ channelId }: MessageListProps) {\r\n const { channelId: resolvedChannelId, messages, loading, hasMore, loadingMore, loadMore } = useChannel(channelId)\r\n const [threadParent, setThreadParent] = useState<StreemoMessage | null>(null)\r\n const threadMessages = useMemo(\r\n () => messages.filter((message) => message.parentId === threadParent?.id),\r\n [messages, threadParent?.id],\r\n )\r\n\r\n if (!resolvedChannelId) return null\r\n if (loading) return <LoadingSpinner label=\"Loading messages...\" />\r\n\r\n return (\r\n <section className=\"st-message-list\">\r\n {hasMore && (\r\n <button onClick={() => void loadMore()} disabled={loadingMore}>\r\n {loadingMore ? 'Loading...' : 'Load more'}\r\n </button>\r\n )}\r\n {messages\r\n .filter((item) => !item.parentId)\r\n .map((message) => (\r\n <Message key={message.id} message={message} onThread={setThreadParent} />\r\n ))}\r\n {threadParent && (\r\n <Thread parent={threadParent} messages={threadMessages} onClose={() => setThreadParent(null)} />\r\n )}\r\n </section>\r\n )\r\n}\r\n","import type { StreemoAttachment } from '../../types/models'\r\n\r\nexport type AttachmentPreviewProps = {\r\n attachment: StreemoAttachment\r\n}\r\n\r\nexport function AttachmentPreview({ attachment }: AttachmentPreviewProps) {\r\n if (attachment.type === 'image') {\r\n return <img className=\"st-attachment st-attachment--image\" src={attachment.url} alt={attachment.name ?? 'attachment'} />\r\n }\r\n return (\r\n <a className=\"st-attachment st-attachment--file\" href={attachment.url} target=\"_blank\" rel=\"noreferrer\">\r\n {attachment.name ?? attachment.url}\r\n </a>\r\n )\r\n}\r\n","const DEFAULT_REACTIONS = ['👍', '❤️', '😂', '🎉', '🔥']\r\n\r\nexport type ReactionPickerProps = {\r\n onPick: (reaction: string) => void\r\n}\r\n\r\nexport function ReactionPicker({ onPick }: ReactionPickerProps) {\r\n return (\r\n <div className=\"st-reaction-picker\" role=\"toolbar\" aria-label=\"Reactions\">\r\n {DEFAULT_REACTIONS.map((reaction) => (\r\n <button key={reaction} onClick={() => onPick(reaction)} aria-label={`Add reaction ${reaction}`}>\r\n {reaction}\r\n </button>\r\n ))}\r\n </div>\r\n )\r\n}\r\n","import type { StreemoMessage } from '../../types/models'\r\nimport { AttachmentPreview } from './AttachmentPreview'\r\nimport { ReactionPicker } from './ReactionPicker'\r\n\r\nexport type MessageProps = {\r\n message: StreemoMessage\r\n isOwn?: boolean\r\n onThread?: (message: StreemoMessage) => void\r\n}\r\n\r\nexport function Message({ message, isOwn, onThread }: MessageProps) {\r\n return (\r\n <article className={`st-message ${isOwn ? 'is-own' : ''}`}>\r\n <header className=\"st-message__meta\">\r\n <span>{message.userId}</span>\r\n <time>{new Date(message.createdAt).toLocaleTimeString()}</time>\r\n {message.deliveryStatus && <small>{message.deliveryStatus}</small>}\r\n </header>\r\n <p>{message.text}</p>\r\n {!!message.attachments?.length && (\r\n <div className=\"st-message__attachments\">\r\n {message.attachments.map((attachment) => (\r\n <AttachmentPreview key={attachment.id} attachment={attachment} />\r\n ))}\r\n </div>\r\n )}\r\n <div className=\"st-message__actions\">\r\n <button onClick={() => onThread?.(message)}>Thread</button>\r\n <ReactionPicker onPick={() => undefined} />\r\n </div>\r\n </article>\r\n )\r\n}\r\n","import type { StreemoMessage } from '../../types/models'\r\nimport { Message } from './Message'\r\n\r\nexport type ThreadProps = {\r\n parent: StreemoMessage\r\n messages: StreemoMessage[]\r\n onClose: () => void\r\n}\r\n\r\nexport function Thread({ parent, messages, onClose }: ThreadProps) {\r\n return (\r\n <aside className=\"st-thread\">\r\n <header className=\"st-thread__header\">\r\n <strong>Thread</strong>\r\n <button onClick={onClose}>Close</button>\r\n </header>\r\n <Message message={parent} />\r\n {messages.map((item) => (\r\n <Message key={item.id} message={item} />\r\n ))}\r\n </aside>\r\n )\r\n}\r\n","import { useState } from 'react'\r\nimport { useChannel } from '../../hooks/useChannel'\r\n\r\nexport type MessageInputProps = {\r\n channelId?: string\r\n parentId?: string\r\n placeholder?: string\r\n}\r\n\r\nexport function MessageInput({ channelId, parentId, placeholder = 'Write a message...' }: MessageInputProps) {\r\n const { sendMessage, sendTyping } = useChannel(channelId)\r\n const [value, setValue] = useState('')\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n const submit = async () => {\r\n const text = value.trim()\r\n if (!text) return\r\n setError(null)\r\n try {\r\n await sendMessage(text, { parentId })\r\n setValue('')\r\n await sendTyping(false)\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Message send failed')\r\n }\r\n }\r\n\r\n return (\r\n <div className=\"st-message-input\">\r\n <input\r\n value={value}\r\n placeholder={placeholder}\r\n onChange={(event) => {\r\n setValue(event.target.value)\r\n void sendTyping(true)\r\n }}\r\n onBlur={() => void sendTyping(false)}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n event.preventDefault()\r\n void submit()\r\n }\r\n }}\r\n />\r\n <button onClick={() => void submit()} disabled={!value.trim()}>\r\n Send\r\n </button>\r\n {error ? <small className=\"st-error\">{error}</small> : null}\r\n </div>\r\n )\r\n}\r\n","import { useChannel } from '../../hooks/useChannel'\r\n\r\nexport type TypingIndicatorProps = {\r\n channelId?: string\r\n}\r\n\r\nexport function TypingIndicator({ channelId }: TypingIndicatorProps) {\r\n const { typingUsers } = useChannel(channelId)\r\n if (!typingUsers.length) return null\r\n const text =\r\n typingUsers.length === 1\r\n ? `${typingUsers[0].userId} is typing...`\r\n : `${typingUsers[0].userId} and ${typingUsers.length - 1} others are typing...`\r\n return <p className=\"st-typing-indicator\">{text}</p>\r\n}\r\n","import { createContext, useContext, type PropsWithChildren } from 'react'\r\nimport { useCall } from '../../hooks/useCall'\r\n\r\ntype CallRoomContextValue = ReturnType<typeof useCall>\r\n\r\nconst CallRoomContext = createContext<CallRoomContextValue | null>(null)\r\n\r\nexport type CallRoomProps = PropsWithChildren<{\r\n roomId: string\r\n autoJoin?: boolean\r\n}>\r\n\r\nexport function CallRoom({ roomId, autoJoin = true, children }: CallRoomProps) {\r\n const value = useCall({ roomId, enabled: autoJoin })\r\n return <CallRoomContext.Provider value={value}>{children}</CallRoomContext.Provider>\r\n}\r\n\r\nexport function useCallRoomContext(): CallRoomContextValue {\r\n const value = useContext(CallRoomContext)\r\n if (!value) throw new Error('Call components must be used within <CallRoom>')\r\n return value\r\n}\r\n","import { useEffect, useMemo, useRef, useState } from 'react'\n\ntype Props = {\n stream: MediaStream | null\n muted?: boolean\n mirrored?: boolean\n label: string\n subtitle?: string\n videoActive?: boolean\n i18n?: {\n resumePlayback?: string\n audioOnlyMuted?: string\n audioOnlyConnected?: string\n }\n}\n\nexport function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, videoActive, i18n }: Props) {\n const ref = useRef<HTMLVideoElement | null>(null)\n const [hasVideoTrack, setHasVideoTrack] = useState(false)\n const [needsInteraction, setNeedsInteraction] = useState(false)\n\n const texts = {\n resumePlayback: i18n?.resumePlayback ?? 'Enable video/audio',\n audioOnlyMuted: i18n?.audioOnlyMuted ?? 'Microphone only',\n audioOnlyConnected: i18n?.audioOnlyConnected ?? 'Audio connected',\n }\n\n const initials = useMemo(() => {\n const parts = label\n .replace(/\\(.*\\)/g, '')\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n if (parts.length === 0) return 'U'\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase()\n return `${parts[0][0] ?? ''}${parts[1][0] ?? ''}`.toUpperCase()\n }, [label])\n\n useEffect(() => {\n if (!ref.current) return\n ref.current.srcObject = stream\n ref.current.muted = muted\n void ref.current.play()\n .then(() => setNeedsInteraction(false))\n .catch(() => setNeedsInteraction(true))\n }, [stream, muted])\n\n useEffect(() => {\n if (!stream) {\n setHasVideoTrack(false)\n return\n }\n\n const trackCleanups = new Map<MediaStreamTrack, () => void>()\n\n const evaluateHasVideo = () => {\n const hasVideo = stream\n .getVideoTracks()\n .some((track) => track.readyState === 'live' && track.enabled && !track.muted)\n setHasVideoTrack(hasVideo)\n }\n\n const bindTrack = (track: MediaStreamTrack) => {\n const update = () => evaluateHasVideo()\n track.addEventListener('mute', update)\n track.addEventListener('unmute', update)\n track.addEventListener('ended', update)\n trackCleanups.set(track, () => {\n track.removeEventListener('mute', update)\n track.removeEventListener('unmute', update)\n track.removeEventListener('ended', update)\n })\n }\n\n const unbindTrack = (track: MediaStreamTrack) => {\n const cleanup = trackCleanups.get(track)\n if (cleanup) {\n cleanup()\n trackCleanups.delete(track)\n }\n }\n\n stream.getVideoTracks().forEach((track) => bindTrack(track))\n\n const onAddTrack = (event: MediaStreamTrackEvent) => {\n if (event.track.kind === 'video') {\n bindTrack(event.track)\n }\n evaluateHasVideo()\n }\n\n const onRemoveTrack = (event: MediaStreamTrackEvent) => {\n if (event.track.kind === 'video') {\n unbindTrack(event.track)\n }\n evaluateHasVideo()\n }\n\n evaluateHasVideo()\n\n stream.addEventListener('addtrack', onAddTrack)\n stream.addEventListener('removetrack', onRemoveTrack)\n\n return () => {\n stream.removeEventListener('addtrack', onAddTrack)\n stream.removeEventListener('removetrack', onRemoveTrack)\n trackCleanups.forEach((cleanup) => cleanup())\n trackCleanups.clear()\n }\n }, [stream])\n\n const handleResumePlayback = async () => {\n if (!ref.current) return\n try {\n ref.current.muted = muted\n await ref.current.play()\n setNeedsInteraction(false)\n } catch {\n setNeedsInteraction(true)\n }\n }\n\n const resolvedHasVideoTrack = videoActive ?? hasVideoTrack\n\n return (\n <div className={`vc-video-tile ${resolvedHasVideoTrack ? '' : 'audio-only'}`}>\n <video\n ref={ref}\n autoPlay\n playsInline\n muted={muted}\n className={mirrored ? 'vc-video-mirrored' : ''}\n style={{ display: resolvedHasVideoTrack ? 'block' : 'none' }}\n />\n {needsInteraction && (\n <button className=\"vc-video-play-button\" onClick={handleResumePlayback}>\n {texts.resumePlayback}\n </button>\n )}\n {!resolvedHasVideoTrack && (\n <div className=\"vc-video-placeholder\">\n <div className=\"vc-avatar-circle\">{initials}</div>\n <span className=\"vc-muted\">{muted ? texts.audioOnlyMuted : texts.audioOnlyConnected}</span>\n </div>\n )}\n <p>{label}</p>\n {subtitle && <p className=\"vc-video-subtitle\">{subtitle}</p>}\n </div>\n )\n}\n","import { VideoTile } from '../../VideoTile'\r\n\r\nexport type ParticipantTileProps = {\r\n userId: string\r\n stream?: MediaStream\r\n subtitle?: string\r\n videoActive?: boolean\r\n}\r\n\r\nexport function ParticipantTile({ userId, stream, subtitle, videoActive }: ParticipantTileProps) {\r\n return <VideoTile stream={stream ?? null} label={userId} subtitle={subtitle} videoActive={videoActive} />\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\nimport { ParticipantTile } from './ParticipantTile'\r\nimport { VideoTile } from '../../VideoTile'\r\n\r\nexport function ParticipantGrid() {\r\n const call = useCallRoomContext()\r\n return (\r\n <section className=\"st-participant-grid\">\r\n <VideoTile stream={call.localStream} label=\"You\" muted mirrored />\r\n {call.participants.map((userId) => (\r\n <ParticipantTile\r\n key={userId}\r\n userId={userId}\r\n stream={call.remoteStreams[userId]}\r\n videoActive={call.remoteTrackStates[userId]?.video}\r\n subtitle={call.remoteTrackStates[userId]?.connectionState}\r\n />\r\n ))}\r\n </section>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function CameraToggle() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.toggleCamera} disabled={!call.hasCameraTrack}>\r\n {call.cameraEnabled ? 'Camera off' : 'Camera on'}\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function JoinCallButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.joinCall} disabled={call.joined}>\r\n Join call\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function LeaveCallButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.leaveCall} disabled={!call.joined}>\r\n Leave call\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function MuteButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={call.toggleMic} disabled={!call.hasMicTrack}>\r\n {call.micEnabled ? 'Mute' : 'Unmute'}\r\n </button>\r\n )\r\n}\r\n","import { useCallRoomContext } from './CallRoom'\r\n\r\nexport function ScreenShareButton() {\r\n const call = useCallRoomContext()\r\n return (\r\n <button onClick={() => void call.toggleScreenShare()}>\r\n {call.screenSharing ? 'Stop share' : 'Share screen'}\r\n </button>\r\n )\r\n}\r\n","import { CameraToggle } from './CameraToggle'\r\nimport { JoinCallButton } from './JoinCallButton'\r\nimport { LeaveCallButton } from './LeaveCallButton'\r\nimport { MuteButton } from './MuteButton'\r\nimport { ScreenShareButton } from './ScreenShareButton'\r\n\r\nexport function CallControls() {\r\n return (\r\n <div className=\"st-call-controls\">\r\n <JoinCallButton />\r\n <LeaveCallButton />\r\n <MuteButton />\r\n <CameraToggle />\r\n <ScreenShareButton />\r\n </div>\r\n )\r\n}\r\n","import { Avatar as StreemoAvatar } from 'streemo-ui-kit-web'\r\n\r\nexport type AvatarProps = {\r\n name: string\r\n image?: string\r\n size?: number\r\n}\r\n\r\nexport function Avatar({ name, image, size = 32 }: AvatarProps) {\r\n return <StreemoAvatar name={name} src={image ?? undefined} size={size} />\r\n}\r\n","export type PresenceBadgeProps = {\r\n status: 'online' | 'offline' | 'away'\r\n}\r\n\r\nexport function PresenceBadge({ status }: PresenceBadgeProps) {\r\n return <span className={`st-presence st-presence--${status}`} aria-label={status} />\r\n}\r\n","import { PresenceBadge } from './PresenceBadge'\r\n\r\nexport type UserStatusProps = {\r\n name: string\r\n status: 'online' | 'offline' | 'away'\r\n}\r\n\r\nexport function UserStatus({ name, status }: UserStatusProps) {\r\n return (\r\n <div className=\"st-user-status\">\r\n <PresenceBadge status={status} />\r\n <span>{name}</span>\r\n </div>\r\n )\r\n}\r\n","import { Component, type ErrorInfo, type ReactNode } from 'react'\r\n\r\ntype ErrorBoundaryProps = {\r\n children: ReactNode\r\n fallback?: ReactNode\r\n}\r\n\r\ntype ErrorBoundaryState = {\r\n hasError: boolean\r\n}\r\n\r\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\r\n state: ErrorBoundaryState = { hasError: false }\r\n\r\n static getDerivedStateFromError(): ErrorBoundaryState {\r\n return { hasError: true }\r\n }\r\n\r\n componentDidCatch(error: Error, info: ErrorInfo): void {\r\n console.error('Streemo ErrorBoundary caught error', error, info)\r\n }\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n return this.props.fallback ?? <div className=\"st-error\">Something went wrong in Streemo UI.</div>\r\n }\r\n return this.props.children\r\n }\r\n}\r\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport type { ChatMessage, TypingParticipant } from './useWebRTCCall'\n\nexport type ChatPanelProps = {\n messages: ChatMessage[]\n typingParticipants: TypingParticipant[]\n unreadCount: number\n hasMore: boolean\n loadingHistory: boolean\n currentUserId: string\n onSend: (text: string) => void\n onEdit: (id: string, text: string) => void\n onDelete: (id: string) => void\n onTyping: (isTyping: boolean) => void\n onLoadMore: () => void\n onMarkRead: () => void\n onFocusChange?: (focused: boolean) => void\n placeholder?: string\n}\n\nexport function ChatPanel({\n messages,\n typingParticipants,\n unreadCount,\n hasMore,\n loadingHistory,\n currentUserId,\n onSend,\n onEdit,\n onDelete,\n onTyping,\n onLoadMore,\n onMarkRead,\n onFocusChange,\n placeholder = 'Write a message...',\n}: ChatPanelProps) {\n const [draft, setDraft] = useState('')\n const [editingId, setEditingId] = useState<string | null>(null)\n const [editingText, setEditingText] = useState('')\n const listRef = useRef<HTMLDivElement | null>(null)\n const typingTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const typingLine = useMemo(() => {\n if (typingParticipants.length === 0) return ''\n const names = typingParticipants.map((item) => item.senderName || 'Guest')\n if (names.length === 1) return `${names[0]} is typing...`\n if (names.length === 2) return `${names[0]} and ${names[1]} are typing...`\n return `${names[0]} and ${names.length - 1} others are typing...`\n }, [typingParticipants])\n\n useEffect(() => {\n if (!listRef.current) return\n const el = listRef.current\n const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 60\n if (nearBottom) {\n el.scrollTop = el.scrollHeight\n onMarkRead()\n }\n }, [messages, onMarkRead])\n\n const handleScroll = () => {\n const el = listRef.current\n if (!el) return\n if (el.scrollTop < 40 && hasMore && !loadingHistory) {\n onLoadMore()\n }\n const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 60\n if (nearBottom) {\n onMarkRead()\n }\n }\n\n const notifyTyping = () => {\n onTyping(true)\n if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current)\n typingTimeoutRef.current = setTimeout(() => onTyping(false), 1200)\n }\n\n return (\n <section className=\"vc-chat-panel\">\n <div className=\"vc-chat-header\">\n <h3>Chat</h3>\n {unreadCount > 0 && <span className=\"vc-chat-unread\">Unread: {unreadCount}</span>}\n </div>\n <div\n ref={listRef}\n className=\"vc-chat-list\"\n onScroll={handleScroll}\n onFocus={() => onFocusChange?.(true)}\n onBlur={() => onFocusChange?.(false)}\n tabIndex={0}\n >\n {hasMore && <p className=\"vc-chat-muted\">{loadingHistory ? 'Loading...' : 'Scroll up to load more'}</p>}\n {messages.map((message) => {\n const isOwn = message.userId === currentUserId\n return (\n <div key={message.id} className={`vc-chat-item ${isOwn ? 'own' : ''}`}>\n <p className=\"vc-chat-meta\">\n <strong>{message.senderName || 'Guest'}</strong>\n <span>{new Date(message.sentAt).toLocaleTimeString()}</span>\n {message.editedAt && <span>(edited)</span>}\n {message.deliveryStatus === 'sending' && <span>(sending)</span>}\n {message.deliveryStatus === 'failed' && <span>(failed)</span>}\n </p>\n {message.deletedAt ? (\n <p className=\"vc-chat-deleted\">Message deleted</p>\n ) : editingId === message.id ? (\n <div className=\"vc-chat-edit-row\">\n <input value={editingText} onChange={(e) => setEditingText(e.target.value)} />\n <button\n onClick={() => {\n onEdit(message.id, editingText)\n setEditingId(null)\n }}\n >\n Save\n </button>\n <button onClick={() => setEditingId(null)}>Cancel</button>\n </div>\n ) : (\n <p>{message.text}</p>\n )}\n {isOwn && !message.deletedAt && editingId !== message.id && (\n <div className=\"vc-chat-actions\">\n <button\n onClick={() => {\n setEditingId(message.id)\n setEditingText(message.text)\n }}\n >\n Edit\n </button>\n <button onClick={() => onDelete(message.id)}>Delete</button>\n </div>\n )}\n </div>\n )\n })}\n </div>\n {typingLine && <p className=\"vc-chat-muted\">{typingLine}</p>}\n <div className=\"vc-chat-input-row\">\n <input\n value={draft}\n placeholder={placeholder}\n onChange={(e) => {\n setDraft(e.target.value)\n notifyTyping()\n }}\n onFocus={() => onFocusChange?.(true)}\n onBlur={() => onFocusChange?.(false)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n const value = draft.trim()\n if (!value) return\n onSend(value)\n setDraft('')\n onTyping(false)\n }\n }}\n />\n <button\n onClick={() => {\n const value = draft.trim()\n if (!value) return\n onSend(value)\n setDraft('')\n onTyping(false)\n }}\n disabled={!draft.trim()}\n >\n Send\n </button>\n </div>\n </section>\n )\n}\n","import { useMemo } from 'react'\nimport { useWebRTCCall } from './useWebRTCCall'\nimport { VideoTile } from './VideoTile'\nimport { ChatPanel } from './ChatPanel'\nimport type { ServerAuthConfig } from './auth'\nimport type { TokenProvider } from './tokenProvider'\n\nexport type VideoCallWidgetProps = {\n roomId: string\n userId: string\n userName: string\n roomToken?: string\n wsBaseUrl?: string\n tokenProvider?: TokenProvider\n apiBaseUrl?: string\n auth?: ServerAuthConfig\n enabled: boolean\n localLabelSuffix?: string\n showChat?: boolean\n}\n\nexport function VideoCallWidget({\n roomId,\n userId,\n userName,\n roomToken,\n wsBaseUrl,\n tokenProvider,\n apiBaseUrl,\n auth,\n enabled,\n localLabelSuffix = '(you)',\n showChat = true,\n}: VideoCallWidgetProps) {\n const call = useWebRTCCall({\n roomId,\n userId,\n roomToken,\n wsBaseUrl,\n tokenProvider,\n apiBaseUrl,\n auth,\n enabled,\n })\n\n const remotes = useMemo(() => Object.entries(call.remoteStreams), [call.remoteStreams])\n\n return (\n <div className=\"vc-root\">\n <div className=\"vc-toolbar\">\n <span className=\"vc-muted\">\n WS: {call.connected ? 'connected' : 'disconnected'} | participants: {call.participants.length + 1}\n </span>\n <div className=\"vc-row vc-wrap\">\n <button onClick={call.toggleMic} disabled={!call.hasMicTrack}>\n {call.micEnabled ? 'Mute mic' : 'Unmute mic'}\n </button>\n <button onClick={call.toggleCamera} disabled={!call.hasCameraTrack}>\n {call.cameraEnabled ? 'Disable camera' : 'Enable camera'}\n </button>\n </div>\n </div>\n\n {call.error && <p className=\"vc-error\">{call.error}</p>}\n\n <section className=\"vc-video-grid\">\n <VideoTile stream={call.localStream} muted mirrored label={`${userName} ${localLabelSuffix}`.trim()} />\n {remotes.map(([peerUserId, stream]) => (\n <VideoTile\n key={peerUserId}\n stream={stream}\n label={`peer: ${peerUserId.slice(0, 8)}`}\n subtitle={`remote video: ${call.remoteTrackStates[peerUserId]?.video ? 'on' : 'off'} | remote audio: ${call.remoteTrackStates[peerUserId]?.audio ? 'on' : 'off'} | pc: ${call.remoteTrackStates[peerUserId]?.connectionState ?? 'new'}`}\n />\n ))}\n </section>\n {showChat && (\n <ChatPanel\n messages={call.chatMessages}\n typingParticipants={call.typingParticipants}\n unreadCount={call.chatUnreadCount}\n hasMore={call.chatHasMore}\n loadingHistory={call.chatLoadingHistory}\n currentUserId={userId}\n onSend={(text) => call.sendChatMessage(text, userName)}\n onEdit={call.editChatMessage}\n onDelete={call.deleteChatMessage}\n onTyping={(isTyping) => call.sendTyping(isTyping, userName)}\n onLoadMore={call.loadMoreChatMessages}\n onMarkRead={call.markChatRead}\n onFocusChange={call.setChatFocused}\n />\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","createTheme","useEffect","useState","useState","useEffect","useMemo","useEffect","useMemo","useState","useState","useEffect","useMemo","useEffect","useMemo","useState","useState","useEffect","useMemo","useMemo","useEffect","useMemo","useState","useState","useEffect","useMemo","useMemo","useState","useCallback","useEffect","useMemo","useRef","useState","useMemo","useRef","useState","useCallback","localStream","useEffect","useState","useMemo","useMemo","useMemo","useCallback","useEffect","useState","useState","useCallback","useEffect","jsx","jsx","jsx","jsxs","jsx","jsx","useMemo","useState","jsx","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useMemo","useState","jsx","jsxs","useState","jsx","createContext","useContext","jsx","createContext","useContext","useEffect","useMemo","useRef","useState","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","jsx","jsx","jsx","jsx","jsxs","jsx","jsx","jsx","jsxs","jsx","useEffect","useMemo","useRef","useState","jsx","jsxs","useMemo","jsx","jsxs","useMemo"]}
|