/** * 主入口文件 * 初始化应用,连接各个模块 */ import store from './store.js'; import UIRenderer from './renderer.js'; import apiClient from './api.js'; // import wsManager from './websocket.js'; import { mockCallSession } from './models.js'; import { showNotification, generateId } from './utils.js'; // 全局变量 let renderer = null; let connectionId = ""; /** * 初始化应用 */ // function initApp() { // // 初始化渲染器 // renderer = new UIRenderer(store); // // 初始化WebSocket连接 // wsManager.connect(); // // 绑定WebSocket事件 // bindWebSocketEvents(); // // 绑定DOM事件 // bindDomEvents(); // // 初始化WebRTC (如果需要) // // initWebRTC(); // console.log('App initialized'); // } /** * 绑定WebSocket事件 */ function bindWebSocketEvents() { // wsManager.on('connect', () => { // console.log('WebSocket connected'); // showNotification('已连接到服务器'); // }); // wsManager.on('disconnect', () => { // console.log('WebSocket disconnected'); // showNotification('与服务器的连接已断开', 5000); // }); // wsManager.on('message-received', (data) => { // console.log('Message received:', data); // store.addMessage(data.message); // }); // wsManager.on('user-joined', (data) => { // console.log('User joined:', data); // showNotification(`${data.userId} 加入了通话`); // }); // wsManager.on('user-left', (data) => { // console.log('User left:', data); // showNotification(`${data.userId} 离开了通话`); // }); // wsManager.on('media-state-changed', (data) => { // console.log('Media state changed:', data); // // 更新远端媒体状态 // if (data.userId !== store.getLocalUser().id) { // store.updateRemoteMedia(data); // } // }); // wsManager.on('network-quality', (data) => { // console.log('Network quality changed:', data); // // 更新网络质量 // const state = store.getState(); // if (data.userId === state.session.remoteUser.id) { // state.session.remoteUser.networkQuality = data.quality; // store.notify({ type: 'NETWORK_CHANGE', quality: data.quality }); // } // }); // wsManager.on('call-ended', (data) => { // console.log('Call ended:', data); // store.endCall(); // showNotification('通话已结束', 3000); // }); // wsManager.on('call-request', (data) => { // console.log('Call request received:', data); // // 显示通话请求弹窗 // if (window.showCallRequest) { // const caller = { // name: mockCallSession.remoteUser.name, // avatar: mockCallSession.remoteUser.avatar // }; // window.showCallRequest(caller); // connectionId = data.connectionId; // } // }); // //处理发送消息响应 // wsManager.on('chat-message', (data) => { // console.log('chat-message:', data); // // 显示消息 // store.addMessage({ // data: data.message, // }); // }); } /** * 绑定DOM事件 */ function bindDomEvents() { // 切换侧边栏 window.toggleSidebar = function () { store.toggleSidebar(); }; // 切换麦克风 window.toggleMute = function (button) { const state = store.getState(); const currentState = state.session.localUser.mediaState.audio; store.updateLocalMedia('audio', !currentState); }; // 切换视频 window.toggleVideo = function (button) { const state = store.getState(); const currentState = state.session.localUser.mediaState.video; store.updateLocalMedia('video', !currentState); }; // 切换本地视频(用于悬停控制) window.toggleLocalVideo = function () { window.toggleVideo(); }; // 切换录屏 window.toggleRecording = function (button) { const state = store.getState(); const currentState = state.session.localUser.mediaState.recording || false; store.updateLocalMedia('recording', !currentState); // 显示录制状态通知 if (!currentState) { showNotification('开始录制'); } else { showNotification('停止录制'); } }; // 结束通话 window.endCall = function () { // 显示确认对话框 document.getElementById('endCallDialog').classList.remove('hidden'); }; // 取消结束通话 window.cancelEndCall = function () { document.getElementById('endCallDialog').classList.add('hidden'); }; // 确认结束通话 window.confirmEndCall = function () { document.getElementById('endCallDialog').classList.add('hidden'); store.endCall(); showNotification('通话已结束'); }; // 显示通话请求弹窗 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); }; // 发送消息 window.sendMessage = function () { const chatInput = document.getElementById('chatInput'); const content = chatInput.value.trim(); if (content) { const state = store.getState(); const message = { id: state.id, senderId: state.session.localUser.id, senderName: state.session.localUser.name, senderAvatar: state.session.localUser.avatar, content: content, type: 'text', timestamp: new Date().toISOString(), isSelf: true }; store.addMessage(message); const newMessage = { id: state.id, senderId: state.session.remoteUser.id, senderName: state.session.remoteUser.name, senderAvatar: state.session.remoteUser.avatar, content: content, type: 'text', timestamp: new Date().toISOString(), isSelf: false }; chatInput.value = ''; // 发送消息到服务器 store.sendChatMessage(newMessage); //wsManager.send('chat-message', message); } }; // 处理聊天输入回车 window.handleChatSubmit = function (event) { if (event.key === 'Enter') { window.sendMessage(); } }; // 打开图片选择器 window.openImagePicker = function () { document.getElementById('imageInput').click(); }; // 处理图片上传 window.handleImageUpload = function (event) { const file = event.target.files[0]; if (file) { // 检查文件类型 if (!file.type.startsWith('image/')) { showNotification('请选择图片文件', 3000); return; } // 检查文件大小(限制为5MB) if (file.size > 5 * 1024 * 1024) { showNotification('图片文件不能超过5MB', 3000); return; } // 读取图片文件 const reader = new FileReader(); reader.onload = function (e) { const imageUrl = e.target.result; sendImageMessage(imageUrl, file.name); }; reader.readAsDataURL(file); // 重置文件输入 event.target.value = ''; } }; // 发送图片消息 function sendImageMessage(imageUrl, fileName) { const state = store.getState(); const newMessage = { id: generateId(), senderId: state.session.localUser.id, senderName: state.session.localUser.name, senderAvatar: state.session.localUser.avatar, content: imageUrl, fileName: fileName, type: 'file', timestamp: new Date().toISOString(), isSelf: true }; store.addMessage(newMessage); // 发送消息到服务器 // wsManager.send('send-message', newMessage); } // 键盘快捷键 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); // 绑定通话请求对话框事件 if (document.getElementById('rejectCall')) { document.getElementById('rejectCall').addEventListener('click', window.rejectCall); } if (document.getElementById('acceptCall')) { document.getElementById('acceptCall').addEventListener('click', window.acceptCall); } } // 页面加载完成后初始化 window.addEventListener('DOMContentLoaded', async () => { try { // 检查本地存储中是否有连接ID const connectionId = localStorage.getItem('connectionId'); if (!connectionId) { // 如果没有连接ID,跳转到连接界面 window.location.href = './connect/connect.html'; return; } // 初始化 store //await store.init(); // 初始化渲染器 new UIRenderer(store); // 加入通话 await store.joinCall(connectionId); // 设置WebRTC连接 await store.setUp(connectionId); // 绑定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 };