feat: sockt 弹窗功能添加
This commit is contained in:
132
src/components/ConnectionStatusBar/index.js
Normal file
132
src/components/ConnectionStatusBar/index.js
Normal file
@@ -0,0 +1,132 @@
|
||||
// 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;
|
||||
Reference in New Issue
Block a user