@realtimexsco/live-chat 1.5.4 → 1.5.6
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/firebase-messaging-sw.js +37 -32
- package/dist/index.cjs +991 -570
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +993 -572
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/PERMISSIONS.md +0 -445
package/dist/index.mjs
CHANGED
|
@@ -9,8 +9,8 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
|
9
9
|
import { cva } from 'class-variance-authority';
|
|
10
10
|
import * as React11 from 'react';
|
|
11
11
|
import React11__default, { createContext, useState, useEffect, useMemo, useContext, useCallback, useRef, useLayoutEffect, Fragment as Fragment$1, useSyncExternalStore } from 'react';
|
|
12
|
-
import { Loader2, X, Users, Video, Phone, PhoneOff, Sun, Moon, Settings, Search, UserPlus, ChevronDown, ArrowLeft, WifiOff, Wifi, Sparkles, MessageSquareText, ChevronRight, Pin, Star, MoreVertical, Info, UserKey, ShieldUser, Paperclip, Clock, MessageSquareX, Trash2, LogOut, Ban, CheckCheck, Check, Camera, Save, Pencil, Mail, CornerUpLeft, CheckSquare, Smile, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon, MessageCircleMore, History, Shield, Send, AlertCircle, ShieldCheck, UserMinus, LayoutGrid, Rows3, MessageCircle, ExternalLink, Download, ChevronLeft, ZoomOut, ZoomIn, RotateCcw, Music, Hand, MicOff, MonitorUp, XIcon, ArrowRight, MoreHorizontal, PinOff, StarOff, ImageIcon, Film, Play, Pause, FileText, FileSpreadsheet, FileIcon, MessageSquare, Eye, Captions, Mic, VideoOff } from 'lucide-react';
|
|
13
|
-
import {
|
|
12
|
+
import { Loader2, X, Users, Video, Phone, PhoneOff, Sun, Moon, Settings, Search, UserPlus, ChevronDown, ArrowLeft, WifiOff, Wifi, Sparkles, MessageSquareText, ChevronRight, Pin, Star, MoreVertical, Info, UserKey, ShieldUser, Paperclip, Clock, MessageSquareX, Trash2, LogOut, Ban, CheckCheck, Check, Camera, Save, Pencil, Mail, CornerUpLeft, CheckSquare, Smile, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon, MessageCircleMore, History, Shield, Send, AlertCircle, ShieldCheck, UserMinus, LayoutGrid, Rows3, MessageCircle, ExternalLink, Download, ChevronLeft, ZoomOut, ZoomIn, RotateCcw, Music, Hand, MicOff, MonitorUp, XIcon, ArrowRight, MoreHorizontal, PinOff, StarOff, ImageIcon, Film, Play, Pause, FileText, FileSpreadsheet, FileIcon, MessageSquare, Eye, Captions, Mic, VideoOff, Circle } from 'lucide-react';
|
|
13
|
+
import { flushSync } from 'react-dom';
|
|
14
14
|
import EmojiPicker, { Theme } from 'emoji-picker-react';
|
|
15
15
|
import { getDefaultClassNames, DayPicker } from 'react-day-picker';
|
|
16
16
|
import toast$1, { Toaster, toast } from 'react-hot-toast';
|
|
@@ -884,12 +884,13 @@ var init_store_helpers = __esm({
|
|
|
884
884
|
});
|
|
885
885
|
|
|
886
886
|
// src/notifications/open-conversation.ts
|
|
887
|
-
var OPEN_CONVERSATION_EVENT, NOTIFICATION_CLICK_SW_TYPE, PUSH_BROADCAST_CHANNEL, PUSH_DATA_CACHE_NAME, PENDING_STORAGE_KEY, PENDING_OPEN_CACHE_PATH, resolveConversationIdFromPushData, normalizePushMeta, parsePendingRaw, peekPendingOpenConversation, peekPendingOpenRequest, consumePendingOpenConversation, consumePendingOpenRequest, requestOpenConversation, buildChannelFromPushRequest, mapConversationToChannel, stripConversationIdFromUrl, cacheRequestForPath, consumePendingOpenFromPushCache, readConversationIdFromLocation, consumedUrlConversationIds, lastHandledOpenId, lastHandledOpenAt, shouldHandleOpen, handleNotificationOpen, installNotificationClickBridge;
|
|
887
|
+
var OPEN_CONVERSATION_EVENT, NOTIFICATION_CLICK_SW_TYPE, CHAT_HEARTBEAT_SW_TYPE, PUSH_BROADCAST_CHANNEL, PUSH_DATA_CACHE_NAME, PENDING_STORAGE_KEY, PENDING_OPEN_CACHE_PATH, resolveConversationIdFromPushData, normalizePushMeta, parsePendingRaw, peekPendingOpenConversation, peekPendingOpenRequest, consumePendingOpenConversation, consumePendingOpenRequest, requestOpenConversation, buildChannelFromPushRequest, mapConversationToChannel, stripConversationIdFromUrl, cacheRequestForPath, consumePendingOpenFromPushCache, readConversationIdFromLocation, consumedUrlConversationIds, lastHandledOpenId, lastHandledOpenAt, shouldHandleOpen, handleNotificationOpen, installNotificationClickBridge;
|
|
888
888
|
var init_open_conversation = __esm({
|
|
889
889
|
"src/notifications/open-conversation.ts"() {
|
|
890
890
|
init_store_helpers();
|
|
891
891
|
OPEN_CONVERSATION_EVENT = "realtimex:open-conversation";
|
|
892
892
|
NOTIFICATION_CLICK_SW_TYPE = "realtimex:notification-click";
|
|
893
|
+
CHAT_HEARTBEAT_SW_TYPE = "realtimex:chat-heartbeat";
|
|
893
894
|
PUSH_BROADCAST_CHANNEL = "realtimex-push";
|
|
894
895
|
PUSH_DATA_CACHE_NAME = "realtimex-push-data-v1";
|
|
895
896
|
PENDING_STORAGE_KEY = "realtimex:pending-open-conversation";
|
|
@@ -4611,6 +4612,67 @@ var init_utils2 = __esm({
|
|
|
4611
4612
|
"src/lib/utils.ts"() {
|
|
4612
4613
|
}
|
|
4613
4614
|
});
|
|
4615
|
+
function TooltipProvider({
|
|
4616
|
+
delayDuration = 0,
|
|
4617
|
+
...props
|
|
4618
|
+
}) {
|
|
4619
|
+
return /* @__PURE__ */ jsx(
|
|
4620
|
+
Tooltip$1.Provider,
|
|
4621
|
+
{
|
|
4622
|
+
"data-slot": "tooltip-provider",
|
|
4623
|
+
delayDuration,
|
|
4624
|
+
...props
|
|
4625
|
+
}
|
|
4626
|
+
);
|
|
4627
|
+
}
|
|
4628
|
+
function Tooltip({
|
|
4629
|
+
...props
|
|
4630
|
+
}) {
|
|
4631
|
+
return /* @__PURE__ */ jsx(Tooltip$1.Root, { "data-slot": "tooltip", ...props });
|
|
4632
|
+
}
|
|
4633
|
+
function TooltipTrigger({
|
|
4634
|
+
...props
|
|
4635
|
+
}) {
|
|
4636
|
+
return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
4637
|
+
}
|
|
4638
|
+
function TooltipContent({
|
|
4639
|
+
className,
|
|
4640
|
+
sideOffset = 0,
|
|
4641
|
+
children,
|
|
4642
|
+
showArrow = true,
|
|
4643
|
+
arrowClassName,
|
|
4644
|
+
...props
|
|
4645
|
+
}) {
|
|
4646
|
+
return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsxs(
|
|
4647
|
+
Tooltip$1.Content,
|
|
4648
|
+
{
|
|
4649
|
+
"data-slot": "tooltip-content",
|
|
4650
|
+
sideOffset,
|
|
4651
|
+
className: cn(
|
|
4652
|
+
"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
|
|
4653
|
+
className
|
|
4654
|
+
),
|
|
4655
|
+
...props,
|
|
4656
|
+
children: [
|
|
4657
|
+
children,
|
|
4658
|
+
showArrow ? /* @__PURE__ */ jsx(
|
|
4659
|
+
Tooltip$1.Arrow,
|
|
4660
|
+
{
|
|
4661
|
+
className: cn(
|
|
4662
|
+
"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]",
|
|
4663
|
+
arrowClassName
|
|
4664
|
+
)
|
|
4665
|
+
}
|
|
4666
|
+
) : null
|
|
4667
|
+
]
|
|
4668
|
+
}
|
|
4669
|
+
) });
|
|
4670
|
+
}
|
|
4671
|
+
var init_tooltip = __esm({
|
|
4672
|
+
"src/ui/tooltip.tsx"() {
|
|
4673
|
+
init_utils2();
|
|
4674
|
+
}
|
|
4675
|
+
});
|
|
4614
4676
|
function Avatar({
|
|
4615
4677
|
className,
|
|
4616
4678
|
size = "default",
|
|
@@ -4750,9 +4812,8 @@ var init_ParticipantView = __esm({
|
|
|
4750
4812
|
isHandRaised = false,
|
|
4751
4813
|
className
|
|
4752
4814
|
}) => {
|
|
4753
|
-
const { webcamStream,
|
|
4815
|
+
const { webcamStream, webcamOn, micOn, displayName, isActiveSpeaker } = sdk.useParticipant(participantId);
|
|
4754
4816
|
const videoRef = useRef(null);
|
|
4755
|
-
const audioRef = useRef(null);
|
|
4756
4817
|
const [hasFrame, setHasFrame] = useState(false);
|
|
4757
4818
|
useEffect(() => {
|
|
4758
4819
|
const el = videoRef.current;
|
|
@@ -4765,17 +4826,6 @@ var init_ParticipantView = __esm({
|
|
|
4765
4826
|
setHasFrame(false);
|
|
4766
4827
|
}
|
|
4767
4828
|
}, [webcamOn, webcamStream]);
|
|
4768
|
-
useEffect(() => {
|
|
4769
|
-
if (isLocal) return;
|
|
4770
|
-
const el = audioRef.current;
|
|
4771
|
-
if (!el) return;
|
|
4772
|
-
if (micOn && micStream?.track) {
|
|
4773
|
-
el.srcObject = new MediaStream([micStream.track]);
|
|
4774
|
-
el.play().catch(() => void 0);
|
|
4775
|
-
} else {
|
|
4776
|
-
el.srcObject = null;
|
|
4777
|
-
}
|
|
4778
|
-
}, [micOn, micStream, isLocal]);
|
|
4779
4829
|
const name = displayName || fallbackName || "Participant";
|
|
4780
4830
|
const showVideo = webcamOn && hasFrame;
|
|
4781
4831
|
return /* @__PURE__ */ jsxs(
|
|
@@ -4808,8 +4858,7 @@ var init_ParticipantView = __esm({
|
|
|
4808
4858
|
)
|
|
4809
4859
|
}
|
|
4810
4860
|
),
|
|
4811
|
-
|
|
4812
|
-
isHandRaised && /* @__PURE__ */ jsx("span", { className: "absolute top-2 left-2 flex size-7 items-center justify-center rounded-full bg-amber-400 text-neutral-900 shadow", children: /* @__PURE__ */ jsx(Hand, { size: 14 }) }),
|
|
4861
|
+
isHandRaised && /* @__PURE__ */ jsx("span", { className: "absolute top-2 left-2 flex size-7 items-center justify-center rounded-full bg-amber-400 text-neutral-900 shadow-lg shadow-amber-400/30 animate-[bounce_1s_ease-in-out_2]", children: /* @__PURE__ */ jsx(Hand, { size: 14 }) }),
|
|
4813
4862
|
!showVideo && /* @__PURE__ */ jsxs(Avatar, { size: "lg", className: "size-20", children: [
|
|
4814
4863
|
/* @__PURE__ */ jsx(AvatarImage, { src: fallbackImage, alt: name }),
|
|
4815
4864
|
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-neutral-700 text-xl font-medium text-white", children: name.charAt(0).toUpperCase() })
|
|
@@ -4866,7 +4915,7 @@ var init_AudioCallView = __esm({
|
|
|
4866
4915
|
}
|
|
4867
4916
|
),
|
|
4868
4917
|
isMuted && /* @__PURE__ */ jsx("span", { className: "absolute -right-1 -bottom-1 flex size-9 items-center justify-center rounded-full bg-neutral-700 ring-4 ring-neutral-900", children: /* @__PURE__ */ jsx(MicOff, { size: 16, className: "text-white/80" }) }),
|
|
4869
|
-
isRemoteHandRaised && /* @__PURE__ */ jsx("span", { className: "absolute -left-1 -top-1 flex size-9 items-center justify-center rounded-full bg-amber-400 text-neutral-900 ring-4 ring-neutral-900", children: /* @__PURE__ */ jsx(Hand, { size: 16 }) })
|
|
4918
|
+
isRemoteHandRaised && /* @__PURE__ */ jsx("span", { className: "absolute -left-1 -top-1 flex size-9 items-center justify-center rounded-full bg-amber-400 text-neutral-900 shadow-lg shadow-amber-400/30 ring-4 ring-neutral-900 animate-[bounce_1s_ease-in-out_2]", children: /* @__PURE__ */ jsx(Hand, { size: 16 }) })
|
|
4870
4919
|
] }),
|
|
4871
4920
|
/* @__PURE__ */ jsx("p", { className: "text-xl font-semibold tracking-tight", children: name })
|
|
4872
4921
|
] });
|
|
@@ -4890,13 +4939,13 @@ var init_ScreenShareView = __esm({
|
|
|
4890
4939
|
el.srcObject = null;
|
|
4891
4940
|
}
|
|
4892
4941
|
}, [screenShareOn, screenShareStream]);
|
|
4893
|
-
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
4894
|
-
/* @__PURE__ */
|
|
4895
|
-
|
|
4942
|
+
return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-1 items-center justify-center overflow-hidden rounded-2xl bg-black ring-1 ring-white/10 shadow-2xl", children: [
|
|
4943
|
+
/* @__PURE__ */ jsx("video", { ref: videoRef, playsInline: true, muted: isLocal, className: "max-h-full max-w-full object-contain" }),
|
|
4944
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute top-3 left-3 flex items-center gap-1.5 rounded-full bg-black/70 px-3 py-1.5 text-xs font-medium text-white shadow backdrop-blur-sm", children: [
|
|
4945
|
+
/* @__PURE__ */ jsx(MonitorUp, { size: 13, className: "text-indigo-300" }),
|
|
4896
4946
|
isLocal ? "You are presenting" : `${displayName || "Someone"} is presenting`
|
|
4897
|
-
] })
|
|
4898
|
-
|
|
4899
|
-
] });
|
|
4947
|
+
] })
|
|
4948
|
+
] }) });
|
|
4900
4949
|
};
|
|
4901
4950
|
ScreenShareView_default = ScreenShareView;
|
|
4902
4951
|
}
|
|
@@ -4936,22 +4985,47 @@ var init_popover = __esm({
|
|
|
4936
4985
|
init_utils2();
|
|
4937
4986
|
}
|
|
4938
4987
|
});
|
|
4939
|
-
var circleBtn, idleBtnClass, activeBtnClass, QUICK_REACTIONS, CallControls, CallControls_default;
|
|
4988
|
+
var circleBtn, idleBtnClass, activeBtnClass, ControlButton, QUICK_REACTIONS, CallControls, CallControls_default;
|
|
4940
4989
|
var init_CallControls = __esm({
|
|
4941
4990
|
"src/call/CallControls.tsx"() {
|
|
4942
4991
|
init_button();
|
|
4943
4992
|
init_popover();
|
|
4993
|
+
init_tooltip();
|
|
4944
4994
|
init_utils2();
|
|
4945
4995
|
init_call_store();
|
|
4946
4996
|
circleBtn = "size-13 rounded-full text-white transition-all duration-150 disabled:opacity-40 hover:scale-105 active:scale-95";
|
|
4947
4997
|
idleBtnClass = "bg-white/10 hover:bg-white/20";
|
|
4948
4998
|
activeBtnClass = "bg-white text-neutral-900 hover:bg-white/90";
|
|
4999
|
+
ControlButton = ({
|
|
5000
|
+
icon,
|
|
5001
|
+
label,
|
|
5002
|
+
active,
|
|
5003
|
+
activeClassName = activeBtnClass,
|
|
5004
|
+
className,
|
|
5005
|
+
onClick
|
|
5006
|
+
}) => /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
5007
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
5008
|
+
Button,
|
|
5009
|
+
{
|
|
5010
|
+
variant: "ghost",
|
|
5011
|
+
size: "icon",
|
|
5012
|
+
"aria-label": label,
|
|
5013
|
+
onClick,
|
|
5014
|
+
className: cn(circleBtn, active ? activeClassName : idleBtnClass, className),
|
|
5015
|
+
children: icon
|
|
5016
|
+
}
|
|
5017
|
+
) }),
|
|
5018
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", className: "z-[1000000]", children: label })
|
|
5019
|
+
] });
|
|
4949
5020
|
QUICK_REACTIONS = ["\u{1F44D}", "\u2764\uFE0F", "\u{1F602}", "\u{1F62E}", "\u{1F44F}", "\u{1F389}"];
|
|
4950
5021
|
CallControls = ({
|
|
4951
5022
|
sdk,
|
|
4952
5023
|
onReaction,
|
|
4953
5024
|
isHandRaised,
|
|
4954
|
-
onToggleRaiseHand
|
|
5025
|
+
onToggleRaiseHand,
|
|
5026
|
+
isChatOpen,
|
|
5027
|
+
onToggleChat,
|
|
5028
|
+
isVideoActive
|
|
4955
5029
|
}) => {
|
|
4956
5030
|
const {
|
|
4957
5031
|
toggleMic,
|
|
@@ -4960,81 +5034,124 @@ var init_CallControls = __esm({
|
|
|
4960
5034
|
localWebcamOn,
|
|
4961
5035
|
localScreenShareOn,
|
|
4962
5036
|
toggleScreenShare,
|
|
5037
|
+
recordingState,
|
|
5038
|
+
startRecording,
|
|
5039
|
+
stopRecording,
|
|
4963
5040
|
leave
|
|
4964
5041
|
} = sdk.useMeeting();
|
|
4965
5042
|
const endCall = useCallStore((s) => s.endCall);
|
|
5043
|
+
const isRecording = recordingState === "RECORDING_STARTED" || recordingState === "RECORDING_STARTING";
|
|
5044
|
+
const isRecordingBusy = recordingState === "RECORDING_STARTING" || recordingState === "RECORDING_STOPPING";
|
|
5045
|
+
const handleToggleRecording = () => {
|
|
5046
|
+
if (isRecordingBusy) return;
|
|
5047
|
+
if (isRecording) {
|
|
5048
|
+
stopRecording();
|
|
5049
|
+
return;
|
|
5050
|
+
}
|
|
5051
|
+
startRecording("", "", {
|
|
5052
|
+
layout: { type: "GRID", priority: "SPEAKER", gridSize: 4 },
|
|
5053
|
+
orientation: "landscape",
|
|
5054
|
+
theme: "DEFAULT",
|
|
5055
|
+
mode: "video-and-audio",
|
|
5056
|
+
quality: "high"
|
|
5057
|
+
});
|
|
5058
|
+
};
|
|
4966
5059
|
const handleLeave = () => {
|
|
4967
5060
|
leave();
|
|
4968
5061
|
endCall();
|
|
4969
5062
|
};
|
|
4970
5063
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-5 py-6", children: [
|
|
4971
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
5064
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 rounded-full bg-white/10 p-2 shadow-lg shadow-black/20 backdrop-blur-sm", children: [
|
|
4972
5065
|
/* @__PURE__ */ jsx(
|
|
4973
|
-
|
|
5066
|
+
ControlButton,
|
|
4974
5067
|
{
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
5068
|
+
icon: localMicOn ? /* @__PURE__ */ jsx(Mic, { size: 20 }) : /* @__PURE__ */ jsx(MicOff, { size: 20 }),
|
|
5069
|
+
label: localMicOn ? "Mute microphone" : "Unmute microphone",
|
|
5070
|
+
active: !localMicOn,
|
|
5071
|
+
onClick: () => toggleMic()
|
|
5072
|
+
}
|
|
5073
|
+
),
|
|
5074
|
+
isVideoActive ? /* @__PURE__ */ jsx(
|
|
5075
|
+
ControlButton,
|
|
5076
|
+
{
|
|
5077
|
+
icon: localWebcamOn ? /* @__PURE__ */ jsx(Video, { size: 20 }) : /* @__PURE__ */ jsx(VideoOff, { size: 20 }),
|
|
5078
|
+
label: localWebcamOn ? "Turn off camera" : "Turn on camera",
|
|
5079
|
+
active: !localWebcamOn,
|
|
5080
|
+
onClick: () => toggleWebcam()
|
|
5081
|
+
}
|
|
5082
|
+
) : /* @__PURE__ */ jsx(
|
|
5083
|
+
ControlButton,
|
|
5084
|
+
{
|
|
5085
|
+
icon: /* @__PURE__ */ jsx(Video, { size: 20 }),
|
|
5086
|
+
label: "Switch to video call",
|
|
5087
|
+
onClick: () => toggleWebcam()
|
|
4981
5088
|
}
|
|
4982
5089
|
),
|
|
5090
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "mx-0.5 h-7 w-px shrink-0 bg-white/15" }),
|
|
4983
5091
|
/* @__PURE__ */ jsx(
|
|
4984
|
-
|
|
5092
|
+
ControlButton,
|
|
4985
5093
|
{
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
onClick: () =>
|
|
4991
|
-
children: localWebcamOn ? /* @__PURE__ */ jsx(Video, { size: 20 }) : /* @__PURE__ */ jsx(VideoOff, { size: 20 })
|
|
5094
|
+
icon: /* @__PURE__ */ jsx(MonitorUp, { size: 20 }),
|
|
5095
|
+
label: localScreenShareOn ? "Stop sharing your screen" : "Share your screen",
|
|
5096
|
+
active: localScreenShareOn,
|
|
5097
|
+
activeClassName: "bg-indigo-500 hover:bg-indigo-400",
|
|
5098
|
+
onClick: () => toggleScreenShare()
|
|
4992
5099
|
}
|
|
4993
5100
|
),
|
|
4994
5101
|
/* @__PURE__ */ jsx(
|
|
4995
|
-
|
|
5102
|
+
ControlButton,
|
|
4996
5103
|
{
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
onClick:
|
|
5002
|
-
children: /* @__PURE__ */ jsx(MonitorUp, { size: 20 })
|
|
5104
|
+
icon: /* @__PURE__ */ jsx(Circle, { size: 14, className: cn("fill-current", isRecording && "animate-pulse") }),
|
|
5105
|
+
label: isRecording ? "Stop recording" : "Start recording",
|
|
5106
|
+
active: isRecording,
|
|
5107
|
+
activeClassName: "bg-red-600 hover:bg-red-500",
|
|
5108
|
+
onClick: handleToggleRecording
|
|
5003
5109
|
}
|
|
5004
5110
|
),
|
|
5005
5111
|
/* @__PURE__ */ jsx(
|
|
5006
|
-
|
|
5112
|
+
ControlButton,
|
|
5007
5113
|
{
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
onClick: onToggleRaiseHand
|
|
5013
|
-
|
|
5114
|
+
icon: /* @__PURE__ */ jsx(Hand, { size: 20, className: isHandRaised ? "animate-[bounce_1s_ease-in-out_2]" : void 0 }),
|
|
5115
|
+
label: isHandRaised ? "Lower hand" : "Raise hand",
|
|
5116
|
+
active: isHandRaised,
|
|
5117
|
+
activeClassName: "bg-amber-400 text-neutral-900 hover:bg-amber-300",
|
|
5118
|
+
onClick: onToggleRaiseHand
|
|
5119
|
+
}
|
|
5120
|
+
),
|
|
5121
|
+
/* @__PURE__ */ jsx(
|
|
5122
|
+
ControlButton,
|
|
5123
|
+
{
|
|
5124
|
+
icon: /* @__PURE__ */ jsx(MessageSquare, { size: 20 }),
|
|
5125
|
+
label: isChatOpen ? "Close in-call chat" : "Open in-call chat",
|
|
5126
|
+
active: isChatOpen,
|
|
5127
|
+
onClick: onToggleChat
|
|
5014
5128
|
}
|
|
5015
5129
|
),
|
|
5016
5130
|
/* @__PURE__ */ jsxs(Popover, { children: [
|
|
5017
|
-
/* @__PURE__ */
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5131
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
5132
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
5133
|
+
Button,
|
|
5134
|
+
{
|
|
5135
|
+
variant: "ghost",
|
|
5136
|
+
size: "icon",
|
|
5137
|
+
className: cn(circleBtn, idleBtnClass),
|
|
5138
|
+
"aria-label": "Send a reaction",
|
|
5139
|
+
children: /* @__PURE__ */ jsx(Smile, { size: 20 })
|
|
5140
|
+
}
|
|
5141
|
+
) }) }),
|
|
5142
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", className: "z-[1000000]", children: "React" })
|
|
5143
|
+
] }),
|
|
5027
5144
|
/* @__PURE__ */ jsx(
|
|
5028
5145
|
PopoverContent,
|
|
5029
5146
|
{
|
|
5030
5147
|
side: "top",
|
|
5031
5148
|
align: "center",
|
|
5032
|
-
className: "w-auto rounded-full border-white/10 bg-neutral-900 p-1.5 shadow-xl",
|
|
5149
|
+
className: "z-[1000000] w-auto rounded-full border-white/10 bg-neutral-900 p-1.5 shadow-xl",
|
|
5033
5150
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5", children: QUICK_REACTIONS.map((emoji) => /* @__PURE__ */ jsx(
|
|
5034
5151
|
"button",
|
|
5035
5152
|
{
|
|
5036
5153
|
type: "button",
|
|
5037
|
-
className: "flex size-10 items-center justify-center rounded-full text-xl transition-transform hover:scale-125 hover:bg-white/10",
|
|
5154
|
+
className: "flex size-10 items-center justify-center rounded-full text-xl transition-transform hover:scale-125 hover:bg-white/10 active:scale-95",
|
|
5038
5155
|
"aria-label": `React with ${emoji}`,
|
|
5039
5156
|
onClick: () => onReaction(emoji),
|
|
5040
5157
|
children: emoji
|
|
@@ -5045,17 +5162,20 @@ var init_CallControls = __esm({
|
|
|
5045
5162
|
)
|
|
5046
5163
|
] })
|
|
5047
5164
|
] }),
|
|
5048
|
-
/* @__PURE__ */
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5165
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
5166
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
5167
|
+
Button,
|
|
5168
|
+
{
|
|
5169
|
+
variant: "ghost",
|
|
5170
|
+
size: "icon",
|
|
5171
|
+
className: cn(circleBtn, "bg-red-600 shadow-lg shadow-red-600/30 hover:bg-red-500"),
|
|
5172
|
+
"aria-label": "End call",
|
|
5173
|
+
onClick: handleLeave,
|
|
5174
|
+
children: /* @__PURE__ */ jsx(PhoneOff, { size: 22 })
|
|
5175
|
+
}
|
|
5176
|
+
) }),
|
|
5177
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", className: "z-[1000000]", children: "Leave call" })
|
|
5178
|
+
] })
|
|
5059
5179
|
] });
|
|
5060
5180
|
};
|
|
5061
5181
|
CallControls_default = CallControls;
|
|
@@ -5112,15 +5232,18 @@ var init_useCallReactions = __esm({
|
|
|
5112
5232
|
}, []);
|
|
5113
5233
|
const { send, localParticipant } = sdk.useMeeting({
|
|
5114
5234
|
onData: (data) => {
|
|
5235
|
+
console.log("[realtimex-call] data channel received:", data);
|
|
5115
5236
|
try {
|
|
5116
5237
|
const raw = typeof data.payload === "string" ? data.payload : new TextDecoder().decode(data.payload);
|
|
5117
5238
|
const message = JSON.parse(raw);
|
|
5239
|
+
console.log("[realtimex-call] data channel parsed:", message, "from", data.from);
|
|
5118
5240
|
if (message.type === "reaction") {
|
|
5119
5241
|
addFloatingReaction(message.emoji, data.from);
|
|
5120
5242
|
} else if (message.type === "raise-hand") {
|
|
5121
5243
|
setRaisedHands((prev) => ({ ...prev, [data.from]: message.raised }));
|
|
5122
5244
|
}
|
|
5123
|
-
} catch {
|
|
5245
|
+
} catch (err) {
|
|
5246
|
+
console.warn("[realtimex-call] data channel payload not decodable:", err, data);
|
|
5124
5247
|
}
|
|
5125
5248
|
}
|
|
5126
5249
|
});
|
|
@@ -5133,12 +5256,22 @@ var init_useCallReactions = __esm({
|
|
|
5133
5256
|
return next;
|
|
5134
5257
|
});
|
|
5135
5258
|
}, [localParticipant?.id]);
|
|
5259
|
+
const sendDataMessage = useCallback(
|
|
5260
|
+
(message) => {
|
|
5261
|
+
send(JSON.stringify(message)).then((ok) => {
|
|
5262
|
+
console.log("[realtimex-call] data channel send result:", ok, message);
|
|
5263
|
+
}).catch((err) => {
|
|
5264
|
+
console.warn("[realtimex-call] data channel send failed:", err, message);
|
|
5265
|
+
});
|
|
5266
|
+
},
|
|
5267
|
+
[send]
|
|
5268
|
+
);
|
|
5136
5269
|
const sendReaction = useCallback(
|
|
5137
5270
|
(emoji) => {
|
|
5138
5271
|
if (localParticipant?.id) addFloatingReaction(emoji, localParticipant.id);
|
|
5139
|
-
|
|
5272
|
+
sendDataMessage({ type: "reaction", emoji });
|
|
5140
5273
|
},
|
|
5141
|
-
[
|
|
5274
|
+
[localParticipant?.id, addFloatingReaction, sendDataMessage]
|
|
5142
5275
|
);
|
|
5143
5276
|
const toggleRaiseHand = useCallback(() => {
|
|
5144
5277
|
setIsHandRaised((prev) => {
|
|
@@ -5146,15 +5279,15 @@ var init_useCallReactions = __esm({
|
|
|
5146
5279
|
if (localParticipant?.id) {
|
|
5147
5280
|
setRaisedHands((hands) => ({ ...hands, [localParticipant.id]: next }));
|
|
5148
5281
|
}
|
|
5149
|
-
|
|
5282
|
+
sendDataMessage({ type: "raise-hand", raised: next });
|
|
5150
5283
|
return next;
|
|
5151
5284
|
});
|
|
5152
|
-
}, [
|
|
5285
|
+
}, [localParticipant?.id, sendDataMessage]);
|
|
5153
5286
|
return { floatingReactions, raisedHands, isHandRaised, sendReaction, toggleRaiseHand };
|
|
5154
5287
|
};
|
|
5155
5288
|
}
|
|
5156
5289
|
});
|
|
5157
|
-
var MeetingView, MeetingView_default;
|
|
5290
|
+
var RemoteParticipantWatcher, MeetingView, MeetingView_default;
|
|
5158
5291
|
var init_MeetingView = __esm({
|
|
5159
5292
|
"src/call/MeetingView.tsx"() {
|
|
5160
5293
|
init_ParticipantView();
|
|
@@ -5165,11 +5298,48 @@ var init_MeetingView = __esm({
|
|
|
5165
5298
|
init_useCallReactions();
|
|
5166
5299
|
init_call_store();
|
|
5167
5300
|
init_utils2();
|
|
5168
|
-
|
|
5301
|
+
RemoteParticipantWatcher = ({
|
|
5302
|
+
sdk,
|
|
5303
|
+
participantId,
|
|
5304
|
+
onWebcamChange
|
|
5305
|
+
}) => {
|
|
5306
|
+
const { webcamOn, micStream, micOn } = sdk.useParticipant(participantId);
|
|
5307
|
+
const audioRef = useRef(null);
|
|
5308
|
+
useEffect(() => {
|
|
5309
|
+
onWebcamChange(participantId, webcamOn);
|
|
5310
|
+
return () => onWebcamChange(participantId, false);
|
|
5311
|
+
}, [participantId, webcamOn]);
|
|
5312
|
+
useEffect(() => {
|
|
5313
|
+
const el = audioRef.current;
|
|
5314
|
+
if (!el) return;
|
|
5315
|
+
if (micOn && micStream?.track) {
|
|
5316
|
+
el.srcObject = new MediaStream([micStream.track]);
|
|
5317
|
+
el.play().catch(() => void 0);
|
|
5318
|
+
} else {
|
|
5319
|
+
el.srcObject = null;
|
|
5320
|
+
}
|
|
5321
|
+
}, [micOn, micStream]);
|
|
5322
|
+
return /* @__PURE__ */ jsx("audio", { ref: audioRef, autoPlay: true, playsInline: true });
|
|
5323
|
+
};
|
|
5324
|
+
MeetingView = ({
|
|
5325
|
+
sdk,
|
|
5326
|
+
mode,
|
|
5327
|
+
peerName,
|
|
5328
|
+
peerAvatar,
|
|
5329
|
+
isChatOpen,
|
|
5330
|
+
onToggleChat
|
|
5331
|
+
}) => {
|
|
5169
5332
|
const endCall = useCallStore((s) => s.endCall);
|
|
5170
5333
|
const [hasJoined, setHasJoined] = useState(false);
|
|
5171
5334
|
const hasJoinedRef = useRef(false);
|
|
5172
5335
|
const [groupView, setGroupView] = useState("grid");
|
|
5336
|
+
const [meetingState, setMeetingState] = useState("CONNECTING");
|
|
5337
|
+
const [remoteWebcamOn, setRemoteWebcamOn] = useState({});
|
|
5338
|
+
const handleRemoteWebcamChange = useCallback((participantId, on) => {
|
|
5339
|
+
setRemoteWebcamOn(
|
|
5340
|
+
(prev) => prev[participantId] === on ? prev : { ...prev, [participantId]: on }
|
|
5341
|
+
);
|
|
5342
|
+
}, []);
|
|
5173
5343
|
const {
|
|
5174
5344
|
join,
|
|
5175
5345
|
participants,
|
|
@@ -5185,7 +5355,8 @@ var init_MeetingView = __esm({
|
|
|
5185
5355
|
onMeetingLeft: () => {
|
|
5186
5356
|
if (!hasJoinedRef.current) return;
|
|
5187
5357
|
endCall();
|
|
5188
|
-
}
|
|
5358
|
+
},
|
|
5359
|
+
onMeetingStateChanged: ({ state }) => setMeetingState(state)
|
|
5189
5360
|
});
|
|
5190
5361
|
const { floatingReactions, raisedHands, isHandRaised, sendReaction, toggleRaiseHand } = useCallReactions(sdk);
|
|
5191
5362
|
useEffect(() => {
|
|
@@ -5201,149 +5372,58 @@ var init_MeetingView = __esm({
|
|
|
5201
5372
|
(id) => id !== localParticipant?.id
|
|
5202
5373
|
);
|
|
5203
5374
|
const isGroup = remoteIds.length > 1;
|
|
5375
|
+
const remoteParticipantWatchers = remoteIds.map((id) => /* @__PURE__ */ jsx(
|
|
5376
|
+
RemoteParticipantWatcher,
|
|
5377
|
+
{
|
|
5378
|
+
sdk,
|
|
5379
|
+
participantId: id,
|
|
5380
|
+
onWebcamChange: handleRemoteWebcamChange
|
|
5381
|
+
},
|
|
5382
|
+
id
|
|
5383
|
+
));
|
|
5384
|
+
const anyRemoteWebcamOn = Object.values(remoteWebcamOn).some(Boolean);
|
|
5385
|
+
const showVideoGrid = mode === "video" || localWebcamOn || anyRemoteWebcamOn;
|
|
5204
5386
|
const controls = /* @__PURE__ */ jsx(
|
|
5205
5387
|
CallControls_default,
|
|
5206
5388
|
{
|
|
5207
5389
|
sdk,
|
|
5208
5390
|
onReaction: sendReaction,
|
|
5209
5391
|
isHandRaised,
|
|
5210
|
-
onToggleRaiseHand: toggleRaiseHand
|
|
5392
|
+
onToggleRaiseHand: toggleRaiseHand,
|
|
5393
|
+
isChatOpen,
|
|
5394
|
+
onToggleChat,
|
|
5395
|
+
isVideoActive: showVideoGrid
|
|
5211
5396
|
}
|
|
5212
5397
|
);
|
|
5398
|
+
const connectionStatusText = meetingState === "CONNECTING" ? "Connecting\u2026" : meetingState === "DISCONNECTED" ? "Reconnecting\u2026" : meetingState === "FAILED" ? "Connection lost" : null;
|
|
5399
|
+
const statusBanner = connectionStatusText && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-center gap-1.5 bg-amber-500/15 px-4 py-1.5 text-xs font-medium text-amber-300", children: [
|
|
5400
|
+
/* @__PURE__ */ jsx("span", { className: "size-1.5 animate-pulse rounded-full bg-amber-400" }),
|
|
5401
|
+
connectionStatusText
|
|
5402
|
+
] });
|
|
5213
5403
|
if (presenterId) {
|
|
5214
|
-
return /* @__PURE__ */ jsxs(
|
|
5215
|
-
|
|
5216
|
-
/* @__PURE__ */
|
|
5217
|
-
|
|
5218
|
-
{
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
isLocal: presenterId === localParticipant?.id,
|
|
5222
|
-
className: "flex flex-1 flex-col overflow-hidden p-4 pb-2"
|
|
5223
|
-
}
|
|
5224
|
-
),
|
|
5225
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 overflow-x-auto px-4 pb-2", children: [
|
|
5226
|
-
localParticipant?.id && /* @__PURE__ */ jsx(
|
|
5227
|
-
ParticipantView_default,
|
|
5404
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5405
|
+
remoteParticipantWatchers,
|
|
5406
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-1 flex-col", children: [
|
|
5407
|
+
statusBanner,
|
|
5408
|
+
/* @__PURE__ */ jsx(FloatingReactions_default, { reactions: floatingReactions }),
|
|
5409
|
+
/* @__PURE__ */ jsx(
|
|
5410
|
+
ScreenShareView_default,
|
|
5228
5411
|
{
|
|
5229
5412
|
sdk,
|
|
5230
|
-
|
|
5231
|
-
isLocal:
|
|
5232
|
-
|
|
5233
|
-
className: "aspect-video h-20 min-h-0 w-32 shrink-0"
|
|
5413
|
+
presenterId,
|
|
5414
|
+
isLocal: presenterId === localParticipant?.id,
|
|
5415
|
+
className: "flex flex-1 flex-col overflow-hidden p-4 pb-2"
|
|
5234
5416
|
}
|
|
5235
5417
|
),
|
|
5236
|
-
|
|
5237
|
-
ParticipantView_default,
|
|
5238
|
-
{
|
|
5239
|
-
sdk,
|
|
5240
|
-
participantId: id,
|
|
5241
|
-
fallbackName: peerName,
|
|
5242
|
-
fallbackImage: peerAvatar,
|
|
5243
|
-
isHandRaised: !!raisedHands[id],
|
|
5244
|
-
className: "aspect-video h-20 min-h-0 w-32 shrink-0"
|
|
5245
|
-
},
|
|
5246
|
-
id
|
|
5247
|
-
))
|
|
5248
|
-
] }),
|
|
5249
|
-
controls
|
|
5250
|
-
] });
|
|
5251
|
-
}
|
|
5252
|
-
const showVideoGrid = mode === "video" || localWebcamOn;
|
|
5253
|
-
if (!showVideoGrid) {
|
|
5254
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative flex flex-1 flex-col", children: [
|
|
5255
|
-
/* @__PURE__ */ jsx(FloatingReactions_default, { reactions: floatingReactions }),
|
|
5256
|
-
/* @__PURE__ */ jsx(
|
|
5257
|
-
AudioCallView_default,
|
|
5258
|
-
{
|
|
5259
|
-
sdk,
|
|
5260
|
-
remoteParticipantId: remoteIds[0],
|
|
5261
|
-
peerName,
|
|
5262
|
-
peerAvatar,
|
|
5263
|
-
isRemoteHandRaised: !!(remoteIds[0] && raisedHands[remoteIds[0]])
|
|
5264
|
-
}
|
|
5265
|
-
),
|
|
5266
|
-
controls
|
|
5267
|
-
] });
|
|
5268
|
-
}
|
|
5269
|
-
const focusedId = groupView === "speaker" ? activeSpeakerId && activeSpeakerId !== localParticipant?.id ? activeSpeakerId : remoteIds[0] || localParticipant?.id : null;
|
|
5270
|
-
const stripIds = focusedId ? [localParticipant?.id, ...remoteIds].filter(
|
|
5271
|
-
(id) => !!id && id !== focusedId
|
|
5272
|
-
) : [];
|
|
5273
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative flex flex-1 flex-col", children: [
|
|
5274
|
-
/* @__PURE__ */ jsx(FloatingReactions_default, { reactions: floatingReactions }),
|
|
5275
|
-
isGroup && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-1 px-4 pt-2", children: [
|
|
5276
|
-
/* @__PURE__ */ jsx(
|
|
5277
|
-
"button",
|
|
5278
|
-
{
|
|
5279
|
-
type: "button",
|
|
5280
|
-
"aria-label": "Grid view",
|
|
5281
|
-
onClick: () => setGroupView("grid"),
|
|
5282
|
-
className: cn(
|
|
5283
|
-
"flex size-8 items-center justify-center rounded-lg transition-colors",
|
|
5284
|
-
groupView === "grid" ? "bg-white/15 text-white" : "text-white/50 hover:text-white/80"
|
|
5285
|
-
),
|
|
5286
|
-
children: /* @__PURE__ */ jsx(LayoutGrid, { size: 16 })
|
|
5287
|
-
}
|
|
5288
|
-
),
|
|
5289
|
-
/* @__PURE__ */ jsx(
|
|
5290
|
-
"button",
|
|
5291
|
-
{
|
|
5292
|
-
type: "button",
|
|
5293
|
-
"aria-label": "Speaker view",
|
|
5294
|
-
onClick: () => setGroupView("speaker"),
|
|
5295
|
-
className: cn(
|
|
5296
|
-
"flex size-8 items-center justify-center rounded-lg transition-colors",
|
|
5297
|
-
groupView === "speaker" ? "bg-white/15 text-white" : "text-white/50 hover:text-white/80"
|
|
5298
|
-
),
|
|
5299
|
-
children: /* @__PURE__ */ jsx(Rows3, { size: 16 })
|
|
5300
|
-
}
|
|
5301
|
-
)
|
|
5302
|
-
] }),
|
|
5303
|
-
focusedId ? /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3 overflow-y-auto p-4", children: [
|
|
5304
|
-
/* @__PURE__ */ jsx(
|
|
5305
|
-
ParticipantView_default,
|
|
5306
|
-
{
|
|
5307
|
-
sdk,
|
|
5308
|
-
participantId: focusedId,
|
|
5309
|
-
isLocal: focusedId === localParticipant?.id,
|
|
5310
|
-
fallbackName: peerName,
|
|
5311
|
-
fallbackImage: peerAvatar,
|
|
5312
|
-
isHandRaised: !!raisedHands[focusedId],
|
|
5313
|
-
className: "min-h-[240px] flex-1"
|
|
5314
|
-
}
|
|
5315
|
-
),
|
|
5316
|
-
stripIds.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex gap-2 overflow-x-auto", children: stripIds.map((id) => /* @__PURE__ */ jsx(
|
|
5317
|
-
ParticipantView_default,
|
|
5318
|
-
{
|
|
5319
|
-
sdk,
|
|
5320
|
-
participantId: id,
|
|
5321
|
-
isLocal: id === localParticipant?.id,
|
|
5322
|
-
fallbackName: peerName,
|
|
5323
|
-
fallbackImage: peerAvatar,
|
|
5324
|
-
isHandRaised: !!raisedHands[id],
|
|
5325
|
-
className: "aspect-video h-20 min-h-0 w-32 shrink-0"
|
|
5326
|
-
},
|
|
5327
|
-
id
|
|
5328
|
-
)) })
|
|
5329
|
-
] }) : /* @__PURE__ */ jsxs(
|
|
5330
|
-
"div",
|
|
5331
|
-
{
|
|
5332
|
-
className: "grid flex-1 auto-rows-fr gap-3 overflow-y-auto p-4",
|
|
5333
|
-
style: {
|
|
5334
|
-
gridTemplateColumns: `repeat(${Math.min(
|
|
5335
|
-
Math.max(remoteIds.length + 1, 1),
|
|
5336
|
-
3
|
|
5337
|
-
)}, minmax(0, 1fr))`
|
|
5338
|
-
},
|
|
5339
|
-
children: [
|
|
5418
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 overflow-x-auto px-4 pb-2", children: [
|
|
5340
5419
|
localParticipant?.id && /* @__PURE__ */ jsx(
|
|
5341
5420
|
ParticipantView_default,
|
|
5342
5421
|
{
|
|
5343
5422
|
sdk,
|
|
5344
5423
|
participantId: localParticipant.id,
|
|
5345
5424
|
isLocal: true,
|
|
5346
|
-
isHandRaised: !!raisedHands[localParticipant.id]
|
|
5425
|
+
isHandRaised: !!raisedHands[localParticipant.id],
|
|
5426
|
+
className: "aspect-video h-20 min-h-0 w-32 shrink-0"
|
|
5347
5427
|
}
|
|
5348
5428
|
),
|
|
5349
5429
|
remoteIds.map((id) => /* @__PURE__ */ jsx(
|
|
@@ -5353,37 +5433,160 @@ var init_MeetingView = __esm({
|
|
|
5353
5433
|
participantId: id,
|
|
5354
5434
|
fallbackName: peerName,
|
|
5355
5435
|
fallbackImage: peerAvatar,
|
|
5356
|
-
isHandRaised: !!raisedHands[id]
|
|
5436
|
+
isHandRaised: !!raisedHands[id],
|
|
5437
|
+
className: "aspect-video h-20 min-h-0 w-32 shrink-0"
|
|
5357
5438
|
},
|
|
5358
5439
|
id
|
|
5359
5440
|
))
|
|
5360
|
-
]
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5441
|
+
] }),
|
|
5442
|
+
controls
|
|
5443
|
+
] })
|
|
5444
|
+
] });
|
|
5445
|
+
}
|
|
5446
|
+
if (!showVideoGrid) {
|
|
5447
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5448
|
+
remoteParticipantWatchers,
|
|
5449
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-1 flex-col", children: [
|
|
5450
|
+
statusBanner,
|
|
5451
|
+
/* @__PURE__ */ jsx(FloatingReactions_default, { reactions: floatingReactions }),
|
|
5452
|
+
/* @__PURE__ */ jsx(
|
|
5453
|
+
AudioCallView_default,
|
|
5454
|
+
{
|
|
5455
|
+
sdk,
|
|
5456
|
+
remoteParticipantId: remoteIds[0],
|
|
5457
|
+
peerName,
|
|
5458
|
+
peerAvatar,
|
|
5459
|
+
isRemoteHandRaised: !!(remoteIds[0] && raisedHands[remoteIds[0]])
|
|
5460
|
+
}
|
|
5461
|
+
),
|
|
5462
|
+
controls
|
|
5463
|
+
] })
|
|
5464
|
+
] });
|
|
5465
|
+
}
|
|
5466
|
+
const focusedId = groupView === "speaker" ? activeSpeakerId && activeSpeakerId !== localParticipant?.id ? activeSpeakerId : remoteIds[0] || localParticipant?.id : null;
|
|
5467
|
+
const stripIds = focusedId ? [localParticipant?.id, ...remoteIds].filter(
|
|
5468
|
+
(id) => !!id && id !== focusedId
|
|
5469
|
+
) : [];
|
|
5470
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5471
|
+
remoteParticipantWatchers,
|
|
5472
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-1 flex-col", children: [
|
|
5473
|
+
statusBanner,
|
|
5474
|
+
/* @__PURE__ */ jsx(FloatingReactions_default, { reactions: floatingReactions }),
|
|
5475
|
+
isGroup && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-1 px-4 pt-2", children: [
|
|
5476
|
+
/* @__PURE__ */ jsx(
|
|
5477
|
+
"button",
|
|
5478
|
+
{
|
|
5479
|
+
type: "button",
|
|
5480
|
+
"aria-label": "Grid view",
|
|
5481
|
+
onClick: () => setGroupView("grid"),
|
|
5482
|
+
className: cn(
|
|
5483
|
+
"flex size-8 items-center justify-center rounded-lg transition-colors",
|
|
5484
|
+
groupView === "grid" ? "bg-white/15 text-white" : "text-white/50 hover:text-white/80"
|
|
5485
|
+
),
|
|
5486
|
+
children: /* @__PURE__ */ jsx(LayoutGrid, { size: 16 })
|
|
5487
|
+
}
|
|
5488
|
+
),
|
|
5489
|
+
/* @__PURE__ */ jsx(
|
|
5490
|
+
"button",
|
|
5491
|
+
{
|
|
5492
|
+
type: "button",
|
|
5493
|
+
"aria-label": "Speaker view",
|
|
5494
|
+
onClick: () => setGroupView("speaker"),
|
|
5495
|
+
className: cn(
|
|
5496
|
+
"flex size-8 items-center justify-center rounded-lg transition-colors",
|
|
5497
|
+
groupView === "speaker" ? "bg-white/15 text-white" : "text-white/50 hover:text-white/80"
|
|
5498
|
+
),
|
|
5499
|
+
children: /* @__PURE__ */ jsx(Rows3, { size: 16 })
|
|
5500
|
+
}
|
|
5501
|
+
)
|
|
5502
|
+
] }),
|
|
5503
|
+
focusedId ? /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3 overflow-y-auto p-4", children: [
|
|
5504
|
+
/* @__PURE__ */ jsx(
|
|
5505
|
+
ParticipantView_default,
|
|
5506
|
+
{
|
|
5507
|
+
sdk,
|
|
5508
|
+
participantId: focusedId,
|
|
5509
|
+
isLocal: focusedId === localParticipant?.id,
|
|
5510
|
+
fallbackName: peerName,
|
|
5511
|
+
fallbackImage: peerAvatar,
|
|
5512
|
+
isHandRaised: !!raisedHands[focusedId],
|
|
5513
|
+
className: "min-h-[240px] flex-1"
|
|
5514
|
+
}
|
|
5515
|
+
),
|
|
5516
|
+
stripIds.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex gap-2 overflow-x-auto", children: stripIds.map((id) => /* @__PURE__ */ jsx(
|
|
5517
|
+
ParticipantView_default,
|
|
5518
|
+
{
|
|
5519
|
+
sdk,
|
|
5520
|
+
participantId: id,
|
|
5521
|
+
isLocal: id === localParticipant?.id,
|
|
5522
|
+
fallbackName: peerName,
|
|
5523
|
+
fallbackImage: peerAvatar,
|
|
5524
|
+
isHandRaised: !!raisedHands[id],
|
|
5525
|
+
className: "aspect-video h-20 min-h-0 w-32 shrink-0"
|
|
5526
|
+
},
|
|
5527
|
+
id
|
|
5528
|
+
)) })
|
|
5529
|
+
] }) : /* @__PURE__ */ jsxs(
|
|
5530
|
+
"div",
|
|
5531
|
+
{
|
|
5532
|
+
className: "grid flex-1 auto-rows-fr gap-3 overflow-y-auto p-4",
|
|
5533
|
+
style: {
|
|
5534
|
+
gridTemplateColumns: `repeat(${Math.min(
|
|
5535
|
+
Math.max(remoteIds.length + 1, 1),
|
|
5536
|
+
3
|
|
5537
|
+
)}, minmax(0, 1fr))`
|
|
5538
|
+
},
|
|
5539
|
+
children: [
|
|
5540
|
+
localParticipant?.id && /* @__PURE__ */ jsx(
|
|
5541
|
+
ParticipantView_default,
|
|
5542
|
+
{
|
|
5543
|
+
sdk,
|
|
5544
|
+
participantId: localParticipant.id,
|
|
5545
|
+
isLocal: true,
|
|
5546
|
+
isHandRaised: !!raisedHands[localParticipant.id]
|
|
5547
|
+
}
|
|
5548
|
+
),
|
|
5549
|
+
remoteIds.map((id) => /* @__PURE__ */ jsx(
|
|
5550
|
+
ParticipantView_default,
|
|
5551
|
+
{
|
|
5552
|
+
sdk,
|
|
5553
|
+
participantId: id,
|
|
5554
|
+
fallbackName: peerName,
|
|
5555
|
+
fallbackImage: peerAvatar,
|
|
5556
|
+
isHandRaised: !!raisedHands[id]
|
|
5557
|
+
},
|
|
5558
|
+
id
|
|
5559
|
+
))
|
|
5560
|
+
]
|
|
5561
|
+
}
|
|
5562
|
+
),
|
|
5563
|
+
controls
|
|
5564
|
+
] })
|
|
5565
|
+
] });
|
|
5566
|
+
};
|
|
5567
|
+
MeetingView_default = MeetingView;
|
|
5568
|
+
}
|
|
5569
|
+
});
|
|
5570
|
+
|
|
5571
|
+
// src/call/CallSession.tsx
|
|
5572
|
+
var CallSession_exports = {};
|
|
5573
|
+
__export(CallSession_exports, {
|
|
5574
|
+
default: () => CallSession_default
|
|
5575
|
+
});
|
|
5576
|
+
var CallSession, CallSession_default;
|
|
5577
|
+
var init_CallSession = __esm({
|
|
5578
|
+
"src/call/CallSession.tsx"() {
|
|
5579
|
+
init_useStore();
|
|
5580
|
+
init_videosdk_loader();
|
|
5581
|
+
init_MeetingView();
|
|
5582
|
+
CallSession = ({
|
|
5583
|
+
meetingId,
|
|
5584
|
+
token,
|
|
5585
|
+
mode,
|
|
5586
|
+
peerName,
|
|
5386
5587
|
peerAvatar,
|
|
5588
|
+
isChatOpen,
|
|
5589
|
+
onToggleChat,
|
|
5387
5590
|
onError
|
|
5388
5591
|
}) => {
|
|
5389
5592
|
const [sdk, setSdk] = useState(null);
|
|
@@ -5426,7 +5629,17 @@ var init_CallSession = __esm({
|
|
|
5426
5629
|
token,
|
|
5427
5630
|
reinitialiseMeetingOnConfigChange: false,
|
|
5428
5631
|
joinWithoutUserInteraction: true,
|
|
5429
|
-
children: /* @__PURE__ */ jsx(
|
|
5632
|
+
children: /* @__PURE__ */ jsx(
|
|
5633
|
+
MeetingView_default,
|
|
5634
|
+
{
|
|
5635
|
+
sdk,
|
|
5636
|
+
mode,
|
|
5637
|
+
peerName,
|
|
5638
|
+
peerAvatar,
|
|
5639
|
+
isChatOpen,
|
|
5640
|
+
onToggleChat
|
|
5641
|
+
}
|
|
5642
|
+
)
|
|
5430
5643
|
}
|
|
5431
5644
|
);
|
|
5432
5645
|
};
|
|
@@ -5438,67 +5651,7 @@ var init_CallSession = __esm({
|
|
|
5438
5651
|
init_useStore();
|
|
5439
5652
|
init_api_service();
|
|
5440
5653
|
init_socket_service2();
|
|
5441
|
-
|
|
5442
|
-
// src/ui/tooltip.tsx
|
|
5443
|
-
init_utils2();
|
|
5444
|
-
function TooltipProvider({
|
|
5445
|
-
delayDuration = 0,
|
|
5446
|
-
...props
|
|
5447
|
-
}) {
|
|
5448
|
-
return /* @__PURE__ */ jsx(
|
|
5449
|
-
Tooltip$1.Provider,
|
|
5450
|
-
{
|
|
5451
|
-
"data-slot": "tooltip-provider",
|
|
5452
|
-
delayDuration,
|
|
5453
|
-
...props
|
|
5454
|
-
}
|
|
5455
|
-
);
|
|
5456
|
-
}
|
|
5457
|
-
function Tooltip({
|
|
5458
|
-
...props
|
|
5459
|
-
}) {
|
|
5460
|
-
return /* @__PURE__ */ jsx(Tooltip$1.Root, { "data-slot": "tooltip", ...props });
|
|
5461
|
-
}
|
|
5462
|
-
function TooltipTrigger({
|
|
5463
|
-
...props
|
|
5464
|
-
}) {
|
|
5465
|
-
return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
5466
|
-
}
|
|
5467
|
-
function TooltipContent({
|
|
5468
|
-
className,
|
|
5469
|
-
sideOffset = 0,
|
|
5470
|
-
children,
|
|
5471
|
-
showArrow = true,
|
|
5472
|
-
arrowClassName,
|
|
5473
|
-
...props
|
|
5474
|
-
}) {
|
|
5475
|
-
return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsxs(
|
|
5476
|
-
Tooltip$1.Content,
|
|
5477
|
-
{
|
|
5478
|
-
"data-slot": "tooltip-content",
|
|
5479
|
-
sideOffset,
|
|
5480
|
-
className: cn(
|
|
5481
|
-
"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
|
|
5482
|
-
className
|
|
5483
|
-
),
|
|
5484
|
-
...props,
|
|
5485
|
-
children: [
|
|
5486
|
-
children,
|
|
5487
|
-
showArrow ? /* @__PURE__ */ jsx(
|
|
5488
|
-
Tooltip$1.Arrow,
|
|
5489
|
-
{
|
|
5490
|
-
className: cn(
|
|
5491
|
-
"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]",
|
|
5492
|
-
arrowClassName
|
|
5493
|
-
)
|
|
5494
|
-
}
|
|
5495
|
-
) : null
|
|
5496
|
-
]
|
|
5497
|
-
}
|
|
5498
|
-
) });
|
|
5499
|
-
}
|
|
5500
|
-
|
|
5501
|
-
// src/chat/ChatContext.tsx
|
|
5654
|
+
init_tooltip();
|
|
5502
5655
|
init_utils2();
|
|
5503
5656
|
|
|
5504
5657
|
// src/config/chat-endpoints.ts
|
|
@@ -6419,11 +6572,353 @@ var useCallDuration = (startedAt) => {
|
|
|
6419
6572
|
const pad = (n) => String(n).padStart(2, "0");
|
|
6420
6573
|
return hours > 0 ? `${hours}:${pad(minutes)}:${pad(seconds)}` : `${pad(minutes)}:${pad(seconds)}`;
|
|
6421
6574
|
};
|
|
6575
|
+
|
|
6576
|
+
// src/call/CallChatPanel.tsx
|
|
6577
|
+
init_useStore();
|
|
6578
|
+
init_store_helpers();
|
|
6579
|
+
init_utils2();
|
|
6580
|
+
init_button();
|
|
6581
|
+
|
|
6582
|
+
// src/chat/lib/chat-theme.ts
|
|
6583
|
+
init_utils2();
|
|
6584
|
+
var getChatScopeClass = (isDark) => cn("chat-theme-scope", isDark && "dark");
|
|
6585
|
+
var chatSheetContentClass = "flex w-full flex-col gap-0 p-0 bg-(--chat-surface) text-(--chat-text)";
|
|
6586
|
+
var chatSheetHeaderClass = "border-b border-(--chat-border) px-4 py-3 pr-11 text-left";
|
|
6587
|
+
var chatSheetBodyClass = "chat-message-scroll flex-1 overflow-y-auto bg-(--chat-surface) p-3";
|
|
6588
|
+
var chatSheetTitleClass = "text-[13px] font-semibold tracking-tight text-(--chat-text)";
|
|
6589
|
+
var chatSheetSubtitleClass = "text-[11px] text-(--chat-muted)";
|
|
6590
|
+
var chatDetailRowClass = "flex items-start justify-between gap-3 border-b border-(--chat-border) py-2.5 last:border-b-0";
|
|
6591
|
+
var chatDetailLabelClass = "text-[11px] text-(--chat-muted)";
|
|
6592
|
+
var chatDetailValueClass = "text-[13px] font-medium text-(--chat-text) text-right";
|
|
6593
|
+
var chatDialogContentClass = "overflow-hidden rounded-2xl border border-(--chat-border) bg-(--chat-surface) p-0 text-(--chat-text) shadow-[var(--chat-shadow)]";
|
|
6594
|
+
var chatDropdownContentClass = "rounded-xl border border-(--chat-border) bg-(--chat-surface) text-(--chat-text) shadow-lg";
|
|
6595
|
+
var chatOptionsMenuClass = "min-w-[220px] rounded-xl border border-(--chat-border) bg-(--chat-surface) p-1.5 text-(--chat-text) shadow-[0_10px_40px_rgba(0,0,0,0.12)]";
|
|
6596
|
+
var chatOptionsMenuLabelClass = "px-2.5 pb-0.5 pt-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-(--chat-muted)";
|
|
6597
|
+
var chatOptionsMenuSeparatorClass = "my-1.5 h-px bg-(--chat-border)";
|
|
6598
|
+
var chatOptionsMenuItemClass = "cursor-pointer gap-2.5 rounded-lg px-2.5 py-2 text-[13px] font-medium text-(--chat-text) focus:bg-(--chat-hover) focus:text-(--chat-text) data-[highlighted]:bg-(--chat-hover) [&_svg]:size-[15px] [&_svg]:shrink-0 [&_svg]:text-(--chat-muted)";
|
|
6599
|
+
var chatOptionsMenuItemDestructiveClass = "cursor-pointer gap-2.5 rounded-lg px-2.5 py-2 text-[13px] font-medium text-(--chat-danger-text) focus:bg-red-500/10 focus:text-(--chat-danger-text) data-[highlighted]:bg-red-500/10 data-[highlighted]:text-(--chat-danger-text) [&_svg]:size-[15px] [&_svg]:shrink-0 [&_svg]:!text-(--chat-danger-text)";
|
|
6600
|
+
var chatOptionsMenuSubTriggerClass = "cursor-pointer gap-2.5 rounded-lg px-2.5 py-2 pr-7 text-[13px] font-medium text-(--chat-text) focus:bg-(--chat-hover) focus:text-(--chat-text) data-[highlighted]:bg-(--chat-hover) data-[state=open]:bg-(--chat-hover) [&_svg]:size-[15px] [&_svg]:shrink-0 [&_svg]:text-(--chat-muted)";
|
|
6601
|
+
var chatPopoverContentClass = "w-auto border border-(--chat-border) bg-(--chat-surface) p-0 text-(--chat-text) shadow-2xl";
|
|
6602
|
+
var chatInputClass = "border border-(--chat-border) bg-(--chat-input-bg) text-(--chat-text) shadow-none placeholder:text-(--chat-muted) focus-visible:border-(--chat-theme-20) focus-visible:ring-2 focus-visible:ring-(--chat-theme-10)";
|
|
6603
|
+
var chatSidebarSearchShellClass = "relative flex min-w-0 flex-1 items-center rounded-lg border border-(--chat-border) bg-(--chat-search-bg) px-2.5 transition-colors focus-within:border-(--chat-theme) focus-within:shadow-[0_0_0_2px_var(--chat-theme-10)]";
|
|
6604
|
+
var chatSidebarSearchInputClass = "h-8 w-full min-w-0 border-0 bg-transparent px-1.5 text-xs text-(--chat-text) shadow-none outline-none placeholder:text-(--chat-muted)/60 focus-visible:border-0 focus-visible:shadow-none focus-visible:ring-0";
|
|
6605
|
+
var chatSelectClass = "h-10 w-full cursor-pointer appearance-none rounded-xl border border-(--chat-border) bg-(--chat-input-bg) pl-3 pr-9 text-sm text-(--chat-text) shadow-none focus-visible:border-(--chat-theme-20) focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--chat-theme-10)";
|
|
6606
|
+
var chatListItemClass = "transition-colors hover:bg-(--chat-hover)";
|
|
6607
|
+
var chatLoadMoreButtonClass = "h-7 gap-1 rounded-full border border-(--chat-border) bg-(--chat-elevated) px-4 text-[10px] font-medium text-(--chat-text) transition-colors hover:border-(--chat-theme-20) hover:bg-(--chat-theme-5) hover:text-(--chat-theme) disabled:opacity-50 [&_svg]:size-3 [&_svg]:text-current";
|
|
6608
|
+
var chatDrawerSectionHeadingClass = "mb-1 px-0.5 text-[10px] font-semibold tracking-wide text-(--chat-muted)";
|
|
6609
|
+
var chatHeaderToolbarIconProps = { size: 14, strokeWidth: 1.75 };
|
|
6610
|
+
var chatSavedMessageModalIconClass = "shrink-0 text-(--chat-theme)";
|
|
6611
|
+
var chatHeaderToolbarIconLgProps = { size: 22, strokeWidth: 1.75 };
|
|
6612
|
+
var chatHeaderToolbarIconSmProps = { size: 11, strokeWidth: 1.75 };
|
|
6613
|
+
var chatDrawerFileRowClass = "flex items-center gap-2 rounded-md border border-(--chat-border)/70 bg-(--chat-elevated) px-2 py-1.5 transition-colors hover:bg-(--chat-hover)/50";
|
|
6614
|
+
var chatDrawerFileIconWrapClass = "flex size-8 shrink-0 items-center justify-center rounded-md bg-(--chat-hover)";
|
|
6615
|
+
var chatDrawerMediaFrameClass = "overflow-hidden rounded-md border border-(--chat-border)/70 bg-(--chat-elevated)";
|
|
6616
|
+
var buildChatThemeStyles = (themeColor) => ({
|
|
6617
|
+
"--chat-theme": themeColor,
|
|
6618
|
+
"--chat-theme-5": `${themeColor}0D`,
|
|
6619
|
+
"--chat-theme-10": `${themeColor}1A`,
|
|
6620
|
+
"--chat-theme-20": `${themeColor}33`,
|
|
6621
|
+
"--chat-theme-40": `${themeColor}66`,
|
|
6622
|
+
"--chat-theme-60": `${themeColor}99`,
|
|
6623
|
+
"--read-tick-color": themeColor.toLowerCase() === "#0000ff" || themeColor.toLowerCase().includes("007aff") ? "#00e5ff" : "#40C4FF"
|
|
6624
|
+
});
|
|
6625
|
+
|
|
6626
|
+
// src/chat/lib/chat-theme-storage.ts
|
|
6627
|
+
var STORAGE_KEY = "chat-color-mode";
|
|
6628
|
+
var loadChatColorMode = () => {
|
|
6629
|
+
if (typeof window === "undefined") return null;
|
|
6630
|
+
try {
|
|
6631
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
6632
|
+
return stored === "dark" || stored === "light" ? stored : null;
|
|
6633
|
+
} catch {
|
|
6634
|
+
return null;
|
|
6635
|
+
}
|
|
6636
|
+
};
|
|
6637
|
+
var saveChatColorMode = (mode) => {
|
|
6638
|
+
if (typeof window === "undefined") return;
|
|
6639
|
+
try {
|
|
6640
|
+
localStorage.setItem(STORAGE_KEY, mode);
|
|
6641
|
+
} catch {
|
|
6642
|
+
}
|
|
6643
|
+
};
|
|
6644
|
+
var CHAT_THEME_SHELL_CLASS = "chat-theme-shell";
|
|
6645
|
+
function withThemeTransition(apply) {
|
|
6646
|
+
if (typeof document === "undefined") {
|
|
6647
|
+
apply();
|
|
6648
|
+
return;
|
|
6649
|
+
}
|
|
6650
|
+
flushSync(apply);
|
|
6651
|
+
}
|
|
6652
|
+
|
|
6653
|
+
// src/context/ChatThemeContext.tsx
|
|
6654
|
+
init_utils2();
|
|
6655
|
+
var ChatThemeContext = createContext(null);
|
|
6656
|
+
var ChatThemeProvider = ({
|
|
6657
|
+
children,
|
|
6658
|
+
themeColor,
|
|
6659
|
+
colorMode,
|
|
6660
|
+
defaultColorMode = "light",
|
|
6661
|
+
onColorModeChange,
|
|
6662
|
+
showColorModeToggle = true
|
|
6663
|
+
}) => {
|
|
6664
|
+
const isControlled = colorMode !== void 0;
|
|
6665
|
+
const [internalMode, setInternalMode] = useState(defaultColorMode);
|
|
6666
|
+
const [isThemeTransitionReady, setIsThemeTransitionReady] = useState(false);
|
|
6667
|
+
const skipThemeTransitionRef = useRef(true);
|
|
6668
|
+
useLayoutEffect(() => {
|
|
6669
|
+
if (!isControlled) {
|
|
6670
|
+
const stored = loadChatColorMode();
|
|
6671
|
+
if (stored) {
|
|
6672
|
+
setInternalMode(stored);
|
|
6673
|
+
}
|
|
6674
|
+
}
|
|
6675
|
+
const frame = requestAnimationFrame(() => {
|
|
6676
|
+
skipThemeTransitionRef.current = false;
|
|
6677
|
+
setIsThemeTransitionReady(true);
|
|
6678
|
+
});
|
|
6679
|
+
return () => cancelAnimationFrame(frame);
|
|
6680
|
+
}, [isControlled]);
|
|
6681
|
+
const resolvedMode = isControlled ? colorMode : internalMode;
|
|
6682
|
+
const isDark = resolvedMode === "dark";
|
|
6683
|
+
const setColorMode = useCallback(
|
|
6684
|
+
(mode) => {
|
|
6685
|
+
const apply = () => {
|
|
6686
|
+
if (!isControlled) {
|
|
6687
|
+
setInternalMode(mode);
|
|
6688
|
+
saveChatColorMode(mode);
|
|
6689
|
+
}
|
|
6690
|
+
onColorModeChange?.(mode);
|
|
6691
|
+
};
|
|
6692
|
+
if (skipThemeTransitionRef.current) {
|
|
6693
|
+
apply();
|
|
6694
|
+
return;
|
|
6695
|
+
}
|
|
6696
|
+
withThemeTransition(apply);
|
|
6697
|
+
},
|
|
6698
|
+
[isControlled, onColorModeChange]
|
|
6699
|
+
);
|
|
6700
|
+
const toggleColorMode = useCallback(() => {
|
|
6701
|
+
setColorMode(resolvedMode === "dark" ? "light" : "dark");
|
|
6702
|
+
}, [resolvedMode, setColorMode]);
|
|
6703
|
+
const value = useMemo(
|
|
6704
|
+
() => ({
|
|
6705
|
+
colorMode: resolvedMode,
|
|
6706
|
+
isDark,
|
|
6707
|
+
isThemeTransitionReady,
|
|
6708
|
+
themeColor,
|
|
6709
|
+
themeStyles: buildChatThemeStyles(themeColor),
|
|
6710
|
+
scopeClassName: cn(
|
|
6711
|
+
getChatScopeClass(isDark),
|
|
6712
|
+
!isThemeTransitionReady && "chat-theme-no-transition"
|
|
6713
|
+
),
|
|
6714
|
+
setColorMode,
|
|
6715
|
+
toggleColorMode,
|
|
6716
|
+
showColorModeToggle
|
|
6717
|
+
}),
|
|
6718
|
+
[
|
|
6719
|
+
resolvedMode,
|
|
6720
|
+
isDark,
|
|
6721
|
+
isThemeTransitionReady,
|
|
6722
|
+
themeColor,
|
|
6723
|
+
setColorMode,
|
|
6724
|
+
toggleColorMode,
|
|
6725
|
+
showColorModeToggle
|
|
6726
|
+
]
|
|
6727
|
+
);
|
|
6728
|
+
return /* @__PURE__ */ jsx(ChatThemeContext.Provider, { value, children });
|
|
6729
|
+
};
|
|
6730
|
+
var useChatTheme = () => {
|
|
6731
|
+
const context = useContext(ChatThemeContext);
|
|
6732
|
+
if (!context) {
|
|
6733
|
+
throw new Error("useChatTheme must be used within ChatThemeProvider");
|
|
6734
|
+
}
|
|
6735
|
+
return context;
|
|
6736
|
+
};
|
|
6737
|
+
|
|
6738
|
+
// src/chat/lib/chat-message-bubble.ts
|
|
6739
|
+
init_utils2();
|
|
6740
|
+
function getBubbleCornerClasses(isSender) {
|
|
6741
|
+
return isSender ? "rounded-tl-[18px] rounded-tr-[18px] rounded-bl-[18px] rounded-br-none" : "rounded-tl-[18px] rounded-tr-[18px] rounded-br-[18px] rounded-bl-none";
|
|
6742
|
+
}
|
|
6743
|
+
function getChatBubbleClasses({
|
|
6744
|
+
isSender = false,
|
|
6745
|
+
surface,
|
|
6746
|
+
className
|
|
6747
|
+
}) {
|
|
6748
|
+
const resolvedSurface = surface ?? (isSender ? "sent" : "received");
|
|
6749
|
+
const isNeutral = resolvedSurface === "neutral";
|
|
6750
|
+
return cn(
|
|
6751
|
+
"relative",
|
|
6752
|
+
getBubbleCornerClasses(isSender),
|
|
6753
|
+
resolvedSurface === "sent" && "chat-bubble-sent bg-(--chat-theme) text-white",
|
|
6754
|
+
resolvedSurface === "received" && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
6755
|
+
isNeutral && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
6756
|
+
className
|
|
6757
|
+
);
|
|
6758
|
+
}
|
|
6759
|
+
var CallChatPanel = ({ conversationId, isGroupCall, onClose, className }) => {
|
|
6760
|
+
const { scopeClassName, themeStyles } = useChatTheme();
|
|
6761
|
+
const rawMessages = useStore((s) => s.messagesByConversation[conversationId]);
|
|
6762
|
+
const loggedUserDetails = useStore((s) => s.loggedUserDetails);
|
|
6763
|
+
const conversations = useStore((s) => s.conversations);
|
|
6764
|
+
const emitDmSend = useStore((s) => s.emitDmSend);
|
|
6765
|
+
const emitGroupMessageSend2 = useStore((s) => s.emitGroupMessageSend);
|
|
6766
|
+
const [text, setText] = useState("");
|
|
6767
|
+
const [optimistic, setOptimistic] = useState([]);
|
|
6768
|
+
const listEndRef = useRef(null);
|
|
6769
|
+
const loggedUserId = String(loggedUserDetails?._id || "");
|
|
6770
|
+
const serverMessages = useMemo(() => {
|
|
6771
|
+
return (rawMessages || []).filter((m) => !m?.isSystemMessage && !m?.isDeletedForEveryone).map((m) => {
|
|
6772
|
+
const senderId = String(m.sender?._id || m.sender || "");
|
|
6773
|
+
return {
|
|
6774
|
+
id: String(m._id || m.id || ""),
|
|
6775
|
+
content: String(m.content || ""),
|
|
6776
|
+
senderName: senderId === loggedUserId ? "You" : m.sender?.name || "Unknown",
|
|
6777
|
+
isOwn: senderId === loggedUserId,
|
|
6778
|
+
timestamp: m.createdAt || m.timestamp || (/* @__PURE__ */ new Date()).toISOString()
|
|
6779
|
+
};
|
|
6780
|
+
});
|
|
6781
|
+
}, [rawMessages, loggedUserId]);
|
|
6782
|
+
useEffect(() => {
|
|
6783
|
+
if (!optimistic.length) return;
|
|
6784
|
+
setOptimistic(
|
|
6785
|
+
(prev) => prev.filter(
|
|
6786
|
+
(pending) => !serverMessages.some(
|
|
6787
|
+
(real) => real.isOwn && real.content === pending.content
|
|
6788
|
+
)
|
|
6789
|
+
)
|
|
6790
|
+
);
|
|
6791
|
+
}, [serverMessages]);
|
|
6792
|
+
const messages = useMemo(
|
|
6793
|
+
() => [...serverMessages, ...optimistic].sort(
|
|
6794
|
+
(a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
|
6795
|
+
),
|
|
6796
|
+
[serverMessages, optimistic]
|
|
6797
|
+
);
|
|
6798
|
+
useEffect(() => {
|
|
6799
|
+
listEndRef.current?.scrollIntoView({ block: "end" });
|
|
6800
|
+
}, [messages.length]);
|
|
6801
|
+
const handleSend = () => {
|
|
6802
|
+
const content = text.trim();
|
|
6803
|
+
if (!content) return;
|
|
6804
|
+
setText("");
|
|
6805
|
+
setOptimistic((prev) => [
|
|
6806
|
+
...prev,
|
|
6807
|
+
{
|
|
6808
|
+
id: `pending-${Date.now()}`,
|
|
6809
|
+
content,
|
|
6810
|
+
senderName: "You",
|
|
6811
|
+
isOwn: true,
|
|
6812
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6813
|
+
pending: true
|
|
6814
|
+
}
|
|
6815
|
+
]);
|
|
6816
|
+
const payload = {
|
|
6817
|
+
tempId: `temp-${Date.now()}`,
|
|
6818
|
+
sender: loggedUserId,
|
|
6819
|
+
content,
|
|
6820
|
+
type: "text",
|
|
6821
|
+
conversationId
|
|
6822
|
+
};
|
|
6823
|
+
if (isGroupCall) {
|
|
6824
|
+
emitGroupMessageSend2(payload);
|
|
6825
|
+
} else {
|
|
6826
|
+
const conversation = findConversationById(conversations, conversationId);
|
|
6827
|
+
payload.receiver = getOtherParticipantId(conversation, loggedUserId);
|
|
6828
|
+
emitDmSend(payload);
|
|
6829
|
+
}
|
|
6830
|
+
};
|
|
6831
|
+
return /* @__PURE__ */ jsxs(
|
|
6832
|
+
"div",
|
|
6833
|
+
{
|
|
6834
|
+
className: cn(
|
|
6835
|
+
scopeClassName,
|
|
6836
|
+
"flex flex-col border-l border-(--chat-border) bg-(--chat-surface) text-(--chat-text)",
|
|
6837
|
+
className
|
|
6838
|
+
),
|
|
6839
|
+
style: themeStyles,
|
|
6840
|
+
children: [
|
|
6841
|
+
/* @__PURE__ */ jsxs("div", { className: cn(chatSheetHeaderClass, "flex items-center justify-between"), children: [
|
|
6842
|
+
/* @__PURE__ */ jsx("p", { className: chatSheetTitleClass, children: "In-call chat" }),
|
|
6843
|
+
/* @__PURE__ */ jsx(
|
|
6844
|
+
"button",
|
|
6845
|
+
{
|
|
6846
|
+
type: "button",
|
|
6847
|
+
"aria-label": "Close chat panel",
|
|
6848
|
+
onClick: onClose,
|
|
6849
|
+
className: "flex size-7 items-center justify-center rounded-lg text-(--chat-muted) transition-colors hover:bg-(--chat-hover) hover:text-(--chat-text)",
|
|
6850
|
+
children: /* @__PURE__ */ jsx(X, { size: 16 })
|
|
6851
|
+
}
|
|
6852
|
+
)
|
|
6853
|
+
] }),
|
|
6854
|
+
/* @__PURE__ */ jsxs("div", { className: cn(chatSheetBodyClass, "space-y-3"), children: [
|
|
6855
|
+
messages.length === 0 && /* @__PURE__ */ jsx("p", { className: "pt-6 text-center text-xs text-(--chat-muted)", children: "No messages yet \u2014 say hi without leaving the call." }),
|
|
6856
|
+
messages.map((message) => /* @__PURE__ */ jsxs(
|
|
6857
|
+
"div",
|
|
6858
|
+
{
|
|
6859
|
+
className: cn("flex flex-col", message.isOwn ? "items-end" : "items-start"),
|
|
6860
|
+
children: [
|
|
6861
|
+
/* @__PURE__ */ jsx("span", { className: "mb-0.5 text-[11px] font-medium text-(--chat-muted)", children: message.isOwn ? "You" : message.senderName }),
|
|
6862
|
+
/* @__PURE__ */ jsx(
|
|
6863
|
+
"div",
|
|
6864
|
+
{
|
|
6865
|
+
className: cn(
|
|
6866
|
+
getChatBubbleClasses({ isSender: message.isOwn }),
|
|
6867
|
+
"max-w-[85%] px-3 py-1.5 text-sm break-words",
|
|
6868
|
+
message.pending && "opacity-60"
|
|
6869
|
+
),
|
|
6870
|
+
children: message.content
|
|
6871
|
+
}
|
|
6872
|
+
)
|
|
6873
|
+
]
|
|
6874
|
+
},
|
|
6875
|
+
message.id
|
|
6876
|
+
)),
|
|
6877
|
+
/* @__PURE__ */ jsx("div", { ref: listEndRef })
|
|
6878
|
+
] }),
|
|
6879
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-t border-(--chat-border) p-3", children: [
|
|
6880
|
+
/* @__PURE__ */ jsx(
|
|
6881
|
+
"input",
|
|
6882
|
+
{
|
|
6883
|
+
value: text,
|
|
6884
|
+
onChange: (e) => setText(e.target.value),
|
|
6885
|
+
onKeyDown: (e) => {
|
|
6886
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
6887
|
+
e.preventDefault();
|
|
6888
|
+
handleSend();
|
|
6889
|
+
}
|
|
6890
|
+
},
|
|
6891
|
+
placeholder: "Message\u2026",
|
|
6892
|
+
className: cn(chatInputClass, "min-w-0 flex-1 rounded-full px-3.5 py-2 text-sm")
|
|
6893
|
+
}
|
|
6894
|
+
),
|
|
6895
|
+
/* @__PURE__ */ jsx(
|
|
6896
|
+
Button,
|
|
6897
|
+
{
|
|
6898
|
+
variant: "ghost",
|
|
6899
|
+
size: "icon",
|
|
6900
|
+
"aria-label": "Send message",
|
|
6901
|
+
disabled: !text.trim(),
|
|
6902
|
+
onClick: handleSend,
|
|
6903
|
+
className: cn(
|
|
6904
|
+
"size-9 shrink-0 rounded-full transition-colors",
|
|
6905
|
+
text.trim() ? "bg-(--chat-theme) text-white hover:opacity-90" : "bg-(--chat-hover) text-(--chat-muted)"
|
|
6906
|
+
),
|
|
6907
|
+
children: /* @__PURE__ */ jsx(Send, { size: 16 })
|
|
6908
|
+
}
|
|
6909
|
+
)
|
|
6910
|
+
] })
|
|
6911
|
+
]
|
|
6912
|
+
}
|
|
6913
|
+
);
|
|
6914
|
+
};
|
|
6915
|
+
var CallChatPanel_default = CallChatPanel;
|
|
6422
6916
|
var CallSession2 = React11__default.lazy(() => Promise.resolve().then(() => (init_CallSession(), CallSession_exports)));
|
|
6423
6917
|
var CallOverlay = () => {
|
|
6424
6918
|
const uiStatus = useCallStore((s) => s.uiStatus);
|
|
6425
6919
|
const mode = useCallStore((s) => s.mode);
|
|
6426
6920
|
const callId = useCallStore((s) => s.callId);
|
|
6921
|
+
const conversationId = useCallStore((s) => s.conversationId);
|
|
6427
6922
|
const meetingId = useCallStore((s) => s.meetingId);
|
|
6428
6923
|
const token = useCallStore((s) => s.token);
|
|
6429
6924
|
const error = useCallStore((s) => s.error);
|
|
@@ -6435,112 +6930,111 @@ var CallOverlay = () => {
|
|
|
6435
6930
|
const reset = useCallStore((s) => s.reset);
|
|
6436
6931
|
const notifyServerCallFailed = useCallStore((s) => s.notifyServerCallFailed);
|
|
6437
6932
|
const [sessionError, setSessionError] = useState(null);
|
|
6933
|
+
const [isChatOpen, setIsChatOpen] = useState(false);
|
|
6438
6934
|
const secondsLeft = useRingCountdown(uiStatus === "ringing-out", callId);
|
|
6439
6935
|
const duration = useCallDuration(callStartedAt);
|
|
6440
6936
|
useEffect(() => {
|
|
6441
6937
|
setSessionError(null);
|
|
6938
|
+
setIsChatOpen(false);
|
|
6442
6939
|
}, [callId]);
|
|
6443
6940
|
useEffect(() => {
|
|
6444
6941
|
if (sessionError) notifyServerCallFailed();
|
|
6445
6942
|
}, [sessionError, notifyServerCallFailed]);
|
|
6446
6943
|
const isOpen = uiStatus !== "idle" && uiStatus !== "incoming";
|
|
6447
|
-
if (!isOpen
|
|
6944
|
+
if (!isOpen) return null;
|
|
6448
6945
|
const displayError = error || sessionError;
|
|
6449
6946
|
const peerName = peer?.name || caller?.name || "";
|
|
6450
6947
|
const peerAvatar = peer?.avatar || caller?.profileImage || void 0;
|
|
6451
|
-
const isVideo = mode === "video";
|
|
6452
|
-
return
|
|
6453
|
-
/* @__PURE__ */ jsx(
|
|
6454
|
-
|
|
6455
|
-
{
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
isGroupCall && /* @__PURE__ */ jsx(Users, { size: 14, className: "text-white/50" }),
|
|
6473
|
-
peerName && /* @__PURE__ */ jsx("span", { className: "font-medium text-white/90", children: peerName }),
|
|
6474
|
-
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-white/30", children: "\xB7" }),
|
|
6475
|
-
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: duration })
|
|
6476
|
-
] }),
|
|
6477
|
-
/* @__PURE__ */ jsx(
|
|
6478
|
-
React11__default.Suspense,
|
|
6479
|
-
{
|
|
6480
|
-
fallback: /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-3 text-white/80", children: [
|
|
6481
|
-
/* @__PURE__ */ jsx(Loader2, { className: "size-8 animate-spin" }),
|
|
6482
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "Loading call\u2026" })
|
|
6483
|
-
] }),
|
|
6484
|
-
children: /* @__PURE__ */ jsx(
|
|
6485
|
-
CallSession2,
|
|
6486
|
-
{
|
|
6487
|
-
meetingId,
|
|
6488
|
-
token,
|
|
6489
|
-
mode,
|
|
6490
|
-
peerName,
|
|
6491
|
-
peerAvatar,
|
|
6492
|
-
onError: setSessionError
|
|
6493
|
-
}
|
|
6494
|
-
)
|
|
6495
|
-
}
|
|
6496
|
-
)
|
|
6497
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-6 p-6 text-center", children: [
|
|
6498
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
|
|
6499
|
-
uiStatus === "ringing-out" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6500
|
-
/* @__PURE__ */ jsx("span", { className: "absolute inline-flex size-32 animate-ping rounded-full bg-white/10" }),
|
|
6501
|
-
/* @__PURE__ */ jsx(
|
|
6502
|
-
"span",
|
|
6503
|
-
{
|
|
6504
|
-
className: "absolute inline-flex size-32 animate-ping rounded-full bg-white/5",
|
|
6505
|
-
style: { animationDelay: "0.6s" }
|
|
6506
|
-
}
|
|
6507
|
-
)
|
|
6508
|
-
] }),
|
|
6509
|
-
peerName ? /* @__PURE__ */ jsxs(Avatar, { className: "relative size-28 ring-4 ring-white/10", children: [
|
|
6510
|
-
/* @__PURE__ */ jsx(AvatarImage, { src: peerAvatar, alt: peerName }),
|
|
6511
|
-
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-neutral-700 text-3xl font-medium text-white", children: peerName.charAt(0).toUpperCase() })
|
|
6512
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "relative flex size-28 items-center justify-center rounded-full bg-white/10", children: isVideo ? /* @__PURE__ */ jsx(Video, { size: 36 }) : /* @__PURE__ */ jsx(Phone, { size: 36 }) })
|
|
6513
|
-
] }),
|
|
6514
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
6515
|
-
peerName && /* @__PURE__ */ jsxs("p", { className: "flex items-center justify-center gap-1.5 text-xl font-semibold tracking-tight", children: [
|
|
6516
|
-
isGroupCall && /* @__PURE__ */ jsx(Users, { size: 16, className: "text-white/50" }),
|
|
6517
|
-
peerName
|
|
6518
|
-
] }),
|
|
6519
|
-
/* @__PURE__ */ jsxs("p", { className: "mt-1 text-sm text-white/60", children: [
|
|
6520
|
-
uiStatus === "creating" && "Starting call\u2026",
|
|
6521
|
-
uiStatus === "ringing-out" && `${isVideo ? "Video calling" : "Calling"}\u2026 \xB7 ${secondsLeft}s`,
|
|
6522
|
-
uiStatus === "joining" && "Connecting\u2026"
|
|
6523
|
-
] })
|
|
6948
|
+
const isVideo = mode === "video";
|
|
6949
|
+
return /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-40 flex flex-col overflow-hidden bg-gradient-to-b from-neutral-900 via-neutral-950 to-black text-white", children: displayError ? /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-4 p-6 text-center", children: [
|
|
6950
|
+
/* @__PURE__ */ jsx("p", { className: "max-w-sm text-sm text-white/80", children: displayError }),
|
|
6951
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: reset, children: [
|
|
6952
|
+
/* @__PURE__ */ jsx(X, { size: 16, className: "mr-1" }),
|
|
6953
|
+
" Close"
|
|
6954
|
+
] })
|
|
6955
|
+
] }) : uiStatus === "in-call" && meetingId && token && mode && conversationId ? /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col min-h-0", children: [
|
|
6956
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-center gap-2 px-4 py-3 text-sm text-white/70", children: [
|
|
6957
|
+
isGroupCall && /* @__PURE__ */ jsx(Users, { size: 14, className: "text-white/50" }),
|
|
6958
|
+
peerName && /* @__PURE__ */ jsx("span", { className: "font-medium text-white/90", children: peerName }),
|
|
6959
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-white/30", children: "\xB7" }),
|
|
6960
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: duration })
|
|
6961
|
+
] }),
|
|
6962
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 min-h-0", children: [
|
|
6963
|
+
/* @__PURE__ */ jsx(
|
|
6964
|
+
React11__default.Suspense,
|
|
6965
|
+
{
|
|
6966
|
+
fallback: /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-3 text-white/80", children: [
|
|
6967
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-8 animate-spin" }),
|
|
6968
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "Loading call\u2026" })
|
|
6524
6969
|
] }),
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6970
|
+
children: /* @__PURE__ */ jsx(
|
|
6971
|
+
CallSession2,
|
|
6972
|
+
{
|
|
6973
|
+
meetingId,
|
|
6974
|
+
token,
|
|
6975
|
+
mode,
|
|
6976
|
+
peerName,
|
|
6977
|
+
peerAvatar,
|
|
6978
|
+
isChatOpen,
|
|
6979
|
+
onToggleChat: () => setIsChatOpen((v) => !v),
|
|
6980
|
+
onError: setSessionError
|
|
6981
|
+
}
|
|
6982
|
+
)
|
|
6983
|
+
}
|
|
6984
|
+
),
|
|
6985
|
+
isChatOpen && /* @__PURE__ */ jsx(
|
|
6986
|
+
CallChatPanel_default,
|
|
6987
|
+
{
|
|
6988
|
+
conversationId,
|
|
6989
|
+
isGroupCall,
|
|
6990
|
+
onClose: () => setIsChatOpen(false),
|
|
6991
|
+
className: "hidden w-80 shrink-0 sm:flex"
|
|
6992
|
+
}
|
|
6993
|
+
)
|
|
6994
|
+
] })
|
|
6995
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-6 p-6 text-center", children: [
|
|
6996
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
|
|
6997
|
+
uiStatus === "ringing-out" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6998
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inline-flex size-32 animate-ping rounded-full bg-white/10" }),
|
|
6999
|
+
/* @__PURE__ */ jsx(
|
|
7000
|
+
"span",
|
|
7001
|
+
{
|
|
7002
|
+
className: "absolute inline-flex size-32 animate-ping rounded-full bg-white/5",
|
|
7003
|
+
style: { animationDelay: "0.6s" }
|
|
7004
|
+
}
|
|
7005
|
+
)
|
|
7006
|
+
] }),
|
|
7007
|
+
peerName ? /* @__PURE__ */ jsxs(Avatar, { className: "relative size-28 ring-4 ring-white/10", children: [
|
|
7008
|
+
/* @__PURE__ */ jsx(AvatarImage, { src: peerAvatar, alt: peerName }),
|
|
7009
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-neutral-700 text-3xl font-medium text-white", children: peerName.charAt(0).toUpperCase() })
|
|
7010
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "relative flex size-28 items-center justify-center rounded-full bg-white/10", children: isVideo ? /* @__PURE__ */ jsx(Video, { size: 36 }) : /* @__PURE__ */ jsx(Phone, { size: 36 }) })
|
|
7011
|
+
] }),
|
|
7012
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
7013
|
+
peerName && /* @__PURE__ */ jsxs("p", { className: "flex items-center justify-center gap-1.5 text-xl font-semibold tracking-tight", children: [
|
|
7014
|
+
isGroupCall && /* @__PURE__ */ jsx(Users, { size: 16, className: "text-white/50" }),
|
|
7015
|
+
peerName
|
|
7016
|
+
] }),
|
|
7017
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-1 text-sm text-white/60", children: [
|
|
7018
|
+
uiStatus === "creating" && "Starting call\u2026",
|
|
7019
|
+
uiStatus === "ringing-out" && `${isVideo ? "Video calling" : "Calling"}\u2026 \xB7 ${secondsLeft}s`,
|
|
7020
|
+
uiStatus === "joining" && "Connecting\u2026"
|
|
7021
|
+
] })
|
|
7022
|
+
] }),
|
|
7023
|
+
uiStatus === "ringing-out" && /* @__PURE__ */ jsxs("div", { className: "mt-1 flex flex-col items-center gap-2", children: [
|
|
7024
|
+
/* @__PURE__ */ jsx(
|
|
7025
|
+
Button,
|
|
7026
|
+
{
|
|
7027
|
+
variant: "ghost",
|
|
7028
|
+
size: "icon",
|
|
7029
|
+
className: "size-16 rounded-full bg-red-600 text-white shadow-lg shadow-red-600/30 transition-transform hover:scale-105 hover:bg-red-500 active:scale-95",
|
|
7030
|
+
"aria-label": "Cancel call",
|
|
7031
|
+
onClick: cancelCall,
|
|
7032
|
+
children: /* @__PURE__ */ jsx(PhoneOff, { size: 24 })
|
|
7033
|
+
}
|
|
7034
|
+
),
|
|
7035
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-white/60", children: "Cancel" })
|
|
7036
|
+
] })
|
|
7037
|
+
] }) });
|
|
6544
7038
|
};
|
|
6545
7039
|
var CallOverlay_default = CallOverlay;
|
|
6546
7040
|
|
|
@@ -6876,162 +7370,6 @@ function AlertDialogCancel({
|
|
|
6876
7370
|
|
|
6877
7371
|
// src/chat/ChatOverlay.tsx
|
|
6878
7372
|
init_utils2();
|
|
6879
|
-
|
|
6880
|
-
// src/chat/lib/chat-theme.ts
|
|
6881
|
-
init_utils2();
|
|
6882
|
-
var getChatScopeClass = (isDark) => cn("chat-theme-scope", isDark && "dark");
|
|
6883
|
-
var chatSheetContentClass = "flex w-full flex-col gap-0 p-0 bg-(--chat-surface) text-(--chat-text)";
|
|
6884
|
-
var chatSheetHeaderClass = "border-b border-(--chat-border) px-4 py-3 pr-11 text-left";
|
|
6885
|
-
var chatSheetBodyClass = "chat-message-scroll flex-1 overflow-y-auto bg-(--chat-surface) p-3";
|
|
6886
|
-
var chatSheetTitleClass = "text-[13px] font-semibold tracking-tight text-(--chat-text)";
|
|
6887
|
-
var chatSheetSubtitleClass = "text-[11px] text-(--chat-muted)";
|
|
6888
|
-
var chatDetailRowClass = "flex items-start justify-between gap-3 border-b border-(--chat-border) py-2.5 last:border-b-0";
|
|
6889
|
-
var chatDetailLabelClass = "text-[11px] text-(--chat-muted)";
|
|
6890
|
-
var chatDetailValueClass = "text-[13px] font-medium text-(--chat-text) text-right";
|
|
6891
|
-
var chatDialogContentClass = "overflow-hidden rounded-2xl border border-(--chat-border) bg-(--chat-surface) p-0 text-(--chat-text) shadow-[var(--chat-shadow)]";
|
|
6892
|
-
var chatDropdownContentClass = "rounded-xl border border-(--chat-border) bg-(--chat-surface) text-(--chat-text) shadow-lg";
|
|
6893
|
-
var chatOptionsMenuClass = "min-w-[220px] rounded-xl border border-(--chat-border) bg-(--chat-surface) p-1.5 text-(--chat-text) shadow-[0_10px_40px_rgba(0,0,0,0.12)]";
|
|
6894
|
-
var chatOptionsMenuLabelClass = "px-2.5 pb-0.5 pt-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-(--chat-muted)";
|
|
6895
|
-
var chatOptionsMenuSeparatorClass = "my-1.5 h-px bg-(--chat-border)";
|
|
6896
|
-
var chatOptionsMenuItemClass = "cursor-pointer gap-2.5 rounded-lg px-2.5 py-2 text-[13px] font-medium text-(--chat-text) focus:bg-(--chat-hover) focus:text-(--chat-text) data-[highlighted]:bg-(--chat-hover) [&_svg]:size-[15px] [&_svg]:shrink-0 [&_svg]:text-(--chat-muted)";
|
|
6897
|
-
var chatOptionsMenuItemDestructiveClass = "cursor-pointer gap-2.5 rounded-lg px-2.5 py-2 text-[13px] font-medium text-(--chat-danger-text) focus:bg-red-500/10 focus:text-(--chat-danger-text) data-[highlighted]:bg-red-500/10 data-[highlighted]:text-(--chat-danger-text) [&_svg]:size-[15px] [&_svg]:shrink-0 [&_svg]:!text-(--chat-danger-text)";
|
|
6898
|
-
var chatOptionsMenuSubTriggerClass = "cursor-pointer gap-2.5 rounded-lg px-2.5 py-2 pr-7 text-[13px] font-medium text-(--chat-text) focus:bg-(--chat-hover) focus:text-(--chat-text) data-[highlighted]:bg-(--chat-hover) data-[state=open]:bg-(--chat-hover) [&_svg]:size-[15px] [&_svg]:shrink-0 [&_svg]:text-(--chat-muted)";
|
|
6899
|
-
var chatPopoverContentClass = "w-auto border border-(--chat-border) bg-(--chat-surface) p-0 text-(--chat-text) shadow-2xl";
|
|
6900
|
-
var chatInputClass = "border border-(--chat-border) bg-(--chat-input-bg) text-(--chat-text) shadow-none placeholder:text-(--chat-muted) focus-visible:border-(--chat-theme-20) focus-visible:ring-2 focus-visible:ring-(--chat-theme-10)";
|
|
6901
|
-
var chatSidebarSearchShellClass = "relative flex min-w-0 flex-1 items-center rounded-lg border border-(--chat-border) bg-(--chat-search-bg) px-2.5 transition-colors focus-within:border-(--chat-theme) focus-within:shadow-[0_0_0_2px_var(--chat-theme-10)]";
|
|
6902
|
-
var chatSidebarSearchInputClass = "h-8 w-full min-w-0 border-0 bg-transparent px-1.5 text-xs text-(--chat-text) shadow-none outline-none placeholder:text-(--chat-muted)/60 focus-visible:border-0 focus-visible:shadow-none focus-visible:ring-0";
|
|
6903
|
-
var chatSelectClass = "h-10 w-full cursor-pointer appearance-none rounded-xl border border-(--chat-border) bg-(--chat-input-bg) pl-3 pr-9 text-sm text-(--chat-text) shadow-none focus-visible:border-(--chat-theme-20) focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--chat-theme-10)";
|
|
6904
|
-
var chatListItemClass = "transition-colors hover:bg-(--chat-hover)";
|
|
6905
|
-
var chatLoadMoreButtonClass = "h-7 gap-1 rounded-full border border-(--chat-border) bg-(--chat-elevated) px-4 text-[10px] font-medium text-(--chat-text) transition-colors hover:border-(--chat-theme-20) hover:bg-(--chat-theme-5) hover:text-(--chat-theme) disabled:opacity-50 [&_svg]:size-3 [&_svg]:text-current";
|
|
6906
|
-
var chatDrawerSectionHeadingClass = "mb-1 px-0.5 text-[10px] font-semibold tracking-wide text-(--chat-muted)";
|
|
6907
|
-
var chatHeaderToolbarIconProps = { size: 14, strokeWidth: 1.75 };
|
|
6908
|
-
var chatSavedMessageModalIconClass = "shrink-0 text-(--chat-theme)";
|
|
6909
|
-
var chatHeaderToolbarIconLgProps = { size: 22, strokeWidth: 1.75 };
|
|
6910
|
-
var chatHeaderToolbarIconSmProps = { size: 11, strokeWidth: 1.75 };
|
|
6911
|
-
var chatDrawerFileRowClass = "flex items-center gap-2 rounded-md border border-(--chat-border)/70 bg-(--chat-elevated) px-2 py-1.5 transition-colors hover:bg-(--chat-hover)/50";
|
|
6912
|
-
var chatDrawerFileIconWrapClass = "flex size-8 shrink-0 items-center justify-center rounded-md bg-(--chat-hover)";
|
|
6913
|
-
var chatDrawerMediaFrameClass = "overflow-hidden rounded-md border border-(--chat-border)/70 bg-(--chat-elevated)";
|
|
6914
|
-
var buildChatThemeStyles = (themeColor) => ({
|
|
6915
|
-
"--chat-theme": themeColor,
|
|
6916
|
-
"--chat-theme-5": `${themeColor}0D`,
|
|
6917
|
-
"--chat-theme-10": `${themeColor}1A`,
|
|
6918
|
-
"--chat-theme-20": `${themeColor}33`,
|
|
6919
|
-
"--chat-theme-40": `${themeColor}66`,
|
|
6920
|
-
"--chat-theme-60": `${themeColor}99`,
|
|
6921
|
-
"--read-tick-color": themeColor.toLowerCase() === "#0000ff" || themeColor.toLowerCase().includes("007aff") ? "#00e5ff" : "#40C4FF"
|
|
6922
|
-
});
|
|
6923
|
-
|
|
6924
|
-
// src/chat/lib/chat-theme-storage.ts
|
|
6925
|
-
var STORAGE_KEY = "chat-color-mode";
|
|
6926
|
-
var loadChatColorMode = () => {
|
|
6927
|
-
if (typeof window === "undefined") return null;
|
|
6928
|
-
try {
|
|
6929
|
-
const stored = localStorage.getItem(STORAGE_KEY);
|
|
6930
|
-
return stored === "dark" || stored === "light" ? stored : null;
|
|
6931
|
-
} catch {
|
|
6932
|
-
return null;
|
|
6933
|
-
}
|
|
6934
|
-
};
|
|
6935
|
-
var saveChatColorMode = (mode) => {
|
|
6936
|
-
if (typeof window === "undefined") return;
|
|
6937
|
-
try {
|
|
6938
|
-
localStorage.setItem(STORAGE_KEY, mode);
|
|
6939
|
-
} catch {
|
|
6940
|
-
}
|
|
6941
|
-
};
|
|
6942
|
-
var CHAT_THEME_SHELL_CLASS = "chat-theme-shell";
|
|
6943
|
-
function withThemeTransition(apply) {
|
|
6944
|
-
if (typeof document === "undefined") {
|
|
6945
|
-
apply();
|
|
6946
|
-
return;
|
|
6947
|
-
}
|
|
6948
|
-
flushSync(apply);
|
|
6949
|
-
}
|
|
6950
|
-
|
|
6951
|
-
// src/context/ChatThemeContext.tsx
|
|
6952
|
-
init_utils2();
|
|
6953
|
-
var ChatThemeContext = createContext(null);
|
|
6954
|
-
var ChatThemeProvider = ({
|
|
6955
|
-
children,
|
|
6956
|
-
themeColor,
|
|
6957
|
-
colorMode,
|
|
6958
|
-
defaultColorMode = "light",
|
|
6959
|
-
onColorModeChange,
|
|
6960
|
-
showColorModeToggle = true
|
|
6961
|
-
}) => {
|
|
6962
|
-
const isControlled = colorMode !== void 0;
|
|
6963
|
-
const [internalMode, setInternalMode] = useState(defaultColorMode);
|
|
6964
|
-
const [isThemeTransitionReady, setIsThemeTransitionReady] = useState(false);
|
|
6965
|
-
const skipThemeTransitionRef = useRef(true);
|
|
6966
|
-
useLayoutEffect(() => {
|
|
6967
|
-
if (!isControlled) {
|
|
6968
|
-
const stored = loadChatColorMode();
|
|
6969
|
-
if (stored) {
|
|
6970
|
-
setInternalMode(stored);
|
|
6971
|
-
}
|
|
6972
|
-
}
|
|
6973
|
-
const frame = requestAnimationFrame(() => {
|
|
6974
|
-
skipThemeTransitionRef.current = false;
|
|
6975
|
-
setIsThemeTransitionReady(true);
|
|
6976
|
-
});
|
|
6977
|
-
return () => cancelAnimationFrame(frame);
|
|
6978
|
-
}, [isControlled]);
|
|
6979
|
-
const resolvedMode = isControlled ? colorMode : internalMode;
|
|
6980
|
-
const isDark = resolvedMode === "dark";
|
|
6981
|
-
const setColorMode = useCallback(
|
|
6982
|
-
(mode) => {
|
|
6983
|
-
const apply = () => {
|
|
6984
|
-
if (!isControlled) {
|
|
6985
|
-
setInternalMode(mode);
|
|
6986
|
-
saveChatColorMode(mode);
|
|
6987
|
-
}
|
|
6988
|
-
onColorModeChange?.(mode);
|
|
6989
|
-
};
|
|
6990
|
-
if (skipThemeTransitionRef.current) {
|
|
6991
|
-
apply();
|
|
6992
|
-
return;
|
|
6993
|
-
}
|
|
6994
|
-
withThemeTransition(apply);
|
|
6995
|
-
},
|
|
6996
|
-
[isControlled, onColorModeChange]
|
|
6997
|
-
);
|
|
6998
|
-
const toggleColorMode = useCallback(() => {
|
|
6999
|
-
setColorMode(resolvedMode === "dark" ? "light" : "dark");
|
|
7000
|
-
}, [resolvedMode, setColorMode]);
|
|
7001
|
-
const value = useMemo(
|
|
7002
|
-
() => ({
|
|
7003
|
-
colorMode: resolvedMode,
|
|
7004
|
-
isDark,
|
|
7005
|
-
isThemeTransitionReady,
|
|
7006
|
-
themeColor,
|
|
7007
|
-
themeStyles: buildChatThemeStyles(themeColor),
|
|
7008
|
-
scopeClassName: cn(
|
|
7009
|
-
getChatScopeClass(isDark),
|
|
7010
|
-
!isThemeTransitionReady && "chat-theme-no-transition"
|
|
7011
|
-
),
|
|
7012
|
-
setColorMode,
|
|
7013
|
-
toggleColorMode,
|
|
7014
|
-
showColorModeToggle
|
|
7015
|
-
}),
|
|
7016
|
-
[
|
|
7017
|
-
resolvedMode,
|
|
7018
|
-
isDark,
|
|
7019
|
-
isThemeTransitionReady,
|
|
7020
|
-
themeColor,
|
|
7021
|
-
setColorMode,
|
|
7022
|
-
toggleColorMode,
|
|
7023
|
-
showColorModeToggle
|
|
7024
|
-
]
|
|
7025
|
-
);
|
|
7026
|
-
return /* @__PURE__ */ jsx(ChatThemeContext.Provider, { value, children });
|
|
7027
|
-
};
|
|
7028
|
-
var useChatTheme = () => {
|
|
7029
|
-
const context = useContext(ChatThemeContext);
|
|
7030
|
-
if (!context) {
|
|
7031
|
-
throw new Error("useChatTheme must be used within ChatThemeProvider");
|
|
7032
|
-
}
|
|
7033
|
-
return context;
|
|
7034
|
-
};
|
|
7035
7373
|
var ChatSheetContent = ({
|
|
7036
7374
|
className,
|
|
7037
7375
|
style,
|
|
@@ -7087,6 +7425,66 @@ init_avatar();
|
|
|
7087
7425
|
init_button();
|
|
7088
7426
|
init_utils2();
|
|
7089
7427
|
init_call_store();
|
|
7428
|
+
|
|
7429
|
+
// src/call/ringtone.ts
|
|
7430
|
+
var audioCtx = null;
|
|
7431
|
+
var scheduledTimer = null;
|
|
7432
|
+
var activeOscillators = [];
|
|
7433
|
+
var RING_ON_MS = 1200;
|
|
7434
|
+
var RING_OFF_MS = 2400;
|
|
7435
|
+
var RING_FREQUENCIES = [440, 480];
|
|
7436
|
+
var getContext = () => {
|
|
7437
|
+
if (typeof window === "undefined") return null;
|
|
7438
|
+
const Ctor = window.AudioContext || window.webkitAudioContext;
|
|
7439
|
+
if (!Ctor) return null;
|
|
7440
|
+
if (!audioCtx || audioCtx.state === "closed") audioCtx = new Ctor();
|
|
7441
|
+
return audioCtx;
|
|
7442
|
+
};
|
|
7443
|
+
var stopOscillators = () => {
|
|
7444
|
+
activeOscillators.forEach((osc) => {
|
|
7445
|
+
try {
|
|
7446
|
+
osc.stop();
|
|
7447
|
+
} catch {
|
|
7448
|
+
}
|
|
7449
|
+
});
|
|
7450
|
+
activeOscillators = [];
|
|
7451
|
+
};
|
|
7452
|
+
var ringBurst = (ctx) => {
|
|
7453
|
+
const onSeconds = RING_ON_MS / 1e3;
|
|
7454
|
+
const gain = ctx.createGain();
|
|
7455
|
+
gain.gain.setValueAtTime(0, ctx.currentTime);
|
|
7456
|
+
gain.gain.linearRampToValueAtTime(0.15, ctx.currentTime + 0.05);
|
|
7457
|
+
gain.gain.setValueAtTime(0.15, ctx.currentTime + onSeconds - 0.05);
|
|
7458
|
+
gain.gain.linearRampToValueAtTime(0, ctx.currentTime + onSeconds);
|
|
7459
|
+
gain.connect(ctx.destination);
|
|
7460
|
+
RING_FREQUENCIES.forEach((freq) => {
|
|
7461
|
+
const osc = ctx.createOscillator();
|
|
7462
|
+
osc.type = "sine";
|
|
7463
|
+
osc.frequency.value = freq;
|
|
7464
|
+
osc.connect(gain);
|
|
7465
|
+
osc.start();
|
|
7466
|
+
osc.stop(ctx.currentTime + onSeconds);
|
|
7467
|
+
activeOscillators.push(osc);
|
|
7468
|
+
});
|
|
7469
|
+
};
|
|
7470
|
+
var playDefaultRingtone = () => {
|
|
7471
|
+
if (scheduledTimer) return;
|
|
7472
|
+
const ctx = getContext();
|
|
7473
|
+
if (!ctx) return;
|
|
7474
|
+
ctx.resume().catch(() => void 0);
|
|
7475
|
+
const cycle = () => {
|
|
7476
|
+
ringBurst(ctx);
|
|
7477
|
+
scheduledTimer = setTimeout(cycle, RING_ON_MS + RING_OFF_MS);
|
|
7478
|
+
};
|
|
7479
|
+
cycle();
|
|
7480
|
+
};
|
|
7481
|
+
var stopDefaultRingtone = () => {
|
|
7482
|
+
if (scheduledTimer) {
|
|
7483
|
+
clearTimeout(scheduledTimer);
|
|
7484
|
+
scheduledTimer = null;
|
|
7485
|
+
}
|
|
7486
|
+
stopOscillators();
|
|
7487
|
+
};
|
|
7090
7488
|
var IncomingCallDialog = ({ ringtoneUrl }) => {
|
|
7091
7489
|
const uiStatus = useCallStore((s) => s.uiStatus);
|
|
7092
7490
|
const callId = useCallStore((s) => s.callId);
|
|
@@ -7109,6 +7507,12 @@ var IncomingCallDialog = ({ ringtoneUrl }) => {
|
|
|
7109
7507
|
el.pause();
|
|
7110
7508
|
}
|
|
7111
7509
|
}, [isOpen, ringtoneUrl]);
|
|
7510
|
+
useEffect(() => {
|
|
7511
|
+
if (ringtoneUrl) return;
|
|
7512
|
+
if (isOpen) playDefaultRingtone();
|
|
7513
|
+
else stopDefaultRingtone();
|
|
7514
|
+
return () => stopDefaultRingtone();
|
|
7515
|
+
}, [isOpen, ringtoneUrl]);
|
|
7112
7516
|
if (!isOpen) return null;
|
|
7113
7517
|
const callerName = caller?.name || "Unknown caller";
|
|
7114
7518
|
const name = isGroupCall ? peer?.name || callerName : callerName;
|
|
@@ -7376,7 +7780,7 @@ var Chat = ({
|
|
|
7376
7780
|
}),
|
|
7377
7781
|
[uiConfig.components, uiConfig.classNames, uiConfig.features]
|
|
7378
7782
|
);
|
|
7379
|
-
return /* @__PURE__ */ jsx(ChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(ChatCustomizationProvider, { customization, children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx("div", { className: "chat-container-root flex h-full min-h-0 w-full flex-1 flex-col overflow-hidden", children: isSessionReady ? /* @__PURE__ */ jsxs(ChatEffectiveSettingsProvider, { enabled: true, children: [
|
|
7783
|
+
return /* @__PURE__ */ jsx(ChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(ChatCustomizationProvider, { customization, children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx("div", { className: "chat-container-root relative flex h-full min-h-0 w-full flex-1 flex-col overflow-hidden", children: isSessionReady ? /* @__PURE__ */ jsxs(ChatEffectiveSettingsProvider, { enabled: true, children: [
|
|
7380
7784
|
children,
|
|
7381
7785
|
/* @__PURE__ */ jsx(CallLayer_default, {})
|
|
7382
7786
|
] }) : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-gray-400 font-bold", children: "Initializing session..." }) }) }) }) });
|
|
@@ -7833,6 +8237,7 @@ init_avatar();
|
|
|
7833
8237
|
|
|
7834
8238
|
// src/chat/ChatThemeToggle.tsx
|
|
7835
8239
|
init_button();
|
|
8240
|
+
init_tooltip();
|
|
7836
8241
|
init_utils2();
|
|
7837
8242
|
var ChatThemeToggle = ({ className }) => {
|
|
7838
8243
|
const { isDark, toggleColorMode } = useChatTheme();
|
|
@@ -7890,6 +8295,7 @@ var buildLoggedUserProfile = (loggedUserDetails) => ({
|
|
|
7890
8295
|
|
|
7891
8296
|
// src/chat/sidebar/create-chat-dialog/CreateChatDialog.tsx
|
|
7892
8297
|
init_button();
|
|
8298
|
+
init_tooltip();
|
|
7893
8299
|
init_utils2();
|
|
7894
8300
|
|
|
7895
8301
|
// src/chat/sidebar/create-chat-dialog/useCreateChatDialog.ts
|
|
@@ -8340,6 +8746,9 @@ function GroupCreateTab({
|
|
|
8340
8746
|
) })
|
|
8341
8747
|
] });
|
|
8342
8748
|
}
|
|
8749
|
+
|
|
8750
|
+
// src/chat/components/AdminPermissionTooltip.tsx
|
|
8751
|
+
init_tooltip();
|
|
8343
8752
|
init_utils2();
|
|
8344
8753
|
function AdminPermissionTooltip({
|
|
8345
8754
|
disabled,
|
|
@@ -8966,6 +9375,7 @@ var LoggedUserSettingsContent_default = LoggedUserSettingsContent;
|
|
|
8966
9375
|
|
|
8967
9376
|
// src/chat/sidebar/LoggedUserSettingsTrigger.tsx
|
|
8968
9377
|
init_button();
|
|
9378
|
+
init_tooltip();
|
|
8969
9379
|
init_utils2();
|
|
8970
9380
|
var LoggedUserSettingsTrigger = ({
|
|
8971
9381
|
onClick,
|
|
@@ -10632,6 +11042,7 @@ init_call_store();
|
|
|
10632
11042
|
init_utils2();
|
|
10633
11043
|
|
|
10634
11044
|
// src/chat/header/header-right/OptionsMenuItem.tsx
|
|
11045
|
+
init_tooltip();
|
|
10635
11046
|
init_utils2();
|
|
10636
11047
|
function OptionsMenuItem({
|
|
10637
11048
|
icon: Icon,
|
|
@@ -11678,28 +12089,6 @@ function MessageForwardedLabel({ isSender, className, overlay }) {
|
|
|
11678
12089
|
}
|
|
11679
12090
|
);
|
|
11680
12091
|
}
|
|
11681
|
-
|
|
11682
|
-
// src/chat/lib/chat-message-bubble.ts
|
|
11683
|
-
init_utils2();
|
|
11684
|
-
function getBubbleCornerClasses(isSender) {
|
|
11685
|
-
return isSender ? "rounded-tl-[18px] rounded-tr-[18px] rounded-bl-[18px] rounded-br-none" : "rounded-tl-[18px] rounded-tr-[18px] rounded-br-[18px] rounded-bl-none";
|
|
11686
|
-
}
|
|
11687
|
-
function getChatBubbleClasses({
|
|
11688
|
-
isSender = false,
|
|
11689
|
-
surface,
|
|
11690
|
-
className
|
|
11691
|
-
}) {
|
|
11692
|
-
const resolvedSurface = surface ?? (isSender ? "sent" : "received");
|
|
11693
|
-
const isNeutral = resolvedSurface === "neutral";
|
|
11694
|
-
return cn(
|
|
11695
|
-
"relative",
|
|
11696
|
-
getBubbleCornerClasses(isSender),
|
|
11697
|
-
resolvedSurface === "sent" && "chat-bubble-sent bg-(--chat-theme) text-white",
|
|
11698
|
-
resolvedSurface === "received" && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
11699
|
-
isNeutral && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
11700
|
-
className
|
|
11701
|
-
);
|
|
11702
|
-
}
|
|
11703
12092
|
init_utils2();
|
|
11704
12093
|
init_client();
|
|
11705
12094
|
function getPreviewKind(name) {
|
|
@@ -16314,6 +16703,7 @@ init_avatar();
|
|
|
16314
16703
|
|
|
16315
16704
|
// src/chat/message/MessageReactions.tsx
|
|
16316
16705
|
init_utils2();
|
|
16706
|
+
init_tooltip();
|
|
16317
16707
|
var MessageReactions = ({
|
|
16318
16708
|
groupedReactions,
|
|
16319
16709
|
reactions,
|
|
@@ -20726,6 +21116,7 @@ init_normalize_helpers();
|
|
|
20726
21116
|
init_useStore();
|
|
20727
21117
|
init_open_conversation();
|
|
20728
21118
|
var RETRY_DELAYS_MS = [1e3, 3e3, 8e3, 2e4];
|
|
21119
|
+
var CHAT_HEARTBEAT_INTERVAL_MS = 15e3;
|
|
20729
21120
|
var recentToastIds = /* @__PURE__ */ new Set();
|
|
20730
21121
|
var rememberToastId = (id) => {
|
|
20731
21122
|
if (!id) return true;
|
|
@@ -20948,6 +21339,36 @@ var ForegroundPushBridge = ({ onPush }) => {
|
|
|
20948
21339
|
window.removeEventListener(PUSH_CHANGED_EVENT, onPushChanged);
|
|
20949
21340
|
};
|
|
20950
21341
|
}, []);
|
|
21342
|
+
useEffect(() => {
|
|
21343
|
+
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
|
|
21344
|
+
return;
|
|
21345
|
+
}
|
|
21346
|
+
let interval = null;
|
|
21347
|
+
const sendHeartbeat = () => {
|
|
21348
|
+
navigator.serviceWorker.getRegistration().then(
|
|
21349
|
+
(registration) => registration?.active?.postMessage({ type: CHAT_HEARTBEAT_SW_TYPE })
|
|
21350
|
+
).catch(() => void 0);
|
|
21351
|
+
};
|
|
21352
|
+
const startHeartbeat = () => {
|
|
21353
|
+
if (interval || !getStoredPushToken()) return;
|
|
21354
|
+
sendHeartbeat();
|
|
21355
|
+
interval = setInterval(sendHeartbeat, CHAT_HEARTBEAT_INTERVAL_MS);
|
|
21356
|
+
};
|
|
21357
|
+
const stopHeartbeat = () => {
|
|
21358
|
+
if (interval) clearInterval(interval);
|
|
21359
|
+
interval = null;
|
|
21360
|
+
};
|
|
21361
|
+
startHeartbeat();
|
|
21362
|
+
const onPushChanged = (event) => {
|
|
21363
|
+
if (event.detail?.enabled) startHeartbeat();
|
|
21364
|
+
else stopHeartbeat();
|
|
21365
|
+
};
|
|
21366
|
+
window.addEventListener(PUSH_CHANGED_EVENT, onPushChanged);
|
|
21367
|
+
return () => {
|
|
21368
|
+
stopHeartbeat();
|
|
21369
|
+
window.removeEventListener(PUSH_CHANGED_EVENT, onPushChanged);
|
|
21370
|
+
};
|
|
21371
|
+
}, []);
|
|
20951
21372
|
useEffect(() => {
|
|
20952
21373
|
const onOpen = (event) => {
|
|
20953
21374
|
const id = String(
|