feat: improve pin mode about session group (#369)

* 🚧 wip: add pin group

* 💄 style: improve styles

*  feat: improve pin mode session group
This commit is contained in:
Arvin Xu
2023-10-27 22:03:10 +08:00
committed by GitHub
parent e78d893ba4
commit 75c58835b0
13 changed files with 106 additions and 41 deletions
@@ -7,7 +7,17 @@ import FolderPanel from '@/features/FolderPanel';
import SessionListContent from '../../features/SessionListContent';
import Header from './SessionHeader';
const useStyles = createStyles(({ stylish }) => stylish.noScrollbar);
const useStyles = createStyles(({ stylish, css, cx }) =>
cx(
stylish.noScrollbar,
css`
padding: 0 6px;
display: flex;
flex-direction: column;
gap: 2px;
`,
),
);
const Sessions = memo(() => {
const { styles } = useStyles();
@@ -15,7 +25,7 @@ const Sessions = memo(() => {
return (
<FolderPanel>
<Header />
<DraggablePanelBody className={styles} style={{ padding: 0 }}>
<DraggablePanelBody className={styles}>
<SessionListContent />
</DraggablePanelBody>
</FolderPanel>
@@ -6,10 +6,10 @@ import { memo } from 'react';
const useStyles = createStyles(({ css, prefixCls, token }) => ({
container: css`
border-radius: 0;
.${prefixCls}-collapse-header {
padding-inline: 16px !important;
color: ${token.colorTextDescription} !important;
border-radius: 8px !important;
&:hover {
color: ${token.colorText} !important;
@@ -49,7 +49,7 @@ const Inbox = memo(() => {
active={mobile ? false : activeId === INBOX_SESSION_ID}
avatar={avatarRender}
ref={ref}
style={{ alignItems: 'center' }}
style={{ alignItems: 'center', borderRadius: 8 }}
title={t('inbox.title')}
/>
</Link>
@@ -18,6 +18,7 @@ const useStyles = createStyles(({ css }) => {
return {
container: css`
position: relative;
border-radius: 8px;
`,
modalRoot: css`
@@ -96,21 +97,23 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
);
return (
<Item
actions={actions}
// needn't active state in mobile
active={mobile ? false : active}
addon={addon}
avatar={avatarRender}
className={styles.container}
date={updateAt}
description={description || systemRole}
loading={loading}
pin={pin}
ref={ref}
showAction={open || isHovering}
title={title}
/>
<Flexbox paddingBlock={1}>
<Item
actions={actions}
// needn't active state in mobile
active={mobile ? false : active}
addon={addon}
avatar={avatarRender}
className={styles.container}
date={updateAt}
description={description || systemRole}
loading={loading}
pin={pin}
ref={ref}
showAction={open || isHovering}
title={title}
/>
</Flexbox>
);
}, shallow);
@@ -1,12 +1,11 @@
import { createStyles, useResponsive } from 'antd-style';
import isEqual from 'fast-deep-equal';
import Link from 'next/link';
import { memo } from 'react';
import LazyLoad from 'react-lazy-load';
import { SESSION_CHAT_URL } from '@/const/url';
import { useSessionHydrated, useSessionStore } from '@/store/session';
import { sessionSelectors } from '@/store/session/selectors';
import { LobeAgentSession } from '@/types/session';
import AddButton from './AddButton';
import SessionItem from './Item';
@@ -18,8 +17,10 @@ const useStyles = createStyles(
`,
);
const SessionList = memo(() => {
const list = useSessionStore(sessionSelectors.sessionList, isEqual);
interface SessionListProps {
dataSource: LobeAgentSession[];
}
const SessionList = memo<SessionListProps>(({ dataSource }) => {
const [activeSession, switchSession] = useSessionStore((s) => [s.activeSession, s.switchSession]);
const { styles } = useStyles();
const isInit = useSessionHydrated();
@@ -28,8 +29,8 @@ const SessionList = memo(() => {
return !isInit ? (
<SkeletonList />
) : list.length > 0 ? (
list.map(({ id }) => (
) : dataSource.length > 0 ? (
dataSource.map(({ id }) => (
<LazyLoad className={styles} key={id}>
<Link
aria-label={id}
@@ -1,28 +1,52 @@
import { CollapseProps } from 'antd';
import { memo, useMemo } from 'react';
import isEqual from 'fast-deep-equal';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { preferenceSelectors, useGlobalStore } from '@/store/global';
import { useSessionStore } from '@/store/session';
import { sessionSelectors } from '@/store/session/selectors';
import CollapseGroup from './CollapseGroup';
import Inbox from './Inbox';
import SessionList from './List';
const SessionListContent = memo(() => {
const { t } = useTranslation('common');
const items: CollapseProps['items'] = useMemo(
() => [
{
children: <SessionList />,
key: 'sessionList',
label: t('sessionList'),
},
],
[],
);
const { t } = useTranslation('chat');
const unpinnedSessionList = useSessionStore(sessionSelectors.unpinnedSessionList, isEqual);
const pinnedList = useSessionStore(sessionSelectors.pinnedSessionList, isEqual);
const hasPinnedSessionList = useSessionStore(sessionSelectors.hasPinnedSessionList);
const [sessionGroupKeys, updatePreference] = useGlobalStore((s) => [
preferenceSelectors.sessionGroupKeys(s),
s.updatePreference,
]);
const items = [
hasPinnedSessionList && {
children: <SessionList dataSource={pinnedList} />,
key: 'pinned',
label: t('pin'),
},
{
children: <SessionList dataSource={unpinnedSessionList} />,
key: 'sessionList',
label: t('sessionList'),
},
].filter(Boolean) as CollapseProps['items'];
return (
<>
<Inbox />
<CollapseGroup defaultActiveKey={['sessionList']} items={items} />
<CollapseGroup
activeKey={sessionGroupKeys}
items={items}
onChange={(keys) => {
const sessionGroupKeys = typeof keys === 'string' ? [keys] : keys;
updatePreference({ sessionGroupKeys });
}}
/>
</>
);
});
+3 -1
View File
@@ -18,12 +18,14 @@ export default {
newAgent: '新建助手',
noDescription: '暂无描述',
pin: '置顶',
pinOff: '取消置顶',
regenerate: '重新生成',
roleAndArchive: '角色与记录',
searchAgentPlaceholder: '搜索助手和对话...',
send: '发送',
sendPlaceholder: '输入聊天内容...',
sessionList: '助手列表',
shareModal: {
download: '下载截图',
imageType: '图片格式',
+1 -2
View File
@@ -45,6 +45,7 @@ export default {
noDescription: '暂无描述',
ok: '确定',
password: '密码',
pin: '置顶',
pinOff: '取消置顶',
regenerate: '重新生成',
@@ -52,7 +53,6 @@ export default {
reset: '重置',
retry: '重试',
send: '发送',
sessionList: '助手列表',
setting: '设置',
share: '分享',
stop: '停止',
@@ -62,7 +62,6 @@ export default {
setting: '设置',
},
temp: '临时',
updateAgent: '更新助理信息',
upgradeVersion: {
action: '立即升级',
+2
View File
@@ -22,6 +22,7 @@ export interface GlobalPreference {
guide?: Guide;
inputHeight: number;
mobileShowTopic?: boolean;
sessionGroupKeys: string[];
sessionsWidth: number;
showChatSideBar?: boolean;
showSessionPanel?: boolean;
@@ -49,6 +50,7 @@ export const initialState: GlobalState = {
guide: {},
inputHeight: 200,
mobileShowTopic: false,
sessionGroupKeys: ['pinned', 'sessionList'],
sessionsWidth: 320,
showChatSideBar: true,
showSessionPanel: true,
+1
View File
@@ -1 +1,2 @@
export * from './selectors/preference';
export * from './selectors/settings';
+10
View File
@@ -0,0 +1,10 @@
import { GlobalStore } from '@/store/global';
import { initialState } from '../initialState';
const sessionGroupKeys = (s: GlobalStore): string[] =>
s.preference.sessionGroupKeys || initialState.preference.sessionGroupKeys;
export const preferenceSelectors = {
sessionGroupKeys: sessionGroupKeys,
};
@@ -7,8 +7,11 @@ import {
currentSessionSafe,
getSessionById,
getSessionMetaById,
hasPinnedSessionList,
hasSessionList,
pinnedSessionList,
sessionList,
unpinnedSessionList,
} from './list';
const isInboxSession = (s: SessionStore) => s.activeId === INBOX_SESSION_ID;
@@ -21,7 +24,10 @@ export const sessionSelectors = {
getExportAgent,
getSessionById,
getSessionMetaById,
hasPinnedSessionList,
hasSessionList,
isInboxSession,
pinnedSessionList,
sessionList,
unpinnedSessionList,
};
@@ -39,10 +39,17 @@ export const sessionList = (s: SessionStore) => {
});
};
export const pinnedSessionList = (s: SessionStore) => sessionList(s).filter((s) => s.pinned);
export const unpinnedSessionList = (s: SessionStore) => sessionList(s).filter((s) => !s.pinned);
export const hasSessionList = (s: SessionStore) => {
const list = sessionList(s);
return list?.length > 0;
};
export const hasPinnedSessionList = (s: SessionStore) => {
const list = pinnedSessionList(s);
return list?.length > 0;
};
export const getSessionById =
(id: string) =>