1 import { useEffect } from 'react';
3 import { useLoading } from '@proton/hooks';
4 import { isPreviewAvailable } from '@proton/shared/lib/helpers/preview';
6 import { logError } from '../../utils/errorHandling';
7 import { useLinksListing } from '../_links';
8 import { usePublicLinksListingProvider } from '../_links/useLinksListing/usePublicLinksListing';
9 import { useUserSettings } from '../_settings';
10 import type { UserSortParams } from '../_settings/sorting';
11 import { useAbortSignal, useControlledSorting, useMemoArrayNoMatterTheOrder } from './utils';
12 import type { SortParams } from './utils/useSorting';
14 export function useFileViewNavigation(
15 useNavigation: boolean,
17 parentLinkId?: string,
18 currentLinkId?: string
20 const { sort } = useUserSettings();
21 const linksListing = useLinksListing();
22 return useFileViewNavigationBase(useNavigation, shareId, linksListing, sort, parentLinkId, currentLinkId);
25 export function usePublicFileViewNavigation(
26 useNavigation: boolean,
28 sortParams: SortParams,
29 parentLinkId?: string,
30 currentLinkId?: string
32 const linksListing = usePublicLinksListingProvider();
33 return useFileViewNavigationBase(useNavigation, shareId, linksListing, sortParams, parentLinkId, currentLinkId);
36 function useFileViewNavigationBase(
37 useNavigation: boolean,
39 linksListing: ReturnType<typeof useLinksListing | typeof usePublicLinksListingProvider>,
40 sort: UserSortParams | SortParams,
41 parentLinkId?: string,
42 currentLinkId?: string
44 const [isLoading, withLoading] = useLoading(true);
46 const { getCachedChildren, loadChildren } = linksListing;
48 const abortSignal = useAbortSignal([shareId, parentLinkId]);
49 const { links: children, isDecrypting } = parentLinkId
50 ? getCachedChildren(abortSignal, shareId, parentLinkId)
51 : { links: [], isDecrypting: false };
52 const cachedChildren = useMemoArrayNoMatterTheOrder(children);
53 const { sortedList } = useControlledSorting(useNavigation ? cachedChildren : [], sort, async () => {});
54 const linksAvailableForPreview = sortedList.filter(({ mimeType, size }) => isPreviewAvailable(mimeType, size));
57 if (!useNavigation || !parentLinkId) {
61 const ac = new AbortController();
62 withLoading(loadChildren(ac.signal, shareId, parentLinkId)).catch(logError);
66 }, [useNavigation, parentLinkId]);
68 const index = linksAvailableForPreview.findIndex(({ linkId }) => linkId === currentLinkId);
70 if (!useNavigation || isLoading || isDecrypting || index === -1) {
76 total: linksAvailableForPreview.length,
77 nextLinkId: linksAvailableForPreview[index < linksAvailableForPreview.length ? index + 1 : 0]?.linkId,
78 prevLinkId: linksAvailableForPreview[index > 0 ? index - 1 : linksAvailableForPreview.length - 1]?.linkId,