133 lines
3.7 KiB
JavaScript
133 lines
3.7 KiB
JavaScript
// src/components/ConnectionStatusBar/index.js
|
|
/**
|
|
* Socket 连接状态栏组件
|
|
* 显示 Socket 连接状态并提供重试功能
|
|
*/
|
|
|
|
import React from 'react';
|
|
import {
|
|
Alert,
|
|
AlertIcon,
|
|
AlertTitle,
|
|
AlertDescription,
|
|
Button,
|
|
CloseButton,
|
|
Box,
|
|
HStack,
|
|
useColorModeValue,
|
|
Slide,
|
|
} from '@chakra-ui/react';
|
|
import { MdRefresh } from 'react-icons/md';
|
|
|
|
/**
|
|
* 连接状态枚举
|
|
*/
|
|
export const CONNECTION_STATUS = {
|
|
CONNECTED: 'connected', // 已连接
|
|
DISCONNECTED: 'disconnected', // 已断开
|
|
RECONNECTING: 'reconnecting', // 重连中
|
|
FAILED: 'failed', // 连接失败
|
|
};
|
|
|
|
/**
|
|
* 连接状态栏组件
|
|
*/
|
|
const ConnectionStatusBar = ({
|
|
status = CONNECTION_STATUS.CONNECTED,
|
|
reconnectAttempt = 0,
|
|
maxReconnectAttempts = 5,
|
|
onRetry,
|
|
onClose,
|
|
}) => {
|
|
// 仅在非正常状态时显示
|
|
const shouldShow = status !== CONNECTION_STATUS.CONNECTED;
|
|
|
|
// 状态配置
|
|
const statusConfig = {
|
|
[CONNECTION_STATUS.DISCONNECTED]: {
|
|
status: 'warning',
|
|
title: '连接已断开',
|
|
description: '正在尝试重新连接...',
|
|
},
|
|
[CONNECTION_STATUS.RECONNECTING]: {
|
|
status: 'warning',
|
|
title: '正在重新连接',
|
|
description: `尝试重连中 (第 ${reconnectAttempt}/${maxReconnectAttempts} 次)`,
|
|
},
|
|
[CONNECTION_STATUS.FAILED]: {
|
|
status: 'error',
|
|
title: '连接失败',
|
|
description: '无法连接到服务器,请检查网络连接',
|
|
},
|
|
};
|
|
|
|
const config = statusConfig[status] || statusConfig[CONNECTION_STATUS.DISCONNECTED];
|
|
|
|
// 颜色配置
|
|
const bg = useColorModeValue(
|
|
{
|
|
warning: 'orange.50',
|
|
error: 'red.50',
|
|
}[config.status],
|
|
{
|
|
warning: 'orange.900',
|
|
error: 'red.900',
|
|
}[config.status]
|
|
);
|
|
|
|
return (
|
|
<Slide
|
|
direction="top"
|
|
in={shouldShow}
|
|
style={{ zIndex: 10000 }}
|
|
>
|
|
<Alert
|
|
status={config.status}
|
|
variant="subtle"
|
|
bg={bg}
|
|
borderBottom="1px solid"
|
|
borderColor={useColorModeValue('gray.200', 'gray.700')}
|
|
py={3}
|
|
px={{ base: 4, md: 6 }}
|
|
>
|
|
<AlertIcon />
|
|
<Box flex="1">
|
|
<HStack spacing={2} align="center" flexWrap="wrap">
|
|
<AlertTitle fontSize="sm" fontWeight="bold" mb={0}>
|
|
{config.title}
|
|
</AlertTitle>
|
|
<AlertDescription fontSize="sm" mb={0}>
|
|
{config.description}
|
|
</AlertDescription>
|
|
</HStack>
|
|
</Box>
|
|
|
|
{/* 重试按钮(仅失败状态显示) */}
|
|
{status === CONNECTION_STATUS.FAILED && onRetry && (
|
|
<Button
|
|
size="sm"
|
|
colorScheme="red"
|
|
leftIcon={<MdRefresh />}
|
|
onClick={onRetry}
|
|
mr={2}
|
|
flexShrink={0}
|
|
>
|
|
立即重试
|
|
</Button>
|
|
)}
|
|
|
|
{/* 关闭按钮(仅失败状态显示) */}
|
|
{status === CONNECTION_STATUS.FAILED && onClose && (
|
|
<CloseButton
|
|
onClick={onClose}
|
|
size="sm"
|
|
flexShrink={0}
|
|
/>
|
|
)}
|
|
</Alert>
|
|
</Slide>
|
|
);
|
|
};
|
|
|
|
export default ConnectionStatusBar;
|