Browse Source

移动端:视频区域在消息上方(flex-col布局)
桌面端:视频区域在消息左方(flex-row布局)
使用Tailwind响应式类(md:前缀)实现不同屏幕尺寸的自动切换

yourname 7 months ago
parent
commit
64a25c8182
1 changed files with 97 additions and 102 deletions
  1. 97 102
      client/mobile/components/Classroom/ClassroomLayout.tsx

+ 97 - 102
client/mobile/components/Classroom/ClassroomLayout.tsx

@@ -37,127 +37,122 @@ export const ClassroomLayout = ({ children, role }: ClassroomLayoutProps) => {
   } = useClassroomContext();
 
   return (
-    <div className="flex flex-col h-screen bg-gray-100">
-      <div className="flex-1 flex">
-        {/* 视频区域 */}
-        {showVideo && (
-          <div className="flex-1 p-4">
-            <div className="bg-white rounded-lg shadow p-4 h-full">
-              <div
-                id="remoteVideoContainer"
-                ref={remoteVideoContainer}
-                className="grid grid-cols-1 md:grid-cols-2 gap-4"
-              >
-                {/* 远程视频将在这里动态添加 */}
-              </div>
+    <div className="flex flex-col md:flex-row h-screen bg-gray-100">
+      {/* 视频区域 */}
+      {showVideo && (
+        <div className="flex-1 p-4">
+          <div className="bg-white rounded-lg shadow p-4 h-full">
+            <div
+              id="remoteVideoContainer"
+              ref={remoteVideoContainer}
+              className="grid grid-cols-1 md:grid-cols-2 gap-4"
+            >
+              {/* 远程视频将在这里动态添加 */}
             </div>
           </div>
-        )}
-
-        {/* 消息和控制面板列 */}
-        <div className={`${showVideo ? 'w-96' : 'flex-1'} flex flex-col`}>
-
+        </div>
+      )}
 
-          {/* 消息区域 */}
-          <div className="bg-white shadow-lg p-4">
-            <div className="h-full flex flex-col">
-              {/* 消息列表 */}
-              <div className="flex-1 overflow-y-auto mb-1">
-                {messageList.map((msg, i) => (
-                  <div key={i} className="text-sm mb-1">{msg}</div>
-                ))}
-              </div>
+      {/* 消息和控制面板列 */}
+      <div className={`${showVideo ? 'w-full md:w-96' : 'flex-1'} flex flex-col`}>
+        {/* 消息区域 */}
+        <div className="bg-white shadow-lg p-4">
+          <div className="h-full flex flex-col">
+            {/* 消息列表 */}
+            <div className="flex-1 overflow-y-auto mb-1">
+              {messageList.map((msg, i) => (
+                <div key={i} className="text-sm mb-1">{msg}</div>
+              ))}
+            </div>
 
-              {/* 控制面板 */}
-              <div className="bg-white shadow-lg p-2 flex flex-col gap-3 mb-1 border-b border-gray-200">
-                <div className="flex flex-wrap gap-2">
-                  {role === Role.Teacher && (
-                    <button
-                      onClick={() => setShowVideo(!showVideo)}
-                      className={`p-2 rounded-full ${showVideo ? 'bg-gray-500' : 'bg-gray-300'} text-white`}
-                      title={showVideo ? '隐藏视频' : '显示视频'}
-                    >
-                      <VideoCameraIcon className="w-4 h-4" />
-                    </button>
-                  )}
+            {/* 控制面板 */}
+            <div className="bg-white shadow-lg p-2 flex flex-col gap-3 mb-1 border-b border-gray-200">
+              <div className="flex flex-wrap gap-2">
+                {role === Role.Teacher && (
                   <button
-                    onClick={toggleCamera}
-                    className={`p-2 rounded-full ${isCameraOn ? 'bg-green-500' : 'bg-red-500'} text-white`}
-                    title={isCameraOn ? '关闭摄像头' : '开启摄像头'}
+                    onClick={() => setShowVideo(!showVideo)}
+                    className={`p-2 rounded-full ${showVideo ? 'bg-gray-500' : 'bg-gray-300'} text-white`}
+                    title={showVideo ? '隐藏视频' : '显示视频'}
                   >
-                    <CameraIcon className="w-4 h-4" />
+                    <VideoCameraIcon className="w-4 h-4" />
                   </button>
+                )}
+                <button
+                  onClick={toggleCamera}
+                  className={`p-2 rounded-full ${isCameraOn ? 'bg-green-500' : 'bg-red-500'} text-white`}
+                  title={isCameraOn ? '关闭摄像头' : '开启摄像头'}
+                >
+                  <CameraIcon className="w-4 h-4" />
+                </button>
+                <button
+                  onClick={toggleAudio}
+                  className={`p-2 rounded-full ${isAudioOn ? 'bg-green-500' : 'bg-red-500'} text-white`}
+                  title={isAudioOn ? '关闭麦克风' : '开启麦克风'}
+                >
+                  <MicrophoneIcon className="w-4 h-4" />
+                </button>
+                {role === Role.Teacher && (
                   <button
-                    onClick={toggleAudio}
-                    className={`p-2 rounded-full ${isAudioOn ? 'bg-green-500' : 'bg-red-500'} text-white`}
-                    title={isAudioOn ? '关闭麦克风' : '开启麦克风'}
+                    onClick={toggleScreenShare}
+                    className={`p-2 rounded-full ${isScreenSharing ? 'bg-green-500' : 'bg-blue-500'} text-white`}
+                    title={isScreenSharing ? '停止共享' : '共享屏幕'}
                   >
-                    <MicrophoneIcon className="w-4 h-4" />
+                    <ShareIcon className="w-4 h-4" />
                   </button>
-                  {role === Role.Teacher && (
-                    <button
-                      onClick={toggleScreenShare}
-                      className={`p-2 rounded-full ${isScreenSharing ? 'bg-green-500' : 'bg-blue-500'} text-white`}
-                      title={isScreenSharing ? '停止共享' : '共享屏幕'}
-                    >
-                      <ShareIcon className="w-4 h-4" />
-                    </button>
-                  )}
-                  {role === Role.Teacher && shareLink && (
+                )}
+                {role === Role.Teacher && shareLink && (
+                  <button
+                    onClick={() => setShowShareLink(!showShareLink)}
+                    className="p-2 rounded-full bg-blue-500 text-white"
+                    title="分享链接"
+                  >
+                    <ClipboardDocumentIcon className="w-4 h-4" />
+                  </button>
+                )}
+              </div>
+
+              {showShareLink && shareLink && (
+                <div className="bg-blue-50 p-2 rounded">
+                  <div className="flex items-center gap-1">
+                    <input
+                      type="text"
+                      value={shareLink}
+                      readOnly
+                      className="flex-1 text-xs border rounded px-2 py-1 truncate"
+                    />
                     <button
-                      onClick={() => setShowShareLink(!showShareLink)}
-                      className="p-2 rounded-full bg-blue-500 text-white"
-                      title="分享链接"
+                      onClick={() => navigator.clipboard.writeText(shareLink)}
+                      className="p-2 bg-blue-500 text-white rounded"
+                      title="复制链接"
                     >
                       <ClipboardDocumentIcon className="w-4 h-4" />
                     </button>
-                  )}
-                </div>
-
-                {showShareLink && shareLink && (
-                  <div className="bg-blue-50 p-2 rounded">
-                    <div className="flex items-center gap-1">
-                      <input
-                        type="text"
-                        value={shareLink}
-                        readOnly
-                        className="flex-1 text-xs border rounded px-2 py-1 truncate"
-                      />
-                      <button
-                        onClick={() => navigator.clipboard.writeText(shareLink)}
-                        className="p-2 bg-blue-500 text-white rounded"
-                        title="复制链接"
-                      >
-                        <ClipboardDocumentIcon className="w-4 h-4" />
-                      </button>
-                    </div>
                   </div>
-                )}
-                
-                {/* 角色特定内容 */}
-                <div className="flex-1 overflow-y-auto">
-                  {children}
                 </div>
-
-              </div>
-              <div className="relative">
-                <textarea
-                  value={msgText}
-                  onChange={(e) => setMsgText(e.target.value)}
-                  className="w-full border rounded px-2 py-1 pr-10"
-                  placeholder="输入消息..."
-                  rows={3}
-                />
-                <button
-                  onClick={sendMessage}
-                  className="absolute right-2 bottom-2 p-1 bg-blue-500 text-white rounded-full"
-                >
-                  <PaperAirplaneIcon className="w-4 h-4" />
-                </button>
+              )}
+              
+              {/* 角色特定内容 */}
+              <div className="flex-1 overflow-y-auto">
+                {children}
               </div>
             </div>
-          </div>
 
+            <div className="relative">
+              <textarea
+                value={msgText}
+                onChange={(e) => setMsgText(e.target.value)}
+                className="w-full border rounded px-2 py-1 pr-10"
+                placeholder="输入消息..."
+                rows={3}
+              />
+              <button
+                onClick={sendMessage}
+                className="absolute right-2 bottom-2 p-1 bg-blue-500 text-white rounded-full"
+              >
+                <PaperAirplaneIcon className="w-4 h-4" />
+              </button>
+            </div>
+          </div>
         </div>
       </div>
     </div>