mirror of
https://github.com/FranP-code/ChatGPT.git
synced 2025-10-13 00:13:25 +00:00
146 lines
4.4 KiB
TypeScript
Vendored
146 lines
4.4 KiB
TypeScript
Vendored
import { useEffect, useState } from 'react';
|
|
import { Table, Modal, Popconfirm, Button, message } from 'antd';
|
|
import { invoke, path, fs } from '@tauri-apps/api';
|
|
|
|
import useJson from '@/hooks/useJson';
|
|
import useData from '@/hooks/useData';
|
|
import useColumns from '@/hooks/useColumns';
|
|
import FilePath from '@/components/FilePath';
|
|
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
|
import { chatRoot, CHAT_DOWNLOAD_JSON } from '@/utils';
|
|
import { downloadColumns } from './config';
|
|
|
|
function renderFile(buff: Uint8Array, type: string) {
|
|
const renderType = {
|
|
pdf: 'application/pdf',
|
|
png: 'image/png',
|
|
}[type];
|
|
return URL.createObjectURL(new Blob([buff], { type: renderType }));
|
|
}
|
|
|
|
export default function Download() {
|
|
const [source, setSource] = useState('');
|
|
const [isVisible, setVisible] = useState(false);
|
|
const { opData, opInit, opReplace, opSafeKey } = useData([]);
|
|
const { columns, ...opInfo } = useColumns(downloadColumns());
|
|
const { rowSelection, selectedRows, rowReset } = useTableRowSelection({ rowType: 'row' });
|
|
const { json, refreshJson, updateJson } = useJson<any[]>(CHAT_DOWNLOAD_JSON);
|
|
const selectedItems = rowSelection.selectedRowKeys || [];
|
|
|
|
useEffect(() => {
|
|
if (!json || json.length <= 0) return;
|
|
opInit(json);
|
|
}, [json?.length]);
|
|
|
|
useEffect(() => {
|
|
if (!opInfo.opType) return;
|
|
(async () => {
|
|
const record = opInfo?.opRecord;
|
|
const isImg = ['png'].includes(record?.ext);
|
|
const file = await path.join(
|
|
await chatRoot(),
|
|
'download',
|
|
isImg ? 'img' : record?.ext,
|
|
`${record?.id}.${record?.ext}`,
|
|
);
|
|
if (opInfo.opType === 'preview') {
|
|
const data = await fs.readBinaryFile(file);
|
|
const sourceData = renderFile(data, record?.ext);
|
|
setSource(sourceData);
|
|
setVisible(true);
|
|
return;
|
|
}
|
|
if (opInfo.opType === 'delete') {
|
|
await fs.removeFile(file);
|
|
await handleRefresh();
|
|
}
|
|
if (opInfo.opType === 'rowedit') {
|
|
const data = opReplace(opInfo?.opRecord?.[opSafeKey], opInfo?.opRecord);
|
|
await updateJson(data);
|
|
message.success('Name has been changed!');
|
|
}
|
|
opInfo.resetRecord();
|
|
})();
|
|
}, [opInfo.opType]);
|
|
|
|
const handleDelete = async () => {
|
|
if (opData?.length === selectedRows.length) {
|
|
const downloadDir = await path.join(await chatRoot(), 'download');
|
|
await fs.removeDir(downloadDir, { recursive: true });
|
|
await handleRefresh();
|
|
message.success('All files have been cleared!');
|
|
return;
|
|
}
|
|
|
|
const rows = selectedRows.map(async (i) => {
|
|
const isImg = ['png'].includes(i?.ext);
|
|
const file = await path.join(
|
|
await chatRoot(),
|
|
'download',
|
|
isImg ? 'img' : i?.ext,
|
|
`${i?.id}.${i?.ext}`,
|
|
);
|
|
await fs.removeFile(file);
|
|
return file;
|
|
});
|
|
Promise.all(rows).then(async () => {
|
|
await handleRefresh();
|
|
message.success('All files selected are cleared!');
|
|
});
|
|
};
|
|
|
|
const handleRefresh = async () => {
|
|
await invoke('download_list', { pathname: CHAT_DOWNLOAD_JSON, dir: 'download' });
|
|
rowReset();
|
|
const data = await refreshJson();
|
|
opInit(data);
|
|
};
|
|
|
|
const handleCancel = () => {
|
|
setVisible(false);
|
|
opInfo.resetRecord();
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<div className="chat-table-btns">
|
|
<div>
|
|
{selectedItems.length > 0 && (
|
|
<>
|
|
<Popconfirm
|
|
overlayStyle={{ width: 250 }}
|
|
title="Files cannot be recovered after deletion, are you sure you want to delete them?"
|
|
placement="topLeft"
|
|
onConfirm={handleDelete}
|
|
okText="Yes"
|
|
cancelText="No"
|
|
>
|
|
<Button>Delete</Button>
|
|
</Popconfirm>
|
|
<span className="num">Selected {selectedItems.length} items</span>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<FilePath paths={CHAT_DOWNLOAD_JSON} />
|
|
<Table
|
|
rowKey="id"
|
|
columns={columns}
|
|
scroll={{ x: 800 }}
|
|
dataSource={opData}
|
|
rowSelection={rowSelection}
|
|
pagination={TABLE_PAGINATION}
|
|
/>
|
|
<Modal
|
|
open={isVisible}
|
|
title={<div>{opInfo?.opRecord?.name || ''}</div>}
|
|
onCancel={handleCancel}
|
|
footer={false}
|
|
destroyOnClose
|
|
>
|
|
<img style={{ maxWidth: '100%' }} src={source} />
|
|
</Modal>
|
|
</div>
|
|
);
|
|
}
|