167 lines
5.6 KiB
TypeScript
167 lines
5.6 KiB
TypeScript
import { useShallow } from 'zustand/react/shallow';
|
|
import { useFileStore } from '../store';
|
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
import path from 'path-browserify';
|
|
import prettyBytes from 'pretty-bytes';
|
|
import clsx from 'clsx';
|
|
import { isObjectNull } from '@/utils/is-null';
|
|
import FileOutlined from '@ant-design/icons/FileOutlined';
|
|
import FolderOutlined from '@ant-design/icons/FolderOutlined';
|
|
import { IconButton } from '@kevisual/center-components/button/index.tsx';
|
|
import { render, unmount } from '@kevisual/resources/pages/Bootstrap.tsx';
|
|
import UploadOutlined from '@ant-design/icons/lib/icons/UploadOutlined';
|
|
import { Tooltip } from '@mui/material';
|
|
export const CardPath = ({ children }: any) => {
|
|
const userAppStore = useFileStore(
|
|
useShallow((state) => {
|
|
return {
|
|
list: state.list,
|
|
getList: state.getList,
|
|
setPath: state.setPath,
|
|
path: state.path,
|
|
};
|
|
}),
|
|
);
|
|
const paths = ['root', ...userAppStore.path.split('/').filter((item) => item)];
|
|
const onDirectoryClick = (prefix: string) => {
|
|
if (prefix === 'root') {
|
|
userAppStore.setPath('');
|
|
userAppStore.getList();
|
|
return;
|
|
}
|
|
userAppStore.setPath(prefix.replace('root/', '') + '/');
|
|
userAppStore.getList();
|
|
};
|
|
return (
|
|
<div className='border border-gray-200 rounded'>
|
|
<div className='p-2'>
|
|
<div className='flex flex-col'>
|
|
<div className=' flex gap-2 py-2'>
|
|
<div>Path: </div>
|
|
<div className='flex'>
|
|
{paths.map((item, index) => {
|
|
const isLast = index === paths.length - 1;
|
|
return (
|
|
<div
|
|
key={index}
|
|
className={clsx('select-none', !isLast && 'hover:text-gray-400 cursor-pointer')}
|
|
onClick={(e) => {
|
|
if (!isLast) {
|
|
onDirectoryClick(paths.slice(0, index + 1).join('/'));
|
|
}
|
|
}}>
|
|
{item}/
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className=''>{children}</div>
|
|
</div>
|
|
);
|
|
};
|
|
export const List = () => {
|
|
const [tab, setTab] = useState<'folder' | 'upload'>('folder');
|
|
const uploadRef = useRef<HTMLDivElement>(null);
|
|
const userAppStore = useFileStore(
|
|
useShallow((state) => {
|
|
return {
|
|
list: state.list,
|
|
getList: state.getList,
|
|
setPath: state.setPath,
|
|
path: state.path,
|
|
getFile: state.getFile,
|
|
file: state.file,
|
|
};
|
|
}),
|
|
);
|
|
useEffect(() => {
|
|
userAppStore.getList();
|
|
}, []);
|
|
const onDirectoryClick = (prefix: string) => {
|
|
userAppStore.setPath(prefix);
|
|
userAppStore.getList();
|
|
};
|
|
const allFolderApp = useMemo(() => {
|
|
return (
|
|
<>
|
|
<CardPath>
|
|
<div className='flex flex-col'>
|
|
{userAppStore.list.map((item, index) => {
|
|
if (item.prefix) {
|
|
let showPrefix = item.prefix.replace(userAppStore.path, '');
|
|
showPrefix = showPrefix.replace('/', '');
|
|
return (
|
|
<div
|
|
className=' border-t border-gray-200 flex gap-2 p-2'
|
|
key={index}
|
|
onClick={() => {
|
|
onDirectoryClick(item.prefix);
|
|
}}>
|
|
<div>
|
|
<FolderOutlined />
|
|
</div>
|
|
<div>{showPrefix}</div>
|
|
</div>
|
|
);
|
|
}
|
|
const name = path.basename(item.name);
|
|
const size = prettyBytes(item.size);
|
|
return (
|
|
<div
|
|
className=' border-t border-gray-200 flex gap-2 p-2'
|
|
key={index}
|
|
onClick={() => {
|
|
userAppStore.getFile(item.name);
|
|
}}>
|
|
<div>
|
|
<FileOutlined />
|
|
</div>
|
|
<div>{name}</div>
|
|
<div>size: {size}</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</CardPath>
|
|
<div>
|
|
<pre>{!isObjectNull(userAppStore.file) && JSON.stringify(userAppStore.file, null, 2)}</pre>
|
|
</div>
|
|
</>
|
|
);
|
|
}, [userAppStore.list, userAppStore.path]);
|
|
|
|
useEffect(() => {
|
|
if (tab === 'upload') {
|
|
render(uploadRef.current!);
|
|
} else {
|
|
uploadRef.current && unmount(uploadRef.current!);
|
|
}
|
|
console.log('unmount', tab, uploadRef.current);
|
|
}, [tab]);
|
|
return (
|
|
<div className='flex w-full h-full'>
|
|
<div className='flex gap-2 border border-gray-200 shadow-md p-2'>
|
|
<div className='flex flex-col gap-2'>
|
|
<Tooltip title='所有的资源文件' placement='right'>
|
|
<IconButton sx={{ py: 1 }} color={tab !== 'folder' ? 'primary' : 'secondary'} onClick={() => setTab('folder')}>
|
|
<FolderOutlined />
|
|
</IconButton>
|
|
</Tooltip>
|
|
<Tooltip title='上传资源文件管理' placement='right'>
|
|
<IconButton sx={{ py: 1 }} color={tab !== 'upload' ? 'primary' : 'secondary'} onClick={() => setTab('upload')}>
|
|
<UploadOutlined />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</div>
|
|
</div>
|
|
<div className='grow' style={{ height: 'calc(100% - 0px)', overflow: 'hidden' }}>
|
|
{tab === 'folder' && <div className='p-4 w-full h-full'>{allFolderApp}</div>}
|
|
{tab === 'upload' && <div className='w-full h-full' ref={uploadRef}></div>}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|