From 2708d429a96ed9a7590d134157fed147bd499fd8 Mon Sep 17 00:00:00 2001 From: Apoorv Mishra Date: Thu, 13 Oct 2022 05:18:43 +0530 Subject: [PATCH] Set subscribe/unsubscribe state correctly for documents (#4266) --- app/hooks/useRequest.ts | 43 ++++++++++++++++++++++++++++++++++++++ app/menus/DocumentMenu.tsx | 21 +++++++++++++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 app/hooks/useRequest.ts diff --git a/app/hooks/useRequest.ts b/app/hooks/useRequest.ts new file mode 100644 index 000000000..c68b43d7b --- /dev/null +++ b/app/hooks/useRequest.ts @@ -0,0 +1,43 @@ +import * as React from "react"; + +type RequestResponse = { + /** The return value of the request function. */ + data: T | undefined; + /** The request error, if any. */ + error: unknown; + /** Whether the request is currently in progress. */ + loading: boolean; + /** Function to start the request. */ + request: () => Promise; +}; + +/** + * A hook to make an API request and track its state within a component. + * + * @param requestFn The function to call to make the request, it should return a promise. + * @returns + */ +export default function useRequest( + requestFn: () => Promise +): RequestResponse { + const [data, setData] = React.useState(); + const [loading, setLoading] = React.useState(false); + const [error, setError] = React.useState(); + + const request = React.useCallback(async () => { + setLoading(true); + try { + const response = await requestFn(); + setData(response); + return response; + } catch (err) { + setError(err); + } finally { + setLoading(false); + } + + return undefined; + }, [requestFn]); + + return { data, loading, error, request }; +} diff --git a/app/menus/DocumentMenu.tsx b/app/menus/DocumentMenu.tsx index 2d28db984..bcff282ae 100644 --- a/app/menus/DocumentMenu.tsx +++ b/app/menus/DocumentMenu.tsx @@ -43,6 +43,7 @@ import useActionContext from "~/hooks/useActionContext"; import useCurrentTeam from "~/hooks/useCurrentTeam"; import useMobile from "~/hooks/useMobile"; import usePolicy from "~/hooks/usePolicy"; +import useRequest from "~/hooks/useRequest"; import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; import { MenuItem } from "~/types"; @@ -79,7 +80,7 @@ function DocumentMenu({ onClose, }: Props) { const team = useCurrentTeam(); - const { policies, collections, documents } = useStores(); + const { policies, collections, documents, subscriptions } = useStores(); const { showToast } = useToasts(); const menu = useMenuState({ modal, @@ -96,6 +97,22 @@ function DocumentMenu({ const { t } = useTranslation(); const isMobile = useMobile(); const file = React.useRef(null); + const { data, loading, request } = useRequest(() => + subscriptions.fetchPage({ + documentId: document.id, + event: "documents.update", + }) + ); + + const handleOpen = React.useCallback(async () => { + if (!data && !loading) { + request(); + } + + if (onOpen) { + onOpen(); + } + }, [data, loading, onOpen, request]); const handleRestore = React.useCallback( async ( @@ -219,7 +236,7 @@ function DocumentMenu({