feat: 支持会话置顶 (#32)

This commit is contained in:
Arvin Xu
2023-07-30 22:29:39 +08:00
committed by GitHub
parent 5492ee6a65
commit fc44b5dc42
5 changed files with 75 additions and 16 deletions

View File

@@ -19,10 +19,9 @@ interface SessionItemProps {
active?: boolean;
id: string;
loading?: boolean;
pin?: boolean;
}
const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading, pin }) => {
const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading }) => {
const ref = useRef(null);
const isHovering = useHover(ref);
@@ -33,6 +32,7 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading, pi
const [defaultModel] = useSettings((s) => [s.settings.model], shallow);
const [
pin,
title,
description,
systemRole,
@@ -42,11 +42,13 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading, pi
model,
chatLength,
removeSession,
pinSession,
] = useSessionStore((s) => {
const session = sessionSelectors.getSessionById(id)(s);
const meta = session.meta;
const systemRole = session.config.systemRole;
return [
session.pinned,
agentSelectors.getTitle(meta),
meta.description,
systemRole,
@@ -56,6 +58,7 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading, pi
session.config.model,
chatSelectors.currentChats(s).length,
s.removeSession,
s.pinSession,
];
}, shallow);
@@ -66,8 +69,9 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading, pi
icon: <Icon icon={pin ? PinOff : Pin} />,
key: 'pin',
label: t(pin ? 'pinOff' : 'pin'),
// TODO: 动作绑定
onClick: () => {},
onClick: () => {
pinSession(id, !pin);
},
},
{
children: [
@@ -154,7 +158,16 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading, pi
style={{ color: theme.colorText }}
title={title}
/>
<Dropdown arrow={false} menu={{ items }} trigger={['click']}>
<Dropdown
arrow={false}
menu={{
items,
onClick: ({ domEvent }) => {
domEvent.stopPropagation();
},
}}
trigger={['click']}
>
<ActionIcon
className="session-remove"
icon={MoreVertical}

View File

@@ -31,6 +31,11 @@ export interface SessionAction {
*/
importSessions: (sessions: LobeSessions) => void;
/**
* 置顶会话
* @param sessionId
*/
pinSession: (sessionId: string, pinned?: boolean) => void;
/**
* 生成压缩后的消息
* @returns 压缩后的消息
@@ -42,12 +47,13 @@ export interface SessionAction {
* @returns void
*/
removeSession: (sessionId: string) => void;
/**
* @title 切换会话
* @param sessionId - 会话索引
* @returns void
*/
switchSession: (sessionId?: string | 'new') => Promise<void>;
switchSession: (sessionId?: string) => Promise<void>;
}
export const createSessionSlice: StateCreator<
@@ -104,6 +110,19 @@ export const createSessionSlice: StateCreator<
}),
});
},
// genShareUrl: () => {
// const session = sessionSelectors.currentSession(get());
// if (!session) return '';
//
// const agent = session.config;
// return genShareMessagesUrl(session.chats, agent.systemRole);
// },
pinSession: (sessionId, pinned) => {
const nextValue = typeof pinned === 'boolean' ? pinned : !get().sessions[sessionId].pinned;
get().dispatchSession({ id: sessionId, pinned: nextValue, type: 'toggleSessionPinned' });
},
removeSession: (sessionId) => {
get().dispatchSession({ id: sessionId, type: 'removeSession' });
@@ -122,11 +141,4 @@ export const createSessionSlice: StateCreator<
// 新会话
await Router.push(`/chat/${sessionId}`);
},
// genShareUrl: () => {
// const session = sessionSelectors.currentSession(get());
// if (!session) return '';
//
// const agent = session.config;
// return genShareMessagesUrl(session.chats, agent.systemRole);
// },
});

View File

@@ -63,6 +63,11 @@ interface UpdateSessionAgentConfig {
id: string;
type: 'updateSessionConfig';
}
interface ToggleSessionPinned {
id: string;
pinned: boolean;
type: 'toggleSessionPinned';
}
export type SessionDispatch =
| AddSession
@@ -70,7 +75,8 @@ export type SessionDispatch =
| RemoveSession
| UpdateSessionMeta
| UpdateSessionAgentConfig
| UpdateSessionTopic;
| UpdateSessionTopic
| ToggleSessionPinned;
export const sessionsReducer = (state: LobeSessions, payload: SessionDispatch): LobeSessions => {
switch (payload.type) {
@@ -89,6 +95,16 @@ export const sessionsReducer = (state: LobeSessions, payload: SessionDispatch):
});
}
case 'toggleSessionPinned': {
return produce(state, (draft) => {
const { pinned, id } = payload;
const session = draft[id];
if (!session) return;
session.pinned = pinned;
});
}
case 'updateSessionMeta': {
return produce(state, (draft) => {
const chat = draft[payload.id];

View File

@@ -21,8 +21,19 @@ export const sessionList = (s: SessionStore) => {
.map((c) => c.content)
.join(''),
]);
return Object.values(filterChats).sort((a, b) => (b.updateAt || 0) - (a.updateAt || 0));
// 先按照 `pinned` 字段进行排序,置顶的会排在前面。然后,根据 `updateAt` 字段进行倒序排序。
return Object.values(filterChats).sort((a, b) => {
if (a.pinned && !b.pinned) {
return -1;
}
if (!a.pinned && b.pinned) {
return 1;
}
if (a.updateAt && b.updateAt) {
return b.updateAt - a.updateAt;
}
return 0;
});
};
export const getSessionById =

View File

@@ -19,6 +19,13 @@ interface LobeSessionBase extends BaseDataModel {
* 聊天记录
*/
chats: ChatMessageMap;
/**
* 置顶
*/
pinned?: boolean;
/**
* 主题
*/
topics?: ChatTopicMap;
/**
* 每个会话的类别