Files
webRtc/WebApp/client/public/onebyone/main.js
2026-03-04 18:40:19 +08:00

364 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 主入口文件
* 初始化应用,连接各个模块
*/
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;
}
});
}
/**
* 绑定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 newMessage = {
id: generateId(),
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(newMessage);
chatInput.value = '';
// 发送消息到服务器
// wsManager.send('send-message', newMessage);
}
};
// 处理聊天输入回车
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);
}
}
/**
* 初始化WebRTC
*/
function initWebRTC() {
// 这里可以添加WebRTC初始化代码
console.log('Initializing WebRTC...');
}
// 页面加载完成后初始化
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 };