Skip to content

Commit

Permalink
✨ feat: 支持 Agent 和 Dance List 空状态处理
Browse files Browse the repository at this point in the history
  • Loading branch information
rdmclin2 committed Apr 14, 2024
1 parent 3e7e388 commit a7d9a4d
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 48 deletions.
4 changes: 2 additions & 2 deletions src/app/home/apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ export const apps = [
'https://registry.npmmirror.com/@lobehub/assets-emoji/latest/files/assets/card-index.webp',
component: <AgentPanel />,
key: 'agent',
label: '角色订阅',
label: '角色',
},
{
avatar:
'https://registry.npmmirror.com/@lobehub/assets-emoji/latest/files/assets/folding-hand-fan.webp',
component: <DancePanel />,
key: 'dance',
label: '舞蹈',
label: '跳舞',
},
{
avatar:
Expand Down
63 changes: 43 additions & 20 deletions src/components/GridList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Icon } from '@lobehub/ui';
import { Empty, Space } from 'antd';
import classNames from 'classnames';
import { Loader2 } from 'lucide-react';
import React, { memo } from 'react';
Expand All @@ -15,6 +16,9 @@ interface Item {

interface GridListProps {
className?: string;
empty?: {
actions?: React.ReactNode[];
};
isActivated?: (id: string) => boolean;
isChecked?: (id: string) => boolean;
items: Item[];
Expand All @@ -24,35 +28,54 @@ interface GridListProps {
}

const GridList = (props: GridListProps) => {
const { items, className, style, onClick, isActivated, isChecked, loading = false } = props;
const {
items,
className,
style,
onClick,
isActivated,
isChecked,
loading = false,
empty,
} = props;
const { styles } = useStyles();

const Loading = () => (
<Center gap={16} horizontal>
<Center gap={16} horizontal className={styles.loading}>
<Icon icon={Loader2} spin />
加载中...
</Center>
);

const List = () =>
items.map((item) => {
const { avatar, name, id } = item;
return (
<ListItem
key={id}
title={name}
avatar={avatar}
onClick={() => {
if (onClick) onClick(id);
}}
active={isActivated ? isActivated(id) : false}
checked={isChecked ? isChecked(id) : false}
/>
);
});
const List = () => (
<div className={styles.list}>
{items.map((item) => {
const { avatar, name, id } = item;
return (
<ListItem
key={id}
title={name}
avatar={avatar}
onClick={() => {
if (onClick) onClick(id);
}}
active={isActivated ? isActivated(id) : false}
checked={isChecked ? isChecked(id) : false}
/>
);
})}
</div>
);

const EmptyList = () => (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据">
{empty?.actions ? <Space>{empty.actions}</Space> : null}
</Empty>
);

return (
<div className={classNames(className, styles.list)} style={style}>
{loading ? <Loading /> : <List />}
<div className={classNames(className, styles.grid)} style={style}>
{loading ? <Loading /> : items.length === 0 ? <EmptyList /> : <List />}
</div>
);
};
Expand Down
12 changes: 10 additions & 2 deletions src/components/GridList/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ import { createStyles } from 'antd-style';
import { LIST_GRID_GAP, LIST_GRID_HEIGHT, LIST_GRID_WIDTH } from '@/constants/common';

export const useStyles = createStyles(({ css }) => ({
grid: css`
width: 100%;
height: 100%;
`,
loading: css`
display: flex;
align-items: center;
justify-content: center;
min-height: 240px;
`,
list: css`
overflow: auto;
display: grid;
Expand All @@ -11,7 +21,5 @@ export const useStyles = createStyles(({ css }) => ({
grid-template-columns: repeat(auto-fill, ${LIST_GRID_WIDTH}px);
grid-template-rows: repeat(auto-fill, ${LIST_GRID_HEIGHT}px);
justify-items: center;
height: 100%;
`,
}));
20 changes: 19 additions & 1 deletion src/panels/AgentPanel/Agent/List/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { GradientButton } from '@lobehub/ui';
import React, { memo } from 'react';

import GridList from '@/components/GridList';
import { useAgentStore } from '@/store/agent';

interface AgentListProps {
className?: string;
setTab?: (tab: string) => void;
style?: React.CSSProperties;
}

const AgentList = (props: AgentListProps) => {
const { className, style } = props;
const { className, style, setTab } = props;

const [subscribedList, activateAgent, currentIdentifier] = useAgentStore((s) => [
s.subscribedList,
Expand All @@ -30,6 +32,22 @@ const AgentList = (props: AgentListProps) => {
activateAgent(id);
}}
isActivated={(id) => id === currentIdentifier}
empty={{
actions: [
<GradientButton
key="subscribe"
glow
size={'middle'}
onClick={() => {
if (setTab) {
setTab('market');
}
}}
>
+ 订阅角色
</GradientButton>,
],
}}
/>
);
};
Expand Down
5 changes: 3 additions & 2 deletions src/panels/AgentPanel/Agent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@ const useStyles = createStyles(({ css }) => ({

interface AgentProps {
className?: string;
setTab?: (tab: string) => void;
style?: React.CSSProperties;
}

const Agent = (props: AgentProps) => {
const { styles } = useStyles();
const { style, className } = props;
const { style, className, setTab } = props;

return (
<div className={classNames(className, styles.container)} style={style}>
<div className={styles.content}>
<TopBanner title="Hello, Let's Chat!" />
<AgentList />
<AgentList setTab={setTab} />
</div>
<AgentCard />
</div>
Expand Down
5 changes: 3 additions & 2 deletions src/panels/AgentPanel/Market/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React, { memo } from 'react';
import TopBanner from '@/components/TopBanner';

import AgentCard from './Card';
import AgentIndex from './List';
import AgentList from './List';

const useStyles = createStyles(({ css }) => ({
background: css`
Expand Down Expand Up @@ -37,6 +37,7 @@ const useStyles = createStyles(({ css }) => ({

interface AgentProps {
className?: string;
setTab?: (tab: string) => void;
style?: React.CSSProperties;
}

Expand All @@ -48,7 +49,7 @@ const Agent = (props: AgentProps) => {
<div className={classNames(className, styles.container)} style={style}>
<div className={styles.content}>
<TopBanner title="Find Your Lovest Vidol" />
<AgentIndex />
<AgentList />
</div>
<AgentCard />
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/panels/AgentPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ const ControlPanel = (props: ControlPanelProps) => {
className={className}
panelKey="agent"
style={style}
title="智能体"
title="角色"
extra={<Segmented options={options} size="small" value={tab} onChange={setTab} />}
>
<div className={styles.content}>{tab === 'agent' ? <Agent /> : <Market />}</div>
<div className={styles.content}>
{tab === 'agent' ? <Agent setTab={setTab} /> : <Market />}
</div>
</PanelContainer>
);
};
Expand Down
20 changes: 19 additions & 1 deletion src/panels/DancePanel/Dance/List/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { GradientButton } from '@lobehub/ui';
import React from 'react';

import GridList from '@/components/GridList';
import { useDanceStore } from '@/store/dance';

interface DanceListProps {
className?: string;
setTab?: (tab: string) => void;
style?: React.CSSProperties;
}

const DanceList = (props: DanceListProps) => {
const { className, style } = props;
const { className, style, setTab } = props;
const [danceList, activateDance, currentIdentifier] = useDanceStore((s) => [
s.danceList,
s.activateDance,
Expand All @@ -29,6 +31,22 @@ const DanceList = (props: DanceListProps) => {
activateDance(id);
}}
isActivated={(id) => id === currentIdentifier}
empty={{
actions: [
<GradientButton
key={'subscribe'}
glow
size={'middle'}
onClick={() => {
if (setTab) {
setTab('market');
}
}}
>
+ 订阅舞蹈
</GradientButton>,
],
}}
/>
);
};
Expand Down
21 changes: 7 additions & 14 deletions src/panels/DancePanel/Dance/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { GridBackground } from '@lobehub/ui';
import { createStyles } from 'antd-style';
import classNames from 'classnames';
import React, { memo } from 'react';
import { Center } from 'react-layout-kit';

import TopBanner from '@/components/TopBanner';

import DanceCard from './Card';
import DanceList from './List';
Expand Down Expand Up @@ -37,25 +37,18 @@ const useStyles = createStyles(({ css }) => ({

interface DanceProps {
className?: string;
setTab?: (tab: string) => void;
style?: React.CSSProperties;
}

const Dance = (props: DanceProps) => {
const { style, className } = props;
const { theme, styles } = useStyles();
const { style, className, setTab } = props;
const { styles } = useStyles();
return (
<div className={classNames(className, styles.container)} style={style}>
<div className={styles.content}>
<Center>
<h1 className={styles.title}> Just Dance </h1>
<GridBackground
animation
className={styles.background}
colorFront={theme.colorText}
random
/>
</Center>
<DanceList />
<TopBanner title={"Let's Dance"} />
<DanceList setTab={setTab} />
</div>
<DanceCard />
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/panels/DancePanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ const DancePanel = (props: DancePanelProps) => {
className={className}
panelKey="dance"
style={style}
title="舞蹈订阅"
title="跳舞"
extra={<Segmented options={options} size="small" value={tab} onChange={setTab} />}
>
<div className={styles.content}>
<div className={styles.content}>{tab === 'dance' ? <Dance /> : <Market />}</div>
<div className={styles.content}>
{tab === 'dance' ? <Dance setTab={setTab} /> : <Market />}
</div>
</div>
</PanelContainer>
);
Expand Down

0 comments on commit a7d9a4d

Please sign in to comment.