@xipkg/calls 0.0.8 → 0.0.9

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 CHANGED
@@ -750,57 +750,66 @@ var BottomBar = ({ saveUserChoices = true }) => {
750
750
  updateStore("mode", "compact");
751
751
  navigation.navigateToClassroomBoard(activeClassroom, activeBoardId);
752
752
  };
753
- return /* @__PURE__ */ jsx("div", { className: cn("relative w-full", isChatOpen && "invisible sm:visible"), children: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-row justify-between p-4 pt-1", children: [
754
- /* @__PURE__ */ jsx("div", {}),
755
- /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-4", children: [
756
- /* @__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(
757
- DevicesBar,
758
- {
759
- microTrack: microphoneTrack?.track,
760
- microEnabled: isMicrophoneEnabled,
761
- microTrackToggle: {
762
- showIcon: true,
763
- source: Track.Source.Microphone,
764
- onChange: handleMicrophoneToggle
765
- },
766
- videoTrack: cameraTrack?.track,
767
- videoEnabled: isCameraEnabled,
768
- videoTrackToggle: {
769
- showIcon: true,
770
- source: Track.Source.Camera,
771
- onChange: handleCameraToggle
772
- },
773
- className: "relative"
774
- }
775
- ) }),
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: [
777
- /* @__PURE__ */ jsx(ScreenShareButton, {}),
778
- isTutor && /* @__PURE__ */ jsx(WhiteBoardButton, {}),
779
- /* @__PURE__ */ jsx(ChatButton, {}),
780
- /* @__PURE__ */ jsx(RaiseHandButton, {})
753
+ return /* @__PURE__ */ jsx(
754
+ "div",
755
+ {
756
+ className: cn(
757
+ "relative w-full shrink-0 pb-[max(0px,env(safe-area-inset-bottom))]",
758
+ isChatOpen && "max-sm:invisible"
759
+ ),
760
+ children: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-row justify-between p-4 pt-1", children: [
761
+ /* @__PURE__ */ jsx("div", {}),
762
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-4", children: [
763
+ /* @__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(
764
+ DevicesBar,
765
+ {
766
+ microTrack: microphoneTrack?.track,
767
+ microEnabled: isMicrophoneEnabled,
768
+ microTrackToggle: {
769
+ showIcon: true,
770
+ source: Track.Source.Microphone,
771
+ onChange: handleMicrophoneToggle
772
+ },
773
+ videoTrack: cameraTrack?.track,
774
+ videoEnabled: isCameraEnabled,
775
+ videoTrackToggle: {
776
+ showIcon: true,
777
+ source: Track.Source.Camera,
778
+ onChange: handleCameraToggle
779
+ },
780
+ className: "relative"
781
+ }
782
+ ) }),
783
+ /* @__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: [
784
+ /* @__PURE__ */ jsx(ScreenShareButton, {}),
785
+ isTutor && /* @__PURE__ */ jsx(WhiteBoardButton, {}),
786
+ /* @__PURE__ */ jsx(ChatButton, {}),
787
+ /* @__PURE__ */ jsx(RaiseHandButton, {})
788
+ ] })
789
+ ] }),
790
+ /* @__PURE__ */ jsxs("div", { className: "relative flex flex-row items-center justify-center gap-4", children: [
791
+ showBackToBoardButton && /* @__PURE__ */ jsxs(Tooltip, { delayDuration: 1e3, children: [
792
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
793
+ Button,
794
+ {
795
+ size: "m",
796
+ variant: "default",
797
+ onClick: handleBackToBoard,
798
+ className: "bg-brand-100 hover:bg-brand-80 absolute top-1 left-[-132px] m-0 h-10 w-[128px] rounded-xl px-2",
799
+ "data-umami-event": "call-back-to-board",
800
+ children: [
801
+ /* @__PURE__ */ jsx(WhiteBoard, { className: "fill-brand-0 h-5 w-5" }),
802
+ /* @__PURE__ */ jsx("span", { className: "text-brand-0 ml-2", children: "\u041A \u0434\u043E\u0441\u043A\u0435" })
803
+ ]
804
+ }
805
+ ) }),
806
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "center", children: "\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043A \u0434\u043E\u0441\u043A\u0435 \u0434\u043B\u044F \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u043D\u043E\u0439 \u0440\u0430\u0431\u043E\u0442\u044B" })
807
+ ] }),
808
+ /* @__PURE__ */ jsx("div", { className: "bg-gray-0 border-gray-10 flex h-[48px] w-[48px] items-center justify-center gap-1 rounded-[16px] border p-1", children: /* @__PURE__ */ jsx(DisconnectButton, {}) })
809
+ ] })
781
810
  ] })
782
- ] }),
783
- /* @__PURE__ */ jsxs("div", { className: "relative flex flex-row items-center justify-center gap-4", children: [
784
- showBackToBoardButton && /* @__PURE__ */ jsxs(Tooltip, { delayDuration: 1e3, children: [
785
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
786
- Button,
787
- {
788
- size: "m",
789
- variant: "default",
790
- onClick: handleBackToBoard,
791
- className: "bg-brand-100 hover:bg-brand-80 absolute top-1 left-[-132px] m-0 h-10 w-[128px] rounded-xl px-2",
792
- "data-umami-event": "call-back-to-board",
793
- children: [
794
- /* @__PURE__ */ jsx(WhiteBoard, { className: "fill-brand-0 h-5 w-5" }),
795
- /* @__PURE__ */ jsx("span", { className: "text-brand-0 ml-2", children: "\u041A \u0434\u043E\u0441\u043A\u0435" })
796
- ]
797
- }
798
- ) }),
799
- /* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "center", children: "\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043A \u0434\u043E\u0441\u043A\u0435 \u0434\u043B\u044F \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u043D\u043E\u0439 \u0440\u0430\u0431\u043E\u0442\u044B" })
800
- ] }),
801
- /* @__PURE__ */ jsx("div", { className: "bg-gray-0 border-gray-10 flex h-[48px] w-[48px] items-center justify-center gap-1 rounded-[16px] border p-1", children: /* @__PURE__ */ jsx(DisconnectButton, {}) })
802
- ] })
803
- ] }) });
811
+ }
812
+ );
804
813
  };
805
814
  var ActiveRoom = () => {
806
815
  useHandFocus();
@@ -811,11 +820,11 @@ var ActiveRoom = () => {
811
820
  const mode = useCallStore((state) => state.mode);
812
821
  const videoTrackForBlur = mode === "full" ? videoTrack : null;
813
822
  useVideoBlur(videoTrackForBlur);
814
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col justify-stretch", children: [
823
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [
815
824
  /* @__PURE__ */ jsx(CallsOnboarding, {}),
816
- /* @__PURE__ */ jsx(UpBar, {}),
817
- /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-1 items-stretch justify-center gap-4 overflow-x-hidden overflow-y-visible 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, {}) }),
825
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsx(UpBar, {}) }),
826
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 items-stretch justify-center gap-4 overflow-hidden sm:px-4", children: [
827
+ /* @__PURE__ */ jsx("div", { className: "flex min-h-0 w-full min-w-0 flex-1 justify-center text-center text-gray-100", children: /* @__PURE__ */ jsx(VideoGrid, {}) }),
819
828
  /* @__PURE__ */ jsx(Chat, {})
820
829
  ] }),
821
830
  /* @__PURE__ */ jsx(BottomBar, {})
@@ -841,9 +850,9 @@ var Call = () => {
841
850
  className: "h-full",
842
851
  style: focusMode ? {
843
852
  "--header-height": "0px",
844
- "--available-height": "calc(100dvh - 0px - var(--upbar-height) - var(--bottom-bar-height))"
853
+ "--available-height": "100%"
845
854
  } : void 0,
846
- children: /* @__PURE__ */ jsx("div", { className: "flex h-full w-full flex-col", children: isStarted ? /* @__PURE__ */ jsx("div", { id: "videoConferenceContainer", className: "bg-gray-5 h-full", children: /* @__PURE__ */ jsx(ActiveRoom, {}) }) : /* @__PURE__ */ jsx(PreJoin, {}) })
855
+ children: /* @__PURE__ */ jsx("div", { className: "flex h-full w-full flex-col", children: isStarted ? /* @__PURE__ */ jsx("div", { id: "videoConferenceContainer", className: "bg-gray-5 flex h-full min-h-0 flex-col", children: /* @__PURE__ */ jsx(ActiveRoom, {}) }) : /* @__PURE__ */ jsx(PreJoin, {}) })
847
856
  }
848
857
  );
849
858
  };
@@ -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","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 text-gray-100\" 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 text-gray-100\"\n before={\n <div>\n {kind === 'videoinput' && (\n <Conference width={14} className=\"shrink-0 fill-gray-100\" />\n )}\n {kind === 'audiooutput' && <SoundTwo width={14} className=\"shrink-0 fill-gray-100\" />}\n {!(kind === 'videoinput' || kind === 'audiooutput') && (\n <Microphone width={14} className=\"shrink-0 fill-gray-100\" />\n )}\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 text-gray-100\">\n <div>\n <div className=\"mb-8\">\n <h2 className=\"text-m-base mb-1 font-sans font-medium\">Камера</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=\"text-m-base mb-1 font-sans font-medium\">Звук</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-brand-0 h-5 w-5\" />\n <span className=\"text-brand-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-stretch justify-center gap-4 overflow-x-hidden overflow-y-visible 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"]}
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 text-gray-100\" 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 text-gray-100\"\n before={\n <div>\n {kind === 'videoinput' && (\n <Conference width={14} className=\"shrink-0 fill-gray-100\" />\n )}\n {kind === 'audiooutput' && <SoundTwo width={14} className=\"shrink-0 fill-gray-100\" />}\n {!(kind === 'videoinput' || kind === 'audiooutput') && (\n <Microphone width={14} className=\"shrink-0 fill-gray-100\" />\n )}\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 text-gray-100\">\n <div>\n <div className=\"mb-8\">\n <h2 className=\"text-m-base mb-1 font-sans font-medium\">Камера</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=\"text-m-base mb-1 font-sans font-medium\">Звук</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\n className={cn(\n 'relative w-full shrink-0 pb-[max(0px,env(safe-area-inset-bottom))]',\n isChatOpen && 'max-sm:invisible',\n )}\n >\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-brand-0 h-5 w-5\" />\n <span className=\"text-brand-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\">\n <CallsOnboarding />\n <div className=\"shrink-0\">\n <UpBar />\n </div>\n <div className=\"flex min-h-0 flex-1 items-stretch justify-center gap-4 overflow-hidden sm:px-4\">\n <div className=\"flex min-h-0 w-full min-w-0 flex-1 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': '100%',\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 flex h-full min-h-0 flex-col\">\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.8",
3
+ "version": "0.0.9",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -38,15 +38,15 @@
38
38
  "@xipkg/icons": "^3.0.20",
39
39
  "@xipkg/button": "4.1.0",
40
40
  "@xipkg/toggle": "^4.1.0",
41
- "@xipkg/calls-ui": "^0.0.8",
42
- "@xipkg/calls-utils": "^0.0.8",
43
- "@xipkg/calls-types": "^0.0.8",
44
- "@xipkg/calls-config": "^0.0.8",
45
- "@xipkg/calls-providers": "^0.0.8",
46
- "@xipkg/calls-store": "^0.0.8",
47
- "@xipkg/calls-hooks": "^0.0.8",
48
- "@xipkg/calls-chat": "^0.0.8",
49
- "@xipkg/calls-risehand": "^0.0.8",
41
+ "@xipkg/calls-ui": "^0.0.9",
42
+ "@xipkg/calls-utils": "^0.0.9",
43
+ "@xipkg/calls-types": "^0.0.9",
44
+ "@xipkg/calls-config": "^0.0.9",
45
+ "@xipkg/calls-providers": "^0.0.9",
46
+ "@xipkg/calls-store": "^0.0.9",
47
+ "@xipkg/calls-hooks": "^0.0.9",
48
+ "@xipkg/calls-chat": "^0.0.9",
49
+ "@xipkg/calls-risehand": "^0.0.9",
50
50
  "@xipkg/utils": "^1.8.0"
51
51
  },
52
52
  "devDependencies": {