streemo-video-call-sdk 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +41 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -445,10 +445,10 @@ function usePresence() {
|
|
|
445
445
|
}
|
|
446
446
|
|
|
447
447
|
// src/hooks/useCall.ts
|
|
448
|
-
import { useMemo as
|
|
448
|
+
import { useMemo as useMemo7, useState as useState7 } from "react";
|
|
449
449
|
|
|
450
450
|
// src/useWebRTCCall.ts
|
|
451
|
-
import { useCallback as useCallback2, useEffect as useEffect6, useRef as useRef2, useState as useState6 } from "react";
|
|
451
|
+
import { useCallback as useCallback2, useEffect as useEffect6, useMemo as useMemo6, useRef as useRef2, useState as useState6 } from "react";
|
|
452
452
|
|
|
453
453
|
// src/auth.ts
|
|
454
454
|
function buildAuthHeaders(auth) {
|
|
@@ -773,7 +773,18 @@ function useWebRTCCall(params) {
|
|
|
773
773
|
};
|
|
774
774
|
const { roomId, userId, enabled } = mergedParams;
|
|
775
775
|
const { roomToken, wsBaseUrl, tokenProvider, apiBaseUrl, auth } = mergedParams;
|
|
776
|
+
const resolvedTokenProvider = useMemo6(() => {
|
|
777
|
+
if (tokenProvider) return tokenProvider;
|
|
778
|
+
if (auth) {
|
|
779
|
+
return createServerTokenProvider({
|
|
780
|
+
apiBaseUrl: apiBaseUrl || defaultApiBaseUrl(),
|
|
781
|
+
auth
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
return null;
|
|
785
|
+
}, [tokenProvider, auth?.authToken, auth?.appId, apiBaseUrl]);
|
|
776
786
|
const wsRef = useRef2(null);
|
|
787
|
+
const setupGenerationRef = useRef2(0);
|
|
777
788
|
const peersRef = useRef2(/* @__PURE__ */ new Map());
|
|
778
789
|
const localStreamRef = useRef2(null);
|
|
779
790
|
const remoteStreamsRef = useRef2({});
|
|
@@ -791,6 +802,8 @@ function useWebRTCCall(params) {
|
|
|
791
802
|
const pendingChatPatchesRef = useRef2(/* @__PURE__ */ new Map());
|
|
792
803
|
const typingTimersRef = useRef2(/* @__PURE__ */ new Map());
|
|
793
804
|
const isChatFocusedRef = useRef2(false);
|
|
805
|
+
const handleSignalMessageRef = useRef2(() => {
|
|
806
|
+
});
|
|
794
807
|
const [localStream, setLocalStream] = useState6(null);
|
|
795
808
|
const [remoteStreams, setRemoteStreams] = useState6({});
|
|
796
809
|
const [participants, setParticipants] = useState6([]);
|
|
@@ -1386,6 +1399,9 @@ function useWebRTCCall(params) {
|
|
|
1386
1399
|
userId
|
|
1387
1400
|
]
|
|
1388
1401
|
);
|
|
1402
|
+
useEffect6(() => {
|
|
1403
|
+
handleSignalMessageRef.current = handleSignalMessage;
|
|
1404
|
+
}, [handleSignalMessage]);
|
|
1389
1405
|
useEffect6(() => {
|
|
1390
1406
|
if (!enabled || !roomId || !userId) return;
|
|
1391
1407
|
const peers = peersRef.current;
|
|
@@ -1395,13 +1411,15 @@ function useWebRTCCall(params) {
|
|
|
1395
1411
|
enabled,
|
|
1396
1412
|
roomToken,
|
|
1397
1413
|
wsBaseUrl,
|
|
1398
|
-
tokenProvider,
|
|
1414
|
+
tokenProvider: resolvedTokenProvider ?? void 0,
|
|
1399
1415
|
apiBaseUrl,
|
|
1400
1416
|
auth
|
|
1401
1417
|
};
|
|
1402
1418
|
const setup = async () => {
|
|
1419
|
+
const myGen = ++setupGenerationRef.current;
|
|
1403
1420
|
try {
|
|
1404
1421
|
const resolvedRoomToken = await resolveRoomToken(currentParams);
|
|
1422
|
+
if (myGen !== setupGenerationRef.current) return;
|
|
1405
1423
|
const resolvedWsBaseUrl = resolveWsBaseUrl(currentParams);
|
|
1406
1424
|
if (!resolvedWsBaseUrl) {
|
|
1407
1425
|
setError("wsBaseUrl or apiBaseUrl is required");
|
|
@@ -1432,7 +1450,9 @@ function useWebRTCCall(params) {
|
|
|
1432
1450
|
throw err;
|
|
1433
1451
|
}
|
|
1434
1452
|
}
|
|
1453
|
+
if (myGen !== setupGenerationRef.current) return;
|
|
1435
1454
|
await tuneLocalStream(acquiredLocalStream);
|
|
1455
|
+
if (myGen !== setupGenerationRef.current) return;
|
|
1436
1456
|
localStreamRef.current = acquiredLocalStream;
|
|
1437
1457
|
setLocalStream(acquiredLocalStream);
|
|
1438
1458
|
syncLocalTrackFlags();
|
|
@@ -1452,7 +1472,7 @@ function useWebRTCCall(params) {
|
|
|
1452
1472
|
};
|
|
1453
1473
|
ws.onmessage = (event) => {
|
|
1454
1474
|
const message = JSON.parse(event.data);
|
|
1455
|
-
void
|
|
1475
|
+
void handleSignalMessageRef.current(message);
|
|
1456
1476
|
};
|
|
1457
1477
|
} catch (err) {
|
|
1458
1478
|
const mappedMessage = mapSDKErrorToUIMessage(err);
|
|
@@ -1506,13 +1526,12 @@ function useWebRTCCall(params) {
|
|
|
1506
1526
|
apiBaseUrl,
|
|
1507
1527
|
auth,
|
|
1508
1528
|
enabled,
|
|
1509
|
-
handleSignalMessage,
|
|
1510
1529
|
removePeer,
|
|
1530
|
+
resolvedTokenProvider,
|
|
1511
1531
|
roomId,
|
|
1512
1532
|
roomToken,
|
|
1513
1533
|
send,
|
|
1514
1534
|
syncLocalTrackFlags,
|
|
1515
|
-
tokenProvider,
|
|
1516
1535
|
userId,
|
|
1517
1536
|
wsBaseUrl
|
|
1518
1537
|
]);
|
|
@@ -1660,17 +1679,18 @@ function useWebRTCCall(params) {
|
|
|
1660
1679
|
function useCall({ roomId, enabled = true }) {
|
|
1661
1680
|
const { client } = useStreemoContext();
|
|
1662
1681
|
const [joined, setJoined] = useState7(enabled);
|
|
1682
|
+
const auth = useMemo7(
|
|
1683
|
+
() => ({ appId: client.apiKey, authToken: client.userToken }),
|
|
1684
|
+
[client.apiKey, client.userToken]
|
|
1685
|
+
);
|
|
1663
1686
|
const call = useWebRTCCall({
|
|
1664
1687
|
roomId,
|
|
1665
1688
|
userId: client.user.id,
|
|
1666
1689
|
enabled: joined,
|
|
1667
1690
|
apiBaseUrl: client.baseUrl,
|
|
1668
|
-
auth
|
|
1669
|
-
appId: client.apiKey,
|
|
1670
|
-
authToken: client.userToken
|
|
1671
|
-
}
|
|
1691
|
+
auth
|
|
1672
1692
|
});
|
|
1673
|
-
return
|
|
1693
|
+
return useMemo7(
|
|
1674
1694
|
() => ({
|
|
1675
1695
|
...call,
|
|
1676
1696
|
joined,
|
|
@@ -1682,10 +1702,10 @@ function useCall({ roomId, enabled = true }) {
|
|
|
1682
1702
|
}
|
|
1683
1703
|
|
|
1684
1704
|
// src/hooks/useParticipants.ts
|
|
1685
|
-
import { useMemo as
|
|
1705
|
+
import { useMemo as useMemo8 } from "react";
|
|
1686
1706
|
function useParticipants(params) {
|
|
1687
1707
|
const call = useCall(params);
|
|
1688
|
-
return
|
|
1708
|
+
return useMemo8(
|
|
1689
1709
|
() => ({
|
|
1690
1710
|
participants: call.participants.map((userId) => ({
|
|
1691
1711
|
userId,
|
|
@@ -1753,7 +1773,7 @@ function Channel({ channelId, children }) {
|
|
|
1753
1773
|
}
|
|
1754
1774
|
|
|
1755
1775
|
// src/components/chat/MessageList.tsx
|
|
1756
|
-
import { useMemo as
|
|
1776
|
+
import { useMemo as useMemo9, useState as useState8 } from "react";
|
|
1757
1777
|
|
|
1758
1778
|
// src/components/chat/AttachmentPreview.tsx
|
|
1759
1779
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
@@ -1807,7 +1827,7 @@ import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
|
1807
1827
|
function MessageList({ channelId }) {
|
|
1808
1828
|
const { channelId: resolvedChannelId, messages, loading, hasMore, loadingMore, loadMore } = useChannel(channelId);
|
|
1809
1829
|
const [threadParent, setThreadParent] = useState8(null);
|
|
1810
|
-
const threadMessages =
|
|
1830
|
+
const threadMessages = useMemo9(
|
|
1811
1831
|
() => messages.filter((message) => message.parentId === threadParent?.id),
|
|
1812
1832
|
[messages, threadParent?.id]
|
|
1813
1833
|
);
|
|
@@ -1887,7 +1907,7 @@ function useCallRoomContext() {
|
|
|
1887
1907
|
}
|
|
1888
1908
|
|
|
1889
1909
|
// src/VideoTile.tsx
|
|
1890
|
-
import { useEffect as useEffect7, useMemo as
|
|
1910
|
+
import { useEffect as useEffect7, useMemo as useMemo10, useRef as useRef3, useState as useState10 } from "react";
|
|
1891
1911
|
import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1892
1912
|
function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, i18n }) {
|
|
1893
1913
|
const ref = useRef3(null);
|
|
@@ -1898,7 +1918,7 @@ function VideoTile({ stream, muted = false, mirrored = false, label, subtitle, i
|
|
|
1898
1918
|
audioOnlyMuted: i18n?.audioOnlyMuted ?? "Microphone only",
|
|
1899
1919
|
audioOnlyConnected: i18n?.audioOnlyConnected ?? "Audio connected"
|
|
1900
1920
|
};
|
|
1901
|
-
const initials =
|
|
1921
|
+
const initials = useMemo10(() => {
|
|
1902
1922
|
const parts = label.replace(/\(.*\)/g, "").trim().split(/\s+/).filter(Boolean);
|
|
1903
1923
|
if (parts.length === 0) return "U";
|
|
1904
1924
|
if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
|
|
@@ -2093,7 +2113,7 @@ var ErrorBoundary = class extends Component {
|
|
|
2093
2113
|
};
|
|
2094
2114
|
|
|
2095
2115
|
// src/ChatPanel.tsx
|
|
2096
|
-
import { useEffect as useEffect8, useMemo as
|
|
2116
|
+
import { useEffect as useEffect8, useMemo as useMemo11, useRef as useRef4, useState as useState12 } from "react";
|
|
2097
2117
|
import { jsx as jsx29, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2098
2118
|
function ChatPanel({
|
|
2099
2119
|
messages,
|
|
@@ -2116,7 +2136,7 @@ function ChatPanel({
|
|
|
2116
2136
|
const [editingText, setEditingText] = useState12("");
|
|
2117
2137
|
const listRef = useRef4(null);
|
|
2118
2138
|
const typingTimeoutRef = useRef4(null);
|
|
2119
|
-
const typingLine =
|
|
2139
|
+
const typingLine = useMemo11(() => {
|
|
2120
2140
|
if (typingParticipants.length === 0) return "";
|
|
2121
2141
|
const names = typingParticipants.map((item) => item.senderName || "Guest");
|
|
2122
2142
|
if (names.length === 1) return `${names[0]} is typing...`;
|
|
@@ -2253,7 +2273,7 @@ function ChatPanel({
|
|
|
2253
2273
|
}
|
|
2254
2274
|
|
|
2255
2275
|
// src/VideoCallWidget.tsx
|
|
2256
|
-
import { useMemo as
|
|
2276
|
+
import { useMemo as useMemo12 } from "react";
|
|
2257
2277
|
import { jsx as jsx30, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2258
2278
|
function VideoCallWidget({
|
|
2259
2279
|
roomId,
|
|
@@ -2278,7 +2298,7 @@ function VideoCallWidget({
|
|
|
2278
2298
|
auth,
|
|
2279
2299
|
enabled
|
|
2280
2300
|
});
|
|
2281
|
-
const remotes =
|
|
2301
|
+
const remotes = useMemo12(() => Object.entries(call.remoteStreams), [call.remoteStreams]);
|
|
2282
2302
|
return /* @__PURE__ */ jsxs12("div", { className: "vc-root", children: [
|
|
2283
2303
|
/* @__PURE__ */ jsxs12("div", { className: "vc-toolbar", children: [
|
|
2284
2304
|
/* @__PURE__ */ jsxs12("span", { className: "vc-muted", children: [
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/StreemoClient.ts","../src/provider/StreemoProvider.tsx","../src/theme/StreemoTheme.tsx","../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/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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyListener = (payload: any) => void\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 { 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\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 style: CSSProperties = {\r\n ['--st-color-primary' as string]: theme?.primary ?? '#635bff',\r\n ['--st-color-bg' as string]: theme?.background ?? (mode === 'dark' ? '#111827' : '#ffffff'),\r\n ['--st-color-text' as string]: theme?.text ?? (mode === 'dark' ? '#f9fafb' : '#0f172a'),\r\n ['--st-radius' as string]: theme?.radius ?? '10px',\r\n }\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","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) => 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\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 appId: client.apiKey,\r\n authToken: client.userToken,\r\n },\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, 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\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'\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 const wsRef = useRef<WebSocket | null>(null)\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 [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\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)\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)\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 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,\n apiBaseUrl,\n auth,\n }\n\n const setup = async () => {\n try {\n const resolvedRoomToken = await resolveRoomToken(currentParams)\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 await tuneLocalStream(acquiredLocalStream)\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 handleSignalMessage(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 syncLocalTrackFlags()\n }\n }, [\n apiBaseUrl,\n auth,\n enabled,\n handleSignalMessage,\n removePeer,\n roomId,\n roomToken,\n send,\n syncLocalTrackFlags,\n tokenProvider,\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 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 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 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","export 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 <span className=\"st-spinner__dot\" />\r\n <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 update = () => {\n const hasVideo = stream\n .getVideoTracks()\n .some((track) => track.readyState === 'live' && track.enabled)\n setHasVideoTrack(hasVideo)\n }\n\n update()\n stream.getVideoTracks().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\n return () => {\n stream.getVideoTracks().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 }, [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 { useState } from 'react'\r\n\r\nexport function ScreenShareButton() {\r\n const [sharing, setSharing] = useState(false)\r\n return (\r\n <button\r\n onClick={() => {\r\n setSharing((prev) => !prev)\r\n }}\r\n >\r\n {sharing ? '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","export 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 if (image) {\r\n return <img className=\"st-avatar\" src={image} alt={name} style={{ width: size, height: size }} />\r\n }\r\n return (\r\n <div className=\"st-avatar st-avatar--fallback\" style={{ width: size, height: size }}>\r\n {name.slice(0, 1).toUpperCase()}\r\n </div>\r\n )\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","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","useRef","useState","useRef","useState","useCallback","localStream","useEffect","useState","useMemo","useMemo","useMemo","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","useState","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/provider/StreemoProvider.tsx","../src/theme/StreemoTheme.tsx","../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/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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyListener = (payload: any) => void\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 { 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\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 style: CSSProperties = {\r\n ['--st-color-primary' as string]: theme?.primary ?? '#635bff',\r\n ['--st-color-bg' as string]: theme?.background ?? (mode === 'dark' ? '#111827' : '#ffffff'),\r\n ['--st-color-text' as string]: theme?.text ?? (mode === 'dark' ? '#f9fafb' : '#0f172a'),\r\n ['--st-radius' as string]: theme?.radius ?? '10px',\r\n }\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","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) => 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\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'\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\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)\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)\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 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 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 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 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","export 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 <span className=\"st-spinner__dot\" />\r\n <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 update = () => {\n const hasVideo = stream\n .getVideoTracks()\n .some((track) => track.readyState === 'live' && track.enabled)\n setHasVideoTrack(hasVideo)\n }\n\n update()\n stream.getVideoTracks().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\n return () => {\n stream.getVideoTracks().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 }, [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 { useState } from 'react'\r\n\r\nexport function ScreenShareButton() {\r\n const [sharing, setSharing] = useState(false)\r\n return (\r\n <button\r\n onClick={() => {\r\n setSharing((prev) => !prev)\r\n }}\r\n >\r\n {sharing ? '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","export 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 if (image) {\r\n return <img className=\"st-avatar\" src={image} alt={name} style={{ width: size, height: size }} />\r\n }\r\n return (\r\n <div className=\"st-avatar st-avatar--fallback\" style={{ width: size, height: size }}>\r\n {name.slice(0, 1).toUpperCase()}\r\n </div>\r\n )\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","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","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","useState","jsx","jsx","jsxs","jsx","jsx","jsx","jsxs","jsx","useEffect","useMemo","useRef","useState","jsx","jsxs","useMemo","jsx","jsxs","useMemo"]}
|