Skip to content

Commit

Permalink
♻️ refactor: refactor session group with db mode (#1126)
Browse files Browse the repository at this point in the history
* ♻️ refactor: refactor with db

* 🎨 chore: improve code
  • Loading branch information
arvinxx committed Jan 23, 2024
1 parent a8d200c commit f3955ce
Show file tree
Hide file tree
Showing 38 changed files with 501 additions and 363 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { ActionIcon, Icon } from '@lobehub/ui';
import { App, Dropdown, DropdownProps, MenuProps } from 'antd';
import { createStyles } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { MoreVertical, PencilLine, Settings2, Trash } from 'lucide-react';
import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { useGlobalStore } from '@/store/global';
import { groupHelpers } from '@/store/global/helpers';
import { settingsSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';

const useStyles = createStyles(({ css }) => ({
modalRoot: css`
Expand All @@ -25,8 +22,8 @@ const Actions = memo<ActionsProps>(({ id, openRenameModal, openConfigModal, onOp
const { t } = useTranslation('chat');
const { styles } = useStyles();
const { modal } = App.useApp();
const sessionCustomGroups = useGlobalStore(settingsSelectors.sessionCustomGroups, isEqual);
const updateCustomGroup = useGlobalStore((s) => s.updateCustomGroup);

const [removeSessionGroup] = useSessionStore((s) => [s.removeSessionGroup]);
const items: MenuProps['items'] = useMemo(
() => [
{
Expand Down Expand Up @@ -61,7 +58,7 @@ const Actions = memo<ActionsProps>(({ id, openRenameModal, openConfigModal, onOp
centered: true,
okButtonProps: { danger: true },
onOk: () => {
updateCustomGroup(groupHelpers.removeGroup(id, sessionCustomGroups));
removeSessionGroup(id);
},
rootClassName: styles.modalRoot,
title: t('sessionGroup.confirmRemoveGroupAlert'),
Expand Down
45 changes: 23 additions & 22 deletions src/app/chat/features/SessionListContent/DefaultMode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { memo, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { useGlobalStore } from '@/store/global';
import { preferenceSelectors, settingsSelectors } from '@/store/global/selectors';
import { preferenceSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';
import { sessionSelectors } from '@/store/session/selectors';
import { SessionDefaultGroup } from '@/types/session';

import Actions from '../SessionListContent/CollapseGroup/Actions';
import CollapseGroup from './CollapseGroup';
Expand All @@ -16,35 +17,34 @@ import ConfigGroupModal from './Modals/ConfigGroupModal';
import RenameGroupModal from './Modals/RenameGroupModal';

const SessionListContent = memo(() => {
const { t } = useTranslation('chat');

const [activeGroupId, setActiveGroupId] = useState<string>();
const [renameGroupModalOpen, setRenameGroupModalOpen] = useState(false);
const [configGroupModalOpen, setConfigGroupModalOpen] = useState(false);
const { t } = useTranslation('chat');
const sessionCustomGroups = useGlobalStore(settingsSelectors.sessionCustomGroups, isEqual);
const sessionList =
useSessionStore(sessionSelectors.sessionList(sessionCustomGroups), isEqual) || {};

const [useFetchSessions] = useSessionStore((s) => [s.useFetchSessions]);
useFetchSessions();

const pinnedSessions = useSessionStore(sessionSelectors.pinnedSessions, isEqual);
const defaultSessions = useSessionStore(sessionSelectors.defaultSessions, isEqual);
const customSessionGroups = useSessionStore(sessionSelectors.customSessionGroups, isEqual);

const [sessionGroupKeys, updatePreference] = useGlobalStore((s) => [
preferenceSelectors.sessionGroupKeys(s),
s.updatePreference,
]);
const [ useFetchSessions] = useSessionStore((s) => [
s.useFetchSessions,
]);
useFetchSessions();


const items = useMemo(
() =>
[
sessionList.pinnedList?.length > 0 && {
children: <SessionList dataSource={sessionList.pinnedList} />,
key: 'pinned',
pinnedSessions.length > 0 && {
children: <SessionList dataSource={pinnedSessions} />,
key: SessionDefaultGroup.Pinned,
label: t('pin'),
},
...sessionCustomGroups.map(({ id, name }) => ({
children: sessionList.customList[id] && (
<SessionList dataSource={sessionList.customList[id]} />
),
...customSessionGroups.map(({ id, name, children }) => ({
children: <SessionList dataSource={children} />,
extra: (
<Actions
id={id}
Expand All @@ -59,12 +59,12 @@ const SessionListContent = memo(() => {
label: name,
})),
{
children: <SessionList dataSource={sessionList.defaultList} />,
key: 'defaultList',
children: <SessionList dataSource={defaultSessions} />,
key: SessionDefaultGroup.Default,
label: t('defaultList'),
},
].filter(Boolean) as CollapseProps['items'],
[sessionCustomGroups, sessionList],
[customSessionGroups, pinnedSessions, defaultSessions],
);

return (
Expand All @@ -74,8 +74,9 @@ const SessionListContent = memo(() => {
activeKey={sessionGroupKeys}
items={items}
onChange={(keys) => {
const sessionGroupKeys = typeof keys === 'string' ? [keys] : keys;
updatePreference({ sessionGroupKeys });
const expandSessionGroupKeys = typeof keys === 'string' ? [keys] : keys;

updatePreference({ expandSessionGroupKeys });
}}
/>
{activeGroupId && (
Expand Down
11 changes: 4 additions & 7 deletions src/app/chat/features/SessionListContent/List/Item/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { configService } from '@/services/config';
import { useGlobalStore } from '@/store/global';
import { settingsSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';
import { sessionHelpers } from '@/store/session/helpers';
import { sessionSelectors } from '@/store/session/selectors';
import { sessionGroupSelectors, sessionSelectors } from '@/store/session/selectors';
import { SessionDefaultGroup } from '@/types/session';

const useStyles = createStyles(({ css }) => ({
Expand All @@ -38,11 +36,10 @@ interface ActionProps {
}

const Actions = memo<ActionProps>(({ group, id, openCreateGroupModal, setOpen }) => {
const { t } = useTranslation('chat');

const { styles } = useStyles();
const { t } = useTranslation('chat');

const sessionCustomGroups = useGlobalStore(settingsSelectors.sessionCustomGroups, isEqual);
const sessionCustomGroups = useSessionStore(sessionGroupSelectors.sessionGroupItems, isEqual);
const [pin, removeSession, pinSession, duplicateSession, updateSessionGroup] = useSessionStore(
(s) => {
const session = sessionSelectors.getSessionById(id)(s);
Expand All @@ -51,7 +48,7 @@ const Actions = memo<ActionProps>(({ group, id, openCreateGroupModal, setOpen })
s.removeSession,
s.pinSession,
s.duplicateSession,
s.updateSessionGroup,
s.updateSessionGroupId,
];
},
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { ActionIcon, EditableText, SortableList } from '@lobehub/ui';
import { Popconfirm, message } from 'antd';
import { App, Popconfirm } from 'antd';
import { createStyles } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { PencilLine, Trash } from 'lucide-react';
import { memo, useCallback, useState } from 'react';
import { memo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { useGlobalStore } from '@/store/global';
import { groupHelpers } from '@/store/global/helpers';
import { settingsSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';
import { SessionGroupItem } from '@/types/session';

const useStyles = createStyles(({ css }) => ({
Expand All @@ -26,22 +23,15 @@ const useStyles = createStyles(({ css }) => ({
}));

const GroupItem = memo<SessionGroupItem>(({ id, name }) => {
const [editing, setEditing] = useState(false);
const sessionCustomGroups = useGlobalStore(settingsSelectors.sessionCustomGroups, isEqual);
const updateCustomGroup = useGlobalStore((s) => s.updateCustomGroup);
const { t } = useTranslation('chat');
const { styles } = useStyles();
const { message } = App.useApp();

const handleRename = useCallback(
(input: string) => {
if (!input) return;
if (input.length === 0 || input.length > 20)
return message.warning(t('sessionGroup.tooLong'));
updateCustomGroup(groupHelpers.renameGroup(id, input, sessionCustomGroups));
message.success(t('sessionGroup.renameSuccess'));
},
[id, sessionCustomGroups],
);
const [editing, setEditing] = useState(false);
const [updateSessionGroupName, removeSessionGroup] = useSessionStore((s) => [
s.updateSessionGroupName,
s.removeSessionGroup,
]);

return (
<>
Expand All @@ -57,7 +47,7 @@ const GroupItem = memo<SessionGroupItem>(({ id, name }) => {
type: 'primary',
}}
onConfirm={() => {
updateCustomGroup(groupHelpers.removeGroup(id, sessionCustomGroups));
removeSessionGroup(id);
}}
title={t('sessionGroup.confirmRemoveGroupAlert')}
>
Expand All @@ -67,8 +57,14 @@ const GroupItem = memo<SessionGroupItem>(({ id, name }) => {
) : (
<EditableText
editing={editing}
onChangeEnd={(v) => {
if (name !== v) handleRename(v);
onChangeEnd={(input) => {
if (name !== input) {
if (!input) return;
if (input.length === 0 || input.length > 20)
return message.warning(t('sessionGroup.tooLong'));
updateSessionGroupName(id, input);
message.success(t('sessionGroup.renameSuccess'));
}
setEditing(false);
}}
onEditingChange={(e) => setEditing(e)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { useGlobalStore } from '@/store/global';
import { settingsSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';
import { sessionGroupSelectors } from '@/store/session/selectors';
import { SessionGroupItem } from '@/types/session';

import GroupItem from './GroupItem';
Expand All @@ -30,10 +30,10 @@ const useStyles = createStyles(({ css, token, stylish }) => ({
const ConfigGroupModal = memo<ModalProps>(({ open, onCancel }) => {
const { t } = useTranslation('chat');
const { styles } = useStyles();
const sessionCustomGroups = useGlobalStore(settingsSelectors.sessionCustomGroups, isEqual);
const [addCustomGroup, updateCustomGroup] = useGlobalStore((s) => [
s.addCustomGroup,
s.updateCustomGroup,
const sessionGroupItems = useSessionStore(sessionGroupSelectors.sessionGroupItems, isEqual);
const [addSessionGroup, updateSessionGroupSort] = useSessionStore((s) => [
s.addSessionGroup,
s.updateSessionGroupSort,
]);

return (
Expand All @@ -47,8 +47,10 @@ const ConfigGroupModal = memo<ModalProps>(({ open, onCancel }) => {
>
<Flexbox>
<SortableList
items={sessionCustomGroups}
onChange={(item: SessionGroupItem[]) => updateCustomGroup(item)}
items={sessionGroupItems}
onChange={(items: SessionGroupItem[]) => {
updateSessionGroupSort(items);
}}
renderItem={(item: SessionGroupItem) => (
<SortableList.Item
align={'center'}
Expand All @@ -65,7 +67,7 @@ const ConfigGroupModal = memo<ModalProps>(({ open, onCancel }) => {
<Button
block
icon={<Icon icon={Plus} />}
onClick={() => addCustomGroup(t('sessionGroup.newGroup'))}
onClick={() => addSessionGroup(t('sessionGroup.newGroup'))}
>
{t('sessionGroup.createGroup')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Input, Modal, type ModalProps } from '@lobehub/ui';
import { message } from 'antd';
import isEqual from 'fast-deep-equal';
import { memo, useCallback, useState } from 'react';
import { App } from 'antd';
import { MouseEvent, memo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { useGlobalStore } from '@/store/global';
import { settingsSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';

interface CreateGroupModalProps extends ModalProps {
Expand All @@ -15,41 +14,46 @@ interface CreateGroupModalProps extends ModalProps {
const CreateGroupModal = memo<CreateGroupModalProps>(
({ id, open, onCancel }: CreateGroupModalProps) => {
const { t } = useTranslation('chat');
const sessionCustomGroups = useGlobalStore(settingsSelectors.sessionCustomGroups, isEqual);
const addCustomGroup = useGlobalStore((s) => s.addCustomGroup);
const updateSessionGroup = useSessionStore((s) => s.updateSessionGroup);
const [input, setInput] = useState('');

const handleSubmit = useCallback(
(e: any) => {
if (!input) return;
if (input.length === 0 || input.length > 20)
return message.warning(t('sessionGroup.tooLong'));

const groupId = addCustomGroup(input);
updateSessionGroup(id, groupId);
message.success(t('sessionGroup.createSuccess'));
onCancel?.(e);
},
[id, input, sessionCustomGroups],
);
const toggleExpandSessionGroup = useGlobalStore((s) => s.toggleExpandSessionGroup);
const { message } = App.useApp();
const [updateSessionGroup, addCustomGroup] = useSessionStore((s) => [
s.updateSessionGroupId,
s.addSessionGroup,
]);
const [input, setInput] = useState('');

return (
<div onClick={(e) => e.stopPropagation()}>
<Modal
allowFullscreen
centered
onCancel={onCancel}
onOk={handleSubmit}
onOk={async (e: MouseEvent<HTMLButtonElement>) => {
if (!input) return;

if (input.length === 0 || input.length > 20)
return message.warning(t('sessionGroup.tooLong'));

const groupId = await addCustomGroup(input);
await updateSessionGroup(id, groupId);
toggleExpandSessionGroup(groupId, true);

message.success(t('sessionGroup.createSuccess'));
onCancel?.(e);
}}
open={open}
title={t('sessionGroup.createGroup')}
width={400}
>
<Input
autoFocus
onChange={(e) => setInput(e.target.value)}
placeholder={t('sessionGroup.inputPlaceholder')}
value={input}
/>
<Flexbox paddingBlock={16}>
<Input
autoFocus
onChange={(e) => setInput(e.target.value)}
placeholder={t('sessionGroup.inputPlaceholder')}
value={input}
/>
</Flexbox>
</Modal>
</div>
);
Expand Down
Loading

0 comments on commit f3955ce

Please sign in to comment.