diff --git a/src/renderer/src/hooks/useTags.ts b/src/renderer/src/hooks/useTags.ts index 44d43377c1..cdd0af5246 100644 --- a/src/renderer/src/hooks/useTags.ts +++ b/src/renderer/src/hooks/useTags.ts @@ -1,6 +1,6 @@ import { createSelector } from '@reduxjs/toolkit' import { RootState, useAppDispatch, useAppSelector } from '@renderer/store' -import { setTagsOrder, updateAssistants } from '@renderer/store/assistants' +import { setTagsOrder, updateTagCollapse } from '@renderer/store/assistants' import { flatMap, groupBy, uniq } from 'lodash' import { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' @@ -12,6 +12,8 @@ const selectAssistantsState = (state: RootState) => state.assistants // 记忆化 tagsOrder 选择器(自动处理默认值)--- 这是一个选择器,用于从 store 中获取 tagsOrder 的值。因为之前的tagsOrder是后面新加的,不这样做会报错,所以这里需要处理一下默认值 const selectTagsOrder = createSelector([selectAssistantsState], (assistants) => assistants.tagsOrder ?? []) +const selectCollapsedTags = createSelector([selectAssistantsState], (assistants) => assistants.collapsedTags ?? {}) + // 定义useTags的返回类型,包含所有标签和获取特定标签的助手函数 // 为了不增加新的概念,标签直接作为助手的属性,所以这里的标签是指助手的标签属性 // 但是为了方便管理,增加了一个获取特定标签的助手函数 @@ -20,6 +22,7 @@ export const useTags = () => { const { t } = useTranslation() const dispatch = useAppDispatch() const savedTagsOrder = useAppSelector(selectTagsOrder) + const collapsedTags = useAppSelector(selectCollapsedTags) // 计算所有标签 const allTags = useMemo(() => { @@ -38,28 +41,6 @@ export const useTags = () => { [assistants] ) - const updateTagsOrder = useCallback( - (newOrder: string[]) => { - dispatch(setTagsOrder(newOrder)) - updateAssistants( - assistants.map((assistant) => { - if (!assistant.tags || assistant.tags.length === 0) { - return assistant - } - const newTags = [...assistant.tags] - newTags.sort((a, b) => { - return newOrder.indexOf(a) - newOrder.indexOf(b) - }) - return { - ...assistant, - tags: newTags - } - }) - ) - }, - [assistants, dispatch] - ) - const getGroupedAssistants = useMemo(() => { // 按标签分组,处理多标签的情况 const assistantsByTags = flatMap(assistants, (assistant) => { @@ -100,10 +81,26 @@ export const useTags = () => { return grouped }, [assistants, t, savedTagsOrder]) + const updateTagsOrder = useCallback( + (newOrder: string[]) => { + dispatch(setTagsOrder(newOrder)) + }, + [dispatch] + ) + + const toggleTagCollapse = useCallback( + (tag: string) => { + dispatch(updateTagCollapse(tag)) + }, + [dispatch] + ) + return { allTags, getAssistantsByTag, getGroupedAssistants, - updateTagsOrder + updateTagsOrder, + collapsedTags, + toggleTagCollapse } } diff --git a/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx b/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx index cbcd272791..b164e7b492 100644 --- a/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx @@ -27,10 +27,9 @@ const Assistants: FC = ({ }) => { const { assistants, removeAssistant, addAssistant, updateAssistants } = useAssistants() const [dragging, setDragging] = useState(false) - const [collapsedTags, setCollapsedTags] = useState>({}) const { addAgent } = useAgents() const { t } = useTranslation() - const { getGroupedAssistants } = useTags() + const { getGroupedAssistants, collapsedTags, toggleTagCollapse } = useTags() const { assistantsTabSortType = 'list', setAssistantsTabSortType } = useAssistantsTabSortType() const containerRef = useRef(null) @@ -46,13 +45,6 @@ const Assistants: FC = ({ [activeAssistant, assistants, removeAssistant, setActiveAssistant, onCreateDefaultAssistant] ) - const toggleTagCollapse = useCallback((tag: string) => { - setCollapsedTags((prev) => ({ - ...prev, - [tag]: !prev[tag] - })) - }, []) - const handleSortByChange = useCallback( (sortType: AssistantsSortType) => { setAssistantsTabSortType(sortType) @@ -103,7 +95,6 @@ const Assistants: FC = ({ handleGroupReorder(group.tag, newList)} - style={{ paddingBottom: dragging ? '34px' : 0 }} onDragStart={() => setDragging(true)} onDragEnd={() => setDragging(false)}> {(assistant) => ( @@ -141,7 +132,6 @@ const Assistants: FC = ({ setDragging(true)} onDragEnd={() => setDragging(false)}> {(assistant) => ( diff --git a/src/renderer/src/store/assistants.ts b/src/renderer/src/store/assistants.ts index 14213006d3..35ea98af76 100644 --- a/src/renderer/src/store/assistants.ts +++ b/src/renderer/src/store/assistants.ts @@ -9,12 +9,14 @@ export interface AssistantsState { defaultAssistant: Assistant assistants: Assistant[] tagsOrder: string[] + collapsedTags: Record } const initialState: AssistantsState = { defaultAssistant: getDefaultAssistant(), assistants: [getDefaultAssistant()], - tagsOrder: [] + tagsOrder: [], + collapsedTags: {} } const assistantsSlice = createSlice({ @@ -58,6 +60,26 @@ const assistantsSlice = createSlice({ } } }, + setTagsOrder: (state, action: PayloadAction) => { + const newOrder = action.payload + state.tagsOrder = newOrder + const prevCollapsed = state.collapsedTags || {} + const updatedCollapsed: Record = { ...prevCollapsed } + newOrder.forEach((tag) => { + if (!(tag in updatedCollapsed)) { + updatedCollapsed[tag] = false + } + }) + state.collapsedTags = updatedCollapsed + }, + updateTagCollapse: (state, action: PayloadAction) => { + const tag = action.payload + const prev = state.collapsedTags || {} + state.collapsedTags = { + ...prev, + [tag]: !prev[tag] + } + }, addTopic: (state, action: PayloadAction<{ assistantId: string; topic: Topic }>) => { const topic = action.payload.topic topic.createdAt = topic.createdAt || new Date().toISOString() @@ -130,9 +152,6 @@ const assistantsSlice = createSlice({ } : assistant ) - }, - setTagsOrder: (state, action: PayloadAction) => { - state.tagsOrder = action.payload } } }) @@ -150,7 +169,8 @@ export const { removeAllTopics, setModel, setTagsOrder, - updateAssistantSettings + updateAssistantSettings, + updateTagCollapse } = assistantsSlice.actions export default assistantsSlice.reducer