Skip to content

Commit

Permalink
refactor: replace genericReducerWithAbortController with useRef
Browse files Browse the repository at this point in the history
Signed-off-by: Lin Wang <[email protected]>
  • Loading branch information
wanglam committed Nov 27, 2023
1 parent 15dcaf1 commit a7eef4d
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 54 deletions.
6 changes: 3 additions & 3 deletions public/components/edit_conversation_name_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ export const EditConversationNameModal = ({
defaultTitle,
}: EditConversationNameModalProps) => {
const titleInputRef = useRef<HTMLInputElement>(null);
const { loading, abortController, patchSession } = usePatchSession();
const { loading, abort, patchSession } = usePatchSession();

const handleCancel = useCallback(() => {
abortController?.abort();
abort();
onClose?.('cancelled');
}, [onClose, abortController]);
}, [onClose, abort]);
const handleConfirm = useCallback(async () => {
const title = titleInputRef.current?.value.trim();
if (!title) {
Expand Down
37 changes: 0 additions & 37 deletions public/hooks/fetch_reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,3 @@ export const genericReducer: GenericReducer = (state, action) => {
return state;
}
};

interface StateWithAbortController<T> {
data?: T;
loading: boolean;
error?: Error;
abortController?: AbortController;
}

type ActionWithAbortController<T> =
| { type: 'request'; abortController: AbortController }
| { type: 'success'; payload: State<T>['data'] }
| {
type: 'failure';
error: NonNullable<State<T>['error']> | { body: NonNullable<State<T>['error']> };
};

// TODO use instantiation expressions when typescript is upgraded to >= 4.7
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type GenericReducerWithAbortController<T = any> = Reducer<
StateWithAbortController<T>,
ActionWithAbortController<T>
>;
export const genericReducerWithAbortController: GenericReducerWithAbortController = (
state,
action
) => {
switch (action.type) {
case 'request':
return { data: state.data, loading: true, abortController: action.abortController };
case 'success':
return { loading: false, data: action.payload };
case 'failure':
return { loading: false, error: 'body' in action.error ? action.error.body : action.error };
default:
return state;
}
};
32 changes: 22 additions & 10 deletions public/hooks/use_sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,70 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { useCallback, useReducer } from 'react';
import { useCallback, useReducer, useRef } from 'react';
import { ASSISTANT_API } from '../../common/constants/llm';
import { useCore } from '../contexts/core_context';
import { genericReducerWithAbortController } from './fetch_reducer';
import { genericReducer } from './fetch_reducer';

export const useDeleteSession = () => {
const core = useCore();
const [state, dispatch] = useReducer(genericReducerWithAbortController, { loading: false });
const [state, dispatch] = useReducer(genericReducer, { loading: false });
const abortControllerRef = useRef<AbortController>();

const deleteSession = useCallback(
(sessionId: string) => {
const abortController = new AbortController();
dispatch({ type: 'request', abortController });
abortControllerRef.current = new AbortController();
dispatch({ type: 'request' });
return core.services.http
.delete(`${ASSISTANT_API.SESSION}/${sessionId}`, {
signal: abortController.signal,
signal: abortControllerRef.current.signal,
})
.then((payload) => dispatch({ type: 'success', payload }))
.catch((error) => dispatch({ type: 'failure', error }));
},
[core.services.http]
);

const abort = useCallback(() => {
abortControllerRef.current?.abort();
}, []);

return {
...state,
abort,
deleteSession,
};
};

export const usePatchSession = () => {
const core = useCore();
const [state, dispatch] = useReducer(genericReducerWithAbortController, { loading: false });
const [state, dispatch] = useReducer(genericReducer, { loading: false });
const abortControllerRef = useRef<AbortController>();

const patchSession = useCallback(
(sessionId: string, title: string) => {
const abortController = new AbortController();
dispatch({ type: 'request', abortController });
abortControllerRef.current = new AbortController();
dispatch({ type: 'request' });
return core.services.http
.put(`${ASSISTANT_API.SESSION}/${sessionId}`, {
query: {
title,
},
signal: abortController.signal,
signal: abortControllerRef.current.signal,
})
.then((payload) => dispatch({ type: 'success', payload }))
.catch((error) => dispatch({ type: 'failure', error }));
},
[core.services.http]
);

const abort = useCallback(() => {
abortControllerRef.current?.abort();
}, []);

return {
...state,
abort,
patchSession,
};
};
8 changes: 4 additions & 4 deletions public/tabs/history/delete_conversation_confirm_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ export const DeleteConversationConfirmModal = ({
onClose,
sessionId,
}: DeleteConversationConfirmModalProps) => {
const { loading, data, deleteSession, abortController } = useDeleteSession();
const { loading, deleteSession, abort } = useDeleteSession();

const handleCancel = useCallback(() => {
abortController?.abort();
abort();
onClose?.('canceled');
}, [onClose, abortController]);
}, [onClose, abort]);
const handleConfirm = useCallback(async () => {
try {
await deleteSession(sessionId);
Expand All @@ -32,7 +32,7 @@ export const DeleteConversationConfirmModal = ({
return;
}
onClose?.('deleted');
}, [onClose, deleteSession]);
}, [onClose, deleteSession, sessionId]);

return (
<EuiConfirmModal
Expand Down

0 comments on commit a7eef4d

Please sign in to comment.