Merge branch 'renovate/playwright' into 'main'
[ProtonMail-WebClient.git] / packages / drive-store / lib / usePublicDriveCompat.tsx
blob6875800f191d0a22e14dec1378f3a09b12b47b15
1 import type { ReactNode } from 'react';
2 import { createContext, useContext } from 'react';
4 import { useDriveDocsFeatureFlag, useDriveDocsPublicSharingFF, useOpenDocument } from '../store/_documents';
5 import { type DocumentKeys } from './_documents';
6 import { usePublicNode } from './_nodes';
7 import type { DecryptedNode } from './_nodes/interface';
8 import { usePublicDocsToken } from './_shares';
9 import type { NodeMeta, PublicNodeMeta } from './interface';
11 export interface PublicDriveCompat {
12     /**
13      * Whether or not Docs is enabled. Only uses feature flags, not context aware.
14      */
15     isDocsEnabled: boolean;
17     /**
18      * Whether or not the public docs feature flag is enabled.
19      */
20     isPublicDocsEnabled: boolean;
22     /**
23      * The custom password for the public link.
24      */
25     customPassword: string;
27     /**
28      * The token for the public link.
29      */
30     token: string;
32     /**
33      * The url password for the public link.
34      */
35     urlPassword: string;
37     /**
38      * Whether or not a custom password is needed.
39      */
40     isPasswordNeeded: boolean;
42     /**
43      * Submits the custom password.
44      */
45     submitPassword: (customPassword: string) => Promise<void>;
47     /**
48      * Whether or not the interface is ready to receive calls.
49      */
50     isReady: boolean;
52     /**
53      * Whether or not there was an error loading the public link.
54      */
55     isError: boolean;
57     /**
58      * The error that occurred while loading the public link.
59      */
60     error?: Error;
62     /**
63      * Gets a node, either from cache or fetched.
64      */
65     getNode: (meta: PublicNodeMeta, forceFetch?: boolean) => Promise<DecryptedNode>;
67     /**
68      * Redirects to the authed document.
69      */
70     redirectToAuthedDocument: (meta: NodeMeta) => void;
72     /**
73      * Gets the keys for a given document node.
74      */
75     getDocumentKeys: (meta: PublicNodeMeta) => Promise<Pick<DocumentKeys, 'documentContentKey'>>;
77     /**
78      * Gets the authentication headers for `useApi()`
79      */
80     getPublicAuthHeaders: () => { [key: string]: string };
83 export const usePublicDriveCompatValue = (): PublicDriveCompat => {
84     const { isDocsEnabled } = useDriveDocsFeatureFlag();
85     const { isDocsPublicSharingEnabled } = useDriveDocsPublicSharingFF();
87     const {
88         isReady: isDocsTokenReady,
89         isError,
90         error,
91         getPublicAuthHeaders,
92         customPassword,
93         token,
94         urlPassword,
95         isPasswordNeeded,
96         submitPassword,
97         linkId,
98     } = usePublicDocsToken();
100     const { getNode, getNodeContentKey, didCompleteInitialSetup } = usePublicNode({ isDocsTokenReady, linkId });
101     const { openDocumentWindow } = useOpenDocument();
103     const redirectToAuthedDocument = (meta: NodeMeta) => openDocumentWindow({ ...meta, mode: 'open', window: window });
105     return {
106         isDocsEnabled,
107         customPassword,
108         isPasswordNeeded,
109         submitPassword,
110         token,
111         urlPassword,
112         isReady: isDocsTokenReady && didCompleteInitialSetup,
113         isError,
114         error,
115         redirectToAuthedDocument: redirectToAuthedDocument,
116         isPublicDocsEnabled: isDocsPublicSharingEnabled,
117         getDocumentKeys: async (nodeMeta) => ({
118             documentContentKey: await getNodeContentKey(nodeMeta),
119         }),
120         getNode,
121         getPublicAuthHeaders,
122     };
125 export const PublicCompatContext = createContext<PublicDriveCompat | null>(null);
127 export const usePublicDriveCompat = () => {
128     const context = useContext(PublicCompatContext);
129     if (!context) {
130         throw new Error('No provider for PublicCompatContext');
131     }
132     return context;
135 export const PublicCompatProvider = ({ children }: { children: ReactNode }) => {
136     const value = usePublicDriveCompatValue();
138     return <PublicCompatContext.Provider value={value}>{children}</PublicCompatContext.Provider>;