通话计数和显示隐藏修改完成
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -8,6 +9,7 @@
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
|
||||
<body class="h-screen w-screen flex flex-col text-white bg-grid relative">
|
||||
<!--
|
||||
============================================================
|
||||
@@ -103,7 +105,8 @@
|
||||
-->
|
||||
<header class="glass-strong h-16 flex items-center justify-between px-6 z-50 border-b border-white/10">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg">
|
||||
<div
|
||||
class="w-10 h-10 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg">
|
||||
<i class="fas fa-video text-white text-lg"></i>
|
||||
</div>
|
||||
<div>
|
||||
@@ -152,17 +155,16 @@
|
||||
<div class="absolute inset-0 video-fade-in">
|
||||
<!-- [DATA_FIELD: remoteUser.videoStream] [TYPE: MediaStream | null] [BIND: srcObject] -->
|
||||
<!-- [FALLBACK: remoteUser.avatar] [TYPE: string] [URL] -->
|
||||
<video id="remoteVideo"
|
||||
alt="对方视频"
|
||||
class="w-full h-full object-contain"
|
||||
autoplay
|
||||
data-field="remoteUser.videoStream">
|
||||
<video id="remoteVideo" alt="对方视频" class="w-full h-full object-contain" autoplay
|
||||
data-field="remoteUser.videoStream">
|
||||
</video>
|
||||
|
||||
<!-- 远端未连接时的占位背景 -->
|
||||
<div id="remoteVideoPlaceholder" class="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-indigo-900/80 to-purple-900/80">
|
||||
<div id="remoteVideoPlaceholder"
|
||||
class="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-indigo-900/80 to-purple-900/80">
|
||||
<div class="text-center">
|
||||
<div class="w-32 h-32 rounded-full bg-indigo-700/50 flex items-center justify-center mx-auto mb-4">
|
||||
<div
|
||||
class="w-32 h-32 rounded-full bg-indigo-700/50 flex items-center justify-center mx-auto mb-4">
|
||||
<i class="fas fa-user text-4xl text-white/70"></i>
|
||||
</div>
|
||||
<p class="text-white text-lg font-medium">等待对方连接...</p>
|
||||
@@ -175,12 +177,13 @@
|
||||
<div class="relative">
|
||||
<!-- [DATA_FIELD: remoteUser.avatar] [TYPE: string] [URL] [REQUIRED] -->
|
||||
<img id="remoteAvatar"
|
||||
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop"
|
||||
class="w-8 h-8 rounded-full object-cover"
|
||||
data-field="remoteUser.avatar">
|
||||
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop"
|
||||
class="w-8 h-8 rounded-full object-cover" data-field="remoteUser.avatar">
|
||||
|
||||
<!-- [CONDITIONAL_RENDER: remoteUser.mediaState.isSpeaking === true] -->
|
||||
<div id="remoteSpeakingIndicator" class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-slate-900 hidden" data-field="remoteUser.isSpeaking"></div>
|
||||
<div id="remoteSpeakingIndicator"
|
||||
class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-slate-900 hidden"
|
||||
data-field="remoteUser.isSpeaking"></div>
|
||||
</div>
|
||||
<div>
|
||||
<!-- [DATA_FIELD: remoteUser.name] [TYPE: string] -->
|
||||
@@ -190,7 +193,8 @@
|
||||
<span id="remoteStatus" data-field="remoteUser.status">正在通话</span>
|
||||
|
||||
<!-- [CONDITIONAL_RENDER: remoteUser.mediaState.isSpeaking === true && remoteUser.mediaState.audio === true] -->
|
||||
<div id="remoteAudioWave" class="audio-wave w-6 hidden" data-field="remoteUser.audioActivity">
|
||||
<div id="remoteAudioWave" class="audio-wave w-6 hidden"
|
||||
data-field="remoteUser.audioActivity">
|
||||
<span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -199,7 +203,9 @@
|
||||
|
||||
<!-- 网络状态提示 -->
|
||||
<!-- [CONDITIONAL_RENDER: remoteUser.networkQuality !== 'excellent'] -->
|
||||
<div id="networkStatus" class="absolute top-6 right-6 glass px-3 py-1.5 rounded-full flex items-center gap-2 text-xs hidden" data-field="remoteUser.networkQuality">
|
||||
<div id="networkStatus"
|
||||
class="absolute top-6 right-6 glass px-3 py-1.5 rounded-full flex items-center gap-2 text-xs hidden"
|
||||
data-field="remoteUser.networkQuality">
|
||||
<i class="fas fa-exclamation-triangle text-yellow-500"></i>
|
||||
<!-- [DATA_FIELD: remoteUser.networkQuality] [TYPE: string] [TRANSFORM: quality => text] -->
|
||||
<span class="text-gray-300" id="networkStatusText">网络不稳定</span>
|
||||
@@ -207,9 +213,12 @@
|
||||
|
||||
<!-- 连接中/重连提示 -->
|
||||
<!-- [CONDITIONAL_RENDER: callSession.status === 'connecting'] -->
|
||||
<div id="connectingOverlay" class="absolute inset-0 bg-black/60 flex items-center justify-center hidden" data-field="callSession.status">
|
||||
<div id="connectingOverlay" class="absolute inset-0 bg-black/60 flex items-center justify-center hidden"
|
||||
data-field="callSession.status">
|
||||
<div class="text-center">
|
||||
<div class="w-12 h-12 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin mx-auto mb-3"></div>
|
||||
<div
|
||||
class="w-12 h-12 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin mx-auto mb-3">
|
||||
</div>
|
||||
<p class="text-white font-medium">正在连接...</p>
|
||||
<p class="text-sm text-gray-400 mt-1" id="connectingText">等待对方接受邀请</p>
|
||||
</div>
|
||||
@@ -224,20 +233,19 @@
|
||||
子区域: 本地视频 (Local Video - Picture in Picture)
|
||||
数据源: LocalUser
|
||||
-->
|
||||
<div class="absolute bottom-6 right-6 w-64 h-48 rounded-2xl overflow-hidden shadow-2xl border-2 border-white/20 video-fade-in z-10">
|
||||
<div
|
||||
class="absolute bottom-6 right-6 w-64 h-48 rounded-2xl overflow-hidden shadow-2xl border-2 border-white/20 video-fade-in z-10">
|
||||
<!-- [DATA_FIELD: localUser.videoStream] [TYPE: MediaStream | null] [BIND: srcObject] -->
|
||||
<!-- [FALLBACK: localUser.avatar] [TYPE: string] [URL] -->
|
||||
<video id="localVideo"
|
||||
src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=300&fit=crop"
|
||||
alt="本地视频"
|
||||
class="w-full h-full object-cover"
|
||||
autoplay
|
||||
muted
|
||||
data-field="localUser.videoStream">
|
||||
src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=300&fit=crop" alt="本地视频"
|
||||
class="w-full h-full object-cover" autoplay muted data-field="localUser.videoStream">
|
||||
</video>
|
||||
|
||||
<!-- [CONDITIONAL_RENDER: localUser.mediaState.video === false] -->
|
||||
<div id="localVideoPlaceholder" class="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-indigo-900 to-purple-900 hidden" data-field="localUser.videoOff">
|
||||
<div id="localVideoPlaceholder"
|
||||
class="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-indigo-900 to-purple-900 hidden"
|
||||
data-field="localUser.videoOff">
|
||||
<span class="text-4xl font-bold" id="localInitials">我</span>
|
||||
</div>
|
||||
|
||||
@@ -250,8 +258,10 @@
|
||||
</div>
|
||||
|
||||
<!-- 本地视频悬停控制 -->
|
||||
<div class="absolute inset-0 bg-black/40 opacity-0 hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
|
||||
<button onclick="toggleLocalVideo()" class="w-8 h-8 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors">
|
||||
<div
|
||||
class="absolute inset-0 bg-black/40 opacity-0 hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
|
||||
<button onclick="toggleLocalVideo()"
|
||||
class="w-8 h-8 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors">
|
||||
<i class="fas fa-video text-xs" id="localVideoIcon"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -273,8 +283,8 @@
|
||||
数据源: [localUser, remoteUser]
|
||||
-->
|
||||
<div class="p-4 border-b border-white/10">
|
||||
<h3 class="text-sm font-medium text-gray-400 mb-3">
|
||||
通话成员 (<!-- [DATA_FIELD: userCount] [TYPE: number] [VALUE: 2] -->2)
|
||||
<h3 class="text-sm font-medium text-gray-400 mb-3" id="userCountDisplay">
|
||||
通话成员 (1)
|
||||
</h3>
|
||||
<div class="space-y-2" id="userList">
|
||||
<!-- [LOOP_START: users as user] -->
|
||||
@@ -283,11 +293,11 @@
|
||||
<div class="flex items-center gap-3 p-2 rounded-lg bg-white/5" data-user-id="remote">
|
||||
<div class="relative">
|
||||
<!-- [DATA_FIELD: remoteUser.avatar] -->
|
||||
<img src=""
|
||||
class="w-10 h-10 rounded-full object-cover"
|
||||
data-field="remoteUser.avatar">
|
||||
<img src="" class="w-10 h-10 rounded-full object-cover" data-field="remoteUser.avatar">
|
||||
<!-- [CONDITIONAL_RENDER: remoteUser.status === 'online'] -->
|
||||
<div class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-slate-900"></div>
|
||||
<div
|
||||
class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-slate-900">
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<!-- [DATA_FIELD: remoteUser.name] -->
|
||||
@@ -297,7 +307,8 @@
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- [CONDITIONAL_RENDER: remoteUser.mediaState.audio === false] -->
|
||||
<i class="fas fa-microphone-slash text-gray-500 text-xs hidden" data-field="remoteUser.muteIcon"></i>
|
||||
<i class="fas fa-microphone-slash text-gray-500 text-xs hidden"
|
||||
data-field="remoteUser.muteIcon"></i>
|
||||
<!-- [CONDITIONAL_RENDER: remoteUser.mediaState.isSpeaking === true] -->
|
||||
<div class="audio-wave w-6 hidden" data-field="remoteUser.speakingIndicator">
|
||||
<span></span><span></span><span></span><span></span><span></span>
|
||||
@@ -308,9 +319,7 @@
|
||||
<!-- 本地用户项 -->
|
||||
<div class="flex items-center gap-3 p-2 rounded-lg hover:bg-white/5" data-user-id="local">
|
||||
<!-- [DATA_FIELD: localUser.avatar] -->
|
||||
<img src=""
|
||||
class="w-10 h-10 rounded-full object-cover"
|
||||
data-field="localUser.avatar">
|
||||
<img src="" class="w-10 h-10 rounded-full object-cover" data-field="localUser.avatar">
|
||||
<div class="flex-1">
|
||||
<div class="text-sm font-medium">
|
||||
<!-- [DATA_FIELD: localUser.name] -->我
|
||||
@@ -318,7 +327,8 @@
|
||||
<span class="text-xs bg-indigo-500 px-1.5 rounded ml-1">主持人</span>
|
||||
</div>
|
||||
<!-- [DATA_FIELD: localUser.mediaState] [TRANSFORM: state => statusText] -->
|
||||
<div class="text-xs text-gray-500" id="localMediaStatus" data-field="localUser.mediaStatus">静音中</div>
|
||||
<div class="text-xs text-gray-500" id="localMediaStatus" data-field="localUser.mediaStatus">
|
||||
静音中</div>
|
||||
</div>
|
||||
<!-- [CONDITIONAL_RENDER: localUser.mediaState.audio === false] -->
|
||||
<i class="fas fa-microphone-slash text-gray-500 text-xs" data-field="localUser.muteIcon"></i>
|
||||
@@ -347,17 +357,18 @@
|
||||
<div class="flex gap-3">
|
||||
<!-- [DATA_FIELD: message.senderAvatar] -->
|
||||
<img src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop"
|
||||
class="w-8 h-8 rounded-full object-cover"
|
||||
data-field="message.senderAvatar">
|
||||
class="w-8 h-8 rounded-full object-cover" data-field="message.senderAvatar">
|
||||
<div class="flex-1">
|
||||
<div class="flex items-baseline gap-2 mb-1">
|
||||
<!-- [DATA_FIELD: message.senderName] -->
|
||||
<span class="text-sm font-medium text-indigo-400" data-field="message.senderName">Sarah Chen</span>
|
||||
<span class="text-sm font-medium text-indigo-400" data-field="message.senderName">Sarah
|
||||
Chen</span>
|
||||
<!-- [DATA_FIELD: message.timestamp] [FORMAT: HH:MM] -->
|
||||
<span class="text-xs text-gray-500" data-field="message.time">14:32</span>
|
||||
</div>
|
||||
<!-- [DATA_FIELD: message.content] -->
|
||||
<div class="glass px-3 py-2 rounded-2xl rounded-tl-none text-sm text-gray-200" data-field="message.content">
|
||||
<div class="glass px-3 py-2 rounded-2xl rounded-tl-none text-sm text-gray-200"
|
||||
data-field="message.content">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -369,14 +380,14 @@
|
||||
<div class="flex gap-3 flex-row-reverse">
|
||||
<!-- [DATA_FIELD: message.senderAvatar] -->
|
||||
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop"
|
||||
class="w-8 h-8 rounded-full object-cover"
|
||||
data-field="message.senderAvatar">
|
||||
class="w-8 h-8 rounded-full object-cover" data-field="message.senderAvatar">
|
||||
<div class="flex-1 flex flex-col items-end">
|
||||
<div class="flex items-baseline gap-2 mb-1 flex-row-reverse">
|
||||
<span class="text-sm font-medium text-green-400">我</span>
|
||||
<span class="text-xs text-gray-500" data-field="message.time">14:32</span>
|
||||
</div>
|
||||
<div class="bg-indigo-600 px-3 py-2 rounded-2xl rounded-tr-none text-sm text-white" data-field="message.content">
|
||||
<div class="bg-indigo-600 px-3 py-2 rounded-2xl rounded-tr-none text-sm text-white"
|
||||
data-field="message.content">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -391,20 +402,21 @@
|
||||
-->
|
||||
<div class="p-4 border-t border-white/10">
|
||||
<div class="glass rounded-2xl flex items-center gap-2 p-2">
|
||||
<button class="w-8 h-8 rounded-full hover:bg-white/10 flex items-center justify-center text-gray-400 transition-colors" onclick="openImagePicker()">
|
||||
<button
|
||||
class="w-8 h-8 rounded-full hover:bg-white/10 flex items-center justify-center text-gray-400 transition-colors"
|
||||
onclick="openImagePicker()">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
<!-- 隐藏的文件输入元素 -->
|
||||
<input type="file" id="imageInput" accept="image/*" class="hidden" onchange="handleImageUpload(event)">
|
||||
<input type="file" id="imageInput" accept="image/*" class="hidden"
|
||||
onchange="handleImageUpload(event)">
|
||||
<!-- [INPUT_FIELD] [BIND: inputValue] [EVENT: onEnter => sendMessage()] -->
|
||||
<input type="text"
|
||||
id="chatInput"
|
||||
placeholder="输入消息..."
|
||||
class="flex-1 bg-transparent border-none outline-none text-sm text-white placeholder-gray-500 px-2"
|
||||
data-field="chatInput"
|
||||
onkeypress="handleChatSubmit(event)">
|
||||
<input type="text" id="chatInput" placeholder="输入消息..."
|
||||
class="flex-1 bg-transparent border-none outline-none text-sm text-white placeholder-gray-500 px-2"
|
||||
data-field="chatInput" onkeypress="handleChatSubmit(event)">
|
||||
<!-- [BUTTON] [EVENT: onclick => sendMessage()] -->
|
||||
<button onclick="sendMessage()" class="w-8 h-8 rounded-full bg-indigo-600 hover:bg-indigo-700 flex items-center justify-center transition-colors">
|
||||
<button onclick="sendMessage()"
|
||||
class="w-8 h-8 rounded-full bg-indigo-600 hover:bg-indigo-700 flex items-center justify-center transition-colors">
|
||||
<i class="fas fa-paper-plane text-xs"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -439,60 +451,61 @@
|
||||
|
||||
<!-- 麦克风控制 -->
|
||||
<!-- [DATA_FIELD: localUser.mediaState.audio] [TYPE: boolean] -->
|
||||
<button class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group"
|
||||
onclick="toggleMute(this)"
|
||||
id="micBtn"
|
||||
data-field="localUser.audio"
|
||||
data-active="false">
|
||||
<button
|
||||
class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group"
|
||||
onclick="toggleMute(this)" id="micBtn" data-field="localUser.audio" data-active="false">
|
||||
<i class="fas fa-microphone text-lg" data-icon="default"></i>
|
||||
<i class="fas fa-microphone-slash text-lg hidden text-red-400" data-icon="active"></i>
|
||||
<span class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<span
|
||||
class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
静音 (Space)
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- 摄像头控制 -->
|
||||
<!-- [DATA_FIELD: localUser.mediaState.video] [TYPE: boolean] -->
|
||||
<button class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group"
|
||||
onclick="toggleVideo(this)"
|
||||
id="videoBtn"
|
||||
data-field="localUser.video"
|
||||
data-active="false">
|
||||
<button
|
||||
class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group"
|
||||
onclick="toggleVideo(this)" id="videoBtn" data-field="localUser.video" data-active="false">
|
||||
<i class="fas fa-video text-lg" data-icon="default"></i>
|
||||
<i class="fas fa-video-slash text-lg hidden text-red-400" data-icon="active"></i>
|
||||
<span class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<span
|
||||
class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
关闭视频 (Ctrl+V)
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- 录屏控制 -->
|
||||
<!-- [DATA_FIELD: localUser.mediaState.recording] [TYPE: boolean] -->
|
||||
<button class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group"
|
||||
onclick="toggleRecording(this)"
|
||||
id="recordBtn"
|
||||
data-field="localUser.recording"
|
||||
data-active="false">
|
||||
<button
|
||||
class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group"
|
||||
onclick="toggleRecording(this)" id="recordBtn" data-field="localUser.recording" data-active="false">
|
||||
<i class="fas fa-circle text-lg" data-icon="default"></i>
|
||||
<i class="fas fa-stop text-lg hidden text-red-400" data-icon="active"></i>
|
||||
<span class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<span
|
||||
class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
录制
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- 更多选项 -->
|
||||
<button class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group">
|
||||
<button
|
||||
class="control-btn w-12 h-12 rounded-full glass flex items-center justify-center text-white hover:bg-white/10 relative group">
|
||||
<i class="fas fa-ellipsis-h text-lg"></i>
|
||||
<span class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<span
|
||||
class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
更多选项
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- 结束通话 -->
|
||||
<!-- [EVENT: onclick => endCall()] [API: POST /api/call/:callId/leave] -->
|
||||
<button class="control-btn w-14 h-14 rounded-full bg-red-500 hover:bg-red-600 flex items-center justify-center text-white end-call-pulse ml-4 relative group"
|
||||
onclick="endCall()">
|
||||
<button
|
||||
class="control-btn w-14 h-14 rounded-full bg-red-500 hover:bg-red-600 flex items-center justify-center text-white end-call-pulse ml-4 relative group"
|
||||
onclick="endCall()">
|
||||
<i class="fas fa-phone-slash text-xl"></i>
|
||||
<span class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<span
|
||||
class="absolute -top-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-black/80 rounded text-xs whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
结束通话
|
||||
</span>
|
||||
</button>
|
||||
@@ -500,17 +513,21 @@
|
||||
|
||||
<!-- 右侧聊天按钮 -->
|
||||
<div class="absolute right-6 flex items-center gap-3">
|
||||
<button class="control-btn w-10 h-10 rounded-full glass flex items-center justify-center text-gray-300 hover:text-white hover:bg-white/10 transition-colors relative" onclick="toggleSidebar()">
|
||||
<button
|
||||
class="control-btn w-10 h-10 rounded-full glass flex items-center justify-center text-gray-300 hover:text-white hover:bg-white/10 transition-colors relative"
|
||||
onclick="toggleSidebar()">
|
||||
<i class="fas fa-comment-alt"></i>
|
||||
<!-- 未读消息计数角标 -->
|
||||
<span id="unreadBadge" class="absolute -top-1 -right-1 w-5 h-5 bg-red-500 rounded-full flex items-center justify-center text-xs font-bold text-white hidden">0</span>
|
||||
<span id="unreadBadge"
|
||||
class="absolute -top-1 -right-1 w-5 h-5 bg-red-500 rounded-full flex items-center justify-center text-xs font-bold text-white hidden">0</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
|
||||
<!-- 通知组件 -->
|
||||
<div id="notification" class="fixed top-20 left-1/2 transform -translate-x-1/2 glass px-6 py-3 rounded-full flex items-center gap-3 opacity-0 pointer-events-none transition-all duration-300 z-50 translate-y-[-20px]">
|
||||
<div id="notification"
|
||||
class="fixed top-20 left-1/2 transform -translate-x-1/2 glass px-6 py-3 rounded-full flex items-center gap-3 opacity-0 pointer-events-none transition-all duration-300 z-50 translate-y-[-20px]">
|
||||
<i class="fas fa-info-circle text-indigo-400"></i>
|
||||
<span class="text-sm" id="notificationText">通知内容</span>
|
||||
</div>
|
||||
@@ -529,7 +546,8 @@
|
||||
<button id="cancelEndCall" class="flex-1 py-2 rounded-lg glass hover:bg-white/10 transition-colors">
|
||||
取消
|
||||
</button>
|
||||
<button id="confirmEndCall" class="flex-1 py-2 rounded-lg bg-red-500 hover:bg-red-600 transition-colors">
|
||||
<button id="confirmEndCall"
|
||||
class="flex-1 py-2 rounded-lg bg-red-500 hover:bg-red-600 transition-colors">
|
||||
结束通话
|
||||
</button>
|
||||
</div>
|
||||
@@ -546,7 +564,9 @@
|
||||
<h3 class="text-xl font-bold mb-2" id="callRequestName">Sarah Chen</h3>
|
||||
<p class="text-gray-400 text-sm" id="callRequestText">正在请求与您进行视频通话</p>
|
||||
<div class="mt-4 flex items-center justify-center gap-4">
|
||||
<img id="callRequestAvatar" src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop" class="w-16 h-16 rounded-full object-cover border-4 border-indigo-500">
|
||||
<img id="callRequestAvatar"
|
||||
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop"
|
||||
class="w-16 h-16 rounded-full object-cover border-4 border-indigo-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
@@ -556,7 +576,8 @@
|
||||
<span>拒绝</span>
|
||||
</div>
|
||||
</button>
|
||||
<button id="acceptCall" class="flex-1 py-2 rounded-lg bg-green-500 hover:bg-green-600 transition-colors">
|
||||
<button id="acceptCall"
|
||||
class="flex-1 py-2 rounded-lg bg-green-500 hover:bg-green-600 transition-colors">
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<i class="fas fa-phone"></i>
|
||||
<span>接受</span>
|
||||
@@ -571,4 +592,5 @@
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user