2026-03-03 17:51:30 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 主入口文件
|
|
|
|
|
|
* 初始化应用,连接各个模块
|
|
|
|
|
|
*/
|
|
|
|
|
|
import store from './store.js';
|
|
|
|
|
|
import UIRenderer from './renderer.js';
|
|
|
|
|
|
import apiClient from './api.js';
|
2026-03-12 14:41:00 +08:00
|
|
|
|
import { showNotification } from './utils.js';
|
|
|
|
|
|
import chatMessage from './chatmessage.js';
|
2026-03-03 17:51:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 全局变量
|
2026-03-04 17:55:55 +08:00
|
|
|
|
let connectionId = "";
|
2026-03-03 17:51:30 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 绑定DOM事件
|
|
|
|
|
|
*/
|
|
|
|
|
|
function bindDomEvents() {
|
|
|
|
|
|
// 切换侧边栏
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.toggleSidebar = function () {
|
2026-03-12 14:41:00 +08:00
|
|
|
|
chatMessage.toggleSidebar();
|
2026-03-03 17:51:30 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 切换麦克风
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.toggleMute = function (button) {
|
2026-03-03 17:51:30 +08:00
|
|
|
|
const state = store.getState();
|
|
|
|
|
|
const currentState = state.session.localUser.mediaState.audio;
|
|
|
|
|
|
store.updateLocalMedia('audio', !currentState);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 切换视频
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.toggleVideo = function (button) {
|
2026-03-03 17:51:30 +08:00
|
|
|
|
const state = store.getState();
|
|
|
|
|
|
const currentState = state.session.localUser.mediaState.video;
|
|
|
|
|
|
store.updateLocalMedia('video', !currentState);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 切换本地视频(用于悬停控制)
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.toggleLocalVideo = function () {
|
2026-03-03 17:51:30 +08:00
|
|
|
|
window.toggleVideo();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 切换录屏
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.toggleRecording = function (button) {
|
2026-03-03 17:51:30 +08:00
|
|
|
|
const state = store.getState();
|
|
|
|
|
|
const currentState = state.session.localUser.mediaState.recording || false;
|
|
|
|
|
|
store.updateLocalMedia('recording', !currentState);
|
|
|
|
|
|
|
|
|
|
|
|
// 显示录制状态通知
|
|
|
|
|
|
if (!currentState) {
|
|
|
|
|
|
showNotification('开始录制');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showNotification('停止录制');
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 结束通话
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.endCall = function () {
|
2026-03-03 17:51:30 +08:00
|
|
|
|
// 显示确认对话框
|
|
|
|
|
|
document.getElementById('endCallDialog').classList.remove('hidden');
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 取消结束通话
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.cancelEndCall = function () {
|
2026-03-03 17:51:30 +08:00
|
|
|
|
document.getElementById('endCallDialog').classList.add('hidden');
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 确认结束通话
|
2026-03-04 17:55:55 +08:00
|
|
|
|
window.confirmEndCall = function () {
|
2026-03-03 17:51:30 +08:00
|
|
|
|
document.getElementById('endCallDialog').classList.add('hidden');
|
|
|
|
|
|
store.endCall();
|
|
|
|
|
|
showNotification('通话已结束');
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-03-04 17:55:55 +08:00
|
|
|
|
// 显示通话请求弹窗
|
|
|
|
|
|
window.showCallRequest = function (caller) {
|
|
|
|
|
|
const dialog = document.getElementById('callRequestDialog');
|
|
|
|
|
|
if (dialog) {
|
|
|
|
|
|
// 设置通话请求信息
|
|
|
|
|
|
if (document.getElementById('callRequestName')) {
|
|
|
|
|
|
document.getElementById('callRequestName').textContent = caller.name;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (document.getElementById('callRequestAvatar')) {
|
|
|
|
|
|
document.getElementById('callRequestAvatar').src = caller.avatar;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 显示弹窗
|
|
|
|
|
|
dialog.classList.remove('hidden');
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 拒绝通话
|
|
|
|
|
|
window.rejectCall = function () {
|
|
|
|
|
|
const dialog = document.getElementById('callRequestDialog');
|
|
|
|
|
|
if (dialog) {
|
|
|
|
|
|
dialog.classList.add('hidden');
|
|
|
|
|
|
}
|
|
|
|
|
|
showNotification('已拒绝通话请求');
|
|
|
|
|
|
// 可以在这里添加发送拒绝通话请求到服务器的逻辑
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 接受通话
|
|
|
|
|
|
window.acceptCall = function () {
|
|
|
|
|
|
const dialog = document.getElementById('callRequestDialog');
|
|
|
|
|
|
if (dialog) {
|
|
|
|
|
|
dialog.classList.add('hidden');
|
|
|
|
|
|
}
|
|
|
|
|
|
showNotification('已接受通话请求');
|
|
|
|
|
|
// 可以在这里添加发送接受通话请求到服务器的逻辑
|
|
|
|
|
|
// 然后初始化通话
|
|
|
|
|
|
store.initCall();
|
|
|
|
|
|
store.setUp(connectionId);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-03-12 14:41:00 +08:00
|
|
|
|
// 绑定消息相关事件
|
|
|
|
|
|
chatMessage.bindMessageEvents();
|
2026-03-03 18:06:20 +08:00
|
|
|
|
|
2026-03-03 17:51:30 +08:00
|
|
|
|
// 键盘快捷键
|
|
|
|
|
|
document.addEventListener('keydown', (event) => {
|
|
|
|
|
|
// 空格键静音
|
|
|
|
|
|
if (event.code === 'Space' && !event.target.matches('input, textarea')) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
window.toggleMute();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Ctrl+V 切换视频
|
|
|
|
|
|
if (event.ctrlKey && event.key === 'v') {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
window.toggleVideo();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 绑定对话框事件
|
|
|
|
|
|
document.getElementById('cancelEndCall').addEventListener('click', window.cancelEndCall);
|
|
|
|
|
|
document.getElementById('confirmEndCall').addEventListener('click', window.confirmEndCall);
|
2026-03-04 17:55:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 绑定通话请求对话框事件
|
|
|
|
|
|
if (document.getElementById('rejectCall')) {
|
|
|
|
|
|
document.getElementById('rejectCall').addEventListener('click', window.rejectCall);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (document.getElementById('acceptCall')) {
|
|
|
|
|
|
document.getElementById('acceptCall').addEventListener('click', window.acceptCall);
|
|
|
|
|
|
}
|
2026-03-03 17:51:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-04 18:40:19 +08:00
|
|
|
|
// 页面加载完成后初始化
|
|
|
|
|
|
window.addEventListener('DOMContentLoaded', async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 检查本地存储中是否有连接ID
|
|
|
|
|
|
const connectionId = localStorage.getItem('connectionId');
|
|
|
|
|
|
|
|
|
|
|
|
if (!connectionId) {
|
|
|
|
|
|
// 如果没有连接ID,跳转到连接界面
|
|
|
|
|
|
window.location.href = './connect/connect.html';
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化 store
|
2026-03-04 22:29:10 +08:00
|
|
|
|
//await store.init();
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化渲染器
|
|
|
|
|
|
new UIRenderer(store);
|
2026-03-04 18:40:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 加入通话
|
2026-03-04 22:29:10 +08:00
|
|
|
|
await store.joinCall(connectionId);
|
2026-03-04 18:40:19 +08:00
|
|
|
|
|
2026-03-04 22:29:10 +08:00
|
|
|
|
// 设置WebRTC连接
|
|
|
|
|
|
await store.setUp(connectionId);
|
2026-03-04 18:40:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 绑定DOM事件
|
|
|
|
|
|
bindDomEvents();
|
|
|
|
|
|
|
|
|
|
|
|
console.log('Video call app initialized successfully');
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Error initializing app:', error);
|
|
|
|
|
|
showNotification('初始化失败,请刷新页面重试', 'error');
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2026-03-03 17:51:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 导出全局变量
|
2026-03-12 14:41:00 +08:00
|
|
|
|
export { store, apiClient };
|