|
|
@@ -0,0 +1,117 @@
|
|
|
+import React, { useState, useEffect } from 'react';
|
|
|
+import { useClassroomContext } from './ClassroomProvider';
|
|
|
+import { Button } from '@/client/components/ui/button';
|
|
|
+import { Role } from './useClassroom';
|
|
|
+import { SpeakerXMarkIcon } from '@heroicons/react/24/outline';
|
|
|
+import {
|
|
|
+ AlertDialog,
|
|
|
+ AlertDialogAction,
|
|
|
+ AlertDialogCancel,
|
|
|
+ AlertDialogContent,
|
|
|
+ AlertDialogDescription,
|
|
|
+ AlertDialogFooter,
|
|
|
+ AlertDialogHeader,
|
|
|
+ AlertDialogTitle,
|
|
|
+} from '@/client/components/ui/alert-dialog';
|
|
|
+
|
|
|
+export const AllMuteToggleButton: React.FC = () => {
|
|
|
+ const { role, muteAllIM, unmuteAllIM, classId, checkAllMuteStatus } = useClassroomContext();
|
|
|
+ const [isAllMuted, setIsAllMuted] = useState(false);
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
+
|
|
|
+ // 组件挂载时查询全员禁言状态
|
|
|
+ useEffect(() => {
|
|
|
+ const fetchAllMuteStatus = async () => {
|
|
|
+ if (!classId) return;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const muted = await checkAllMuteStatus();
|
|
|
+ setIsAllMuted(muted);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('查询全员禁言状态失败:', error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ fetchAllMuteStatus();
|
|
|
+ }, [classId, checkAllMuteStatus]);
|
|
|
+ const [confirmDialog, setConfirmDialog] = useState<{
|
|
|
+ open: boolean;
|
|
|
+ action: 'muteAll' | 'unmuteAll' | null;
|
|
|
+ }>({
|
|
|
+ open: false,
|
|
|
+ action: null,
|
|
|
+ });
|
|
|
+
|
|
|
+ // 只有老师才能看到全员禁言按钮
|
|
|
+ if (role !== Role.Teacher) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleToggleAllMute = async () => {
|
|
|
+ if (loading || !classId) return;
|
|
|
+
|
|
|
+ setLoading(true);
|
|
|
+ try {
|
|
|
+ if (isAllMuted) {
|
|
|
+ await unmuteAllIM();
|
|
|
+ setIsAllMuted(false);
|
|
|
+ } else {
|
|
|
+ await muteAllIM();
|
|
|
+ setIsAllMuted(true);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('切换全员禁言状态失败:', error);
|
|
|
+ } finally {
|
|
|
+ setLoading(false);
|
|
|
+ setConfirmDialog({ open: false, action: null });
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const openConfirmDialog = (action: 'muteAll' | 'unmuteAll') => {
|
|
|
+ setConfirmDialog({
|
|
|
+ open: true,
|
|
|
+ action,
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleCancel = () => {
|
|
|
+ setConfirmDialog({ open: false, action: null });
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Button
|
|
|
+ onClick={() => openConfirmDialog(isAllMuted ? 'unmuteAll' : 'muteAll')}
|
|
|
+ className={`p-2 rounded-full ${
|
|
|
+ isAllMuted
|
|
|
+ ? 'bg-green-500 text-white hover:bg-green-600'
|
|
|
+ : 'bg-red-500 text-white hover:bg-red-600'
|
|
|
+ } transition-colors`}
|
|
|
+ disabled={loading}
|
|
|
+ title={isAllMuted ? '取消全员禁言(IM聊天)' : '全员禁言(IM聊天)'}
|
|
|
+ size="icon"
|
|
|
+ variant="ghost"
|
|
|
+ >
|
|
|
+ <SpeakerXMarkIcon className="w-4 h-4" />
|
|
|
+ </Button>
|
|
|
+
|
|
|
+ <AlertDialog open={confirmDialog.open} onOpenChange={(open) => !open && handleCancel()}>
|
|
|
+ <AlertDialogContent>
|
|
|
+ <AlertDialogHeader>
|
|
|
+ <AlertDialogTitle>操作确认</AlertDialogTitle>
|
|
|
+ <AlertDialogDescription>
|
|
|
+ {confirmDialog.action === 'muteAll' && '确定要对所有学生进行全员禁言吗?(IM聊天)'}
|
|
|
+ {confirmDialog.action === 'unmuteAll' && '确定要取消全员禁言吗?(IM聊天)'}
|
|
|
+ </AlertDialogDescription>
|
|
|
+ </AlertDialogHeader>
|
|
|
+ <AlertDialogFooter>
|
|
|
+ <AlertDialogCancel>取消</AlertDialogCancel>
|
|
|
+ <AlertDialogAction onClick={handleToggleAllMute}>
|
|
|
+ 确定
|
|
|
+ </AlertDialogAction>
|
|
|
+ </AlertDialogFooter>
|
|
|
+ </AlertDialogContent>
|
|
|
+ </AlertDialog>
|
|
|
+ </>
|
|
|
+ );
|
|
|
+};
|