Files
workavia-drive/tdrive/frontend/src/app/components/file/file-component.tsx
T
Montassar Ghanmy e0615fa867 📁 Changed TDrive root folder (#16)
📁 Changed TDrive root folder
2023-04-11 10:04:29 +01:00

167 lines
4.8 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useState, useEffect } from 'react';
import classNames, { Argument } from 'classnames';
import { FileThumbnail, FileDetails, FileActions, FileProgress } from './parts';
import {
isPendingFileStatusCancel,
isPendingFileStatusError,
isPendingFileStatusSuccess,
} from 'app/features/files/utils/pending-files';
import { DataFileType } from './types';
import DriveService from 'app/deprecated/Apps/Drive/Drive.js';
import RouterService from 'app/features/router/services/router-service';
import './file.scss';
import { PendingFileRecoilType } from 'app/features/files/types/file';
import Api from 'app/features/global/framework/api-service';
import FileUploadAPIClient from '../../features/files/api/file-upload-api-client';
import LargePreview from './parts/large-preview';
import { MessageFileType } from 'app/features/messages/types/message';
import { useFileViewerModal } from 'app/features/viewer/hooks/use-viewer';
type PropsType = {
source: 'internal' | 'drive' | string;
externalId: string | any;
file: DataFileType;
messageFile: MessageFileType;
context: 'input' | 'message' | 'drive';
progress?: number;
status?: PendingFileRecoilType['status'];
onRemove?: () => void;
className?: string;
large?: boolean;
xlarge?: boolean;
};
export default ({
source,
externalId,
file: _file,
messageFile,
className,
context,
progress,
status,
onRemove,
large,
xlarge,
}: PropsType) => {
const { companyId, workspaceId } = RouterService.getStateFromRoute();
const [file, setFile] = useState<DataFileType>(_file);
const classNameArguments: Argument[] = [
'file-component',
className,
{ 'large-view': large },
{
'file-component-error':
status && (isPendingFileStatusError(status) || isPendingFileStatusCancel(status)),
'file-component-uploading': progress != undefined && progress < 1,
},
];
const { open: openViewer } = useFileViewerModal();
useEffect(() => {
if (source === 'drive') {
(async () => {
if (typeof externalId === 'string') {
externalId = { id: externalId, workspace_id: workspaceId };
}
let driveFile = (await Api.post('/ajax/drive/v2/find', {
options: {
element_id: externalId?.id,
workspace_id: externalId?.workspace_id,
},
})) as any;
driveFile = driveFile?.data || {};
setFile({
...file,
thumbnail: driveFile.preview_link,
name: driveFile.name,
size: driveFile.size,
type: FileUploadAPIClient.mimeToType(
FileUploadAPIClient.extensionToMime(driveFile.extension),
),
});
})();
} else {
setFile(_file);
}
}, [_file]);
const onClickFile = async () => {
if (source === 'internal') {
//Only if upload has ended
if ((!status || isPendingFileStatusSuccess(status)) && file.id) openViewer(messageFile);
}
if (source === 'drive') {
if (typeof externalId === 'string') {
externalId = { id: externalId, workspace_id: workspaceId };
}
const file = (await Api.post('/ajax/drive/v2/find', {
options: {
element_id: externalId?.id,
workspace_id: externalId?.workspace_id,
},
})) as any;
DriveService.viewDocument(file?.data, context === 'input');
}
};
let computedHeight = 200;
let computedWidth = file.thumbnail_ratio * 200;
const isMediaFile = ['image', 'video'].includes(file.type);
if (xlarge) {
computedWidth = Math.max(
160,
Math.min(
Math.min(messageFile.metadata?.thumbnails?.[0]?.width || 600, 600),
file.thumbnail_ratio * document.body.clientHeight * 0.5,
),
);
computedHeight = Math.max(
200,
Math.min(
Math.min(
messageFile.metadata?.thumbnails?.[0]?.height || 10000,
document.body.clientHeight * 0.5,
),
computedWidth / file.thumbnail_ratio,
),
);
}
return (
<div
className={classNames(classNameArguments)}
style={large ? { width: computedWidth, height: computedHeight } : {}}
onClick={() => companyId && onClickFile()}
>
{large && <LargePreview file={file} />}
<div
className={classNames('file-info-container', {
'media-file-info-container': isMediaFile,
})}
>
<FileThumbnail file={file} />
<FileDetails file={file} source={source} />
<FileActions
deletable={context === 'input'}
actionMenu={context === 'message' && source === 'internal'}
status={status}
file={file}
messageFile={messageFile}
onRemove={onRemove}
source={source}
/>
</div>
<FileProgress progress={progress} status={status} file={file} />
</div>
);
};