Files
MoonTVPlus/src/app/watch-room/screen/page.tsx
T
2026-04-05 00:15:53 +08:00

202 lines
7.4 KiB
TypeScript

'use client';
import { Monitor, MonitorPlay, Users } from 'lucide-react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { useWatchRoomContext } from '@/components/WatchRoomProvider';
import { useScreenShare } from '@/hooks/useScreenShare';
const NEW_TAB_KEY_PREFIX = 'watch_room_screen_home_opened_';
export default function WatchRoomScreenPage() {
const router = useRouter();
const watchRoom = useWatchRoomContext();
const { currentRoom, members, leaveRoom } = watchRoom;
const {
currentRoom: screenRoom,
isOwner,
isSharing,
isStarting,
error,
localVideoRef,
remoteVideoRef,
startSharing,
stopSharing,
} = useScreenShare();
useEffect(() => {
if (!currentRoom) {
router.replace('/watch-room');
return;
}
if (currentRoom.roomType !== 'screen') {
router.replace('/watch-room');
}
}, [currentRoom, router]);
useEffect(() => {
if (!screenRoom || !isOwner) return;
const key = `${NEW_TAB_KEY_PREFIX}${screenRoom.id}`;
if (sessionStorage.getItem(key)) return;
sessionStorage.setItem(key, '1');
window.open('/?watchRoomNoConnect=1', '_blank', 'noopener,noreferrer');
}, [isOwner, screenRoom?.id]);
if (!screenRoom || screenRoom.roomType !== 'screen') {
return null;
}
const handleLeave = () => {
if (isOwner && isSharing) {
stopSharing(true);
}
leaveRoom();
router.push('/watch-room');
};
return (
<div className='min-h-screen bg-white text-gray-900 dark:bg-black dark:text-gray-200'>
<div className='mx-auto flex min-h-screen max-w-7xl flex-col gap-4 px-4 py-4 lg:px-8'>
<div className='flex items-center justify-between gap-4 rounded-2xl border border-gray-200 bg-white/90 px-5 py-4 shadow-sm dark:border-gray-800 dark:bg-gray-900/80'>
<div>
<h1 className='flex items-center gap-2 text-2xl font-semibold'>
<Monitor className='h-6 w-6 text-blue-500' />
屏幕共享观影室
</h1>
<p className='mt-1 text-sm text-gray-600 dark:text-gray-400'>
房间:{screenRoom.name} · 房主:{screenRoom.ownerName}
</p>
</div>
<div className='flex items-center gap-2'>
{isOwner && (
<Link
href='/?watchRoomNoConnect=1'
target='_blank'
rel='noreferrer'
className='rounded-lg bg-blue-500 px-4 py-2 text-white'
>
新开主页
</Link>
)}
<button
onClick={handleLeave}
className='rounded-lg bg-gray-200 px-4 py-2 text-gray-900 dark:bg-gray-700 dark:text-gray-100'
>
离开房间
</button>
</div>
</div>
<div className='grid flex-1 grid-cols-1 gap-4 xl:grid-cols-[1fr_320px]'>
<div className='relative flex min-h-[420px] items-center justify-center overflow-hidden rounded-2xl border border-gray-200 bg-black dark:border-gray-800'>
{isOwner ? (
<video
ref={localVideoRef}
autoPlay
muted
playsInline
className='h-full w-full bg-black object-contain'
/>
) : (
<video
ref={remoteVideoRef}
autoPlay
playsInline
controls
className='h-full w-full bg-black object-contain'
/>
)}
{!isSharing && (
<div className='absolute px-6 text-center text-white'>
<MonitorPlay className='mx-auto mb-3 h-12 w-12 text-white/70' />
<p className='text-lg font-medium'>
{isOwner ? '点击开始共享,向房员推送浏览器画面' : '等待房主开始共享屏幕'}
</p>
{isOwner && (
<p className='mt-2 text-sm text-white/70'>
本页不要关闭;已尝试为你新开一个主页标签页方便继续浏览。
</p>
)}
</div>
)}
</div>
<div className='space-y-4'>
<div className='rounded-xl border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900'>
<h2 className='mb-3 font-semibold'>共享状态</h2>
<div className='space-y-2 text-sm text-gray-600 dark:text-gray-400'>
<p>类型:屏幕共享</p>
<p>状态:{isSharing ? '共享中' : '未开始'}</p>
<p>成员:{members.length} </p>
</div>
{error && (
<div className='mt-3 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-300'>
{error}
</div>
)}
<div className='mt-4 flex gap-3'>
{isOwner ? (
<>
<button
onClick={() => startSharing()}
disabled={isStarting || isSharing}
className='flex-1 rounded-lg bg-blue-500 px-4 py-2 text-white disabled:bg-gray-400'
>
{isStarting ? '启动中...' : isSharing ? '共享中' : '开始共享'}
</button>
<button
onClick={() => stopSharing(true)}
disabled={!isSharing}
className='rounded-lg bg-red-500 px-4 py-2 text-white disabled:bg-gray-400'
>
停止
</button>
</>
) : (
<div className='rounded-lg bg-blue-50 px-3 py-2 text-sm text-blue-700 dark:bg-blue-900/20 dark:text-blue-300'>
房员无需操作,房主开始共享后会自动显示画面。
</div>
)}
</div>
</div>
<div className='rounded-xl border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900'>
<h2 className='mb-3 flex items-center gap-2 font-semibold'>
<Users className='h-4 w-4' />
房间成员
</h2>
<div className='space-y-2'>
{members.map((member) => (
<div
key={member.id}
className='flex items-center justify-between rounded-lg bg-gray-50 px-3 py-2 dark:bg-gray-800/70'
>
<span className='text-sm'>{member.name}</span>
{member.isOwner && (
<span className='rounded bg-yellow-100 px-2 py-1 text-xs text-yellow-800 dark:bg-yellow-900/20 dark:text-yellow-300'>
房主
</span>
)}
</div>
))}
</div>
</div>
<div className='rounded-xl border border-blue-200 bg-blue-50 p-4 text-sm text-blue-800 dark:border-blue-800 dark:bg-blue-900/20 dark:text-blue-200'>
本页不再包裹站点导航,便于直接共享。建议使用桌面版 Chrome / Edge,并优先共享标签页。
</div>
</div>
</div>
</div>
</div>
);
}