建房预检测
This commit is contained in:
@@ -8,12 +8,41 @@ import { useEffect,useState } from 'react';
|
||||
import { getAuthInfoFromBrowserCookie } from '@/lib/auth';
|
||||
|
||||
import PageLayout from '@/components/PageLayout';
|
||||
import Toast, { ToastProps } from '@/components/Toast';
|
||||
import { useWatchRoomContext } from '@/components/WatchRoomProvider';
|
||||
|
||||
import type { Room, RoomType } from '@/types/watch-room';
|
||||
|
||||
type TabType = 'create' | 'join' | 'list';
|
||||
|
||||
function getScreenShareHostSupportError() {
|
||||
if (typeof window === 'undefined') return null;
|
||||
|
||||
if (!window.isSecureContext) {
|
||||
return '当前环境不是安全上下文(HTTPS/localhost),不支持屏幕共享';
|
||||
}
|
||||
|
||||
if (!navigator.mediaDevices?.getDisplayMedia) {
|
||||
return '当前浏览器不支持屏幕共享';
|
||||
}
|
||||
|
||||
if (typeof window.RTCPeerConnection === 'undefined') {
|
||||
return '当前浏览器不支持实时屏幕传输';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getScreenShareViewerSupportError() {
|
||||
if (typeof window === 'undefined') return null;
|
||||
|
||||
if (typeof window.RTCPeerConnection === 'undefined') {
|
||||
return '当前浏览器不支持实时屏幕传输';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default function WatchRoomPage() {
|
||||
const router = useRouter();
|
||||
const watchRoom = useWatchRoomContext();
|
||||
@@ -48,6 +77,16 @@ export default function WatchRoomPage() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [createLoading, setCreateLoading] = useState(false);
|
||||
const [joinLoading, setJoinLoading] = useState(false);
|
||||
const [toast, setToast] = useState<ToastProps | null>(null);
|
||||
|
||||
const showToast = (message: string, type: ToastProps['type'] = 'info') => {
|
||||
setToast({
|
||||
message,
|
||||
type,
|
||||
duration: 3000,
|
||||
onClose: () => setToast(null),
|
||||
});
|
||||
};
|
||||
|
||||
// 加载房间列表
|
||||
const loadRooms = async (showLoading = false) => {
|
||||
@@ -82,10 +121,18 @@ export default function WatchRoomPage() {
|
||||
const handleCreateRoom = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!createForm.roomName.trim()) {
|
||||
alert('请输入房间名称');
|
||||
showToast('请输入房间名称', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (createForm.roomType === 'screen') {
|
||||
const supportError = getScreenShareHostSupportError();
|
||||
if (supportError) {
|
||||
showToast(`当前设备无法创建屏幕共享房间:${supportError}`, 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setCreateLoading(true);
|
||||
try {
|
||||
await createRoom({
|
||||
@@ -106,7 +153,7 @@ export default function WatchRoomPage() {
|
||||
roomType: 'sync',
|
||||
});
|
||||
} catch (error: any) {
|
||||
alert(error.message || '创建房间失败');
|
||||
showToast(error.message || '创建房间失败', 'error');
|
||||
} finally {
|
||||
setCreateLoading(false);
|
||||
}
|
||||
@@ -117,10 +164,19 @@ export default function WatchRoomPage() {
|
||||
e.preventDefault();
|
||||
const targetRoomId = roomId || joinForm.roomId.trim().toUpperCase();
|
||||
if (!targetRoomId) {
|
||||
alert('请输入房间ID');
|
||||
showToast('请输入房间ID', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const targetRoom = rooms.find((room) => room.id === targetRoomId);
|
||||
if (targetRoom?.roomType === 'screen') {
|
||||
const supportError = getScreenShareViewerSupportError();
|
||||
if (supportError) {
|
||||
showToast(`当前设备无法加入屏幕共享房间:${supportError}`, 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setJoinLoading(true);
|
||||
try {
|
||||
const result = await joinRoom({
|
||||
@@ -138,7 +194,7 @@ export default function WatchRoomPage() {
|
||||
// 注意:加入房间后,isOwner 状态会在 useWatchRoom 中更新
|
||||
// 跳转逻辑会在 useEffect 中处理
|
||||
} catch (error: any) {
|
||||
alert(error.message || '加入房间失败');
|
||||
showToast(error.message || '加入房间失败', 'error');
|
||||
} finally {
|
||||
setJoinLoading(false);
|
||||
}
|
||||
@@ -219,6 +275,14 @@ export default function WatchRoomPage() {
|
||||
|
||||
// 从房间列表加入房间
|
||||
const handleJoinFromList = (room: Room) => {
|
||||
if (room.roomType === 'screen') {
|
||||
const supportError = getScreenShareViewerSupportError();
|
||||
if (supportError) {
|
||||
showToast(`当前设备无法加入屏幕共享房间:${supportError}`, 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setJoinForm({
|
||||
roomId: room.id,
|
||||
password: '',
|
||||
@@ -810,6 +874,7 @@ export default function WatchRoomPage() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{toast && <Toast {...toast} />}
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,17 +3,47 @@
|
||||
import { Monitor, MonitorPlay, Users } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import Toast, { ToastProps } from '@/components/Toast';
|
||||
import { useWatchRoomContext } from '@/components/WatchRoomProvider';
|
||||
import { useScreenShare } from '@/hooks/useScreenShare';
|
||||
|
||||
const NEW_TAB_KEY_PREFIX = 'watch_room_screen_home_opened_';
|
||||
|
||||
function getScreenShareHostSupportError() {
|
||||
if (typeof window === 'undefined') return null;
|
||||
|
||||
if (!window.isSecureContext) {
|
||||
return '当前环境不是安全上下文(HTTPS/localhost),不支持屏幕共享';
|
||||
}
|
||||
|
||||
if (!navigator.mediaDevices?.getDisplayMedia) {
|
||||
return '当前浏览器不支持屏幕共享';
|
||||
}
|
||||
|
||||
if (typeof window.RTCPeerConnection === 'undefined') {
|
||||
return '当前浏览器不支持实时屏幕传输';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getScreenShareViewerSupportError() {
|
||||
if (typeof window === 'undefined') return null;
|
||||
|
||||
if (typeof window.RTCPeerConnection === 'undefined') {
|
||||
return '当前浏览器不支持实时屏幕传输';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default function WatchRoomScreenPage() {
|
||||
const router = useRouter();
|
||||
const watchRoom = useWatchRoomContext();
|
||||
const { currentRoom, members, leaveRoom } = watchRoom;
|
||||
const [toast, setToast] = useState<ToastProps | null>(null);
|
||||
const {
|
||||
currentRoom: screenRoom,
|
||||
isOwner,
|
||||
@@ -26,6 +56,15 @@ export default function WatchRoomScreenPage() {
|
||||
stopSharing,
|
||||
} = useScreenShare();
|
||||
|
||||
const showToast = (message: string, type: ToastProps['type'] = 'info') => {
|
||||
setToast({
|
||||
message,
|
||||
type,
|
||||
duration: 3000,
|
||||
onClose: () => setToast(null),
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentRoom) {
|
||||
router.replace('/watch-room');
|
||||
@@ -37,6 +76,19 @@ export default function WatchRoomScreenPage() {
|
||||
}
|
||||
}, [currentRoom, router]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!screenRoom || screenRoom.roomType !== 'screen') return;
|
||||
|
||||
const supportError = isOwner
|
||||
? getScreenShareHostSupportError()
|
||||
: getScreenShareViewerSupportError();
|
||||
if (supportError) {
|
||||
showToast(`当前设备无法使用屏幕共享房间:${supportError}`, 'error');
|
||||
leaveRoom();
|
||||
router.replace('/watch-room');
|
||||
}
|
||||
}, [isOwner, leaveRoom, router, screenRoom?.id, screenRoom?.roomType]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!screenRoom || !isOwner) return;
|
||||
|
||||
@@ -196,6 +248,7 @@ export default function WatchRoomScreenPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{toast && <Toast {...toast} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user