import IconFont from '@components/Iconfont';
import { getToolRecentUseKeys } from '@utils/common.ts';
import { isMobile } from '@wander/base-utils';
import type { MenuProps } from 'antd';
import { Menu } from 'antd';
import classNames from 'classnames/bind';
import { floor } from 'lodash';
import { useEffect, useState } from 'react';
import { NavLink, useLocation, useNavigate } from 'react-router-dom';
import { ADVANCE_DRAW_RECOMMEND_CATEGORY_CONFIG_KEY } from '@/constant.ts';
import { aiMenuList } from '@/pages/ToolList/pc/components/Menu/config.tsx';
import { useStore } from '@/store/createStore';
import styles from './index.module.less';
const cx = classNames.bind(styles);
// 每个item高度 48 是item高度 上下还有4px间距 margin 会重叠 只需要加1个4px就够了
const MENU_ITEM_HEIGHT = 52;
// 默认菜单高度 48 每个item 10 默认有10个必须显示
const DEFAULT_MENU_HEIGHT = MENU_ITEM_HEIGHT * 5;
// header菜单栏高度
const HEADER_LAYOUT_HEIGHT = 80;
// 偏差值 避免高度计算不准确
const OVERSCAN_VALUE = 16;
const AiPageMenu = () => {
const navigate = useNavigate();
const location = useLocation();
const [selectedKeys, setSelectedKeys] = useState(['home']);
const toolList = useStore((state) => {
return (state.functionSortMap['DRAW_SIDEBAR'] || []).map((value) => {
return state.functionList.find((value1) => value1.key === value)!;
});
});
// 最近使用工具列表
const { recentlyToolList } = useStore(() => {
// 使用次数配置
const recentUseKeys: string[] = getToolRecentUseKeys();
return {
recentlyToolList: recentUseKeys
.map((value) => {
return toolList.filter((value1) => value1.routeKey === value)?.[0];
})
.filter(Boolean)
.slice(0, 5),
};
});
console.log('toolList', toolList);
console.log('recentlyToolList', recentlyToolList);
// 推荐一级类目列表
const recommendCategoryList = useStore((state) => {
return state.advanceDrawFirstCategoryList.filter((value) => {
return (state.initConfigs[ADVANCE_DRAW_RECOMMEND_CATEGORY_CONFIG_KEY] || []).includes(
value.mid,
);
});
});
// 记录收起菜单位置 的索引 初始值给4 避免闪烁太严重
const [collapseToolIndex, setCollapseToolIndex] = useState(4);
// 记录视口高度
const [innerHeight, setInnerHeight] = useState(0);
// 工具是否已展开
const [toolCollapsed, setToolCollapsed] = useState(false);
useEffect(() => {
const handleResize = () => {
setInnerHeight(window.innerHeight);
};
handleResize();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
useEffect(() => {
// 计算工具显示个数
if (!isMobile() && !toolCollapsed) {
// 工具剩余可占位高度
let toolContainerHeight =
innerHeight - DEFAULT_MENU_HEIGHT - HEADER_LAYOUT_HEIGHT - OVERSCAN_VALUE;
if (recentlyToolList.length) {
toolContainerHeight =
toolContainerHeight - MENU_ITEM_HEIGHT * (recentlyToolList.length + 1);
}
// 显示工具个数
const showToolCount = floor(toolContainerHeight / MENU_ITEM_HEIGHT);
// 留一个查看更多的位置
setCollapseToolIndex(showToolCount - 1);
}
}, [recentlyToolList.length, innerHeight, toolCollapsed, toolList]);
useEffect(() => {
const currentItem = aiMenuList.find((value) => value.route === location.pathname);
setSelectedKeys([currentItem?.key || 'home']);
}, [location.pathname]);
const onSelect: MenuProps['onSelect'] = ({ key, selectedKeys: newSelectedKeys }) => {
setSelectedKeys(newSelectedKeys);
if (key === 'toolMore') {
// 查看更多AI工具
setToolCollapsed(true);
return;
}
if (key === 'collapseToolMenu') {
// 收起更多AI工具
setToolCollapsed(false);
return;
}
};
return (
<div className={cx('menu_container')}>
<Menu
theme="dark"
selectedKeys={selectedKeys}
defaultOpenKeys={['commonTool', 'tools']}
mode="inline"
items={aiMenuList.map((value) => {
if (value.key === 'draw') {
return {
label: value.labelKey,
key: value.key,
icon: value.icon,
children: recommendCategoryList.map((value1) => ({
label: (
<div
onClick={() => {
navigate('/ai/advance_draw/operate', {
state: {
record: {
selectMids: [value1.mid],
},
},
});
}}
>
{value1.name}
</div>
),
key: value1.parentId,
})),
};
}
if (value.key === 'commonTool') {
if (!recentlyToolList.length) {
return null;
}
return {
label: value.labelKey,
key: value.key,
icon: value.icon,
children: recentlyToolList.map((value1) => {
return {
label: <NavLink to={value1.route}>{value1.shortTitle || value1.title}</NavLink>,
// key值和AI工具重复了
key: `${value.key}${value1.key}`,
};
}),
};
}
if (value.key === 'tools') {
return {
label: value.labelKey,
key: value.key,
icon: value.icon,
children: [
...(toolCollapsed ? toolList : toolList.slice(0, collapseToolIndex)).map(
(value) => {
return {
label: <NavLink to={value.route}>{value.shortTitle || value.title}</NavLink>,
key: value.key,
};
},
),
toolCollapsed
? {
label: (
<span>
收起
<IconFont type="icon-arrow-up" style={{ marginLeft: 4, fontSize: 12 }} />
</span>
),
key: 'collapseToolMenu',
}
: {
label: (
<span>
查看更多
<IconFont
type="icon-arrow-bottom"
style={{ marginLeft: 4, fontSize: 12 }}
/>
</span>
),
key: 'toolMore',
},
],
};
}
return {
label: value.route ? (
<NavLink to={value.route}>{value.labelKey}</NavLink>
) : (
value.labelKey
),
key: value.key,
icon: value.icon,
};
})}
onSelect={onSelect}
/>
</div>
);
};
export default AiPageMenu;
.menu_container {
position: fixed;
z-index: 99;
width: 150px;
height: 100vh;
overflow-y: scroll;
user-select: none;
background: #2f3c48;
transition: all 0.3s;
scrollbar-gutter: stable;
&.en {
width: 232px;
}
&::-webkit-scrollbar {
z-index: 999;
width: 6px;
background: transparent;
border-radius: 3px;
}
&::-webkit-scrollbar-track {
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background-color: rgb(255 255 255 / 30%);
border-radius: 3px;
transition: all 0.5s;
}
:global {
.ant-menu-dark {
background: #2f3c48;
}
.ant-menu-item,
.ant-menu-inline.ant-menu-root .ant-menu-submenu-title {
width: 100%;
height: 48px;
padding-right: 0;
padding-left: 12px !important;
margin-inline: 0;
line-height: 48px;
color: #fff;
border-radius: 0;
.ant-menu-title-content {
line-height: 48px;
}
}
.ant-menu-item.ant-menu-item-only-child {
padding-left: 36px !important;
color: rgb(255 255 255 / 60%);
}
.ant-menu .ant-menu-submenu-arrow {
inset-inline-end: 8px;
}
.ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected {
background: rgb(255 255 255 / 10%);
&::after {
position: absolute;
top: 25%;
left: calc(100% - 2px);
width: 2px;
height: 50%;
content: '';
background: #fff;
}
}
.ant-menu-dark.ant-menu-inline .ant-menu-sub.ant-menu-inline {
background: transparent;
}
}
}
import IconFont from '@components/Iconfont';
export const aiMenuList = [
{
labelKey: '首页',
route: '/',
key: 'home',
icon: <IconFont type="icon-home" />,
},
{
labelKey: '常用工具',
key: 'commonTool',
icon: <IconFont type="icon-common-tool" />,
},
{
labelKey: 'AI绘图',
key: 'draw',
icon: <IconFont type="icon-ai-draw" />,
},
{
labelKey: 'AI工具',
key: 'tools',
icon: <IconFont type="icon-ai-tool" />,
},
{
labelKey: '我的创作',
route: '/user/draw/records',
key: 'createRecord',
icon: <IconFont type="icon-create-record" />,
},
];
点击查看更多后 我的创作会被隐藏 看不到除非收起AI工具
最新发布