fix: reduce unnessary rerender due to current thread retrieval

This commit is contained in:
Louis 2025-09-18 17:54:22 +07:00
parent 2a2bc40dfe
commit 6342956cd6
3 changed files with 46 additions and 33 deletions

View File

@ -117,9 +117,11 @@ export const useAssistant = create<AssistantState>((set, get) => ({
} }
}, },
setCurrentAssistant: (assistant, saveToStorage = true) => { setCurrentAssistant: (assistant, saveToStorage = true) => {
set({ currentAssistant: assistant }) if (assistant !== get().currentAssistant) {
if (saveToStorage) { set({ currentAssistant: assistant })
setLastUsedAssistantId(assistant.id) if (saveToStorage) {
setLastUsedAssistantId(assistant.id)
}
} }
}, },
setAssistants: (assistants) => { setAssistants: (assistants) => {

View File

@ -46,7 +46,10 @@ export const useThreads = create<ThreadState>()((set, get) => ({
id: id:
thread.model.provider === 'llama.cpp' || thread.model.provider === 'llama.cpp' ||
thread.model.provider === 'llamacpp' thread.model.provider === 'llamacpp'
? thread.model?.id.split(':').slice(0, 2).join(getServiceHub().path().sep()) ? thread.model?.id
.split(':')
.slice(0, 2)
.join(getServiceHub().path().sep())
: thread.model?.id, : thread.model?.id,
} }
: undefined, : undefined,
@ -94,10 +97,12 @@ export const useThreads = create<ThreadState>()((set, get) => ({
}, },
toggleFavorite: (threadId) => { toggleFavorite: (threadId) => {
set((state) => { set((state) => {
getServiceHub().threads().updateThread({ getServiceHub()
...state.threads[threadId], .threads()
isFavorite: !state.threads[threadId].isFavorite, .updateThread({
}) ...state.threads[threadId],
isFavorite: !state.threads[threadId].isFavorite,
})
return { return {
threads: { threads: {
...state.threads, ...state.threads,
@ -168,7 +173,9 @@ export const useThreads = create<ThreadState>()((set, get) => ({
{} as Record<string, Thread> {} as Record<string, Thread>
) )
Object.values(updatedThreads).forEach((thread) => { Object.values(updatedThreads).forEach((thread) => {
getServiceHub().threads().updateThread({ ...thread, isFavorite: false }) getServiceHub()
.threads()
.updateThread({ ...thread, isFavorite: false })
}) })
return { threads: updatedThreads } return { threads: updatedThreads }
}) })
@ -180,7 +187,7 @@ export const useThreads = create<ThreadState>()((set, get) => ({
return get().threads[threadId] return get().threads[threadId]
}, },
setCurrentThreadId: (threadId) => { setCurrentThreadId: (threadId) => {
set({ currentThreadId: threadId }) if (threadId !== get().currentThreadId) set({ currentThreadId: threadId })
}, },
createThread: async (model, title, assistant) => { createThread: async (model, title, assistant) => {
const newThread: Thread = { const newThread: Thread = {
@ -190,33 +197,38 @@ export const useThreads = create<ThreadState>()((set, get) => ({
updated: Date.now() / 1000, updated: Date.now() / 1000,
assistants: assistant ? [assistant] : [], assistants: assistant ? [assistant] : [],
} }
return await getServiceHub().threads().createThread(newThread).then((createdThread) => { return await getServiceHub()
set((state) => { .threads()
// Get all existing threads as an array .createThread(newThread)
const existingThreads = Object.values(state.threads) .then((createdThread) => {
set((state) => {
// Get all existing threads as an array
const existingThreads = Object.values(state.threads)
// Create new array with the new thread at the beginning // Create new array with the new thread at the beginning
const reorderedThreads = [createdThread, ...existingThreads] const reorderedThreads = [createdThread, ...existingThreads]
// Use setThreads to handle proper ordering (this will assign order 1, 2, 3...) // Use setThreads to handle proper ordering (this will assign order 1, 2, 3...)
get().setThreads(reorderedThreads) get().setThreads(reorderedThreads)
return { return {
currentThreadId: createdThread.id, currentThreadId: createdThread.id,
} }
})
return createdThread
}) })
return createdThread
})
}, },
updateCurrentThreadAssistant: (assistant) => { updateCurrentThreadAssistant: (assistant) => {
set((state) => { set((state) => {
if (!state.currentThreadId) return { ...state } if (!state.currentThreadId) return { ...state }
const currentThread = state.getCurrentThread() const currentThread = state.getCurrentThread()
if (currentThread) if (currentThread)
getServiceHub().threads().updateThread({ getServiceHub()
...currentThread, .threads()
assistants: [{ ...assistant, model: currentThread.model }], .updateThread({
}) ...currentThread,
assistants: [{ ...assistant, model: currentThread.model }],
})
return { return {
threads: { threads: {
...state.threads, ...state.threads,
@ -233,7 +245,10 @@ export const useThreads = create<ThreadState>()((set, get) => ({
set((state) => { set((state) => {
if (!state.currentThreadId) return { ...state } if (!state.currentThreadId) return { ...state }
const currentThread = state.getCurrentThread() const currentThread = state.getCurrentThread()
if (currentThread) getServiceHub().threads().updateThread({ ...currentThread, model }) if (currentThread)
getServiceHub()
.threads()
.updateThread({ ...currentThread, model })
return { return {
threads: { threads: {
...state.threads, ...state.threads,

View File

@ -30,7 +30,6 @@ function ThreadDetail() {
const serviceHub = useServiceHub() const serviceHub = useServiceHub()
const { threadId } = useParams({ from: Route.id }) const { threadId } = useParams({ from: Route.id })
const setCurrentThreadId = useThreads((state) => state.setCurrentThreadId) const setCurrentThreadId = useThreads((state) => state.setCurrentThreadId)
const currentThreadId = useThreads((state) => state.currentThreadId)
const setCurrentAssistant = useAssistant((state) => state.setCurrentAssistant) const setCurrentAssistant = useAssistant((state) => state.setCurrentAssistant)
const assistants = useAssistant((state) => state.assistants) const assistants = useAssistant((state) => state.assistants)
const setMessages = useMessages((state) => state.setMessages) const setMessages = useMessages((state) => state.setMessages)
@ -49,16 +48,13 @@ function ThreadDetail() {
const scrollContainerRef = useRef<HTMLDivElement>(null) const scrollContainerRef = useRef<HTMLDivElement>(null)
useEffect(() => { useEffect(() => {
if (currentThreadId !== threadId) {
setCurrentThreadId(threadId) setCurrentThreadId(threadId)
const assistant = assistants.find( const assistant = assistants.find(
(assistant) => assistant.id === thread?.assistants?.[0]?.id (assistant) => assistant.id === thread?.assistants?.[0]?.id
) )
if (assistant) setCurrentAssistant(assistant) if (assistant) setCurrentAssistant(assistant)
}
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [threadId, currentThreadId, assistants]) }, [threadId, assistants])
useEffect(() => { useEffect(() => {
serviceHub serviceHub