【m】界面分为3个页面
This commit is contained in:
61
WebApp/client/public/onebyone/connect/connect.html
Normal file
61
WebApp/client/public/onebyone/connect/connect.html
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>VideoCall - 连接界面</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<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">
|
||||||
|
<!--
|
||||||
|
============================================================
|
||||||
|
初始连接界面
|
||||||
|
============================================================
|
||||||
|
-->
|
||||||
|
<div class="h-full w-full flex items-center justify-center bg-black/90">
|
||||||
|
<div class="text-center max-w-md px-8">
|
||||||
|
<div class="w-24 h-24 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-full flex items-center justify-center mx-auto mb-8 shadow-lg">
|
||||||
|
<i class="fas fa-video text-white text-4xl"></i>
|
||||||
|
</div>
|
||||||
|
<h1 class="text-3xl font-bold text-white mb-2">VideoCall</h1>
|
||||||
|
<p class="text-gray-400 mb-8">一对一视频通话</p>
|
||||||
|
|
||||||
|
<div class="space-y-4 mb-8">
|
||||||
|
<div class="glass rounded-xl p-4">
|
||||||
|
<label class="block text-sm font-medium text-gray-300 mb-2">连接ID</label>
|
||||||
|
<input type="text"
|
||||||
|
id="connectionIdInput"
|
||||||
|
placeholder="输入连接ID"
|
||||||
|
class="w-full bg-transparent border border-white/20 rounded-lg px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500"
|
||||||
|
autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-gray-500">
|
||||||
|
连接ID是用于建立点对点通话的唯一标识,由发起方生成并分享给接收方。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
|
<button id="connectBtn" class="flex-1 px-6 py-3 bg-indigo-600 hover:bg-indigo-700 rounded-xl transition-colors flex items-center justify-center gap-2">
|
||||||
|
<i class="fas fa-phone"></i>
|
||||||
|
<span>加入通话</span>
|
||||||
|
</button>
|
||||||
|
<button id="createCallBtn" class="flex-1 px-6 py-3 glass hover:bg-white/10 rounded-xl transition-colors flex items-center justify-center gap-2">
|
||||||
|
<i class="fas fa-plus"></i>
|
||||||
|
<span>创建通话</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 通知组件 -->
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- 引入模块化JavaScript文件 -->
|
||||||
|
<script type="module" src="connect.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
120
WebApp/client/public/onebyone/connect/connect.js
Normal file
120
WebApp/client/public/onebyone/connect/connect.js
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/**
|
||||||
|
* 连接界面逻辑
|
||||||
|
* 处理初始连接、创建通话和加入通话的功能
|
||||||
|
*/
|
||||||
|
|
||||||
|
import store from '../store.js';
|
||||||
|
|
||||||
|
// 通知函数
|
||||||
|
function showNotification(message, type = 'info') {
|
||||||
|
const notification = document.getElementById('notification');
|
||||||
|
const notificationText = document.getElementById('notificationText');
|
||||||
|
|
||||||
|
if (notification && notificationText) {
|
||||||
|
notificationText.textContent = message;
|
||||||
|
|
||||||
|
// 清除之前的类
|
||||||
|
notification.className = '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]';
|
||||||
|
|
||||||
|
// 根据类型添加不同的图标
|
||||||
|
const iconElement = notification.querySelector('i');
|
||||||
|
if (iconElement) {
|
||||||
|
iconElement.className = 'fas fa-info-circle text-indigo-400';
|
||||||
|
switch (type) {
|
||||||
|
case 'success':
|
||||||
|
iconElement.className = 'fas fa-check-circle text-green-400';
|
||||||
|
break;
|
||||||
|
case 'error':
|
||||||
|
iconElement.className = 'fas fa-exclamation-circle text-red-400';
|
||||||
|
break;
|
||||||
|
case 'warning':
|
||||||
|
iconElement.className = 'fas fa-exclamation-triangle text-yellow-400';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示通知
|
||||||
|
notification.classList.remove('opacity-0', 'translate-y-[-20px]');
|
||||||
|
notification.classList.add('opacity-100', 'translate-y-0');
|
||||||
|
|
||||||
|
// 3秒后隐藏
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.classList.remove('opacity-100', 'translate-y-0');
|
||||||
|
notification.classList.add('opacity-0', 'translate-y-[-20px]');
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加入通话
|
||||||
|
function joinCall() {
|
||||||
|
const connectionId = document.getElementById('connectionIdInput').value.trim();
|
||||||
|
if (connectionId) {
|
||||||
|
showNotification(`正在加入通话 (${connectionId})`);
|
||||||
|
|
||||||
|
// 保存连接ID到本地存储
|
||||||
|
localStorage.setItem('connectionId', connectionId);
|
||||||
|
|
||||||
|
// 跳转到通话界面
|
||||||
|
window.location.href = '../index.html';
|
||||||
|
} else {
|
||||||
|
showNotification('请输入连接ID', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建通话
|
||||||
|
function createCall() {
|
||||||
|
showNotification('正在创建通话...');
|
||||||
|
|
||||||
|
// 生成随机连接ID
|
||||||
|
const connectionId = 'conn_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
||||||
|
|
||||||
|
// 保存连接ID到本地存储
|
||||||
|
localStorage.setItem('connectionId', connectionId);
|
||||||
|
|
||||||
|
// 跳转到通话界面
|
||||||
|
window.location.href = '../index.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定事件监听器
|
||||||
|
function bindEvents() {
|
||||||
|
// 连接按钮
|
||||||
|
const connectBtn = document.getElementById('connectBtn');
|
||||||
|
if (connectBtn) {
|
||||||
|
connectBtn.addEventListener('click', joinCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建通话按钮
|
||||||
|
const createCallBtn = document.getElementById('createCallBtn');
|
||||||
|
if (createCallBtn) {
|
||||||
|
createCallBtn.addEventListener('click', createCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输入框回车事件
|
||||||
|
const connectionIdInput = document.getElementById('connectionIdInput');
|
||||||
|
if (connectionIdInput) {
|
||||||
|
connectionIdInput.addEventListener('keypress', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
joinCall();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载完成后初始化
|
||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
bindEvents();
|
||||||
|
|
||||||
|
// 检查本地存储中是否有连接ID
|
||||||
|
const savedConnectionId = localStorage.getItem('connectionId');
|
||||||
|
if (savedConnectionId) {
|
||||||
|
const connectionIdInput = document.getElementById('connectionIdInput');
|
||||||
|
if (connectionIdInput) {
|
||||||
|
connectionIdInput.value = savedConnectionId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 导出全局函数
|
||||||
|
window.showNotification = showNotification;
|
||||||
|
window.joinCall = joinCall;
|
||||||
|
window.createCall = createCall;
|
||||||
50
WebApp/client/public/onebyone/endcall/endcall.html
Normal file
50
WebApp/client/public/onebyone/endcall/endcall.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>VideoCall - 通话结束</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<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">
|
||||||
|
<!--
|
||||||
|
============================================================
|
||||||
|
结束通话界面
|
||||||
|
============================================================
|
||||||
|
-->
|
||||||
|
<div class="h-full w-full flex items-center justify-center bg-black/80">
|
||||||
|
<div class="text-center max-w-md px-8">
|
||||||
|
<div class="w-20 h-20 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg">
|
||||||
|
<i class="fas fa-video-slash text-white text-3xl"></i>
|
||||||
|
</div>
|
||||||
|
<h2 class="text-2xl font-bold text-white mb-4">通话已结束</h2>
|
||||||
|
<p class="text-gray-400 mb-8" id="disconnectReason">连接已断开,请检查网络连接后重试</p>
|
||||||
|
<div class="flex flex-col sm:flex-row gap-3 justify-center">
|
||||||
|
<button id="reconnectBtn" class="px-6 py-3 bg-indigo-600 hover:bg-indigo-700 rounded-xl transition-colors flex items-center justify-center gap-2">
|
||||||
|
<i class="fas fa-redo"></i>
|
||||||
|
<span>重新连接</span>
|
||||||
|
</button>
|
||||||
|
<button id="leaveBtn" class="px-6 py-3 glass hover:bg-white/10 rounded-xl transition-colors flex items-center justify-center gap-2">
|
||||||
|
<i class="fas fa-sign-out-alt"></i>
|
||||||
|
<span>返回</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="mt-8 text-xs text-gray-500">
|
||||||
|
<p>连接ID: <span id="disconnectConnectionId">--</span></p>
|
||||||
|
<p>断开时间: <span id="disconnectTime">--</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 通知组件 -->
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- 引入模块化JavaScript文件 -->
|
||||||
|
<script type="module" src="endcall.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
98
WebApp/client/public/onebyone/endcall/endcall.js
Normal file
98
WebApp/client/public/onebyone/endcall/endcall.js
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* 结束通话界面逻辑
|
||||||
|
* 处理通话结束后的操作,如重新连接或返回连接界面
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 通知函数
|
||||||
|
function showNotification(message, type = 'info') {
|
||||||
|
const notification = document.getElementById('notification');
|
||||||
|
const notificationText = document.getElementById('notificationText');
|
||||||
|
|
||||||
|
if (notification && notificationText) {
|
||||||
|
notificationText.textContent = message;
|
||||||
|
|
||||||
|
// 清除之前的类
|
||||||
|
notification.className = '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]';
|
||||||
|
|
||||||
|
// 根据类型添加不同的图标
|
||||||
|
const iconElement = notification.querySelector('i');
|
||||||
|
if (iconElement) {
|
||||||
|
iconElement.className = 'fas fa-info-circle text-indigo-400';
|
||||||
|
switch (type) {
|
||||||
|
case 'success':
|
||||||
|
iconElement.className = 'fas fa-check-circle text-green-400';
|
||||||
|
break;
|
||||||
|
case 'error':
|
||||||
|
iconElement.className = 'fas fa-exclamation-circle text-red-400';
|
||||||
|
break;
|
||||||
|
case 'warning':
|
||||||
|
iconElement.className = 'fas fa-exclamation-triangle text-yellow-400';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示通知
|
||||||
|
notification.classList.remove('opacity-0', 'translate-y-[-20px]');
|
||||||
|
notification.classList.add('opacity-100', 'translate-y-0');
|
||||||
|
|
||||||
|
// 3秒后隐藏
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.classList.remove('opacity-100', 'translate-y-0');
|
||||||
|
notification.classList.add('opacity-0', 'translate-y-[-20px]');
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新连接
|
||||||
|
function reconnectCall() {
|
||||||
|
showNotification('正在重新连接...');
|
||||||
|
|
||||||
|
// 跳转到通话界面
|
||||||
|
window.location.href = '../index.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 离开
|
||||||
|
function leaveCall() {
|
||||||
|
// 清除本地存储中的连接ID
|
||||||
|
localStorage.removeItem('connectionId');
|
||||||
|
|
||||||
|
// 跳转到连接界面
|
||||||
|
window.location.href = '../connect/connect.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定事件监听器
|
||||||
|
function bindEvents() {
|
||||||
|
// 重新连接按钮
|
||||||
|
const reconnectBtn = document.getElementById('reconnectBtn');
|
||||||
|
if (reconnectBtn) {
|
||||||
|
reconnectBtn.addEventListener('click', reconnectCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 离开按钮
|
||||||
|
const leaveBtn = document.getElementById('leaveBtn');
|
||||||
|
if (leaveBtn) {
|
||||||
|
leaveBtn.addEventListener('click', leaveCall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载完成后初始化
|
||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
bindEvents();
|
||||||
|
|
||||||
|
// 更新断开连接信息
|
||||||
|
const disconnectConnectionId = document.getElementById('disconnectConnectionId');
|
||||||
|
const disconnectTime = document.getElementById('disconnectTime');
|
||||||
|
|
||||||
|
if (disconnectConnectionId) {
|
||||||
|
disconnectConnectionId.textContent = localStorage.getItem('connectionId') || '--';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disconnectTime) {
|
||||||
|
disconnectTime.textContent = new Date().toLocaleString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 导出全局函数
|
||||||
|
window.showNotification = showNotification;
|
||||||
|
window.reconnectCall = reconnectCall;
|
||||||
|
window.leaveCall = leaveCall;
|
||||||
@@ -9,6 +9,12 @@
|
|||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="h-screen w-screen flex flex-col text-white bg-grid relative">
|
<body class="h-screen w-screen flex flex-col text-white bg-grid relative">
|
||||||
|
<!--
|
||||||
|
============================================================
|
||||||
|
注意:此文件为视频通话界面
|
||||||
|
初始连接界面请访问 connect.html
|
||||||
|
============================================================
|
||||||
|
-->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
============================================================
|
============================================================
|
||||||
@@ -192,6 +198,10 @@
|
|||||||
<p class="text-sm text-gray-400 mt-1" id="connectingText">等待对方接受邀请</p>
|
<p class="text-sm text-gray-400 mt-1" id="connectingText">等待对方接受邀请</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@@ -325,8 +325,39 @@ function initWebRTC() {
|
|||||||
console.log('Initializing WebRTC...');
|
console.log('Initializing WebRTC...');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面加载完成后初始化应用
|
// 页面加载完成后初始化
|
||||||
document.addEventListener('DOMContentLoaded', initApp);
|
window.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
try {
|
||||||
|
// 检查本地存储中是否有连接ID
|
||||||
|
const connectionId = localStorage.getItem('connectionId');
|
||||||
|
|
||||||
|
if (!connectionId) {
|
||||||
|
// 如果没有连接ID,跳转到连接界面
|
||||||
|
window.location.href = './connect/connect.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 store
|
||||||
|
store.init();
|
||||||
|
|
||||||
|
// 加入通话
|
||||||
|
store.joinCall(connectionId);
|
||||||
|
|
||||||
|
// 初始化渲染器
|
||||||
|
const renderer = new UIRenderer(store);
|
||||||
|
|
||||||
|
// 绑定DOM事件
|
||||||
|
bindDomEvents();
|
||||||
|
|
||||||
|
// 绑定WebSocket事件
|
||||||
|
bindWebSocketEvents();
|
||||||
|
|
||||||
|
console.log('Video call app initialized successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error initializing app:', error);
|
||||||
|
showNotification('初始化失败,请刷新页面重试', 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 导出全局变量
|
// 导出全局变量
|
||||||
export { store, renderer, apiClient, wsManager };
|
export { store, renderer, apiClient, wsManager };
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ class UIRenderer {
|
|||||||
|
|
||||||
// 缓存 DOM 元素
|
// 缓存 DOM 元素
|
||||||
this.elements = {
|
this.elements = {
|
||||||
// 头部
|
// 头部和底部
|
||||||
|
header: document.querySelector('header'),
|
||||||
|
footer: document.querySelector('footer'),
|
||||||
|
// 头部内容
|
||||||
headerTitle: document.getElementById('headerTitle'),
|
headerTitle: document.getElementById('headerTitle'),
|
||||||
callDuration: document.getElementById('callDuration'),
|
callDuration: document.getElementById('callDuration'),
|
||||||
encryptionBadge: document.getElementById('encryptionBadge'),
|
encryptionBadge: document.getElementById('encryptionBadge'),
|
||||||
@@ -46,12 +49,22 @@ class UIRenderer {
|
|||||||
recordBtn: document.getElementById('recordBtn'),
|
recordBtn: document.getElementById('recordBtn'),
|
||||||
connectionQuality: document.getElementById('connectionQuality')
|
connectionQuality: document.getElementById('connectionQuality')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 绑定事件监听器
|
||||||
|
this.bindEventListeners();
|
||||||
|
|
||||||
// 订阅状态变化
|
// 订阅状态变化
|
||||||
this.unsubscribe = stateManager.subscribe(this.render.bind(this));
|
this.unsubscribe = stateManager.subscribe(this.render.bind(this));
|
||||||
// 初始化渲染
|
// 初始化渲染
|
||||||
this.render(this.stateManager.getState(), { type: 'INIT' });
|
this.render(this.stateManager.getState(), { type: 'INIT' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绑定事件监听器
|
||||||
|
bindEventListeners() {
|
||||||
|
// 事件监听器
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 渲染状态变化
|
// 渲染状态变化
|
||||||
render(state, changes) {
|
render(state, changes) {
|
||||||
switch (changes.type) {
|
switch (changes.type) {
|
||||||
@@ -166,6 +179,11 @@ class UIRenderer {
|
|||||||
this.elements.localVideo.autoplay = true;
|
this.elements.localVideo.autoplay = true;
|
||||||
this.elements.localVideo.muted = true; // 本地视频静音,避免回声
|
this.elements.localVideo.muted = true; // 本地视频静音,避免回声
|
||||||
console.log('srcObject set successfully:', this.elements.localVideo.srcObject);
|
console.log('srcObject set successfully:', this.elements.localVideo.srcObject);
|
||||||
|
|
||||||
|
// 隐藏断开连接覆盖层
|
||||||
|
if (this.elements.disconnectedOverlay) {
|
||||||
|
this.elements.disconnectedOverlay.classList.add('hidden');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('Either localVideo element or stream is missing');
|
console.error('Either localVideo element or stream is missing');
|
||||||
}
|
}
|
||||||
@@ -364,8 +382,9 @@ class UIRenderer {
|
|||||||
|
|
||||||
// 渲染通话结束
|
// 渲染通话结束
|
||||||
renderCallEnded() {
|
renderCallEnded() {
|
||||||
// 可以在这里添加通话结束的UI处理
|
|
||||||
console.log('Call ended');
|
console.log('Call ended');
|
||||||
|
// 跳转到结束通话界面
|
||||||
|
window.location.href = './endcall/endcall.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取状态文本
|
// 获取状态文本
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { mockCallSession, mockMessages } from './models.js';
|
|||||||
import { Signaling, WebSocketSignaling } from "../../module/signaling.js";// 信令管理
|
import { Signaling, WebSocketSignaling } from "../../module/signaling.js";// 信令管理
|
||||||
import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
|
import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
|
||||||
import { getServerConfig, getRTCConfiguration } from "../js/config.js";//服务器配置和RTC配置
|
import { getServerConfig, getRTCConfiguration } from "../js/config.js";//服务器配置和RTC配置
|
||||||
|
import { showNotification } from './utils.js'; // 导入通知函数
|
||||||
// 默认视频流尺寸
|
// 默认视频流尺寸
|
||||||
const defaultStreamWidth = 1280;
|
const defaultStreamWidth = 1280;
|
||||||
const defaultStreamHeight = 720;
|
const defaultStreamHeight = 720;
|
||||||
@@ -19,7 +20,10 @@ class CallStateManager {
|
|||||||
let connectionId; // 连接ID
|
let connectionId; // 连接ID
|
||||||
// 核心状态
|
// 核心状态
|
||||||
this.state = {
|
this.state = {
|
||||||
session: { ...mockCallSession },
|
session: {
|
||||||
|
...mockCallSession,
|
||||||
|
status: 'idle' // 初始状态为空闲
|
||||||
|
},
|
||||||
messages: [...mockMessages],
|
messages: [...mockMessages],
|
||||||
isSidebarOpen: false,
|
isSidebarOpen: false,
|
||||||
unreadCount: 0,
|
unreadCount: 0,
|
||||||
@@ -305,6 +309,29 @@ class CallStateManager {
|
|||||||
// [WEBSOCKET_EMIT: leave-call]
|
// [WEBSOCKET_EMIT: leave-call]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加入通话
|
||||||
|
joinCall(connectionId) {
|
||||||
|
this.state.session.status = 'connecting';
|
||||||
|
this.notify({ type: 'CALL_STATUS_CHANGE', status: 'connecting' });
|
||||||
|
showNotification(`正在加入通话 (${connectionId})`);
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
this.init();
|
||||||
|
|
||||||
|
// 保存连接ID
|
||||||
|
this.connectionId = connectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建通话
|
||||||
|
createCall() {
|
||||||
|
this.state.session.status = 'connecting';
|
||||||
|
this.notify({ type: 'CALL_STATUS_CHANGE', status: 'connecting' });
|
||||||
|
showNotification('正在创建通话...');
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
// 模拟远端活动 (开发测试用)
|
// 模拟远端活动 (开发测试用)
|
||||||
simulateRemoteActivity() {
|
simulateRemoteActivity() {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
@@ -342,6 +369,7 @@ class CallStateManager {
|
|||||||
getLocalUser() { return this.state.session.localUser; }
|
getLocalUser() { return this.state.session.localUser; }
|
||||||
getRemoteUser() { return this.state.session.remoteUser; }
|
getRemoteUser() { return this.state.session.remoteUser; }
|
||||||
getMessages() { return this.state.messages; }
|
getMessages() { return this.state.messages; }
|
||||||
|
getConnectionId() { return this.connectionId; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建单例实例
|
// 创建单例实例
|
||||||
@@ -354,4 +382,3 @@ window.addEventListener('beforeunload', async () => {
|
|||||||
await store.renderstreaming.stop(); // 停止WebRTC连接
|
await store.renderstreaming.stop(); // 停止WebRTC连接
|
||||||
}, true);
|
}, true);
|
||||||
export default store;
|
export default store;
|
||||||
|
|
||||||
|
|||||||
@@ -6,3 +6,11 @@ popd
|
|||||||
pause
|
pause
|
||||||
|
|
||||||
node ./build/index.js -s -p 8080 -m private -k ./server.key -c ./server.cert -l dev
|
node ./build/index.js -s -p 8080 -m private -k ./server.key -c ./server.cert -l dev
|
||||||
|
|
||||||
|
|
||||||
|
// 通话测试代码
|
||||||
|
const caller = {
|
||||||
|
name: "Sarah Chen",
|
||||||
|
avatar: "https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop"
|
||||||
|
};
|
||||||
|
window.showCallRequest(caller);
|
||||||
|
|||||||
Reference in New Issue
Block a user