📱 refactor(web): remove legacy isMobile util and migrate to useIsMobile hook
BREAKING CHANGE: helpers/utils.js no longer exports `isMobile()`. Any external code that relied on this function must switch to the `useIsMobile` React hook. Summary ------- 1. Deleted the obsolete `isMobile()` function from helpers/utils.js. 2. Introduced `MOBILE_BREAKPOINT` constant and `matchMedia`-based detection for non-React contexts. 3. Reworked toast positioning logic in utils.js to rely on `matchMedia`. 4. Updated render.js: • Removed isMobile import. • Added MOBILE_BREAKPOINT detection in `truncateText`. 5. Migrated every page/component to the `useIsMobile` hook: • Layout: HeaderBar, PageLayout, SiderBar • Pages: Home, Detail, Playground, User (Add/Edit), Token, Channel, Redemption, Ratio Sync • Components: ChannelsTable, ChannelSelectorModal, ConflictConfirmModal 6. Purged all remaining `isMobile()` calls and legacy imports. 7. Added missing `const isMobile = useIsMobile()` declarations where required. Benefits -------- • Unifies mobile detection with a React-friendly hook. • Eliminates duplicated logic and improves maintainability. • Keeps non-React helpers lightweight by using `matchMedia` directly.
This commit is contained in:
@@ -3,7 +3,8 @@ import { Link, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLucideIcon, sidebarIconColors } from '../../helpers/render.js';
|
||||
import { ChevronLeft } from 'lucide-react';
|
||||
import { useStyle, styleActions } from '../../context/Style/index.js';
|
||||
import { useIsMobile } from '../../hooks/useIsMobile.js';
|
||||
import { useSidebarCollapsed } from '../../hooks/useSidebarCollapsed.js';
|
||||
import {
|
||||
isAdmin,
|
||||
isRoot,
|
||||
@@ -36,10 +37,10 @@ const routerMap = {
|
||||
|
||||
const SiderBar = () => {
|
||||
const { t } = useTranslation();
|
||||
const { state: styleState, dispatch: styleDispatch } = useStyle();
|
||||
const isMobile = useIsMobile();
|
||||
const [collapsed, toggleCollapsed] = useSidebarCollapsed();
|
||||
|
||||
const [selectedKeys, setSelectedKeys] = useState(['home']);
|
||||
const [isCollapsed, setIsCollapsed] = useState(styleState.siderCollapsed);
|
||||
const [chatItems, setChatItems] = useState([]);
|
||||
const [openedKeys, setOpenedKeys] = useState([]);
|
||||
const location = useLocation();
|
||||
@@ -217,10 +218,14 @@ const SiderBar = () => {
|
||||
}
|
||||
}, [location.pathname, routerMapState]);
|
||||
|
||||
// 同步折叠状态
|
||||
// 监控折叠状态变化以更新 body class
|
||||
useEffect(() => {
|
||||
setIsCollapsed(styleState.siderCollapsed);
|
||||
}, [styleState.siderCollapsed]);
|
||||
if (collapsed) {
|
||||
document.body.classList.add('sidebar-collapsed');
|
||||
} else {
|
||||
document.body.classList.remove('sidebar-collapsed');
|
||||
}
|
||||
}, [collapsed]);
|
||||
|
||||
// 获取菜单项对应的颜色
|
||||
const getItemColor = (itemKey) => {
|
||||
@@ -323,32 +328,13 @@ const SiderBar = () => {
|
||||
return (
|
||||
<div
|
||||
className="sidebar-container"
|
||||
style={{ width: isCollapsed ? '60px' : '180px' }}
|
||||
style={{ width: 'var(--sidebar-current-width)' }}
|
||||
>
|
||||
<Nav
|
||||
className="sidebar-nav"
|
||||
defaultIsCollapsed={styleState.siderCollapsed}
|
||||
isCollapsed={isCollapsed}
|
||||
onCollapseChange={(collapsed) => {
|
||||
setIsCollapsed(collapsed);
|
||||
styleDispatch(styleActions.setSiderCollapsed(collapsed));
|
||||
|
||||
// 确保在收起侧边栏时有选中的项目
|
||||
if (selectedKeys.length === 0) {
|
||||
const currentPath = location.pathname;
|
||||
const matchingKey = Object.keys(routerMapState).find(
|
||||
(key) => routerMapState[key] === currentPath,
|
||||
);
|
||||
|
||||
if (matchingKey) {
|
||||
setSelectedKeys([matchingKey]);
|
||||
} else if (currentPath.startsWith('/console/chat/')) {
|
||||
setSelectedKeys(['chat']);
|
||||
} else {
|
||||
setSelectedKeys(['detail']); // 默认选中首页
|
||||
}
|
||||
}
|
||||
}}
|
||||
defaultIsCollapsed={collapsed}
|
||||
isCollapsed={collapsed}
|
||||
onCollapseChange={toggleCollapsed}
|
||||
selectedKeys={selectedKeys}
|
||||
itemStyle="sidebar-nav-item"
|
||||
hoverStyle="sidebar-nav-item:hover"
|
||||
@@ -383,7 +369,7 @@ const SiderBar = () => {
|
||||
>
|
||||
{/* 聊天区域 */}
|
||||
<div className="sidebar-section">
|
||||
{!isCollapsed && (
|
||||
{!collapsed && (
|
||||
<div className="sidebar-group-label">{t('聊天')}</div>
|
||||
)}
|
||||
{chatMenuItems.map((item) => renderSubItem(item))}
|
||||
@@ -392,7 +378,7 @@ const SiderBar = () => {
|
||||
{/* 控制台区域 */}
|
||||
<Divider className="sidebar-divider" />
|
||||
<div>
|
||||
{!isCollapsed && (
|
||||
{!collapsed && (
|
||||
<div className="sidebar-group-label">{t('控制台')}</div>
|
||||
)}
|
||||
{workspaceItems.map((item) => renderNavItem(item))}
|
||||
@@ -403,7 +389,7 @@ const SiderBar = () => {
|
||||
<>
|
||||
<Divider className="sidebar-divider" />
|
||||
<div>
|
||||
{!isCollapsed && (
|
||||
{!collapsed && (
|
||||
<div className="sidebar-group-label">{t('管理员')}</div>
|
||||
)}
|
||||
{adminItems.map((item) => renderNavItem(item))}
|
||||
@@ -414,7 +400,7 @@ const SiderBar = () => {
|
||||
{/* 个人中心区域 */}
|
||||
<Divider className="sidebar-divider" />
|
||||
<div>
|
||||
{!isCollapsed && (
|
||||
{!collapsed && (
|
||||
<div className="sidebar-group-label">{t('个人中心')}</div>
|
||||
)}
|
||||
{financeItems.map((item) => renderNavItem(item))}
|
||||
@@ -425,16 +411,14 @@ const SiderBar = () => {
|
||||
<div
|
||||
className="sidebar-collapse-button"
|
||||
onClick={() => {
|
||||
const newCollapsed = !isCollapsed;
|
||||
setIsCollapsed(newCollapsed);
|
||||
styleDispatch(styleActions.setSiderCollapsed(newCollapsed));
|
||||
toggleCollapsed();
|
||||
}}
|
||||
>
|
||||
<Tooltip content={isCollapsed ? t('展开侧边栏') : t('收起侧边栏')} position="right">
|
||||
<Tooltip content={collapsed ? t('展开侧边栏') : t('收起侧边栏')} position="right">
|
||||
<div className="sidebar-collapse-button-inner">
|
||||
<span
|
||||
className="sidebar-collapse-icon-container"
|
||||
style={{ transform: isCollapsed ? 'rotate(180deg)' : 'rotate(0deg)' }}
|
||||
style={{ transform: collapsed ? 'rotate(180deg)' : 'rotate(0deg)' }}
|
||||
>
|
||||
<ChevronLeft size={16} strokeWidth={2.5} color="var(--semi-color-text-2)" />
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user