188 lines
5.9 KiB
JavaScript
188 lines
5.9 KiB
JavaScript
const DEFAULT_CALLER_NAME = '\u9080\u8bf7\u65b9';
|
|
const DEFAULT_CALLER_AVATAR = '/images/p2.png';
|
|
const DEFAULT_APPLY_REASON = '\u672a\u586b\u5199';
|
|
|
|
function readConnectionIdFromSearch(search) {
|
|
return new URLSearchParams(search).get('connectionId') || '';
|
|
}
|
|
|
|
function hideInviteDialog() {
|
|
const dialog = document.getElementById('callRequestDialog');
|
|
if (dialog) {
|
|
dialog.classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
function normalizeInviteCaller(caller = {}) {
|
|
return {
|
|
connectionId: caller.connectionId || '',
|
|
inviterSocketId: caller.inviterSocketId || '',
|
|
inviterUserId: caller.inviterUserId || '',
|
|
name: caller.name || caller.inviterName || DEFAULT_CALLER_NAME,
|
|
avatar: caller.avatar || caller.inviterAvatar || DEFAULT_CALLER_AVATAR,
|
|
applyReason: caller.applyReason || caller.reason || DEFAULT_APPLY_REASON
|
|
};
|
|
}
|
|
|
|
function renderInviteDialog(caller) {
|
|
const dialog = document.getElementById('callRequestDialog');
|
|
if (!dialog) {
|
|
return false;
|
|
}
|
|
|
|
const callRequestName = document.getElementById('callRequestName');
|
|
const callRequestAvatar = document.getElementById('callRequestAvatar');
|
|
const callRequestText = document.getElementById('callRequestText');
|
|
const callRequestReason = document.getElementById('callRequestReason');
|
|
|
|
if (callRequestName) {
|
|
callRequestName.textContent = caller.name;
|
|
}
|
|
if (callRequestAvatar) {
|
|
callRequestAvatar.src = caller.avatar;
|
|
}
|
|
if (callRequestText) {
|
|
callRequestText.textContent = caller.connectionId
|
|
? `\u6b63\u5728\u9080\u8bf7\u60a8\u52a0\u5165\u901a\u8bdd (${caller.connectionId})`
|
|
: '\u6b63\u5728\u8bf7\u6c42\u4e0e\u60a8\u8fdb\u884c\u89c6\u9891\u901a\u8bdd';
|
|
}
|
|
if (callRequestReason) {
|
|
callRequestReason.textContent = caller.applyReason;
|
|
}
|
|
|
|
dialog.classList.remove('hidden');
|
|
return true;
|
|
}
|
|
|
|
export function createInviteController({
|
|
store,
|
|
notify,
|
|
onAcceptConnection,
|
|
getCurrentView,
|
|
getConnectionId,
|
|
setConnectionId
|
|
}) {
|
|
let pendingInvite = null;
|
|
let signalHandlersBound = false;
|
|
|
|
function showCallRequestDialog(caller = {}) {
|
|
const normalizedCaller = normalizeInviteCaller(caller);
|
|
pendingInvite = normalizedCaller;
|
|
|
|
if (normalizedCaller.connectionId) {
|
|
setConnectionId(normalizedCaller.connectionId);
|
|
}
|
|
|
|
return renderInviteDialog(normalizedCaller);
|
|
}
|
|
|
|
function getInvitePayloadFromUrl(search = window.location.search) {
|
|
const params = new URLSearchParams(search);
|
|
if (params.get('invite') !== '1') {
|
|
return null;
|
|
}
|
|
|
|
return normalizeInviteCaller({
|
|
name: params.get('callerName'),
|
|
avatar: params.get('callerAvatar'),
|
|
connectionId: params.get('connectionId')
|
|
});
|
|
}
|
|
|
|
function bindSignalHandlers() {
|
|
if (signalHandlersBound) {
|
|
return;
|
|
}
|
|
|
|
store.onSocketEvent('invite-call', (payload) => {
|
|
const caller = normalizeInviteCaller(payload);
|
|
showCallRequestDialog(caller);
|
|
notify(`${caller.name} \u9080\u8bf7\u4f60\u52a0\u5165\u901a\u8bdd`);
|
|
});
|
|
|
|
signalHandlersBound = true;
|
|
}
|
|
|
|
async function acceptInvite() {
|
|
hideInviteDialog();
|
|
|
|
const targetConnectionId =
|
|
(pendingInvite && pendingInvite.connectionId) ||
|
|
getConnectionId() ||
|
|
localStorage.getItem('connectionId') ||
|
|
readConnectionIdFromSearch(window.location.search);
|
|
|
|
if (!targetConnectionId) {
|
|
notify('\u7f3a\u5c11\u8fde\u63a5ID\uff0c\u65e0\u6cd5\u63a5\u53d7\u9080\u8bf7', 'error');
|
|
return;
|
|
}
|
|
|
|
setConnectionId(targetConnectionId);
|
|
|
|
if (pendingInvite) {
|
|
try {
|
|
store.sendInviteAccepted({
|
|
connectionId: targetConnectionId,
|
|
targetSocketId: pendingInvite.inviterSocketId,
|
|
targetUserId: pendingInvite.inviterUserId
|
|
});
|
|
} catch (error) {
|
|
console.error('Error accepting invite:', error);
|
|
notify('\u63a5\u53d7\u9080\u8bf7\u5931\u8d25\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5', 'error');
|
|
return;
|
|
}
|
|
}
|
|
|
|
pendingInvite = null;
|
|
notify('\u5df2\u63a5\u53d7\u901a\u8bdd\u8bf7\u6c42');
|
|
|
|
if (getCurrentView() !== 'call') {
|
|
await onAcceptConnection(targetConnectionId);
|
|
}
|
|
}
|
|
|
|
function rejectInvite() {
|
|
hideInviteDialog();
|
|
|
|
if (pendingInvite) {
|
|
try {
|
|
store.sendInviteRejected({
|
|
connectionId: pendingInvite.connectionId,
|
|
targetSocketId: pendingInvite.inviterSocketId,
|
|
targetUserId: pendingInvite.inviterUserId
|
|
});
|
|
} catch (error) {
|
|
console.error('Error rejecting invite:', error);
|
|
}
|
|
}
|
|
|
|
pendingInvite = null;
|
|
notify('\u5df2\u62d2\u7edd\u901a\u8bdd\u8bf7\u6c42');
|
|
}
|
|
|
|
function bindDialogEvents() {
|
|
window.showCallRequest = showCallRequestDialog;
|
|
window.rejectCall = rejectInvite;
|
|
window.acceptCall = acceptInvite;
|
|
|
|
const rejectCallButton = document.getElementById('rejectCall');
|
|
const acceptCallButton = document.getElementById('acceptCall');
|
|
|
|
if (rejectCallButton && !rejectCallButton.dataset.bound) {
|
|
rejectCallButton.addEventListener('click', rejectInvite);
|
|
rejectCallButton.dataset.bound = 'true';
|
|
}
|
|
if (acceptCallButton && !acceptCallButton.dataset.bound) {
|
|
acceptCallButton.addEventListener('click', acceptInvite);
|
|
acceptCallButton.dataset.bound = 'true';
|
|
}
|
|
}
|
|
|
|
return {
|
|
bindDialogEvents,
|
|
bindSignalHandlers,
|
|
getInvitePayloadFromUrl,
|
|
showCallRequestDialog
|
|
};
|
|
}
|