From 300430e2d5a4a1c35ab230315eb0a7e099ba2093 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 6 Feb 2024 05:17:43 +0530 Subject: [PATCH 1/4] fixes weird bug- dark theme hook --- frontend/src/hooks/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/hooks/index.ts b/frontend/src/hooks/index.ts index a2bf3f3f..23fec6e8 100644 --- a/frontend/src/hooks/index.ts +++ b/frontend/src/hooks/index.ts @@ -92,7 +92,7 @@ export function useDarkTheme() { else{ document.documentElement.classList.remove('dark'); } - }) + },[isDarkTheme]) // Function to toggle dark mode const toggleTheme:any = () => { From 3c68cbc955573467e4fb95cfd5db1f3d96a9e88f Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 7 Feb 2024 04:42:39 +0530 Subject: [PATCH 2/4] fix(stream err on changing conversation) --- frontend/src/Navigation.tsx | 1 - frontend/src/conversation/Conversation.tsx | 23 ++++++++++++++----- frontend/src/conversation/conversationApi.ts | 4 ++++ .../src/conversation/conversationSlice.ts | 8 ++++++- frontend/src/hooks/index.ts | 19 +++++++-------- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index c85b87bd..c3bf0a93 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -97,7 +97,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { fetchConversations(); } }, [conversations, dispatch]); - async function fetchConversations() { return await getConversations() .then((fetchedConversations) => { diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index b541c873..6163fcd4 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -4,7 +4,7 @@ import { useDarkTheme } from '../hooks'; import Hero from '../Hero'; import { AppDispatch } from '../store'; import ConversationBubble from './ConversationBubble'; -import { +import conversationSlice, { addQuery, fetchAnswer, selectQueries, @@ -17,16 +17,17 @@ import Spinner from './../assets/spinner.svg'; import { FEEDBACK, Query } from './conversationModels'; import { sendFeedback } from './conversationApi'; import ArrowDown from './../assets/arrow-down.svg'; - +import { selectConversationId } from '../preferences/preferenceSlice'; export default function Conversation() { const queries = useSelector(selectQueries); const status = useSelector(selectStatus); + const conversationId = useSelector(selectConversationId) const dispatch = useDispatch(); const endMessageRef = useRef(null); const inputRef = useRef(null); const [isDarkTheme]= useDarkTheme(); const [hasScrolledToLast, setHasScrolledToLast] = useState(true); - + const fetchStream = useRef(new AbortController()) useEffect(() => { scrollIntoView(); }, [queries.length, queries[queries.length - 1]]); @@ -37,7 +38,13 @@ export default function Conversation() { element.focus(); } }, []); - + useEffect(()=>{ + console.log('changed the conversation', conversationId) + return ()=>{ + console.log('i just did abortion !'); + fetchStream.current.abort(); + } + },[conversationId]) useEffect(() => { const observerCallback: IntersectionObserverCallback = (entries) => { entries.forEach((entry) => { @@ -65,13 +72,17 @@ export default function Conversation() { }); }; + fetchStream.current != null && useEffect(()=>{ + return ()=>{fetchStream.current.abort()} + },[selectConversationId]) const handleQuestion = (question: string) => { question = question.trim(); if (question === '') return; dispatch(addQuery({ prompt: question })); - dispatch(fetchAnswer({ question })); - }; + //@ts-ignore + fetchStream.current = dispatch(fetchAnswer({ question })); + }; const handleFeedback = (query: Query, feedback: FEEDBACK, index: number) => { const prevFeedback = query.feedback; dispatch(updateQuery({ index, query: { feedback } })); diff --git a/frontend/src/conversation/conversationApi.ts b/frontend/src/conversation/conversationApi.ts index a01d034a..b446fc17 100644 --- a/frontend/src/conversation/conversationApi.ts +++ b/frontend/src/conversation/conversationApi.ts @@ -5,6 +5,7 @@ const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; export function fetchAnswerApi( question: string, + signal:AbortSignal, apiKey: string, selectedDocs: Doc, history: Array = [], @@ -65,6 +66,7 @@ export function fetchAnswerApi( conversation_id: conversationId, prompt_id: promptId, }), + signal, }) .then((response) => { if (response.ok) { @@ -87,6 +89,7 @@ export function fetchAnswerApi( export function fetchAnswerSteaming( question: string, + signal:AbortSignal, apiKey: string, selectedDocs: Doc, history: Array = [], @@ -134,6 +137,7 @@ export function fetchAnswerSteaming( 'Content-Type': 'application/json', }, body: JSON.stringify(body), + signal }) .then((response) => { if (!response.body) throw Error('No response body'); diff --git a/frontend/src/conversation/conversationSlice.ts b/frontend/src/conversation/conversationSlice.ts index 3f840d3c..c6dd1b37 100644 --- a/frontend/src/conversation/conversationSlice.ts +++ b/frontend/src/conversation/conversationSlice.ts @@ -16,17 +16,21 @@ const API_STREAMING = import.meta.env.VITE_API_STREAMING === 'true'; export const fetchAnswer = createAsyncThunk( 'fetchAnswer', - async ({ question }, { dispatch, getState }) => { + async ({ question }, { dispatch, getState, signal }) => { const state = getState() as RootState; + console.log('signal', signal); + if (state.preference) { if (API_STREAMING) { await fetchAnswerSteaming( question, + signal, state.preference.apiKey, state.preference.selectedDocs!, state.conversation.queries, state.conversation.conversationId, state.preference.prompt.id, + (event) => { const data = JSON.parse(event.data); @@ -78,6 +82,7 @@ export const fetchAnswer = createAsyncThunk( } else { const answer = await fetchAnswerApi( question, + signal, state.preference.apiKey, state.preference.selectedDocs!, state.conversation.queries, @@ -193,6 +198,7 @@ export const conversationSlice = createSlice({ state.status = 'loading'; }) .addCase(fetchAnswer.rejected, (state, action) => { + if(action.meta.aborted)return state; //ignore error state.status = 'failed'; state.queries[state.queries.length - 1].error = 'Something went wrong. Please try again later.'; diff --git a/frontend/src/hooks/index.ts b/frontend/src/hooks/index.ts index 23fec6e8..8327f766 100644 --- a/frontend/src/hooks/index.ts +++ b/frontend/src/hooks/index.ts @@ -70,7 +70,7 @@ export function useDarkTheme() { useEffect(() => { // Check if dark mode preference exists in local storage - const savedMode:string | null = localStorage.getItem('selectedTheme'); + const savedMode: string | null = localStorage.getItem('selectedTheme'); // Set dark mode based on local storage preference if (savedMode === 'Dark') { @@ -83,22 +83,19 @@ export function useDarkTheme() { document.documentElement.classList.remove('dark'); } }, []); - useEffect(()=>{ - localStorage.setItem('selectedTheme',isDarkTheme ? 'Dark' : 'Light'); - if(isDarkTheme){ + useEffect(() => { + localStorage.setItem('selectedTheme', isDarkTheme ? 'Dark' : 'Light'); + if (isDarkTheme) { document.documentElement.classList.add('dark'); document.documentElement.classList.add('dark:bg-raisin-black'); } - else{ + else { document.documentElement.classList.remove('dark'); } - },[isDarkTheme]) - - // Function to toggle dark mode - const toggleTheme:any = () => { + }, [isDarkTheme]) + //method to toggle theme + const toggleTheme: any = () => { setIsDarkTheme(!isDarkTheme) - }; - return [isDarkTheme, toggleTheme]; } \ No newline at end of file From 0ce39e7f5274ef7206bfabc64b3bb44647b34c3f Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 7 Feb 2024 05:04:16 +0530 Subject: [PATCH 3/4] purge logs and !need code --- frontend/src/conversation/Conversation.tsx | 20 ++++++++----------- .../src/conversation/conversationSlice.ts | 8 +++++--- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index 6163fcd4..12ebba66 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -25,9 +25,9 @@ export default function Conversation() { const dispatch = useDispatch(); const endMessageRef = useRef(null); const inputRef = useRef(null); - const [isDarkTheme]= useDarkTheme(); + const [isDarkTheme] = useDarkTheme(); const [hasScrolledToLast, setHasScrolledToLast] = useState(true); - const fetchStream = useRef(new AbortController()) + const fetchStream = useRef(null) useEffect(() => { scrollIntoView(); }, [queries.length, queries[queries.length - 1]]); @@ -38,13 +38,13 @@ export default function Conversation() { element.focus(); } }, []); - useEffect(()=>{ - console.log('changed the conversation', conversationId) - return ()=>{ - console.log('i just did abortion !'); - fetchStream.current.abort(); + + useEffect(() => { + return () => { + fetchStream.current.abort(); //abort previous stream } - },[conversationId]) + }, [conversationId]) + useEffect(() => { const observerCallback: IntersectionObserverCallback = (entries) => { entries.forEach((entry) => { @@ -72,14 +72,10 @@ export default function Conversation() { }); }; - fetchStream.current != null && useEffect(()=>{ - return ()=>{fetchStream.current.abort()} - },[selectConversationId]) const handleQuestion = (question: string) => { question = question.trim(); if (question === '') return; dispatch(addQuery({ prompt: question })); - //@ts-ignore fetchStream.current = dispatch(fetchAnswer({ question })); }; diff --git a/frontend/src/conversation/conversationSlice.ts b/frontend/src/conversation/conversationSlice.ts index c6dd1b37..dd21c152 100644 --- a/frontend/src/conversation/conversationSlice.ts +++ b/frontend/src/conversation/conversationSlice.ts @@ -18,8 +18,6 @@ export const fetchAnswer = createAsyncThunk( 'fetchAnswer', async ({ question }, { dispatch, getState, signal }) => { const state = getState() as RootState; - console.log('signal', signal); - if (state.preference) { if (API_STREAMING) { await fetchAnswerSteaming( @@ -198,7 +196,11 @@ export const conversationSlice = createSlice({ state.status = 'loading'; }) .addCase(fetchAnswer.rejected, (state, action) => { - if(action.meta.aborted)return state; //ignore error + if(action.meta.aborted) + { + state.status = 'idle'; + return state; + } state.status = 'failed'; state.queries[state.queries.length - 1].error = 'Something went wrong. Please try again later.'; From 615d549494b42e25304392b113f46b3cfc7ba6b1 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 7 Feb 2024 05:09:12 +0530 Subject: [PATCH 4/4] slight fixes, checking for null case --- frontend/src/conversation/Conversation.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index 12ebba66..6813ed0f 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -41,10 +41,9 @@ export default function Conversation() { useEffect(() => { return () => { - fetchStream.current.abort(); //abort previous stream + fetchStream.current && fetchStream.current.abort(); //abort previous stream } }, [conversationId]) - useEffect(() => { const observerCallback: IntersectionObserverCallback = (entries) => { entries.forEach((entry) => {