Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / applications / drive / src / app / store / _views / useRevisionsView.ts
blobd2e6ee0a9db38bd3881a9d2e18b3f180098c7977
1 import { useCallback, useEffect, useState } from 'react';
3 import { useLoading } from '@proton/hooks';
4 import {
5     queryDeleteFileRevision,
6     queryFileRevisions,
7     queryRestoreFileRevision,
8 } from '@proton/shared/lib/api/drive/files';
9 import { SHARE_MEMBER_PERMISSIONS } from '@proton/shared/lib/drive/permissions';
10 import type {
11     DriveFileRestoreRevisionResult,
12     DriveFileRevisionPayload,
13     DriveFileRevisionsResult,
14 } from '@proton/shared/lib/interfaces/drive/file';
15 import { FileRevisionState } from '@proton/shared/lib/interfaces/drive/file';
17 import { revisionPayloadToRevision } from '../_api';
18 import useDebouncedRequest from '../_api/useDebouncedRequest';
19 import type { DriveFileRevision } from '../_revisions';
20 import { useDirectSharingInfo } from '../_shares/useDirectSharingInfo';
22 const filterRevisions = (revisions: DriveFileRevisionPayload[]) => {
23     // Draft state, we don't want to show it to the user
24     return revisions.reduce<DriveFileRevision[]>((filteredRevisions, revision) => {
25         if (revision.State !== FileRevisionState.Draft) {
26             filteredRevisions.push(revisionPayloadToRevision(revision));
27         }
28         return filteredRevisions;
29     }, []);
32 export default function useRevisionsView(shareId: string, linkId: string) {
33     const debouncedRequest = useDebouncedRequest();
34     const [isLoading, withLoading] = useLoading(true);
35     const [revisions, setRevisions] = useState<DriveFileRevision[]>([]);
36     const { getSharePermissions } = useDirectSharingInfo();
37     const [permissions, setPermissions] = useState<SHARE_MEMBER_PERMISSIONS>(SHARE_MEMBER_PERMISSIONS.EDITOR);
39     const loadRevisions = useCallback(
40         (abortSignal: AbortSignal) => {
41             void withLoading(async () => {
42                 await Promise.all([
43                     debouncedRequest<DriveFileRevisionsResult>(queryFileRevisions(shareId, linkId), abortSignal).then(
44                         (result) => {
45                             setRevisions(filterRevisions(result.Revisions));
46                         }
47                     ),
48                     getSharePermissions(abortSignal, shareId).then(setPermissions),
49                 ]);
50             });
51         },
52         [shareId, linkId]
53     );
55     useEffect(() => {
56         const ac = new AbortController();
57         loadRevisions(ac.signal);
58         return () => {
59             ac.abort();
60         };
61     }, [shareId, linkId]);
62     const deleteRevision = async (abortSignal: AbortSignal, revisionId: string) => {
63         await debouncedRequest(queryDeleteFileRevision(shareId, linkId, revisionId), abortSignal);
64         setRevisions(revisions.filter((revision) => revision.id !== revisionId));
65     };
67     const restoreRevision = async (abortSignal: AbortSignal, revisionId: string) => {
68         const { Code } = await debouncedRequest<DriveFileRestoreRevisionResult>(
69             queryRestoreFileRevision(shareId, linkId, revisionId),
70             abortSignal
71         );
72         // If restore happened immediately fetch updated revision list
73         if (Code === 1000) {
74             loadRevisions(abortSignal);
75         }
76         return Code;
77     };
79     return {
80         isLoading,
81         revisions,
82         permissions,
83         deleteRevision,
84         restoreRevision,
85     };