@xipkg/calls 0.0.0 → 0.0.3
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.mjs +52 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useCallback, useState, useMemo } from 'react';
|
|
2
|
-
import { useCallsNavigation, useRoom, useCalls } from '@xipkg/calls-providers';
|
|
3
|
-
import { useInitUserDevices, useVideoSecurity, useParticipantJoinSync, useVideoBlur, usePersistentUserChoices, useResolveInitiallyDefaultDeviceId, useCannotUseDevice } from '@xipkg/calls-hooks';
|
|
4
|
-
import { useCallStore, useFocusModeStore,
|
|
2
|
+
import { useCallsNavigation, useCallsRuntimeConfig, useRoom, useCalls } from '@xipkg/calls-providers';
|
|
3
|
+
import { useInitUserDevices, useVideoSecurity, useParticipantJoinSync, useParticipantSounds, useVideoBlur, usePersistentUserChoices, useResolveInitiallyDefaultDeviceId, useNoiseCancellation, useCannotUseDevice } from '@xipkg/calls-hooks';
|
|
4
|
+
import { useCallStore, useFocusModeStore, usePermissionsStore, openPermissionsDialog } from '@xipkg/calls-store';
|
|
5
5
|
import { ScrollArea } from '@xipkg/scrollarea';
|
|
6
6
|
import { Button } from '@xipkg/button';
|
|
7
7
|
import { WhiteBoard, ArrowLeft, InfoCircle, Settings, Conference, SoundTwo, Microphone } from '@xipkg/icons';
|
|
@@ -9,19 +9,21 @@ import { Tooltip, TooltipTrigger, TooltipContent } from '@xipkg/tooltip';
|
|
|
9
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
import { Avatar, AvatarImage, AvatarFallback } from '@xipkg/avatar';
|
|
11
11
|
import { Track, createLocalVideoTrack, createLocalAudioTrack, facingModeFromLocalTrack } from 'livekit-client';
|
|
12
|
-
import { CallsOnboarding, UpBar, VideoGrid,
|
|
12
|
+
import { CallsOnboarding, UpBar, VideoGrid, DevicesBar, ScreenShareButton, WhiteBoardButton, DisconnectButton, NoiseCancellationSettings, SecureVideo } from '@xipkg/calls-ui';
|
|
13
13
|
import { isSafari } from '@xipkg/calls-utils';
|
|
14
|
-
import {
|
|
14
|
+
import { Toggle } from '@xipkg/toggle';
|
|
15
15
|
import { Label } from '@xipkg/label';
|
|
16
16
|
import { Alert, AlertIcon, AlertContainer, AlertDescription } from '@xipkg/alert';
|
|
17
17
|
import { computeMenuPosition, wasClickOutside } from '@livekit/components-core';
|
|
18
18
|
import { Select, SelectTrigger, SelectValue, SelectContent, SelectGroup, SelectItem } from '@xipkg/select';
|
|
19
19
|
import { useLocalParticipant, usePreviewTracks, usePersistentUserChoices as usePersistentUserChoices$1, useTrackToggle, useMediaDeviceSelect } from '@livekit/components-react';
|
|
20
20
|
import { supportsBackgroundProcessors } from '@livekit/track-processors';
|
|
21
|
+
import { getBaselineAudioCaptureOptions } from '@xipkg/calls-config';
|
|
21
22
|
import { Chat, useChatStore, ChatButton } from '@xipkg/calls-chat';
|
|
22
23
|
import { useHandFocus, RaiseHandButton } from '@xipkg/calls-risehand';
|
|
23
24
|
import { cn } from '@xipkg/utils';
|
|
24
25
|
import '@xipkg/calls-ui/video-security.css';
|
|
26
|
+
import '@xipkg/calls-ui/grid.css';
|
|
25
27
|
|
|
26
28
|
// src/ui/Call.tsx
|
|
27
29
|
var Header = () => {
|
|
@@ -111,7 +113,7 @@ var Controls = ({ audioTrack, videoTrack }) => {
|
|
|
111
113
|
}),
|
|
112
114
|
[handleVideoChange]
|
|
113
115
|
);
|
|
114
|
-
return /* @__PURE__ */ jsx("div", { className: "bg-gray-0 border-gray-10 flex h-
|
|
116
|
+
return /* @__PURE__ */ jsx("div", { className: "bg-gray-0 border-gray-10 flex h-[48px] w-[92px] items-center justify-center gap-1 rounded-[16px] border", children: /* @__PURE__ */ jsx(
|
|
115
117
|
DevicesBar,
|
|
116
118
|
{
|
|
117
119
|
microTrack: audioTrack,
|
|
@@ -327,7 +329,7 @@ var UserTile = ({ audioTrack, videoTrack }) => {
|
|
|
327
329
|
}
|
|
328
330
|
);
|
|
329
331
|
};
|
|
330
|
-
var MediaDeviceSelect = ({ devices }) => /* @__PURE__ */ jsx("ul", { children: devices && devices.map((device) => /* @__PURE__ */ jsx("li", { id: device.deviceId, children: /* @__PURE__ */ jsx(SelectItem, { value: device.deviceId ?? "default", children: device.label }) }, device.deviceId)) });
|
|
332
|
+
var MediaDeviceSelect = ({ devices }) => /* @__PURE__ */ jsx("ul", { children: devices && devices.map((device) => /* @__PURE__ */ jsx("li", { id: device.deviceId, children: /* @__PURE__ */ jsx(SelectItem, { className: "h-auto", value: device.deviceId ?? "default", children: device.label }) }, device.deviceId)) });
|
|
331
333
|
var placeholders = {
|
|
332
334
|
audioinput: "\u0412\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 \u043C\u0438\u043A\u0440\u043E\u0444\u043E\u043D",
|
|
333
335
|
audiooutput: "\u0412\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u0434\u0438\u043D\u0430\u043C\u0438\u043A\u0438",
|
|
@@ -525,7 +527,7 @@ var MediaDevices = ({ audioTrack, videoTrack, noiseCancellation }) => {
|
|
|
525
527
|
[videoTrack, saveVideoInputDeviceId, saveVideoInputEnabled]
|
|
526
528
|
);
|
|
527
529
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
528
|
-
/* @__PURE__ */ jsxs("div", { className: "border-gray-30 flex flex-col justify-between rounded-
|
|
530
|
+
/* @__PURE__ */ jsxs("div", { className: "border-gray-30 bg-gray-0 flex flex-col justify-between rounded-2xl border p-5", children: [
|
|
529
531
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
530
532
|
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
531
533
|
/* @__PURE__ */ jsx("h2", { className: "mb-1 font-sans", children: "\u041A\u0430\u043C\u0435\u0440\u0430" }),
|
|
@@ -567,7 +569,7 @@ var MediaDevices = ({ audioTrack, videoTrack, noiseCancellation }) => {
|
|
|
567
569
|
] }),
|
|
568
570
|
isBlurSupported && /* @__PURE__ */ jsx("div", { className: "my-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
569
571
|
/* @__PURE__ */ jsx(Label, { className: "font-medium text-gray-100", children: "\u0420\u0430\u0437\u043C\u044B\u0442\u0438\u0435 \u0444\u043E\u043D\u0430" }),
|
|
570
|
-
/* @__PURE__ */ jsx(
|
|
572
|
+
/* @__PURE__ */ jsx(Toggle, { checked: blurEnabled, onCheckedChange: saveBlurEnabled })
|
|
571
573
|
] }) }),
|
|
572
574
|
noiseCancellation && /* @__PURE__ */ jsx("div", { className: "my-4", children: /* @__PURE__ */ jsx(NoiseCancellationSettings, { nc: noiseCancellation, hideOffOption: true }) })
|
|
573
575
|
] }),
|
|
@@ -585,6 +587,9 @@ var PreJoin = () => {
|
|
|
585
587
|
saveAudioInputDeviceId,
|
|
586
588
|
saveVideoInputDeviceId
|
|
587
589
|
} = usePersistentUserChoices();
|
|
590
|
+
const {
|
|
591
|
+
noiseCancellation: { featureEnabled: noiseCancellationFeatureEnabled }
|
|
592
|
+
} = useCallsRuntimeConfig();
|
|
588
593
|
const initialUserChoices = useRef(null);
|
|
589
594
|
if (initialUserChoices.current === null) {
|
|
590
595
|
initialUserChoices.current = {
|
|
@@ -598,25 +603,24 @@ var PreJoin = () => {
|
|
|
598
603
|
console.error("PreJoin ERROR:", e);
|
|
599
604
|
}, []);
|
|
600
605
|
useEffect(() => {
|
|
601
|
-
|
|
606
|
+
let cancelled = false;
|
|
607
|
+
const request = async () => {
|
|
602
608
|
try {
|
|
603
|
-
const
|
|
604
|
-
if (
|
|
605
|
-
|
|
606
|
-
video: true,
|
|
607
|
-
audio: true
|
|
608
|
-
});
|
|
609
|
-
stream.getTracks().forEach((track) => track.stop());
|
|
610
|
-
}
|
|
611
|
-
} catch (error) {
|
|
612
|
-
console.log("Permission request failed:", error);
|
|
609
|
+
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
|
|
610
|
+
if (!cancelled) stream.getTracks().forEach((t) => t.stop());
|
|
611
|
+
} catch {
|
|
613
612
|
}
|
|
614
613
|
};
|
|
615
|
-
|
|
614
|
+
request();
|
|
615
|
+
return () => {
|
|
616
|
+
cancelled = true;
|
|
617
|
+
};
|
|
616
618
|
}, []);
|
|
619
|
+
const baselineAudio = getBaselineAudioCaptureOptions();
|
|
617
620
|
const tracks = usePreviewTracks(
|
|
618
621
|
{
|
|
619
622
|
audio: !!initialUserChoices.current && initialUserChoices.current?.audioEnabled && {
|
|
623
|
+
...baselineAudio,
|
|
620
624
|
deviceId: initialUserChoices.current.audioDeviceId
|
|
621
625
|
},
|
|
622
626
|
video: !!initialUserChoices.current && initialUserChoices.current?.videoEnabled && {
|
|
@@ -654,6 +658,7 @@ var PreJoin = () => {
|
|
|
654
658
|
const createAudioTrack = async () => {
|
|
655
659
|
try {
|
|
656
660
|
const track = await createLocalAudioTrack({
|
|
661
|
+
...getBaselineAudioCaptureOptions(),
|
|
657
662
|
deviceId: { exact: audioDeviceId }
|
|
658
663
|
});
|
|
659
664
|
setDynamicAudioTrack(track);
|
|
@@ -677,47 +682,26 @@ var PreJoin = () => {
|
|
|
677
682
|
}, [dynamicAudioTrack]);
|
|
678
683
|
const videoTrack = dynamicVideoTrack || previewVideoTrack;
|
|
679
684
|
const audioTrack = dynamicAudioTrack || previewAudioTrack;
|
|
680
|
-
useEffect(() => {
|
|
681
|
-
console.log("PreJoin tracks debug:", {
|
|
682
|
-
initialUserChoices: initialUserChoices.current,
|
|
683
|
-
videoEnabled,
|
|
684
|
-
audioEnabled,
|
|
685
|
-
videoDeviceId,
|
|
686
|
-
audioDeviceId,
|
|
687
|
-
tracks: tracks?.map((t) => ({ kind: t.kind, enabled: !t.isMuted })),
|
|
688
|
-
previewVideoTrack: previewVideoTrack ? { enabled: !previewVideoTrack.isMuted } : null,
|
|
689
|
-
previewAudioTrack: previewAudioTrack ? { enabled: !previewAudioTrack.isMuted } : null,
|
|
690
|
-
dynamicVideoTrack: dynamicVideoTrack ? { enabled: !dynamicVideoTrack.isMuted } : null,
|
|
691
|
-
dynamicAudioTrack: dynamicAudioTrack ? { enabled: !dynamicAudioTrack.isMuted } : null,
|
|
692
|
-
finalVideoTrack: videoTrack ? { enabled: !videoTrack.isMuted } : null,
|
|
693
|
-
finalAudioTrack: audioTrack ? { enabled: !audioTrack.isMuted } : null
|
|
694
|
-
});
|
|
695
|
-
}, [
|
|
696
|
-
tracks,
|
|
697
|
-
previewVideoTrack,
|
|
698
|
-
previewAudioTrack,
|
|
699
|
-
dynamicVideoTrack,
|
|
700
|
-
dynamicAudioTrack,
|
|
701
|
-
videoTrack,
|
|
702
|
-
audioTrack,
|
|
703
|
-
videoEnabled,
|
|
704
|
-
audioEnabled,
|
|
705
|
-
videoDeviceId,
|
|
706
|
-
audioDeviceId
|
|
707
|
-
]);
|
|
708
685
|
useResolveInitiallyDefaultDeviceId(audioDeviceId, audioTrack, saveAudioInputDeviceId);
|
|
709
686
|
useResolveInitiallyDefaultDeviceId(videoDeviceId, videoTrack, saveVideoInputDeviceId);
|
|
710
687
|
useVideoBlur(videoTrack);
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
688
|
+
const noiseCancellation = useNoiseCancellation(null, {
|
|
689
|
+
localAudioTrack: audioTrack ?? void 0
|
|
690
|
+
});
|
|
691
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ScrollArea, { className: "h-full w-full", children: /* @__PURE__ */ jsxs("div", { className: "bg-gray-5 h-full min-h-[calc(100dvh)] p-5", children: [
|
|
692
|
+
/* @__PURE__ */ jsx(Header, {}),
|
|
693
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-8 lg:grid-cols-2", children: [
|
|
694
|
+
/* @__PURE__ */ jsx(UserTile, { audioTrack, videoTrack }),
|
|
695
|
+
/* @__PURE__ */ jsx(
|
|
696
|
+
MediaDevices,
|
|
697
|
+
{
|
|
698
|
+
audioTrack,
|
|
699
|
+
videoTrack,
|
|
700
|
+
noiseCancellation: noiseCancellationFeatureEnabled ? noiseCancellation : void 0
|
|
701
|
+
}
|
|
702
|
+
)
|
|
703
|
+
] })
|
|
704
|
+
] }) }) });
|
|
721
705
|
};
|
|
722
706
|
var BottomBar = ({ saveUserChoices = true }) => {
|
|
723
707
|
const { saveAudioInputEnabled, saveVideoInputEnabled } = usePersistentUserChoices$1({
|
|
@@ -754,11 +738,6 @@ var BottomBar = ({ saveUserChoices = true }) => {
|
|
|
754
738
|
const { useCurrentUser } = useCalls().auth;
|
|
755
739
|
const { data: user } = useCurrentUser();
|
|
756
740
|
const isTutor = user?.default_layout === "tutor";
|
|
757
|
-
const {
|
|
758
|
-
chat: isChatEnabled,
|
|
759
|
-
raiseHand: isRiseHandEnabled,
|
|
760
|
-
whiteboard: isWhiteboardEnabled
|
|
761
|
-
} = useFeaturesStore((s) => s.features);
|
|
762
741
|
const showBackToBoardButton = mode === "full" && activeBoardId && activeClassroom && room && token && room.state === "connected";
|
|
763
742
|
const handleBackToBoard = () => {
|
|
764
743
|
if (!activeBoardId || !activeClassroom) {
|
|
@@ -796,9 +775,9 @@ var BottomBar = ({ saveUserChoices = true }) => {
|
|
|
796
775
|
) }),
|
|
797
776
|
/* @__PURE__ */ jsxs("div", { className: "bg-gray-0 border-gray-10 flex h-[48px] items-center justify-center gap-1 rounded-[16px] border p-1", children: [
|
|
798
777
|
/* @__PURE__ */ jsx(ScreenShareButton, {}),
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
778
|
+
isTutor && /* @__PURE__ */ jsx(WhiteBoardButton, {}),
|
|
779
|
+
/* @__PURE__ */ jsx(ChatButton, {}),
|
|
780
|
+
/* @__PURE__ */ jsx(RaiseHandButton, {})
|
|
802
781
|
] })
|
|
803
782
|
] }),
|
|
804
783
|
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-row items-center justify-center gap-4", children: [
|
|
@@ -824,23 +803,23 @@ var BottomBar = ({ saveUserChoices = true }) => {
|
|
|
824
803
|
] }) });
|
|
825
804
|
};
|
|
826
805
|
var ActiveRoom = () => {
|
|
827
|
-
const { chat: isChatEnabled } = useFeaturesStore((s) => s.features);
|
|
828
806
|
useHandFocus();
|
|
829
807
|
useParticipantJoinSync();
|
|
808
|
+
useParticipantSounds();
|
|
830
809
|
const { cameraTrack } = useLocalParticipant();
|
|
831
810
|
const videoTrack = cameraTrack?.track;
|
|
832
811
|
const mode = useCallStore((state) => state.mode);
|
|
833
812
|
const videoTrackForBlur = mode === "full" ? videoTrack : null;
|
|
834
813
|
useVideoBlur(videoTrackForBlur);
|
|
835
|
-
return /* @__PURE__ */
|
|
814
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col justify-stretch", children: [
|
|
836
815
|
/* @__PURE__ */ jsx(CallsOnboarding, {}),
|
|
837
816
|
/* @__PURE__ */ jsx(UpBar, {}),
|
|
838
|
-
/* @__PURE__ */ jsxs("div", { className: "flex h-full items-center justify-center gap-4 overflow-hidden
|
|
839
|
-
/* @__PURE__ */ jsx("div", { className: "flex h-full w-full justify-center text-center text-gray-100", children: /* @__PURE__ */ jsx(VideoGrid, {}) }),
|
|
840
|
-
|
|
817
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-1 items-center justify-center gap-4 overflow-hidden sm:px-4", children: [
|
|
818
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-full min-h-0 w-full min-w-0 justify-center text-center text-gray-100", children: /* @__PURE__ */ jsx(VideoGrid, {}) }),
|
|
819
|
+
/* @__PURE__ */ jsx(Chat, {})
|
|
841
820
|
] }),
|
|
842
821
|
/* @__PURE__ */ jsx(BottomBar, {})
|
|
843
|
-
] })
|
|
822
|
+
] });
|
|
844
823
|
};
|
|
845
824
|
var Call = () => {
|
|
846
825
|
const isStarted = useCallStore((state) => state.isStarted);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/PreJoin/components/Header/Header.tsx","../src/ui/PreJoin/components/UserTile/Controls.tsx","../src/ui/PreJoin/components/UserTile/UserTile.tsx","../src/ui/PreJoin/components/MediaDevices/MediaDeviceSelect.tsx","../src/ui/PreJoin/components/MediaDevices/MediaDeviceMenu.tsx","../src/ui/PreJoin/components/MediaDevices/MediaDevices.tsx","../src/ui/PreJoin/PreJoin.tsx","../src/ui/Bottom/BottomBar.tsx","../src/ui/Room/ActiveRoom.tsx","../src/ui/Call.tsx"],"names":["jsx","useMemo","jsxs","Button","useCalls","usePersistentUserChoices","facingMode","kind","useRef","useCallback","useEffect","useState","Track","useCallStore","useRoom","useCallsNavigation","DevicesBar","Tooltip","TooltipTrigger","TooltipContent","useFeaturesStore","useLocalParticipant","useVideoBlur"],"mappings":"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","file":"index.mjs","sourcesContent":["import { Button } from '@xipkg/button';\nimport { ArrowLeft } from '@xipkg/icons';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport { useCalls, useCallsNavigation } from '@xipkg/calls-providers';\n\n/* eslint-disable no-irregular-whitespace */\nexport const Header = () => {\n const navigation = useCallsNavigation();\n const callId = navigation.getCallId();\n\n const { room } = useCalls();\n const { data: classroom } = room.useGetClassroom(Number(callId));\n\n return (\n <div className=\"mb-4 flex flex-col items-start gap-2 sm:flex-row sm:items-center\">\n <div className=\"flex flex-row items-center gap-2\">\n <Tooltip delayDuration={1000}>\n <TooltipTrigger asChild>\n <Button\n onClick={() => {\n if (callId) {\n navigation.navigateToClassroom(callId);\n }\n }}\n type=\"button\"\n variant=\"none\"\n className=\"flex size-[40px] min-h-[40xp] min-w-[40px] items-center justify-center rounded-[12px] p-0\"\n >\n <ArrowLeft className=\"fill-gray-100\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"start\">\n Вернуться в кабинет\n </TooltipContent>\n </Tooltip>\n <h1 className=\"text-xl-base font-semibold text-gray-100\">Присоединиться к занятию</h1>\n </div>\n <p className=\"text-s-base text-gray-60 pt-0 pl-12 align-baseline sm:pt-2 sm:pl-0\">\n {classroom?.name}\n </p>\n </div>\n );\n};\n","import { LocalAudioTrack, LocalVideoTrack, Track } from 'livekit-client';\nimport { useCallback, useMemo } from 'react';\n\nimport { DevicesBar } from '@xipkg/calls-ui';\nimport { usePersistentUserChoices } from '@xipkg/calls-hooks';\n\ntype ControlsProps = {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n};\n\nexport const Controls = ({ audioTrack, videoTrack }: ControlsProps) => {\n const {\n userChoices: { audioEnabled, videoEnabled },\n saveAudioInputEnabled,\n saveVideoInputEnabled,\n } = usePersistentUserChoices();\n\n const handleAudioChange = useCallback(\n async (enabled: boolean) => {\n // console.log('Controls: handleAudioChange', {\n // enabled,\n // audioTrack: !!audioTrack,\n // currentMuted: audioTrack?.isMuted,\n // });\n saveAudioInputEnabled(enabled);\n if (audioTrack) {\n if (enabled) {\n console.log('Controls: unmuting audio track');\n await audioTrack.unmute();\n } else {\n console.log('Controls: muting audio track');\n await audioTrack.mute();\n }\n console.log('Controls: audio track state after change', { muted: audioTrack.isMuted });\n } else {\n console.log('Controls: no audio track available');\n }\n },\n [audioTrack, saveAudioInputEnabled],\n );\n\n const handleVideoChange = useCallback(\n async (enabled: boolean) => {\n // console.log('Controls: handleVideoChange', {\n // enabled,\n // videoTrack: !!videoTrack,\n // currentMuted: videoTrack?.isMuted,\n // });\n saveVideoInputEnabled(enabled);\n if (videoTrack) {\n if (enabled) {\n console.log('Controls: unmuting video track');\n await videoTrack.unmute();\n } else {\n console.log('Controls: muting video track');\n await videoTrack.mute();\n }\n console.log('Controls: video track state after change', { muted: videoTrack.isMuted });\n } else {\n console.log('Controls: no video track available');\n }\n },\n [videoTrack, saveVideoInputEnabled],\n );\n\n const microTrackToggle = useMemo(\n () => ({\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleAudioChange,\n }),\n [handleAudioChange],\n );\n\n const videoTrackToggle = useMemo(\n () => ({\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleVideoChange,\n }),\n [handleVideoChange],\n );\n\n return (\n <div className=\"bg-gray-0 border-gray-10 flex h-12 w-23 items-center justify-center gap-1 rounded-2xl border\">\n <DevicesBar\n microTrack={audioTrack}\n microEnabled={audioEnabled}\n microTrackToggle={microTrackToggle}\n videoTrack={videoTrack}\n videoEnabled={videoEnabled}\n videoTrackToggle={videoTrackToggle}\n />\n </div>\n );\n};\n","import { Avatar, AvatarFallback, AvatarImage } from '@xipkg/avatar';\nimport { useMemo, useRef, useEffect, useState } from 'react';\nimport { facingModeFromLocalTrack, LocalVideoTrack, LocalAudioTrack } from 'livekit-client';\nimport { Controls } from './Controls';\nimport { useCannotUseDevice, usePersistentUserChoices } from '@xipkg/calls-hooks';\nimport { openPermissionsDialog } from '@xipkg/calls-store';\nimport { Button } from '@xipkg/button';\nimport { SecureVideo } from '@xipkg/calls-ui';\nimport { Settings } from '@xipkg/icons';\nimport { isSafari } from '@xipkg/calls-utils';\nimport { useCalls } from '@xipkg/calls-providers';\n\nconst UserTileUI = ({\n audioTrack,\n videoTrack,\n videoEnabled,\n facingMode,\n videoEl,\n userId,\n isCameraDeniedOrPrompted,\n isMicrophoneDeniedOrPrompted,\n isVideoInitiated,\n}: {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n videoEnabled: boolean;\n facingMode: string;\n videoEl: React.RefObject<HTMLVideoElement | null>;\n userId: string;\n isCameraDeniedOrPrompted: boolean;\n isMicrophoneDeniedOrPrompted: boolean;\n isVideoInitiated: boolean;\n}) => {\n const isPermissionsBlocked = isCameraDeniedOrPrompted || isMicrophoneDeniedOrPrompted;\n\n const hintMessage = useMemo(() => {\n if (isPermissionsBlocked) {\n return null;\n }\n if (isCameraDeniedOrPrompted) {\n return isMicrophoneDeniedOrPrompted\n ? 'Камера и микрофон не разрешены'\n : 'Камера не разрешена';\n }\n if (!videoEnabled) {\n return 'Камера отключена';\n }\n if (!isVideoInitiated) {\n return 'Запуск камеры...';\n }\n if (videoTrack && videoEnabled) {\n return '';\n }\n return 'Камера недоступна';\n }, [\n videoTrack,\n videoEnabled,\n isCameraDeniedOrPrompted,\n isMicrophoneDeniedOrPrompted,\n isVideoInitiated,\n isPermissionsBlocked,\n ]);\n\n const permissionsInstructions = useMemo(() => {\n if (isSafari()) {\n const origin =\n typeof window !== 'undefined'\n ? (window.location?.origin?.replace('https://', '') ?? '')\n : '';\n return [\n `Нажмите на иконку ${origin} в адресной строке`,\n 'Снимите запрет на использование камеры и микрофона',\n ];\n }\n return [\n 'Нажмите на значок настроек в адресной строке браузера',\n 'Снимите запрет на использование камеры и микрофона',\n ];\n }, []);\n\n const permissionsButtonLabel = useMemo(() => {\n if (!isMicrophoneDeniedOrPrompted && !isCameraDeniedOrPrompted) {\n return null;\n }\n if (isCameraDeniedOrPrompted && isMicrophoneDeniedOrPrompted) {\n return 'Как разрешить камеру и микрофон';\n }\n if (isMicrophoneDeniedOrPrompted) {\n return 'Как разрешить микрофон';\n }\n if (isCameraDeniedOrPrompted) {\n return 'Как разрешить камеру';\n }\n return null;\n }, [isMicrophoneDeniedOrPrompted, isCameraDeniedOrPrompted]);\n\n const renderVideo = useMemo(() => {\n if (!videoTrack || isCameraDeniedOrPrompted) {\n return null;\n }\n\n return (\n <div className=\"aspect-video h-full w-full transform-[rotateY(180deg)]\">\n <SecureVideo\n ref={videoEl}\n data-lk-facing-mode={facingMode}\n className=\"h-full w-full object-cover\"\n playsInline\n muted\n style={{\n display: !videoEnabled || isCameraDeniedOrPrompted ? 'none' : undefined,\n opacity: videoTrack?.isMuted || !isVideoInitiated ? 0 : 1,\n transition: 'opacity 0.3s ease-in-out',\n }}\n disablePictureInPicture\n disableRemotePlayback\n />\n </div>\n );\n }, [videoTrack, facingMode, videoEl, videoEnabled, isCameraDeniedOrPrompted, isVideoInitiated]);\n\n const renderAvatar = useMemo(() => {\n if (videoTrack && !videoTrack.isMuted && !isCameraDeniedOrPrompted) return null;\n\n return (\n <div className=\"bg-gray-40 flex items-center justify-center rounded-[16px]\">\n <Avatar size=\"xxl\">\n <AvatarImage\n src={`https://api.sovlium.ru/files/users/${userId}/avatar.webp`}\n alt=\"user avatar\"\n />\n <AvatarFallback size=\"xxl\" loading />\n </Avatar>\n </div>\n );\n }, [videoTrack, userId, isCameraDeniedOrPrompted]);\n\n return (\n <div className=\"bg-gray-40 relative flex aspect-video h-full w-full items-center justify-center overflow-hidden rounded-[16px]\">\n <div className=\"relative h-full w-full\">\n {renderVideo}\n {renderAvatar}\n\n {isPermissionsBlocked && (\n <div className=\"bg-opacity-60 absolute inset-0 flex flex-col items-center justify-center gap-4 bg-black p-6 text-center\">\n <p className=\"text-lg font-normal text-white\">\n Хотите, чтобы другие участники услышали вас?\n </p>\n <ol className=\"list-inside list-decimal space-y-2 text-left text-sm text-white\">\n {permissionsInstructions.map((instruction, index) => (\n <li key={index} className=\"flex items-start gap-2\">\n {index === 0 && !isSafari() && <Settings className=\"mt-0.5 h-4 w-4 shrink-0\" />}\n <span>{instruction}</span>\n </li>\n ))}\n </ol>\n <p className=\"text-gray-30 text-sm\">\n Камеру или микрофон можно отключить в любой момент.\n </p>\n {permissionsButtonLabel && (\n <Button size=\"m\" variant=\"ghost\" onClick={openPermissionsDialog}>\n {permissionsButtonLabel}\n </Button>\n )}\n </div>\n )}\n\n {!isPermissionsBlocked && hintMessage && (\n <div className=\"bg-opacity-60 absolute inset-0 flex flex-col items-center justify-center gap-4 bg-black p-6 text-center\">\n <p className=\"text-lg font-normal text-white\">{hintMessage}</p>\n </div>\n )}\n </div>\n\n <div className=\"absolute bottom-5 left-5\">\n <Controls audioTrack={audioTrack} videoTrack={videoTrack} />\n </div>\n </div>\n );\n};\n\ninterface UserTileProps {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n}\n\nexport const UserTile = ({ audioTrack, videoTrack }: UserTileProps) => {\n const { auth } = useCalls();\n const { data: user } = auth.useCurrentUser();\n const { userId } = user ?? {};\n\n const {\n userChoices: { videoEnabled },\n } = usePersistentUserChoices();\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const [isVideoInitiated, setIsVideoInitiated] = useState(false);\n\n const isCameraDeniedOrPrompted = useCannotUseDevice('videoinput');\n const isMicrophoneDeniedOrPrompted = useCannotUseDevice('audioinput');\n\n const facingMode = useMemo(() => {\n if (videoTrack) {\n const { facingMode } = facingModeFromLocalTrack(videoTrack);\n return facingMode;\n }\n return 'undefined';\n }, [videoTrack]);\n\n useEffect(() => {\n if (!videoEnabled) {\n setIsVideoInitiated(false);\n }\n }, [videoEnabled]);\n\n useEffect(() => {\n if (videoTrack) {\n const handleTrackMuted = () => {\n setIsVideoInitiated(false);\n };\n\n const handleTrackUnmuted = () => {\n if (videoEnabled) {\n setIsVideoInitiated(true);\n }\n };\n\n videoTrack.on('muted', handleTrackMuted);\n videoTrack.on('unmuted', handleTrackUnmuted);\n\n return () => {\n videoTrack.off('muted', handleTrackMuted);\n videoTrack.off('unmuted', handleTrackUnmuted);\n };\n }\n }, [videoTrack, videoEnabled]);\n\n useEffect(() => {\n const currentVideoEl = videoEl.current;\n const currentVideoTrack = videoTrack;\n\n const handleVideoLoaded = () => {\n if (currentVideoEl && videoEnabled) {\n setIsVideoInitiated(true);\n currentVideoEl.style.opacity = '1';\n } else if (currentVideoEl) {\n currentVideoEl.style.opacity = '0';\n }\n };\n\n const handleVideoError = () => {\n setIsVideoInitiated(false);\n };\n\n if (currentVideoEl && currentVideoTrack && videoEnabled) {\n currentVideoTrack.attach(currentVideoEl);\n currentVideoEl.addEventListener('loadedmetadata', handleVideoLoaded);\n currentVideoEl.addEventListener('error', handleVideoError);\n }\n\n return () => {\n if (currentVideoTrack) {\n currentVideoTrack.detach();\n }\n if (currentVideoEl) {\n currentVideoEl.removeEventListener('loadedmetadata', handleVideoLoaded);\n currentVideoEl.removeEventListener('error', handleVideoError);\n currentVideoEl.style.opacity = '0';\n }\n };\n }, [videoTrack, videoEnabled]);\n\n return (\n <UserTileUI\n audioTrack={audioTrack}\n videoTrack={videoTrack}\n videoEnabled={videoEnabled}\n facingMode={facingMode}\n videoEl={videoEl}\n userId={userId || 'unknown'}\n isCameraDeniedOrPrompted={isCameraDeniedOrPrompted}\n isMicrophoneDeniedOrPrompted={isMicrophoneDeniedOrPrompted}\n isVideoInitiated={isVideoInitiated}\n />\n );\n};\n","import { SelectItem } from '@xipkg/select';\n\nexport type MediaDeviceKind = 'videoinput' | 'audiooutput' | 'audioinput';\n\ntype MediaDeviceSelectPropsT = {\n devices: MediaDeviceInfo[];\n};\n\nexport const MediaDeviceSelect = ({ devices }: MediaDeviceSelectPropsT) => (\n <ul>\n {devices &&\n devices.map((device) => (\n <li key={device.deviceId} id={device.deviceId}>\n <SelectItem value={device.deviceId ?? 'default'}>{device.label}</SelectItem>\n </li>\n ))}\n </ul>\n);\n","import React from 'react';\nimport { computeMenuPosition, wasClickOutside } from '@livekit/components-core';\nimport { Select, SelectContent, SelectGroup, SelectTrigger, SelectValue } from '@xipkg/select';\nimport { Conference, Microphone, SoundTwo } from '@xipkg/icons';\nimport { useMediaDeviceSelect } from '@livekit/components-react';\nimport { MediaDeviceKind, MediaDeviceSelect } from './MediaDeviceSelect';\n\nconst placeholders = {\n audioinput: 'Встроенный микрофон',\n audiooutput: 'Встроенные динамики',\n videoinput: 'Встроенная камера',\n default: 'По умолчанию',\n};\n\nexport interface MediaDeviceMenuProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n disabled?: boolean;\n kind: MediaDeviceKind;\n initialSelection: string | undefined;\n onActiveDeviceChange?: (kind: MediaDeviceKind, deviceId: string) => void;\n warnDisable?: boolean;\n requestPermissions?: boolean;\n}\n\nexport const MediaDeviceMenu = ({\n warnDisable,\n kind,\n initialSelection,\n onActiveDeviceChange,\n disabled,\n requestPermissions = false,\n}: MediaDeviceMenuProps) => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [updateRequired, setUpdateRequired] = React.useState<boolean>(true);\n const [, setNeedPermissions] = React.useState(requestPermissions);\n const button = React.useRef<HTMLButtonElement>(null);\n const tooltip = React.useRef<HTMLDivElement>(null);\n\n const handleError = React.useCallback((e: Error) => {\n console.error('Media device error:', e);\n }, []);\n const { devices, setActiveMediaDevice } = useMediaDeviceSelect({\n kind,\n room: undefined, // Для PreJoin не нужна комната\n requestPermissions,\n onError: handleError,\n });\n\n React.useLayoutEffect(() => {\n if (isOpen) {\n setNeedPermissions(true);\n }\n }, [isOpen]);\n\n React.useLayoutEffect(() => {\n if (button.current && tooltip.current && (devices || updateRequired)) {\n const handlePositionChange = (x: number, y: number) => {\n if (tooltip.current) {\n tooltip.current.style.left = `${x}px`;\n tooltip.current.style.top = `${y}px`;\n }\n };\n\n computeMenuPosition(button.current, tooltip.current, handlePositionChange);\n }\n setUpdateRequired(false);\n }, [button, tooltip, updateRequired, devices]);\n\n const handleClickOutside = React.useCallback(\n (event: MouseEvent) => {\n if (!tooltip.current) {\n return;\n }\n if (event.target === button.current) {\n return;\n }\n if (isOpen && wasClickOutside(tooltip.current, event)) {\n setIsOpen(false);\n }\n },\n [isOpen, tooltip, button],\n );\n\n React.useEffect(() => {\n document.addEventListener<'click'>('click', handleClickOutside);\n window.addEventListener<'resize'>('resize', () => setUpdateRequired(true));\n return () => {\n document.removeEventListener<'click'>('click', handleClickOutside);\n window.removeEventListener<'resize'>('resize', () => setUpdateRequired(true));\n };\n }, [handleClickOutside, setUpdateRequired]);\n\n const getPlaceholder = () => {\n if (initialSelection === '') return placeholders.default;\n if (!initialSelection && kind) {\n return placeholders[kind] || placeholders.default;\n }\n return placeholders.default;\n };\n async function handleActiveChange(deviceId: string, kind: MediaDeviceKind) {\n setIsOpen(false);\n onActiveDeviceChange?.(kind, deviceId);\n await setActiveMediaDevice(deviceId);\n }\n\n return (\n <div className={`${warnDisable ? 'border-orange-80 rounded-lg border-2' : null}`}>\n <Select\n onValueChange={(value) => handleActiveChange(value, kind)}\n defaultValue={devices?.length > 0 ? initialSelection : undefined}\n disabled={\n disabled || warnDisable || !devices || devices.length === 0 || devices[0].deviceId === ''\n }\n >\n <SelectTrigger\n className=\"flex w-full flex-row\"\n before={\n <div>\n {kind === 'videoinput' && <Conference width={14} />}\n {kind === 'audiooutput' && <SoundTwo width={14} />}\n {!(kind === 'videoinput' || kind === 'audiooutput') && <Microphone width={14} />}\n </div>\n }\n >\n <SelectValue placeholder={getPlaceholder()} />\n </SelectTrigger>\n <SelectContent\n ref={(ref) => ref?.addEventListener('touchend', (e) => e.preventDefault())}\n className=\"w-full\"\n >\n {devices.length !== 0 && devices[0].deviceId !== '' && (\n <SelectGroup>\n <MediaDeviceSelect devices={devices} />\n </SelectGroup>\n )}\n </SelectContent>\n </Select>\n </div>\n );\n};\n","import { useMemo } from 'react';\nimport { Button } from '@xipkg/button';\nimport { Switch } from '@xipkg/switcher';\nimport { Label } from '@xipkg/label';\nimport { Alert, AlertIcon, AlertContainer, AlertDescription } from '@xipkg/alert';\nimport { InfoCircle } from '@xipkg/icons';\nimport { MediaDeviceMenu } from './MediaDeviceMenu';\nimport { LocalAudioTrack, LocalVideoTrack } from 'livekit-client';\nimport { UseNoiseCancellationResult, usePersistentUserChoices } from '@xipkg/calls-hooks';\nimport { useCallStore, usePermissionsStore } from '@xipkg/calls-store';\nimport { useRoom } from '@xipkg/calls-providers';\nimport { supportsBackgroundProcessors } from '@livekit/track-processors';\nimport { NoiseCancellationSettings } from '@xipkg/calls-ui';\n\ninterface MediaDevicesProps {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n noiseCancellation?: UseNoiseCancellationResult;\n}\n\nexport const MediaDevices = ({ audioTrack, videoTrack, noiseCancellation }: MediaDevicesProps) => {\n const {\n userChoices: { audioDeviceId, audioOutputDeviceId, videoDeviceId, blurEnabled },\n saveAudioInputDeviceId,\n saveAudioOutputDeviceId,\n saveVideoInputDeviceId,\n saveAudioInputEnabled,\n saveVideoInputEnabled,\n saveBlurEnabled,\n } = usePersistentUserChoices();\n\n const { updateStore, token, isConnecting } = useCallStore();\n const { room } = useRoom();\n const cameraPermission = usePermissionsStore((s) => s.cameraPermission);\n const microphonePermission = usePermissionsStore((s) => s.microphonePermission);\n\n const isBlurSupported = supportsBackgroundProcessors();\n\n // Ключи по разрешениям: при смене denied → granted меню перемонтируется и заново запрашивает список устройств\n const videoMenuKey = `videoinput-${cameraPermission}`;\n const audioInputMenuKey = `audioinput-${microphonePermission}`;\n const audioOutputMenuKey = `audiooutput-${microphonePermission}`;\n\n const handleJoin = async () => {\n if (!token) {\n console.error('No token available for joining the call');\n return;\n }\n\n // Проверяем, не подключены ли уже\n if (room.state === 'connected') {\n console.log('Already connected to room, just updating store...');\n // Если уже подключены, просто обновляем store\n updateStore('connect', true);\n updateStore('isStarted', true);\n updateStore('isConnecting', false);\n return;\n }\n\n if (isConnecting) {\n // console.log('Already connecting to room...');\n return;\n }\n\n // Устанавливаем флаг подключения\n updateStore('isConnecting', true);\n\n try {\n // Сохраняем текущие настройки устройств в store\n updateStore('audioDeviceId', audioDeviceId);\n updateStore('audioOutputDeviceId', audioOutputDeviceId);\n updateStore('videoDeviceId', videoDeviceId);\n\n // Сохраняем состояние аудио и видео\n updateStore('audioEnabled', audioTrack ? !audioTrack.isMuted : false);\n updateStore('videoEnabled', videoTrack ? !videoTrack.isMuted : false);\n\n // console.log('Preparing to join room...');\n\n // LiveKitRoom автоматически управляет подключением\n // Нам нужно только установить флаг подключения\n updateStore('connect', true);\n updateStore('isStarted', true);\n updateStore('isConnecting', false);\n\n // console.log('Successfully joined room with devices:', {\n // audioDeviceId,\n // audioOutputDeviceId,\n // videoDeviceId,\n // audioEnabled: audioTrack ? !audioTrack.isMuted : false,\n // videoEnabled: videoTrack ? !videoTrack.isMuted : false,\n // });\n } catch (error) {\n console.error('Failed to join room:', error);\n\n // Сбрасываем состояние при ошибке\n updateStore('connect', false);\n updateStore('isStarted', false);\n updateStore('isConnecting', false);\n\n // Если это ошибка отключения клиента, не показываем пользователю\n if (error instanceof Error && error.message.includes('Client initiated disconnect')) {\n console.log('Connection was cancelled by client - this is normal during navigation');\n return;\n }\n\n // Для других ошибок можно показать уведомление пользователю\n console.warn('Connection failed, please try again');\n }\n };\n\n // Обработчики переключения устройств с обработкой ошибок\n const handleAudioDeviceChange = useMemo(\n () => async (_kind: MediaDeviceKind, deviceId: string) => {\n try {\n saveAudioInputDeviceId(deviceId);\n if (audioTrack) {\n await audioTrack.setDeviceId({ exact: deviceId });\n // Синхронизируем состояние после смены устройства\n const isActuallyEnabled = !audioTrack.isMuted;\n // console.log('MediaDevices: audio device changed, syncing state', {\n // deviceId,\n // trackMuted: audioTrack.isMuted,\n // shouldBeEnabled: isActuallyEnabled,\n // });\n saveAudioInputEnabled(isActuallyEnabled);\n }\n } catch (err) {\n console.error('Failed to switch microphone device', err);\n }\n },\n [audioTrack, saveAudioInputDeviceId, saveAudioInputEnabled],\n );\n\n const handleVideoDeviceChange = useMemo(\n () => async (_kind: MediaDeviceKind, deviceId: string) => {\n try {\n saveVideoInputDeviceId(deviceId);\n if (videoTrack) {\n await videoTrack.setDeviceId({ exact: deviceId });\n // Синхронизируем состояние после смены устройства\n const isActuallyEnabled = !videoTrack.isMuted;\n // console.log('MediaDevices: video device changed, syncing state', {\n // deviceId,\n // trackMuted: videoTrack.isMuted,\n // shouldBeEnabled: isActuallyEnabled,\n // });\n saveVideoInputEnabled(isActuallyEnabled);\n }\n } catch (err) {\n console.error('Failed to switch camera device', err);\n }\n },\n [videoTrack, saveVideoInputDeviceId, saveVideoInputEnabled],\n );\n\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"border-gray-30 flex flex-col justify-between rounded-[16px] border p-5\">\n <div>\n <div className=\"mb-8\">\n <h2 className=\"mb-1 font-sans\">Камера</h2>\n <MediaDeviceMenu\n key={videoMenuKey}\n initialSelection={videoDeviceId}\n kind=\"videoinput\"\n onActiveDeviceChange={handleVideoDeviceChange}\n disabled={cameraPermission !== 'granted'}\n />\n </div>\n <div className=\"my-4\">\n <h2 className=\"mb-1 font-sans\">Звук</h2>\n <div className=\"flex flex-col gap-2\">\n <MediaDeviceMenu\n key={audioInputMenuKey}\n initialSelection={audioDeviceId}\n kind=\"audioinput\"\n onActiveDeviceChange={handleAudioDeviceChange}\n disabled={microphonePermission !== 'granted'}\n />\n <MediaDeviceMenu\n key={audioOutputMenuKey}\n initialSelection={audioOutputDeviceId}\n kind=\"audiooutput\"\n onActiveDeviceChange={(_, id) => saveAudioOutputDeviceId(id)}\n disabled={microphonePermission !== 'granted'}\n />\n </div>\n </div>\n {isBlurSupported && (\n <div className=\"my-4\">\n <div className=\"flex items-center justify-between\">\n <Label className=\"font-medium text-gray-100\">Размытие фона</Label>\n <Switch checked={blurEnabled} onCheckedChange={saveBlurEnabled} />\n </div>\n </div>\n )}\n {noiseCancellation && (\n <div className=\"my-4\">\n <NoiseCancellationSettings nc={noiseCancellation} hideOffOption />\n </div>\n )}\n </div>\n <Button onClick={() => handleJoin()} className=\"w-full\" disabled={isConnecting}>\n {isConnecting ? 'Подключение...' : 'Присоединиться'}\n </Button>\n </div>\n <Alert className=\"h-full w-full max-w-[1720px]\" variant=\"brand\">\n <AlertIcon>\n <InfoCircle className=\"fill-brand-100\" />\n </AlertIcon>\n <AlertContainer className=\"h-full\">\n <AlertDescription>\n Перед началом занятия рекомендуется выбрать устройства для видео и звука. Если\n устройства не доступны, проверьте настройки браузера. Необходимое разрешение на\n использование микрофона и камеры будет запрошено автоматически.\n </AlertDescription>\n </AlertContainer>\n </Alert>\n </div>\n );\n};\n","import { ScrollArea } from '@xipkg/scrollarea';\nimport { Header, UserTile, MediaDevices } from './components';\nimport { PermissionsDialog } from '@xipkg/calls-ui';\nimport { useMemo, useRef, useEffect, useCallback, useState } from 'react';\nimport {\n Track,\n LocalVideoTrack,\n LocalAudioTrack,\n createLocalVideoTrack,\n createLocalAudioTrack,\n} from 'livekit-client';\nimport { usePreviewTracks } from '@livekit/components-react';\nimport {\n useVideoBlur,\n useResolveInitiallyDefaultDeviceId,\n usePersistentUserChoices,\n} from '@xipkg/calls-hooks';\n\nexport const PreJoin = () => {\n const {\n userChoices: { audioEnabled, videoEnabled, audioDeviceId, videoDeviceId },\n saveAudioInputDeviceId,\n saveVideoInputDeviceId,\n } = usePersistentUserChoices();\n\n const initialUserChoices = useRef<{\n audioEnabled: boolean;\n videoEnabled: boolean;\n audioDeviceId: string;\n videoDeviceId: string;\n } | null>(null);\n\n // Сохраняем начальные настройки пользователя\n if (initialUserChoices.current === null) {\n initialUserChoices.current = {\n audioEnabled,\n videoEnabled,\n audioDeviceId,\n videoDeviceId,\n };\n }\n\n const onError = useCallback((e: Error) => {\n console.error('PreJoin ERROR:', e);\n }, []);\n\n // Автоматически запрашиваем разрешения при загрузке\n useEffect(() => {\n const requestPermissions = async () => {\n try {\n // Проверяем, есть ли уже разрешения\n const permissions = await navigator.permissions.query({ name: 'camera' as PermissionName });\n if (permissions.state === 'prompt') {\n // Запрашиваем разрешения\n const stream = await navigator.mediaDevices.getUserMedia({\n video: true,\n audio: true,\n });\n // Останавливаем поток, нам нужны только разрешения\n stream.getTracks().forEach((track) => track.stop());\n }\n } catch (error) {\n console.log('Permission request failed:', error);\n }\n };\n\n requestPermissions();\n }, []);\n\n // Preview треки - создаются только если пользователь изначально включил их\n const tracks = usePreviewTracks(\n {\n audio: !!initialUserChoices.current &&\n initialUserChoices.current?.audioEnabled && {\n deviceId: initialUserChoices.current.audioDeviceId,\n },\n video: !!initialUserChoices.current &&\n initialUserChoices.current?.videoEnabled && {\n deviceId: initialUserChoices.current.videoDeviceId,\n },\n },\n onError,\n );\n\n // Динамические треки - создаются \"just-in-time\" когда пользователь включает их\n const [dynamicVideoTrack, setDynamicVideoTrack] = useState<LocalVideoTrack | null>(null);\n const [dynamicAudioTrack, setDynamicAudioTrack] = useState<LocalAudioTrack | null>(null);\n\n const previewVideoTrack = useMemo(\n () => tracks?.filter((track) => track.kind === Track.Kind.Video)[0] as LocalVideoTrack,\n [tracks],\n );\n\n const previewAudioTrack = useMemo(\n () => tracks?.filter((track) => track.kind === Track.Kind.Audio)[0] as LocalAudioTrack,\n [tracks],\n );\n\n // Создаем динамический видео трек если пользователь включил камеру после загрузки\n useEffect(() => {\n const createVideoTrack = async () => {\n try {\n const track = await createLocalVideoTrack({\n deviceId: { exact: videoDeviceId },\n });\n setDynamicVideoTrack(track);\n } catch (error) {\n onError(error as Error);\n }\n };\n\n if (\n videoEnabled &&\n !initialUserChoices.current?.videoEnabled &&\n !previewVideoTrack &&\n !dynamicVideoTrack\n ) {\n createVideoTrack();\n }\n }, [videoEnabled, videoDeviceId, previewVideoTrack, dynamicVideoTrack, onError]);\n\n // Создаем динамический аудио трек если пользователь включил микрофон после загрузки\n useEffect(() => {\n const createAudioTrack = async () => {\n try {\n const track = await createLocalAudioTrack({\n deviceId: { exact: audioDeviceId },\n });\n setDynamicAudioTrack(track);\n } catch (error) {\n onError(error as Error);\n }\n };\n\n if (\n audioEnabled &&\n !initialUserChoices.current?.audioEnabled &&\n !previewAudioTrack &&\n !dynamicAudioTrack\n ) {\n createAudioTrack();\n }\n }, [audioEnabled, audioDeviceId, previewAudioTrack, dynamicAudioTrack, onError]);\n\n // Очистка динамических треков\n useEffect(() => {\n return () => {\n dynamicVideoTrack?.stop();\n };\n }, [dynamicVideoTrack]);\n\n useEffect(() => {\n return () => {\n dynamicAudioTrack?.stop();\n };\n }, [dynamicAudioTrack]);\n\n // Финальные треки (динамические имеют приоритет над preview)\n const videoTrack = dynamicVideoTrack || previewVideoTrack;\n const audioTrack = dynamicAudioTrack || previewAudioTrack;\n\n // Отладочная информация\n useEffect(() => {\n console.log('PreJoin tracks debug:', {\n initialUserChoices: initialUserChoices.current,\n videoEnabled,\n audioEnabled,\n videoDeviceId,\n audioDeviceId,\n tracks: tracks?.map((t) => ({ kind: t.kind, enabled: !t.isMuted })),\n previewVideoTrack: previewVideoTrack ? { enabled: !previewVideoTrack.isMuted } : null,\n previewAudioTrack: previewAudioTrack ? { enabled: !previewAudioTrack.isMuted } : null,\n dynamicVideoTrack: dynamicVideoTrack ? { enabled: !dynamicVideoTrack.isMuted } : null,\n dynamicAudioTrack: dynamicAudioTrack ? { enabled: !dynamicAudioTrack.isMuted } : null,\n finalVideoTrack: videoTrack ? { enabled: !videoTrack.isMuted } : null,\n finalAudioTrack: audioTrack ? { enabled: !audioTrack.isMuted } : null,\n });\n }, [\n tracks,\n previewVideoTrack,\n previewAudioTrack,\n dynamicVideoTrack,\n dynamicAudioTrack,\n videoTrack,\n audioTrack,\n videoEnabled,\n audioEnabled,\n videoDeviceId,\n audioDeviceId,\n ]);\n\n // Разрешаем device ID для треков\n useResolveInitiallyDefaultDeviceId(audioDeviceId, audioTrack, saveAudioInputDeviceId);\n useResolveInitiallyDefaultDeviceId(videoDeviceId, videoTrack, saveVideoInputDeviceId);\n\n // Передаем видеотрек для использования блюра\n useVideoBlur(videoTrack);\n\n return (\n <>\n <ScrollArea className=\"h-full w-full\">\n <div className=\"max-xs:p-4 p-4 pt-1\">\n <Header />\n <div className=\"grid grid-cols-1 gap-8 lg:grid-cols-2\">\n <UserTile audioTrack={audioTrack} videoTrack={videoTrack} />\n <MediaDevices audioTrack={audioTrack} videoTrack={videoTrack} />\n </div>\n </div>\n </ScrollArea>\n <PermissionsDialog />\n </>\n );\n};\n","import {\n ControlBarProps,\n useLocalParticipant,\n usePersistentUserChoices,\n useTrackToggle,\n} from '@livekit/components-react';\nimport { LocalAudioTrack, LocalVideoTrack, Track } from 'livekit-client';\nimport { useCallback } from 'react';\nimport { DisconnectButton, ScreenShareButton, WhiteBoardButton, DevicesBar } from '@xipkg/calls-ui';\nimport { ChatButton, useChatStore } from '@xipkg/calls-chat';\nimport { useCallStore, useFeaturesStore } from '@xipkg/calls-store';\nimport { cn } from '@xipkg/utils';\nimport { WhiteBoard } from '@xipkg/icons';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport { Button } from '@xipkg/button';\nimport { useRoom, useCalls, useCallsNavigation } from '@xipkg/calls-providers';\nimport { RaiseHandButton } from '@xipkg/calls-risehand';\n\nexport const BottomBar = ({ saveUserChoices = true }: ControlBarProps) => {\n const { saveAudioInputEnabled, saveVideoInputEnabled } = usePersistentUserChoices({\n preventSave: !saveUserChoices,\n });\n\n const { isMicrophoneEnabled, isCameraEnabled, microphoneTrack, cameraTrack } =\n useLocalParticipant();\n\n const microphoneToggle = useTrackToggle({\n source: Track.Source.Microphone,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) {\n saveAudioInputEnabled(enabled);\n }\n },\n });\n\n const cameraToggle = useTrackToggle({\n source: Track.Source.Camera,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) {\n saveVideoInputEnabled(enabled);\n }\n },\n });\n\n const handleMicrophoneToggle = useCallback(async () => {\n microphoneToggle.toggle();\n }, [microphoneToggle]);\n\n const handleCameraToggle = useCallback(async () => {\n cameraToggle.toggle();\n }, [cameraToggle]);\n\n const { isChatOpen } = useChatStore();\n const { mode, activeBoardId, activeClassroom, token } = useCallStore();\n const updateStore = useCallStore((state) => state.updateStore);\n const { room } = useRoom();\n const navigation = useCallsNavigation();\n\n const { useCurrentUser } = useCalls().auth;\n const { data: user } = useCurrentUser();\n const isTutor = user?.default_layout === 'tutor';\n\n const {\n chat: isChatEnabled,\n raiseHand: isRiseHandEnabled,\n whiteboard: isWhiteboardEnabled,\n } = useFeaturesStore((s) => s.features);\n\n const showBackToBoardButton =\n mode === 'full' &&\n activeBoardId &&\n activeClassroom &&\n room &&\n token &&\n room.state === 'connected';\n\n const handleBackToBoard = () => {\n if (!activeBoardId || !activeClassroom) {\n return;\n }\n\n if (!room || !token || room.state !== 'connected') {\n return;\n }\n\n updateStore('localFullView', false);\n updateStore('mode', 'compact');\n\n navigation.navigateToClassroomBoard(activeClassroom, activeBoardId);\n };\n\n return (\n <div className={cn('relative w-full', isChatOpen && 'invisible sm:visible')}>\n <div className=\"flex w-full flex-row justify-between p-4 pt-1\">\n <div />\n <div className=\"flex flex-row gap-4\">\n <div className=\"bg-gray-0 border-gray-10 flex h-[48px] w-[92px] items-center justify-center gap-1 rounded-[16px] border\">\n <DevicesBar\n microTrack={microphoneTrack?.track as LocalAudioTrack}\n microEnabled={isMicrophoneEnabled}\n microTrackToggle={{\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleMicrophoneToggle,\n }}\n videoTrack={cameraTrack?.track as unknown as LocalVideoTrack}\n videoEnabled={isCameraEnabled}\n videoTrackToggle={{\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleCameraToggle,\n }}\n className=\"relative\"\n />\n </div>\n <div className=\"bg-gray-0 border-gray-10 flex h-[48px] items-center justify-center gap-1 rounded-[16px] border p-1\">\n <ScreenShareButton />\n {isWhiteboardEnabled && isTutor && <WhiteBoardButton />}\n {isChatEnabled && <ChatButton />}\n {isRiseHandEnabled && <RaiseHandButton />}\n </div>\n </div>\n <div className=\"relative flex flex-row items-center justify-center gap-4\">\n {showBackToBoardButton && (\n <Tooltip delayDuration={1000}>\n <TooltipTrigger asChild>\n <Button\n size=\"m\"\n variant=\"default\"\n onClick={handleBackToBoard}\n className=\"bg-brand-100 hover:bg-brand-80 absolute top-1 left-[-132px] m-0 h-10 w-[128px] rounded-xl px-2\"\n data-umami-event=\"call-back-to-board\"\n >\n <WhiteBoard className=\"fill-gray-0 h-5 w-5\" />\n <span className=\"text-gray-0 ml-2\">К доске</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" align=\"center\">\n Вернуться к доске для совместной работы\n </TooltipContent>\n </Tooltip>\n )}\n <div className=\"bg-gray-0 border-gray-10 flex h-[48px] w-[48px] items-center justify-center gap-1 rounded-[16px] border p-1\">\n <DisconnectButton />\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import { useLocalParticipant } from '@livekit/components-react';\nimport { LocalVideoTrack } from 'livekit-client';\nimport { Chat } from '@xipkg/calls-chat';\nimport { UpBar, VideoGrid, CallsOnboarding } from '@xipkg/calls-ui';\nimport { useCallStore, useFeaturesStore } from '@xipkg/calls-store';\nimport { useVideoBlur, useParticipantJoinSync } from '@xipkg/calls-hooks';\nimport { useHandFocus } from '@xipkg/calls-risehand';\nimport { BottomBar } from '../Bottom/BottomBar';\nimport '@xipkg/calls-ui/video-security.css';\n\nexport const ActiveRoom = () => {\n const { chat: isChatEnabled } = useFeaturesStore((s) => s.features);\n\n // Автоматический фокус на участниках с поднятыми руками\n useHandFocus();\n // Синхронизация состояния при подключении новых участников\n useParticipantJoinSync();\n // Получаем видео трек для применения блюра\n const { cameraTrack } = useLocalParticipant();\n const videoTrack = cameraTrack?.track as LocalVideoTrack | undefined;\n\n // Применяем блюр только в полном режиме\n const mode = useCallStore((state) => state.mode);\n const videoTrackForBlur = mode === 'full' ? videoTrack : null;\n useVideoBlur(videoTrackForBlur);\n\n return (\n <div id=\"videoConferenceContainer\" className=\"bg-gray-0 h-full\">\n <div className=\"flex h-full flex-col justify-stretch\">\n <CallsOnboarding />\n <UpBar />\n <div className=\"flex h-full items-center justify-center gap-4 overflow-hidden p-4\">\n <div className=\"flex h-full w-full justify-center text-center text-gray-100\">\n <VideoGrid />\n </div>\n {isChatEnabled && <Chat />}\n </div>\n <BottomBar />\n </div>\n </div>\n );\n};\n","import { useEffect } from 'react';\nimport { useCallsNavigation } from '@xipkg/calls-providers';\nimport { useInitUserDevices, useVideoSecurity } from '@xipkg/calls-hooks';\nimport { useCallStore, useFocusModeStore } from '@xipkg/calls-store';\nimport { PreJoin } from './PreJoin';\nimport { ActiveRoom } from './Room';\nimport '@xipkg/calls-ui/video-security.css';\n\nexport const Call = () => {\n const isStarted = useCallStore((state) => state.isStarted);\n const focusMode = useFocusModeStore((s) => s.focusMode);\n const { pathname } = useCallsNavigation();\n\n useInitUserDevices();\n useVideoSecurity();\n\n const mode = useCallStore((state) => state.mode);\n const updateStore = useCallStore((state) => state.updateStore);\n\n useEffect(() => {\n const isOnCallPage = /^\\/call\\/[^/]+$/.test(pathname);\n\n if (isOnCallPage && mode === 'compact') {\n updateStore('mode', 'full');\n }\n }, [pathname, mode, updateStore]);\n\n return (\n <div\n className=\"h-full\"\n style={\n focusMode\n ? ({\n '--header-height': '0px',\n '--available-height':\n 'calc(100dvh - 0px - var(--upbar-height) - var(--bottom-bar-height))',\n } as React.CSSProperties)\n : undefined\n }\n >\n <div className=\"flex h-full w-full flex-col\">\n {isStarted ? (\n <div id=\"videoConferenceContainer\" className=\"bg-gray-5 h-full\">\n <ActiveRoom />\n </div>\n ) : (\n <PreJoin />\n )}\n </div>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/ui/PreJoin/components/Header/Header.tsx","../src/ui/PreJoin/components/UserTile/Controls.tsx","../src/ui/PreJoin/components/UserTile/UserTile.tsx","../src/ui/PreJoin/components/MediaDevices/MediaDeviceSelect.tsx","../src/ui/PreJoin/components/MediaDevices/MediaDeviceMenu.tsx","../src/ui/PreJoin/components/MediaDevices/MediaDevices.tsx","../src/ui/PreJoin/PreJoin.tsx","../src/ui/Bottom/BottomBar.tsx","../src/ui/Room/ActiveRoom.tsx","../src/ui/Call.tsx"],"names":["jsx","useMemo","jsxs","Button","useCalls","usePersistentUserChoices","facingMode","kind","useRef","useCallback","useEffect","useState","Track","useCallStore","useRoom","useCallsNavigation","DevicesBar","Tooltip","TooltipTrigger","TooltipContent","useLocalParticipant","useVideoBlur"],"mappings":"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","file":"index.mjs","sourcesContent":["import { Button } from '@xipkg/button';\nimport { ArrowLeft } from '@xipkg/icons';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport { useCalls, useCallsNavigation } from '@xipkg/calls-providers';\n\n/* eslint-disable no-irregular-whitespace */\nexport const Header = () => {\n const navigation = useCallsNavigation();\n const callId = navigation.getCallId();\n\n const { room } = useCalls();\n const { data: classroom } = room.useGetClassroom(Number(callId));\n\n return (\n <div className=\"mb-4 flex flex-col items-start gap-2 sm:flex-row sm:items-center\">\n <div className=\"flex flex-row items-center gap-2\">\n <Tooltip delayDuration={1000}>\n <TooltipTrigger asChild>\n <Button\n onClick={() => {\n if (callId) {\n navigation.navigateToClassroom(callId);\n }\n }}\n type=\"button\"\n variant=\"none\"\n className=\"flex size-[40px] min-h-[40xp] min-w-[40px] items-center justify-center rounded-[12px] p-0\"\n >\n <ArrowLeft className=\"fill-gray-100\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"start\">\n Вернуться в кабинет\n </TooltipContent>\n </Tooltip>\n <h1 className=\"text-xl-base font-semibold text-gray-100\">Присоединиться к занятию</h1>\n </div>\n <p className=\"text-s-base text-gray-60 pt-0 pl-12 align-baseline sm:pt-2 sm:pl-0\">\n {classroom?.name}\n </p>\n </div>\n );\n};\n","import { LocalAudioTrack, LocalVideoTrack, Track } from 'livekit-client';\nimport { useCallback, useMemo } from 'react';\n\nimport { DevicesBar } from '@xipkg/calls-ui';\nimport { usePersistentUserChoices } from '@xipkg/calls-hooks';\n\ntype ControlsProps = {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n};\n\nexport const Controls = ({ audioTrack, videoTrack }: ControlsProps) => {\n const {\n userChoices: { audioEnabled, videoEnabled },\n saveAudioInputEnabled,\n saveVideoInputEnabled,\n } = usePersistentUserChoices();\n\n const handleAudioChange = useCallback(\n async (enabled: boolean) => {\n // console.log('Controls: handleAudioChange', {\n // enabled,\n // audioTrack: !!audioTrack,\n // currentMuted: audioTrack?.isMuted,\n // });\n saveAudioInputEnabled(enabled);\n if (audioTrack) {\n if (enabled) {\n console.log('Controls: unmuting audio track');\n await audioTrack.unmute();\n } else {\n console.log('Controls: muting audio track');\n await audioTrack.mute();\n }\n console.log('Controls: audio track state after change', { muted: audioTrack.isMuted });\n } else {\n console.log('Controls: no audio track available');\n }\n },\n [audioTrack, saveAudioInputEnabled],\n );\n\n const handleVideoChange = useCallback(\n async (enabled: boolean) => {\n // console.log('Controls: handleVideoChange', {\n // enabled,\n // videoTrack: !!videoTrack,\n // currentMuted: videoTrack?.isMuted,\n // });\n saveVideoInputEnabled(enabled);\n if (videoTrack) {\n if (enabled) {\n console.log('Controls: unmuting video track');\n await videoTrack.unmute();\n } else {\n console.log('Controls: muting video track');\n await videoTrack.mute();\n }\n console.log('Controls: video track state after change', { muted: videoTrack.isMuted });\n } else {\n console.log('Controls: no video track available');\n }\n },\n [videoTrack, saveVideoInputEnabled],\n );\n\n const microTrackToggle = useMemo(\n () => ({\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleAudioChange,\n }),\n [handleAudioChange],\n );\n\n const videoTrackToggle = useMemo(\n () => ({\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleVideoChange,\n }),\n [handleVideoChange],\n );\n\n return (\n <div className=\"bg-gray-0 border-gray-10 flex h-[48px] w-[92px] items-center justify-center gap-1 rounded-[16px] border\">\n <DevicesBar\n microTrack={audioTrack}\n microEnabled={audioEnabled}\n microTrackToggle={microTrackToggle}\n videoTrack={videoTrack}\n videoEnabled={videoEnabled}\n videoTrackToggle={videoTrackToggle}\n />\n </div>\n );\n};\n","import { Avatar, AvatarFallback, AvatarImage } from '@xipkg/avatar';\nimport { useMemo, useRef, useEffect, useState } from 'react';\nimport { facingModeFromLocalTrack, LocalVideoTrack, LocalAudioTrack } from 'livekit-client';\nimport { Controls } from './Controls';\nimport { useCannotUseDevice, usePersistentUserChoices } from '@xipkg/calls-hooks';\nimport { openPermissionsDialog } from '@xipkg/calls-store';\nimport { Button } from '@xipkg/button';\nimport { SecureVideo } from '@xipkg/calls-ui';\nimport { Settings } from '@xipkg/icons';\nimport { isSafari } from '@xipkg/calls-utils';\nimport { useCalls } from '@xipkg/calls-providers';\n\nconst UserTileUI = ({\n audioTrack,\n videoTrack,\n videoEnabled,\n facingMode,\n videoEl,\n userId,\n isCameraDeniedOrPrompted,\n isMicrophoneDeniedOrPrompted,\n isVideoInitiated,\n}: {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n videoEnabled: boolean;\n facingMode: string;\n videoEl: React.RefObject<HTMLVideoElement | null>;\n userId: string;\n isCameraDeniedOrPrompted: boolean;\n isMicrophoneDeniedOrPrompted: boolean;\n isVideoInitiated: boolean;\n}) => {\n const isPermissionsBlocked = isCameraDeniedOrPrompted || isMicrophoneDeniedOrPrompted;\n\n const hintMessage = useMemo(() => {\n if (isPermissionsBlocked) {\n return null;\n }\n if (isCameraDeniedOrPrompted) {\n return isMicrophoneDeniedOrPrompted\n ? 'Камера и микрофон не разрешены'\n : 'Камера не разрешена';\n }\n if (!videoEnabled) {\n return 'Камера отключена';\n }\n if (!isVideoInitiated) {\n return 'Запуск камеры...';\n }\n if (videoTrack && videoEnabled) {\n return '';\n }\n return 'Камера недоступна';\n }, [\n videoTrack,\n videoEnabled,\n isCameraDeniedOrPrompted,\n isMicrophoneDeniedOrPrompted,\n isVideoInitiated,\n isPermissionsBlocked,\n ]);\n\n const permissionsInstructions = useMemo(() => {\n if (isSafari()) {\n const origin =\n typeof window !== 'undefined'\n ? (window.location?.origin?.replace('https://', '') ?? '')\n : '';\n return [\n `Нажмите на иконку ${origin} в адресной строке`,\n 'Снимите запрет на использование камеры и микрофона',\n ];\n }\n return [\n 'Нажмите на значок настроек в адресной строке браузера',\n 'Снимите запрет на использование камеры и микрофона',\n ];\n }, []);\n\n const permissionsButtonLabel = useMemo(() => {\n if (!isMicrophoneDeniedOrPrompted && !isCameraDeniedOrPrompted) {\n return null;\n }\n if (isCameraDeniedOrPrompted && isMicrophoneDeniedOrPrompted) {\n return 'Как разрешить камеру и микрофон';\n }\n if (isMicrophoneDeniedOrPrompted) {\n return 'Как разрешить микрофон';\n }\n if (isCameraDeniedOrPrompted) {\n return 'Как разрешить камеру';\n }\n return null;\n }, [isMicrophoneDeniedOrPrompted, isCameraDeniedOrPrompted]);\n\n const renderVideo = useMemo(() => {\n if (!videoTrack || isCameraDeniedOrPrompted) {\n return null;\n }\n\n return (\n <div className=\"aspect-video h-full w-full transform-[rotateY(180deg)]\">\n <SecureVideo\n ref={videoEl}\n data-lk-facing-mode={facingMode}\n className=\"h-full w-full object-cover\"\n playsInline\n muted\n style={{\n display: !videoEnabled || isCameraDeniedOrPrompted ? 'none' : undefined,\n opacity: videoTrack?.isMuted || !isVideoInitiated ? 0 : 1,\n transition: 'opacity 0.3s ease-in-out',\n }}\n disablePictureInPicture\n disableRemotePlayback\n />\n </div>\n );\n }, [videoTrack, facingMode, videoEl, videoEnabled, isCameraDeniedOrPrompted, isVideoInitiated]);\n\n const renderAvatar = useMemo(() => {\n if (videoTrack && !videoTrack.isMuted && !isCameraDeniedOrPrompted) return null;\n\n return (\n <div className=\"bg-gray-40 flex items-center justify-center rounded-[16px]\">\n <Avatar size=\"xxl\">\n <AvatarImage\n src={`https://api.sovlium.ru/files/users/${userId}/avatar.webp`}\n alt=\"user avatar\"\n />\n <AvatarFallback size=\"xxl\" loading />\n </Avatar>\n </div>\n );\n }, [videoTrack, userId, isCameraDeniedOrPrompted]);\n\n return (\n <div className=\"bg-gray-40 relative flex aspect-video h-full w-full items-center justify-center overflow-hidden rounded-[16px]\">\n <div className=\"relative h-full w-full\">\n {renderVideo}\n {renderAvatar}\n\n {isPermissionsBlocked && (\n <div className=\"bg-opacity-60 absolute inset-0 flex flex-col items-center justify-center gap-4 bg-black p-6 text-center\">\n <p className=\"text-lg font-normal text-white\">\n Хотите, чтобы другие участники услышали вас?\n </p>\n <ol className=\"list-inside list-decimal space-y-2 text-left text-sm text-white\">\n {permissionsInstructions.map((instruction, index) => (\n <li key={index} className=\"flex items-start gap-2\">\n {index === 0 && !isSafari() && <Settings className=\"mt-0.5 h-4 w-4 shrink-0\" />}\n <span>{instruction}</span>\n </li>\n ))}\n </ol>\n <p className=\"text-gray-30 text-sm\">\n Камеру или микрофон можно отключить в любой момент.\n </p>\n {permissionsButtonLabel && (\n <Button size=\"m\" variant=\"ghost\" onClick={openPermissionsDialog}>\n {permissionsButtonLabel}\n </Button>\n )}\n </div>\n )}\n\n {!isPermissionsBlocked && hintMessage && (\n <div className=\"bg-opacity-60 absolute inset-0 flex flex-col items-center justify-center gap-4 bg-black p-6 text-center\">\n <p className=\"text-lg font-normal text-white\">{hintMessage}</p>\n </div>\n )}\n </div>\n\n <div className=\"absolute bottom-5 left-5\">\n <Controls audioTrack={audioTrack} videoTrack={videoTrack} />\n </div>\n </div>\n );\n};\n\ninterface UserTileProps {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n}\n\nexport const UserTile = ({ audioTrack, videoTrack }: UserTileProps) => {\n const { auth } = useCalls();\n const { data: user } = auth.useCurrentUser();\n const { userId } = user ?? {};\n\n const {\n userChoices: { videoEnabled },\n } = usePersistentUserChoices();\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const [isVideoInitiated, setIsVideoInitiated] = useState(false);\n\n const isCameraDeniedOrPrompted = useCannotUseDevice('videoinput');\n const isMicrophoneDeniedOrPrompted = useCannotUseDevice('audioinput');\n\n const facingMode = useMemo(() => {\n if (videoTrack) {\n const { facingMode } = facingModeFromLocalTrack(videoTrack);\n return facingMode;\n }\n return 'undefined';\n }, [videoTrack]);\n\n useEffect(() => {\n if (!videoEnabled) {\n setIsVideoInitiated(false);\n }\n }, [videoEnabled]);\n\n useEffect(() => {\n if (videoTrack) {\n const handleTrackMuted = () => {\n setIsVideoInitiated(false);\n };\n\n const handleTrackUnmuted = () => {\n if (videoEnabled) {\n setIsVideoInitiated(true);\n }\n };\n\n videoTrack.on('muted', handleTrackMuted);\n videoTrack.on('unmuted', handleTrackUnmuted);\n\n return () => {\n videoTrack.off('muted', handleTrackMuted);\n videoTrack.off('unmuted', handleTrackUnmuted);\n };\n }\n }, [videoTrack, videoEnabled]);\n\n useEffect(() => {\n const currentVideoEl = videoEl.current;\n const currentVideoTrack = videoTrack;\n\n const handleVideoLoaded = () => {\n if (currentVideoEl && videoEnabled) {\n setIsVideoInitiated(true);\n currentVideoEl.style.opacity = '1';\n } else if (currentVideoEl) {\n currentVideoEl.style.opacity = '0';\n }\n };\n\n const handleVideoError = () => {\n setIsVideoInitiated(false);\n };\n\n if (currentVideoEl && currentVideoTrack && videoEnabled) {\n currentVideoTrack.attach(currentVideoEl);\n currentVideoEl.addEventListener('loadedmetadata', handleVideoLoaded);\n currentVideoEl.addEventListener('error', handleVideoError);\n }\n\n return () => {\n if (currentVideoTrack) {\n currentVideoTrack.detach();\n }\n if (currentVideoEl) {\n currentVideoEl.removeEventListener('loadedmetadata', handleVideoLoaded);\n currentVideoEl.removeEventListener('error', handleVideoError);\n currentVideoEl.style.opacity = '0';\n }\n };\n }, [videoTrack, videoEnabled]);\n\n return (\n <UserTileUI\n audioTrack={audioTrack}\n videoTrack={videoTrack}\n videoEnabled={videoEnabled}\n facingMode={facingMode}\n videoEl={videoEl}\n userId={userId || 'unknown'}\n isCameraDeniedOrPrompted={isCameraDeniedOrPrompted}\n isMicrophoneDeniedOrPrompted={isMicrophoneDeniedOrPrompted}\n isVideoInitiated={isVideoInitiated}\n />\n );\n};\n","import { SelectItem } from '@xipkg/select';\n\nexport type MediaDeviceKind = 'videoinput' | 'audiooutput' | 'audioinput';\n\ntype MediaDeviceSelectPropsT = {\n devices: MediaDeviceInfo[];\n};\n\nexport const MediaDeviceSelect = ({ devices }: MediaDeviceSelectPropsT) => (\n <ul>\n {devices &&\n devices.map((device) => (\n <li key={device.deviceId} id={device.deviceId}>\n <SelectItem className=\"h-auto\" value={device.deviceId ?? 'default'}>\n {device.label}\n </SelectItem>\n </li>\n ))}\n </ul>\n);\n","import React from 'react';\nimport { computeMenuPosition, wasClickOutside } from '@livekit/components-core';\nimport { Select, SelectContent, SelectGroup, SelectTrigger, SelectValue } from '@xipkg/select';\nimport { Conference, Microphone, SoundTwo } from '@xipkg/icons';\nimport { useMediaDeviceSelect } from '@livekit/components-react';\nimport { MediaDeviceKind, MediaDeviceSelect } from './MediaDeviceSelect';\n\nconst placeholders = {\n audioinput: 'Встроенный микрофон',\n audiooutput: 'Встроенные динамики',\n videoinput: 'Встроенная камера',\n default: 'По умолчанию',\n};\n\nexport interface MediaDeviceMenuProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n disabled?: boolean;\n kind: MediaDeviceKind;\n initialSelection: string | undefined;\n onActiveDeviceChange?: (kind: MediaDeviceKind, deviceId: string) => void;\n warnDisable?: boolean;\n requestPermissions?: boolean;\n}\n\nexport const MediaDeviceMenu = ({\n warnDisable,\n kind,\n initialSelection,\n onActiveDeviceChange,\n disabled,\n requestPermissions = false,\n}: MediaDeviceMenuProps) => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [updateRequired, setUpdateRequired] = React.useState<boolean>(true);\n const [, setNeedPermissions] = React.useState(requestPermissions);\n const button = React.useRef<HTMLButtonElement>(null);\n const tooltip = React.useRef<HTMLDivElement>(null);\n\n const handleError = React.useCallback((e: Error) => {\n console.error('Media device error:', e);\n }, []);\n const { devices, setActiveMediaDevice } = useMediaDeviceSelect({\n kind,\n room: undefined, // Для PreJoin не нужна комната\n requestPermissions,\n onError: handleError,\n });\n\n React.useLayoutEffect(() => {\n if (isOpen) {\n setNeedPermissions(true);\n }\n }, [isOpen]);\n\n React.useLayoutEffect(() => {\n if (button.current && tooltip.current && (devices || updateRequired)) {\n const handlePositionChange = (x: number, y: number) => {\n if (tooltip.current) {\n tooltip.current.style.left = `${x}px`;\n tooltip.current.style.top = `${y}px`;\n }\n };\n\n computeMenuPosition(button.current, tooltip.current, handlePositionChange);\n }\n setUpdateRequired(false);\n }, [button, tooltip, updateRequired, devices]);\n\n const handleClickOutside = React.useCallback(\n (event: MouseEvent) => {\n if (!tooltip.current) {\n return;\n }\n if (event.target === button.current) {\n return;\n }\n if (isOpen && wasClickOutside(tooltip.current, event)) {\n setIsOpen(false);\n }\n },\n [isOpen, tooltip, button],\n );\n\n React.useEffect(() => {\n document.addEventListener<'click'>('click', handleClickOutside);\n window.addEventListener<'resize'>('resize', () => setUpdateRequired(true));\n return () => {\n document.removeEventListener<'click'>('click', handleClickOutside);\n window.removeEventListener<'resize'>('resize', () => setUpdateRequired(true));\n };\n }, [handleClickOutside, setUpdateRequired]);\n\n const getPlaceholder = () => {\n if (initialSelection === '') return placeholders.default;\n if (!initialSelection && kind) {\n return placeholders[kind] || placeholders.default;\n }\n return placeholders.default;\n };\n async function handleActiveChange(deviceId: string, kind: MediaDeviceKind) {\n setIsOpen(false);\n onActiveDeviceChange?.(kind, deviceId);\n await setActiveMediaDevice(deviceId);\n }\n\n return (\n <div className={`${warnDisable ? 'border-orange-80 rounded-lg border-2' : null}`}>\n <Select\n onValueChange={(value) => handleActiveChange(value, kind)}\n defaultValue={devices?.length > 0 ? initialSelection : undefined}\n disabled={\n disabled || warnDisable || !devices || devices.length === 0 || devices[0].deviceId === ''\n }\n >\n <SelectTrigger\n className=\"flex w-full flex-row\"\n before={\n <div>\n {kind === 'videoinput' && <Conference width={14} />}\n {kind === 'audiooutput' && <SoundTwo width={14} />}\n {!(kind === 'videoinput' || kind === 'audiooutput') && <Microphone width={14} />}\n </div>\n }\n >\n <SelectValue placeholder={getPlaceholder()} />\n </SelectTrigger>\n <SelectContent\n ref={(ref) => ref?.addEventListener('touchend', (e) => e.preventDefault())}\n className=\"w-full\"\n >\n {devices.length !== 0 && devices[0].deviceId !== '' && (\n <SelectGroup>\n <MediaDeviceSelect devices={devices} />\n </SelectGroup>\n )}\n </SelectContent>\n </Select>\n </div>\n );\n};\n","import { useMemo } from 'react';\nimport { Button } from '@xipkg/button';\nimport { Toggle } from '@xipkg/toggle';\nimport { Label } from '@xipkg/label';\nimport { Alert, AlertIcon, AlertContainer, AlertDescription } from '@xipkg/alert';\nimport { InfoCircle } from '@xipkg/icons';\nimport { MediaDeviceMenu } from './MediaDeviceMenu';\nimport { LocalAudioTrack, LocalVideoTrack } from 'livekit-client';\nimport { UseNoiseCancellationResult, usePersistentUserChoices } from '@xipkg/calls-hooks';\nimport { useCallStore, usePermissionsStore } from '@xipkg/calls-store';\nimport { useRoom } from '@xipkg/calls-providers';\nimport { supportsBackgroundProcessors } from '@livekit/track-processors';\nimport { NoiseCancellationSettings } from '@xipkg/calls-ui';\n\ninterface MediaDevicesProps {\n audioTrack?: LocalAudioTrack;\n videoTrack?: LocalVideoTrack;\n noiseCancellation?: UseNoiseCancellationResult;\n}\n\nexport const MediaDevices = ({ audioTrack, videoTrack, noiseCancellation }: MediaDevicesProps) => {\n const {\n userChoices: { audioDeviceId, audioOutputDeviceId, videoDeviceId, blurEnabled },\n saveAudioInputDeviceId,\n saveAudioOutputDeviceId,\n saveVideoInputDeviceId,\n saveAudioInputEnabled,\n saveVideoInputEnabled,\n saveBlurEnabled,\n } = usePersistentUserChoices();\n\n const { updateStore, token, isConnecting } = useCallStore();\n const { room } = useRoom();\n const cameraPermission = usePermissionsStore((s) => s.cameraPermission);\n const microphonePermission = usePermissionsStore((s) => s.microphonePermission);\n\n const isBlurSupported = supportsBackgroundProcessors();\n\n // Ключи по разрешениям: при смене denied → granted меню перемонтируется и заново запрашивает список устройств\n const videoMenuKey = `videoinput-${cameraPermission}`;\n const audioInputMenuKey = `audioinput-${microphonePermission}`;\n const audioOutputMenuKey = `audiooutput-${microphonePermission}`;\n\n const handleJoin = async () => {\n if (!token) {\n console.error('No token available for joining the call');\n return;\n }\n\n // Проверяем, не подключены ли уже\n if (room.state === 'connected') {\n console.log('Already connected to room, just updating store...');\n // Если уже подключены, просто обновляем store\n updateStore('connect', true);\n updateStore('isStarted', true);\n updateStore('isConnecting', false);\n return;\n }\n\n if (isConnecting) {\n // console.log('Already connecting to room...');\n return;\n }\n\n // Устанавливаем флаг подключения\n updateStore('isConnecting', true);\n\n try {\n // Сохраняем текущие настройки устройств в store\n updateStore('audioDeviceId', audioDeviceId);\n updateStore('audioOutputDeviceId', audioOutputDeviceId);\n updateStore('videoDeviceId', videoDeviceId);\n\n // Сохраняем состояние аудио и видео\n updateStore('audioEnabled', audioTrack ? !audioTrack.isMuted : false);\n updateStore('videoEnabled', videoTrack ? !videoTrack.isMuted : false);\n\n // console.log('Preparing to join room...');\n\n // LiveKitRoom автоматически управляет подключением\n // Нам нужно только установить флаг подключения\n updateStore('connect', true);\n updateStore('isStarted', true);\n updateStore('isConnecting', false);\n\n // console.log('Successfully joined room with devices:', {\n // audioDeviceId,\n // audioOutputDeviceId,\n // videoDeviceId,\n // audioEnabled: audioTrack ? !audioTrack.isMuted : false,\n // videoEnabled: videoTrack ? !videoTrack.isMuted : false,\n // });\n } catch (error) {\n console.error('Failed to join room:', error);\n\n // Сбрасываем состояние при ошибке\n updateStore('connect', false);\n updateStore('isStarted', false);\n updateStore('isConnecting', false);\n\n // Если это ошибка отключения клиента, не показываем пользователю\n if (error instanceof Error && error.message.includes('Client initiated disconnect')) {\n console.log('Connection was cancelled by client - this is normal during navigation');\n return;\n }\n\n // Для других ошибок можно показать уведомление пользователю\n console.warn('Connection failed, please try again');\n }\n };\n\n // Обработчики переключения устройств с обработкой ошибок\n const handleAudioDeviceChange = useMemo(\n () => async (_kind: MediaDeviceKind, deviceId: string) => {\n try {\n saveAudioInputDeviceId(deviceId);\n if (audioTrack) {\n await audioTrack.setDeviceId({ exact: deviceId });\n // Синхронизируем состояние после смены устройства\n const isActuallyEnabled = !audioTrack.isMuted;\n // console.log('MediaDevices: audio device changed, syncing state', {\n // deviceId,\n // trackMuted: audioTrack.isMuted,\n // shouldBeEnabled: isActuallyEnabled,\n // });\n saveAudioInputEnabled(isActuallyEnabled);\n }\n } catch (err) {\n console.error('Failed to switch microphone device', err);\n }\n },\n [audioTrack, saveAudioInputDeviceId, saveAudioInputEnabled],\n );\n\n const handleVideoDeviceChange = useMemo(\n () => async (_kind: MediaDeviceKind, deviceId: string) => {\n try {\n saveVideoInputDeviceId(deviceId);\n if (videoTrack) {\n await videoTrack.setDeviceId({ exact: deviceId });\n // Синхронизируем состояние после смены устройства\n const isActuallyEnabled = !videoTrack.isMuted;\n // console.log('MediaDevices: video device changed, syncing state', {\n // deviceId,\n // trackMuted: videoTrack.isMuted,\n // shouldBeEnabled: isActuallyEnabled,\n // });\n saveVideoInputEnabled(isActuallyEnabled);\n }\n } catch (err) {\n console.error('Failed to switch camera device', err);\n }\n },\n [videoTrack, saveVideoInputDeviceId, saveVideoInputEnabled],\n );\n\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"border-gray-30 bg-gray-0 flex flex-col justify-between rounded-2xl border p-5\">\n <div>\n <div className=\"mb-8\">\n <h2 className=\"mb-1 font-sans\">Камера</h2>\n <MediaDeviceMenu\n key={videoMenuKey}\n initialSelection={videoDeviceId}\n kind=\"videoinput\"\n onActiveDeviceChange={handleVideoDeviceChange}\n disabled={cameraPermission !== 'granted'}\n />\n </div>\n <div className=\"my-4\">\n <h2 className=\"mb-1 font-sans\">Звук</h2>\n <div className=\"flex flex-col gap-2\">\n <MediaDeviceMenu\n key={audioInputMenuKey}\n initialSelection={audioDeviceId}\n kind=\"audioinput\"\n onActiveDeviceChange={handleAudioDeviceChange}\n disabled={microphonePermission !== 'granted'}\n />\n <MediaDeviceMenu\n key={audioOutputMenuKey}\n initialSelection={audioOutputDeviceId}\n kind=\"audiooutput\"\n onActiveDeviceChange={(_, id) => saveAudioOutputDeviceId(id)}\n disabled={microphonePermission !== 'granted'}\n />\n </div>\n </div>\n {isBlurSupported && (\n <div className=\"my-4\">\n <div className=\"flex items-center justify-between\">\n <Label className=\"font-medium text-gray-100\">Размытие фона</Label>\n <Toggle checked={blurEnabled} onCheckedChange={saveBlurEnabled} />\n </div>\n </div>\n )}\n {noiseCancellation && (\n <div className=\"my-4\">\n <NoiseCancellationSettings nc={noiseCancellation} hideOffOption />\n </div>\n )}\n </div>\n <Button onClick={() => handleJoin()} className=\"w-full\" disabled={isConnecting}>\n {isConnecting ? 'Подключение...' : 'Присоединиться'}\n </Button>\n </div>\n <Alert className=\"h-full w-full max-w-[1720px]\" variant=\"brand\">\n <AlertIcon>\n <InfoCircle className=\"fill-brand-100\" />\n </AlertIcon>\n <AlertContainer className=\"h-full\">\n <AlertDescription>\n Перед началом занятия рекомендуется выбрать устройства для видео и звука. Если\n устройства не доступны, проверьте настройки браузера. Необходимое разрешение на\n использование микрофона и камеры будет запрошено автоматически.\n </AlertDescription>\n </AlertContainer>\n </Alert>\n </div>\n );\n};\n","import { ScrollArea } from '@xipkg/scrollarea';\nimport { Header, UserTile, MediaDevices } from './components';\nimport { useMemo, useRef, useEffect, useCallback, useState } from 'react';\nimport {\n Track,\n LocalVideoTrack,\n LocalAudioTrack,\n createLocalVideoTrack,\n createLocalAudioTrack,\n} from 'livekit-client';\nimport { usePreviewTracks } from '@livekit/components-react';\nimport { getBaselineAudioCaptureOptions } from '@xipkg/calls-config';\nimport {\n useVideoBlur,\n useResolveInitiallyDefaultDeviceId,\n usePersistentUserChoices,\n useNoiseCancellation,\n} from '@xipkg/calls-hooks';\nimport { useCallsRuntimeConfig } from '@xipkg/calls-providers';\n\nexport const PreJoin = () => {\n const {\n userChoices: { audioEnabled, videoEnabled, audioDeviceId, videoDeviceId },\n saveAudioInputDeviceId,\n saveVideoInputDeviceId,\n } = usePersistentUserChoices();\n\n const {\n noiseCancellation: { featureEnabled: noiseCancellationFeatureEnabled },\n } = useCallsRuntimeConfig();\n\n const initialUserChoices = useRef<{\n audioEnabled: boolean;\n videoEnabled: boolean;\n audioDeviceId: string;\n videoDeviceId: string;\n } | null>(null);\n\n // Сохраняем начальные настройки пользователя\n if (initialUserChoices.current === null) {\n initialUserChoices.current = {\n audioEnabled,\n videoEnabled,\n audioDeviceId,\n videoDeviceId,\n };\n }\n\n const onError = useCallback((e: Error) => {\n console.error('PreJoin ERROR:', e);\n }, []);\n\n // При входе в PreJoin запрашиваем разрешения — браузер покажет диалог при первом заходе.\n // Если пользователь отклонит или ещё не ответил, useWatchPermissions обновит store и покажем состояние «нет прав» на контролах.\n useEffect(() => {\n let cancelled = false;\n const request = async () => {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });\n if (!cancelled) stream.getTracks().forEach((t) => t.stop());\n } catch {\n // Отказ или ошибка — состояние обработает useWatchPermissions и UI (перечёркнутые контролы)\n }\n };\n request();\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Preview треки - создаются только если пользователь изначально включил их\n const baselineAudio = getBaselineAudioCaptureOptions();\n const tracks = usePreviewTracks(\n {\n audio: !!initialUserChoices.current &&\n initialUserChoices.current?.audioEnabled && {\n ...baselineAudio,\n deviceId: initialUserChoices.current.audioDeviceId,\n },\n video: !!initialUserChoices.current &&\n initialUserChoices.current?.videoEnabled && {\n deviceId: initialUserChoices.current.videoDeviceId,\n },\n },\n onError,\n );\n\n // Динамические треки - создаются \"just-in-time\" когда пользователь включает их\n const [dynamicVideoTrack, setDynamicVideoTrack] = useState<LocalVideoTrack | null>(null);\n const [dynamicAudioTrack, setDynamicAudioTrack] = useState<LocalAudioTrack | null>(null);\n\n const previewVideoTrack = useMemo(\n () => tracks?.filter((track) => track.kind === Track.Kind.Video)[0] as LocalVideoTrack,\n [tracks],\n );\n\n const previewAudioTrack = useMemo(\n () => tracks?.filter((track) => track.kind === Track.Kind.Audio)[0] as LocalAudioTrack,\n [tracks],\n );\n\n // Создаем динамический видео трек если пользователь включил камеру после загрузки\n useEffect(() => {\n const createVideoTrack = async () => {\n try {\n const track = await createLocalVideoTrack({\n deviceId: { exact: videoDeviceId },\n });\n setDynamicVideoTrack(track);\n } catch (error) {\n onError(error as Error);\n }\n };\n\n if (\n videoEnabled &&\n !initialUserChoices.current?.videoEnabled &&\n !previewVideoTrack &&\n !dynamicVideoTrack\n ) {\n createVideoTrack();\n }\n }, [videoEnabled, videoDeviceId, previewVideoTrack, dynamicVideoTrack, onError]);\n\n // Создаем динамический аудио трек если пользователь включил микрофон после загрузки\n useEffect(() => {\n const createAudioTrack = async () => {\n try {\n const track = await createLocalAudioTrack({\n ...getBaselineAudioCaptureOptions(),\n deviceId: { exact: audioDeviceId },\n });\n setDynamicAudioTrack(track);\n } catch (error) {\n onError(error as Error);\n }\n };\n\n if (\n audioEnabled &&\n !initialUserChoices.current?.audioEnabled &&\n !previewAudioTrack &&\n !dynamicAudioTrack\n ) {\n createAudioTrack();\n }\n }, [audioEnabled, audioDeviceId, previewAudioTrack, dynamicAudioTrack, onError]);\n\n // Очистка динамических треков\n useEffect(() => {\n return () => {\n dynamicVideoTrack?.stop();\n };\n }, [dynamicVideoTrack]);\n\n useEffect(() => {\n return () => {\n dynamicAudioTrack?.stop();\n };\n }, [dynamicAudioTrack]);\n\n // Финальные треки (динамические имеют приоритет над preview)\n const videoTrack = dynamicVideoTrack || previewVideoTrack;\n const audioTrack = dynamicAudioTrack || previewAudioTrack;\n\n // Разрешаем device ID для треков\n useResolveInitiallyDefaultDeviceId(audioDeviceId, audioTrack, saveAudioInputDeviceId);\n useResolveInitiallyDefaultDeviceId(videoDeviceId, videoTrack, saveVideoInputDeviceId);\n\n // Передаем видеотрек для использования блюра\n useVideoBlur(videoTrack);\n\n const noiseCancellation = useNoiseCancellation(null, {\n localAudioTrack: audioTrack ?? undefined,\n });\n\n return (\n <>\n <ScrollArea className=\"h-full w-full\">\n <div className=\"bg-gray-5 h-full min-h-[calc(100dvh)] p-5\">\n <Header />\n <div className=\"grid grid-cols-1 gap-8 lg:grid-cols-2\">\n <UserTile audioTrack={audioTrack} videoTrack={videoTrack} />\n <MediaDevices\n audioTrack={audioTrack}\n videoTrack={videoTrack}\n noiseCancellation={noiseCancellationFeatureEnabled ? noiseCancellation : undefined}\n />\n </div>\n </div>\n </ScrollArea>\n </>\n );\n};\n","import {\n ControlBarProps,\n useLocalParticipant,\n usePersistentUserChoices,\n useTrackToggle,\n} from '@livekit/components-react';\nimport { LocalAudioTrack, LocalVideoTrack, Track } from 'livekit-client';\nimport { useCallback } from 'react';\nimport { DisconnectButton, ScreenShareButton, WhiteBoardButton, DevicesBar } from '@xipkg/calls-ui';\nimport { ChatButton, useChatStore } from '@xipkg/calls-chat';\nimport { useCallStore } from '@xipkg/calls-store';\nimport { cn } from '@xipkg/utils';\nimport { WhiteBoard } from '@xipkg/icons';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport { Button } from '@xipkg/button';\nimport { useRoom, useCalls, useCallsNavigation } from '@xipkg/calls-providers';\nimport { RaiseHandButton } from '@xipkg/calls-risehand';\n\nexport const BottomBar = ({ saveUserChoices = true }: ControlBarProps) => {\n const { saveAudioInputEnabled, saveVideoInputEnabled } = usePersistentUserChoices({\n preventSave: !saveUserChoices,\n });\n\n const { isMicrophoneEnabled, isCameraEnabled, microphoneTrack, cameraTrack } =\n useLocalParticipant();\n\n const microphoneToggle = useTrackToggle({\n source: Track.Source.Microphone,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) {\n saveAudioInputEnabled(enabled);\n }\n },\n });\n\n const cameraToggle = useTrackToggle({\n source: Track.Source.Camera,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) {\n saveVideoInputEnabled(enabled);\n }\n },\n });\n\n const handleMicrophoneToggle = useCallback(async () => {\n microphoneToggle.toggle();\n }, [microphoneToggle]);\n\n const handleCameraToggle = useCallback(async () => {\n cameraToggle.toggle();\n }, [cameraToggle]);\n\n const { isChatOpen } = useChatStore();\n const { mode, activeBoardId, activeClassroom, token } = useCallStore();\n const updateStore = useCallStore((state) => state.updateStore);\n const { room } = useRoom();\n const navigation = useCallsNavigation();\n\n const { useCurrentUser } = useCalls().auth;\n const { data: user } = useCurrentUser();\n const isTutor = user?.default_layout === 'tutor';\n\n const showBackToBoardButton =\n mode === 'full' &&\n activeBoardId &&\n activeClassroom &&\n room &&\n token &&\n room.state === 'connected';\n\n const handleBackToBoard = () => {\n if (!activeBoardId || !activeClassroom) {\n return;\n }\n\n if (!room || !token || room.state !== 'connected') {\n return;\n }\n\n updateStore('localFullView', false);\n updateStore('mode', 'compact');\n\n navigation.navigateToClassroomBoard(activeClassroom, activeBoardId);\n };\n\n return (\n <div className={cn('relative w-full', isChatOpen && 'invisible sm:visible')}>\n <div className=\"flex w-full flex-row justify-between p-4 pt-1\">\n <div />\n <div className=\"flex flex-row gap-4\">\n <div className=\"bg-gray-0 border-gray-10 flex h-[48px] w-[92px] items-center justify-center gap-1 rounded-[16px] border\">\n <DevicesBar\n microTrack={microphoneTrack?.track as LocalAudioTrack}\n microEnabled={isMicrophoneEnabled}\n microTrackToggle={{\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleMicrophoneToggle,\n }}\n videoTrack={cameraTrack?.track as unknown as LocalVideoTrack}\n videoEnabled={isCameraEnabled}\n videoTrackToggle={{\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleCameraToggle,\n }}\n className=\"relative\"\n />\n </div>\n <div className=\"bg-gray-0 border-gray-10 flex h-[48px] items-center justify-center gap-1 rounded-[16px] border p-1\">\n <ScreenShareButton />\n {isTutor && <WhiteBoardButton />}\n <ChatButton />\n <RaiseHandButton />\n </div>\n </div>\n <div className=\"relative flex flex-row items-center justify-center gap-4\">\n {showBackToBoardButton && (\n <Tooltip delayDuration={1000}>\n <TooltipTrigger asChild>\n <Button\n size=\"m\"\n variant=\"default\"\n onClick={handleBackToBoard}\n className=\"bg-brand-100 hover:bg-brand-80 absolute top-1 left-[-132px] m-0 h-10 w-[128px] rounded-xl px-2\"\n data-umami-event=\"call-back-to-board\"\n >\n <WhiteBoard className=\"fill-gray-0 h-5 w-5\" />\n <span className=\"text-gray-0 ml-2\">К доске</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" align=\"center\">\n Вернуться к доске для совместной работы\n </TooltipContent>\n </Tooltip>\n )}\n <div className=\"bg-gray-0 border-gray-10 flex h-[48px] w-[48px] items-center justify-center gap-1 rounded-[16px] border p-1\">\n <DisconnectButton />\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import { useLocalParticipant } from '@livekit/components-react';\nimport { LocalVideoTrack } from 'livekit-client';\nimport { Chat } from '@xipkg/calls-chat';\nimport { UpBar, VideoGrid, CallsOnboarding } from '@xipkg/calls-ui';\nimport { useCallStore } from '@xipkg/calls-store';\nimport { useVideoBlur, useParticipantJoinSync, useParticipantSounds } from '@xipkg/calls-hooks';\nimport { useHandFocus } from '@xipkg/calls-risehand';\nimport { BottomBar } from '../Bottom/BottomBar';\nimport '@xipkg/calls-ui/video-security.css';\nimport '@xipkg/calls-ui/grid.css';\n\nexport const ActiveRoom = () => {\n // Автоматический фокус на участниках с поднятыми руками\n useHandFocus();\n // Синхронизация состояния при подключении новых участников\n useParticipantJoinSync();\n useParticipantSounds();\n // Получаем видео трек для применения блюра\n const { cameraTrack } = useLocalParticipant();\n const videoTrack = cameraTrack?.track as LocalVideoTrack | undefined;\n\n // Применяем блюр только в полном режиме\n const mode = useCallStore((state) => state.mode);\n const videoTrackForBlur = mode === 'full' ? videoTrack : null;\n useVideoBlur(videoTrackForBlur);\n\n return (\n <div className=\"flex h-full min-h-0 flex-col justify-stretch\">\n <CallsOnboarding />\n <UpBar />\n <div className=\"flex h-full min-h-0 flex-1 items-center justify-center gap-4 overflow-hidden sm:px-4\">\n <div className=\"flex h-full min-h-0 w-full min-w-0 justify-center text-center text-gray-100\">\n <VideoGrid />\n </div>\n <Chat />\n </div>\n <BottomBar />\n </div>\n );\n};\n","import { useEffect } from 'react';\nimport { useCallsNavigation } from '@xipkg/calls-providers';\nimport { useInitUserDevices, useVideoSecurity } from '@xipkg/calls-hooks';\nimport { useCallStore, useFocusModeStore } from '@xipkg/calls-store';\nimport { PreJoin } from './PreJoin';\nimport { ActiveRoom } from './Room';\nimport '@xipkg/calls-ui/video-security.css';\nimport '@xipkg/calls-ui/grid.css';\n\nexport const Call = () => {\n const isStarted = useCallStore((state) => state.isStarted);\n const focusMode = useFocusModeStore((s) => s.focusMode);\n const { pathname } = useCallsNavigation();\n\n useInitUserDevices();\n useVideoSecurity();\n\n const mode = useCallStore((state) => state.mode);\n const updateStore = useCallStore((state) => state.updateStore);\n\n useEffect(() => {\n const isOnCallPage = /^\\/call\\/[^/]+$/.test(pathname);\n\n if (isOnCallPage && mode === 'compact') {\n updateStore('mode', 'full');\n }\n }, [pathname, mode, updateStore]);\n\n return (\n <div\n className={'h-full'}\n style={\n focusMode\n ? ({\n '--header-height': '0px',\n '--available-height':\n 'calc(100dvh - 0px - var(--upbar-height) - var(--bottom-bar-height))',\n } as React.CSSProperties)\n : undefined\n }\n >\n <div className=\"flex h-full w-full flex-col\">\n {isStarted ? (\n <div id=\"videoConferenceContainer\" className=\"bg-gray-5 h-full\">\n <ActiveRoom />\n </div>\n ) : (\n <PreJoin />\n )}\n </div>\n </div>\n );\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xipkg/calls",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
"@xipkg/scrollarea": "2.2.0",
|
|
34
34
|
"@xipkg/label": "2.0.12",
|
|
35
35
|
"@xipkg/alert": "1.1.0",
|
|
36
|
-
"@xipkg/switcher": "3.0.13",
|
|
37
36
|
"@xipkg/select": "2.2.5",
|
|
38
37
|
"@xipkg/tooltip": "2.1.0",
|
|
39
|
-
"@xipkg/icons": "^
|
|
40
|
-
"@xipkg/button": "
|
|
41
|
-
"@xipkg/
|
|
42
|
-
"@xipkg/calls-
|
|
43
|
-
"@xipkg/calls-
|
|
44
|
-
"@xipkg/calls-
|
|
45
|
-
"@xipkg/calls-
|
|
46
|
-
"@xipkg/calls-
|
|
47
|
-
"@xipkg/calls-
|
|
48
|
-
"@xipkg/calls-
|
|
49
|
-
"@xipkg/calls-
|
|
38
|
+
"@xipkg/icons": "^3.0.15",
|
|
39
|
+
"@xipkg/button": "4.1.0",
|
|
40
|
+
"@xipkg/toggle": "^4.1.0",
|
|
41
|
+
"@xipkg/calls-ui": "^0.0.3",
|
|
42
|
+
"@xipkg/calls-utils": "^0.0.3",
|
|
43
|
+
"@xipkg/calls-types": "^0.0.3",
|
|
44
|
+
"@xipkg/calls-config": "^0.0.3",
|
|
45
|
+
"@xipkg/calls-providers": "^0.0.3",
|
|
46
|
+
"@xipkg/calls-store": "^0.0.3",
|
|
47
|
+
"@xipkg/calls-hooks": "^0.0.3",
|
|
48
|
+
"@xipkg/calls-chat": "^0.0.3",
|
|
49
|
+
"@xipkg/calls-risehand": "^0.0.3"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@tanstack/react-query-devtools": "5.73.3",
|