192 lines
5.6 KiB
TypeScript
192 lines
5.6 KiB
TypeScript
import { ToasterService } from '@features/global/services/toaster-service';
|
|
import { LoadingStateInitTrue } from '@features/global/state/atoms/Loading';
|
|
import useRouterCompany from '@features/router/hooks/use-router-company';
|
|
import { useCallback, useState } from 'react';
|
|
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
|
import { DriveItemAtom, DriveItemChildrenAtom, DriveItemPagination } from '../state/store';
|
|
import { DriveItem } from '../types';
|
|
import { useDriveActions } from './use-drive-actions';
|
|
import { useDriveUpload } from './use-drive-upload';
|
|
import short from 'short-uuid';
|
|
|
|
/**
|
|
* Get in store single item and expose methods to operate on it
|
|
* @param id
|
|
* @returns
|
|
*/
|
|
export const useDriveItem = (id: string) => {
|
|
const companyId = useRouterCompany();
|
|
const item = useRecoilValue(DriveItemAtom(id));
|
|
// const children = useRecoilValue(DriveItemChildrenAtom(id));
|
|
const [children, setChildren] = useRecoilState(DriveItemChildrenAtom(id));
|
|
const [loading, setLoading] = useRecoilState(LoadingStateInitTrue('useDriveItem-' + id));
|
|
const [_, setPaginateItem] = useRecoilState(DriveItemPagination);
|
|
const {
|
|
refresh: refreshItem,
|
|
create,
|
|
update: _update,
|
|
updateLevel: _updateLevel,
|
|
remove: _remove,
|
|
restore: _restore,
|
|
nextPage,
|
|
} = useDriveActions();
|
|
const { uploadVersion: _uploadVersion } = useDriveUpload();
|
|
const refresh = useCallback(
|
|
async (parentId: string, resetPagination?: boolean) => {
|
|
setLoading(true);
|
|
try {
|
|
setPaginateItem(prev => ({ ...prev, page: 0 }));
|
|
await refreshItem(parentId, resetPagination);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
},
|
|
[id, setLoading, refreshItem],
|
|
);
|
|
|
|
const remove = useCallback(async () => {
|
|
setLoading(true);
|
|
try {
|
|
await _remove(id, item?.item?.parent_id || '');
|
|
} catch (e) {
|
|
ToasterService.error('Unable to remove this file.');
|
|
}
|
|
setLoading(false);
|
|
}, [id, setLoading, refresh, item?.item?.parent_id]);
|
|
|
|
const restore = useCallback(async () => {
|
|
setLoading(true);
|
|
try {
|
|
await _restore(id, item?.item?.parent_id || '');
|
|
} catch (e) {
|
|
ToasterService.error('Unable to restore this item.');
|
|
}
|
|
setLoading(false);
|
|
}, [id, setLoading, refresh, item?.item?.parent_id]);
|
|
|
|
const update = useCallback(
|
|
async (update: Partial<DriveItem>, skipLoading = false) => {
|
|
if (!skipLoading) setLoading(true);
|
|
try {
|
|
await _update(update, id, item?.item?.parent_id || '');
|
|
} catch (e) {
|
|
ToasterService.error('Unable to update this file.');
|
|
}
|
|
setLoading(false);
|
|
},
|
|
[id, setLoading, refresh, item?.item?.parent_id],
|
|
);
|
|
|
|
const updateLevel = useCallback(
|
|
async (userId: string, level: string) => {
|
|
setLoading(true);
|
|
try {
|
|
await _updateLevel(id, userId, level);
|
|
} catch (e) {
|
|
ToasterService.error('Unable to update user access.');
|
|
}
|
|
setLoading(false);
|
|
},
|
|
[id, setLoading, refresh, item?.item?.parent_id],
|
|
);
|
|
|
|
const uploadVersion = useCallback(
|
|
async (file: File) => {
|
|
setLoading(true);
|
|
try {
|
|
await _uploadVersion(file, { companyId, id });
|
|
} catch (e) {
|
|
ToasterService.error('Unable to create a new version of this file.');
|
|
}
|
|
setLoading(false);
|
|
},
|
|
[companyId, id, setLoading, refresh, item?.item?.parent_id],
|
|
);
|
|
|
|
const loadNextPage = useRecoilCallback(
|
|
({ set, snapshot }) =>
|
|
async (id: string) => {
|
|
// get current pagination state
|
|
const pagination = await snapshot.getPromise(DriveItemPagination);
|
|
|
|
// if end is true, do not load more
|
|
if (pagination.lastPage === true) return;
|
|
setLoading(true);
|
|
|
|
try {
|
|
const details = await nextPage(id);
|
|
if (details.children.length === 0) {
|
|
set(DriveItemPagination, prev => ({
|
|
...prev,
|
|
lastPage: true,
|
|
}));
|
|
}
|
|
// set children and remove duplicates
|
|
setChildren(prev => [
|
|
...prev,
|
|
...details.children.filter(
|
|
(item, index, self) =>
|
|
index === self.findIndex(t => t.id === item.id),
|
|
),
|
|
]);
|
|
} catch (e) {
|
|
// set pagination end to true
|
|
set(DriveItemPagination, prev => ({
|
|
...prev,
|
|
lastPage: true,
|
|
}));
|
|
console.log('error loading next page: ', e);
|
|
ToasterService.error('Unable to load more items.');
|
|
} finally {
|
|
set(DriveItemPagination, prev => ({
|
|
...prev,
|
|
page: (prev.page + prev.limit),
|
|
}));
|
|
}
|
|
setLoading(false);
|
|
},
|
|
[id, nextPage],
|
|
);
|
|
|
|
const inTrash =
|
|
id.includes('trash') ||
|
|
item?.path?.some(i => i?.parent_id?.includes('trash')) ||
|
|
item?.item?.is_in_trash;
|
|
const sharedWithMe = id == 'shared_with_me';
|
|
|
|
return {
|
|
sharedWithMe,
|
|
inTrash,
|
|
loading: loading,
|
|
children: children || [],
|
|
details: item,
|
|
path: item?.path,
|
|
item: item?.item,
|
|
access: item?.access,
|
|
websockets: item?.websockets,
|
|
versions: item?.versions,
|
|
uploadVersion,
|
|
create,
|
|
update,
|
|
updateLevel,
|
|
remove,
|
|
refresh,
|
|
loadNextPage,
|
|
};
|
|
};
|
|
|
|
const translator = short();
|
|
export const getPublicLink = (item?: DriveItem): string => {
|
|
let publicLink = `${document.location.protocol}//${document.location.host}`;
|
|
try {
|
|
publicLink +=
|
|
`/shared/${translator.fromUUID(item?.company_id || '')}` +
|
|
`/drive/${translator.fromUUID(item?.id || '')}` +
|
|
`/t/${item?.access_info?.public?.token}`;
|
|
} catch (e) {
|
|
return publicLink;
|
|
}
|
|
|
|
return publicLink;
|
|
};
|