31 lines
1.5 KiB
TypeScript
31 lines
1.5 KiB
TypeScript
import { useCallback, useRef, useState } from 'react';
|
||
import { getComments } from '../../services/api/documents';
|
||
import type { CommentOut } from '../../types/api';
|
||
|
||
export type CommentsState = { status: 'loading' } | { status: 'error' } | { status: 'done'; comments: CommentOut[] };
|
||
|
||
/** Комментарии документа по запросу: `load` перечитывает список, `reset` сбрасывает его (при закрытии панели или поповера). */
|
||
export function useDocumentComments(documentId: string | null) {
|
||
const [state, setState] = useState<CommentsState | null>(null);
|
||
// номер последнего запроса: ответ устаревшего запроса или пришедший после reset игнорируется
|
||
const requestNo = useRef(0);
|
||
|
||
const load = useCallback(() => {
|
||
requestNo.current += 1;
|
||
const mine = requestNo.current;
|
||
if (!documentId) return;
|
||
// при перечитывании после добавления старый список остаётся на экране до ответа
|
||
setState((prev) => (prev?.status === 'done' ? prev : { status: 'loading' }));
|
||
getComments(documentId)
|
||
.then((comments) => mine === requestNo.current && setState({ status: 'done', comments }))
|
||
.catch(() => mine === requestNo.current && setState({ status: 'error' }));
|
||
}, [documentId]);
|
||
|
||
const reset = useCallback(() => {
|
||
requestNo.current += 1;
|
||
setState(null);
|
||
}, []);
|
||
|
||
return { state, load, reset };
|
||
}
|