playground: add a rename button (#669)

Signed-off-by: Ookiineko <chiisaineko@protonmail.com>
This commit is contained in:
小さい猫 2024-03-06 23:10:53 +08:00 committed by GitHub
parent 496f4205a4
commit 2c2e2e2ad9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 81 additions and 8 deletions

View File

@ -25,12 +25,18 @@ import { Node } from "./types";
interface FileSystemManagerProps { interface FileSystemManagerProps {
path: string; path: string;
nodes: Node[]; nodes: Node[];
oldName: string;
newName: string;
renameOpen: boolean;
onNewNameChange: () => (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
onCloseRenameModal: () => () => Promise<void>;
onFileUpload: ( onFileUpload: (
isText: boolean isText: boolean
) => (event: ChangeEvent<HTMLInputElement>) => Promise<void>; ) => (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
onDirClick: (name: string) => () => Promise<void>; onDirClick: (name: string) => () => Promise<void>;
onFileClick: (name: string) => (option: string) => Promise<void>; onFileClick: (name: string) => (option: string) => Promise<void>;
onDirCreate: (name: string) => () => Promise<void>; onDirCreate: (name: string) => () => Promise<void>;
onRename: (old_name: string, new_name: string) => () => Promise<void>;
onRefresh: () => Promise<void>; onRefresh: () => Promise<void>;
onLoadSamples: () => Promise<void>; onLoadSamples: () => Promise<void>;
} }
@ -46,6 +52,7 @@ const modalStyle = {
}; };
export const options = [ export const options = [
{ text: "Rename", key: "rename" },
{ text: "Download", key: "download" }, { text: "Download", key: "download" },
{ text: "Download as Text File", key: "download-text" }, { text: "Download as Text File", key: "download-text" },
{ text: "Delete", key: "delete" }, { text: "Delete", key: "delete" },
@ -54,17 +61,23 @@ export const options = [
export default function FileSystemManager({ export default function FileSystemManager({
path = "/", path = "/",
nodes = [], nodes = [],
oldName = "",
newName = "",
renameOpen = false,
onNewNameChange = () => () => Promise.resolve(),
onCloseRenameModal = () => () => Promise.resolve(),
onFileUpload = () => () => Promise.resolve(), onFileUpload = () => () => Promise.resolve(),
onFileClick = () => () => Promise.resolve(), onFileClick = () => () => Promise.resolve(),
onDirClick = () => () => Promise.resolve(), onDirClick = () => () => Promise.resolve(),
onDirCreate = () => () => Promise.resolve(), onDirCreate = () => () => Promise.resolve(),
onRename = () => () => Promise.resolve(),
onRefresh = () => Promise.resolve(), onRefresh = () => Promise.resolve(),
onLoadSamples = () => Promise.resolve(), onLoadSamples = () => Promise.resolve(),
}: FileSystemManagerProps) { }: FileSystemManagerProps) {
const [open, setOpen] = useState(false); const [newFolderOpen, setNewFolderOpen] = useState(false);
const [dirName, setDirName] = useState(""); const [dirName, setDirName] = useState("");
const handleModalOpen = () => setOpen(true); const handleNewFolderModalOpen = () => setNewFolderOpen(true);
const handleModalClose = () => setOpen(false); const handleNewFolderModalClose = () => setNewFolderOpen(false);
return ( return (
<> <>
@ -113,7 +126,7 @@ export default function FileSystemManager({
<IconButton <IconButton
onClick={() => { onClick={() => {
setDirName(""); setDirName("");
handleModalOpen(); handleNewFolderModalOpen();
}} }}
aria-label="create-a-new-folder" aria-label="create-a-new-folder"
size="small" size="small"
@ -165,8 +178,8 @@ export default function FileSystemManager({
</Stack> </Stack>
</Paper> </Paper>
<Modal <Modal
open={open} open={newFolderOpen}
onClose={handleModalClose} onClose={handleNewFolderModalClose}
aria-labelledby="new-folder-name" aria-labelledby="new-folder-name"
aria-describedby="new-folder-name-description" aria-describedby="new-folder-name-description"
> >
@ -183,12 +196,12 @@ export default function FileSystemManager({
onChange={(event) => setDirName(event.target.value)} onChange={(event) => setDirName(event.target.value)}
/> />
<Stack direction="row" justifyContent="flex-end"> <Stack direction="row" justifyContent="flex-end">
<Button onClick={handleModalClose}>Cancel</Button> <Button onClick={handleNewFolderModalClose}>Cancel</Button>
<Button <Button
variant="contained" variant="contained"
onClick={() => { onClick={() => {
onDirCreate(dirName); onDirCreate(dirName);
handleModalClose(); handleNewFolderModalClose();
}} }}
> >
Create Create
@ -197,6 +210,36 @@ export default function FileSystemManager({
</Stack> </Stack>
</Box> </Box>
</Modal> </Modal>
<Modal
open={renameOpen}
onClose={onCloseRenameModal()}
aria-labelledby="new-name"
aria-describedby="new-name-description"
>
<Box sx={modalStyle}>
<Stack spacing={4}>
<Typography id="modal-modal-title" variant="h6" component="h2">
New Name:
</Typography>
<TextField
id="outlined-basic"
label="my-file"
variant="outlined"
value={newName}
onChange={onNewNameChange()}
/>
<Stack direction="row" justifyContent="flex-end">
<Button onClick={onCloseRenameModal()}>Cancel</Button>
<Button
variant="contained"
onClick={onRename(oldName, newName)}
>
Rename
</Button>
</Stack>
</Stack>
</Box>
</Modal>
</> </>
); );
} }

View File

@ -23,6 +23,9 @@ interface WorkspaceProps {
export default function Workspace({ ffmpeg: _ffmpeg }: WorkspaceProps) { export default function Workspace({ ffmpeg: _ffmpeg }: WorkspaceProps) {
const [path, setPath] = useState("/"); const [path, setPath] = useState("/");
const [nodes, setNodes] = useState<Node[]>([]); const [nodes, setNodes] = useState<Node[]>([]);
const [oldName, setOldName] = useState("");
const [newName, setNewName] = useState("");
const [renameOpen, setRenameOpen] = useState(false);
const [args, setArgs] = useState(defaultArgs); const [args, setArgs] = useState(defaultArgs);
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const [time, setTime] = useState(0); const [time, setTime] = useState(0);
@ -38,6 +41,14 @@ export default function Workspace({ ffmpeg: _ffmpeg }: WorkspaceProps) {
} }
}; };
const onNewNameChange = () => async (event: ChangeEvent<HTMLInputElement>) => {
setNewName(event.target.value);
};
const onCloseRenameModal = () => async () => {
setRenameOpen(false);
};
const onFileUpload = const onFileUpload =
(isText: boolean) => (isText: boolean) =>
async ({ target: { files } }: ChangeEvent<HTMLInputElement>) => { async ({ target: { files } }: ChangeEvent<HTMLInputElement>) => {
@ -53,6 +64,11 @@ export default function Workspace({ ffmpeg: _ffmpeg }: WorkspaceProps) {
const onFileClick = (name: string) => async (option: string) => { const onFileClick = (name: string) => async (option: string) => {
const fullPath = `${path}/${name}`; const fullPath = `${path}/${name}`;
switch (option) { switch (option) {
case "rename":
setOldName(name);
setNewName("");
setRenameOpen(true);
break;
case "download": case "download":
downloadFile( downloadFile(
name, name,
@ -93,6 +109,14 @@ export default function Workspace({ ffmpeg: _ffmpeg }: WorkspaceProps) {
refreshDir(path); refreshDir(path);
}; };
const onRename = (old_name: string, new_name: string) => async () => {
if (old_name !== "" && new_name !== "") {
await ffmpeg.rename(`${path}/${old_name}`, `${path}/${new_name}`);
}
setRenameOpen(false);
refreshDir(path);
};
const onLoadSamples = async () => { const onLoadSamples = async () => {
for (const name of Object.keys(SAMPLE_FILES)) { for (const name of Object.keys(SAMPLE_FILES)) {
await ffmpeg.writeFile(name, await fetchFile(SAMPLE_FILES[name])); await ffmpeg.writeFile(name, await fetchFile(SAMPLE_FILES[name]));
@ -130,10 +154,16 @@ export default function Workspace({ ffmpeg: _ffmpeg }: WorkspaceProps) {
<FileSystemManager <FileSystemManager
path={path} path={path}
nodes={nodes} nodes={nodes}
oldName={oldName}
newName={newName}
renameOpen={renameOpen}
onNewNameChange={onNewNameChange}
onCloseRenameModal={onCloseRenameModal}
onFileUpload={onFileUpload} onFileUpload={onFileUpload}
onFileClick={onFileClick} onFileClick={onFileClick}
onDirClick={onDirClick} onDirClick={onDirClick}
onDirCreate={onDirCreate} onDirCreate={onDirCreate}
onRename={onRename}
onLoadSamples={onLoadSamples} onLoadSamples={onLoadSamples}
onRefresh={() => refreshDir(path)} onRefresh={() => refreshDir(path)}
/> />