2025-12-06 23:02:49 +08:00
|
|
|
|
|
2025-12-03 12:56:57 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<router-view />
|
2025-12-03 15:33:48 +08:00
|
|
|
|
<Toast />
|
2025-12-06 23:02:49 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 1v1 通话窗口 -->
|
2025-12-04 12:46:15 +08:00
|
|
|
|
<CallWindow
|
|
|
|
|
|
v-if="webrtcStore.webrtc?.call?.active"
|
|
|
|
|
|
:call="webrtcStore.webrtc.call"
|
|
|
|
|
|
:target="chatStore.currentTarget"
|
|
|
|
|
|
:is-mobile="isMobile"
|
|
|
|
|
|
:local-stream="localStream"
|
|
|
|
|
|
:remote-stream="remoteStream"
|
|
|
|
|
|
@end-call="webrtcStore.webrtc.endCall"
|
|
|
|
|
|
@accept-call="webrtcStore.webrtc.acceptCall"
|
|
|
|
|
|
@toggle-mute="webrtcStore.webrtc.toggleMute"
|
|
|
|
|
|
@toggle-camera="webrtcStore.webrtc.toggleCamera"
|
|
|
|
|
|
@toggle-minimize="webrtcStore.webrtc.call.minimized = !webrtcStore.webrtc.call.minimized"
|
|
|
|
|
|
/>
|
2025-12-06 23:02:49 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 群通话窗口 (已加入时显示) -->
|
|
|
|
|
|
<!-- 修复点:使用 joined 判断,或者 isActive -->
|
|
|
|
|
|
<GroupCallWindow
|
|
|
|
|
|
v-if="groupWebRTC.callState.joined"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 群通话邀请弹窗 (未加入且收到邀请时显示) -->
|
|
|
|
|
|
<GroupCallIncoming
|
|
|
|
|
|
v-if="groupWebRTC.callState.incoming"
|
|
|
|
|
|
/>
|
2025-12-03 12:56:57 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2025-12-04 12:46:15 +08:00
|
|
|
|
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
2025-12-03 15:33:48 +08:00
|
|
|
|
import Toast from '@/components/common/Toast.vue'
|
2025-12-04 12:46:15 +08:00
|
|
|
|
import CallWindow from '@/components/call/CallWindow.vue'
|
2025-12-06 23:02:49 +08:00
|
|
|
|
import GroupCallWindow from '@/components/chat/GroupCallWindow.vue'
|
|
|
|
|
|
import GroupCallIncoming from '@/components/chat/GroupCallIncoming.vue'
|
2025-12-04 12:46:15 +08:00
|
|
|
|
import { useWebRTCStore } from '@/stores/webrtc'
|
|
|
|
|
|
import { useChatStore } from '@/stores/chat'
|
2025-12-08 09:07:56 +08:00
|
|
|
|
import { useMomentStore } from '@/stores/moment'
|
2025-12-06 23:02:49 +08:00
|
|
|
|
import { useGroupWebRTC } from '@/composables/useGroupWebRTC'
|
2025-12-08 09:07:56 +08:00
|
|
|
|
import { wsManager } from '@/api/websocket'
|
|
|
|
|
|
import type { MomentNotifPayload } from '@/types/moment'
|
2025-12-04 12:46:15 +08:00
|
|
|
|
|
|
|
|
|
|
const webrtcStore = useWebRTCStore()
|
|
|
|
|
|
const chatStore = useChatStore()
|
2025-12-08 09:07:56 +08:00
|
|
|
|
const momentStore = useMomentStore()
|
2025-12-06 23:02:49 +08:00
|
|
|
|
const groupWebRTC = useGroupWebRTC()
|
2025-12-04 12:46:15 +08:00
|
|
|
|
const isMobile = ref(window.innerWidth < 768)
|
|
|
|
|
|
|
2025-12-06 23:02:49 +08:00
|
|
|
|
const localStream = computed(() => webrtcStore.webrtc?.localStream ?? null)
|
|
|
|
|
|
const remoteStream = computed(() => webrtcStore.webrtc?.remoteStream ?? null)
|
2025-12-03 12:56:57 +08:00
|
|
|
|
|
2025-12-04 12:46:15 +08:00
|
|
|
|
const handleResize = () => {
|
|
|
|
|
|
isMobile.value = window.innerWidth < 768
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-08 09:07:56 +08:00
|
|
|
|
// 朋友圈通知处理器
|
|
|
|
|
|
const handleMomentNotification = (payload: MomentNotifPayload) => {
|
|
|
|
|
|
momentStore.handleWsNotification(payload)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-04 12:46:15 +08:00
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
window.addEventListener('resize', handleResize)
|
2025-12-06 23:02:49 +08:00
|
|
|
|
// 确保监听启动
|
|
|
|
|
|
groupWebRTC.initListener()
|
2025-12-08 09:07:56 +08:00
|
|
|
|
// 注册朋友圈通知处理器
|
|
|
|
|
|
wsManager.onMomentNotification(handleMomentNotification)
|
2025-12-04 12:46:15 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
window.removeEventListener('resize', handleResize)
|
2025-12-08 09:07:56 +08:00
|
|
|
|
// 移除朋友圈通知处理器
|
|
|
|
|
|
wsManager.offMomentNotification(handleMomentNotification)
|
2025-12-04 12:46:15 +08:00
|
|
|
|
})
|
|
|
|
|
|
</script>
|