From 8afedf0641d7fbe435154e015e04fcf443b3408b Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Mon, 25 Apr 2022 18:06:50 +0800 Subject: [PATCH] feat: select encoding for decompressing zip file --- src/component/Modals/Compress.js | 26 ++----- src/component/Modals/Decompress.js | 10 ++- src/config.ts | 11 ++- src/redux/explorer/action.ts | 118 ++++++++++++++++++++++++++++- src/utils/path.ts | 7 ++ 5 files changed, 144 insertions(+), 28 deletions(-) create mode 100644 src/utils/path.ts diff --git a/src/component/Modals/Compress.js b/src/component/Modals/Compress.js index f6777c0..d5824de 100644 --- a/src/component/Modals/Compress.js +++ b/src/component/Modals/Compress.js @@ -14,6 +14,7 @@ import { useDispatch } from "react-redux"; import API from "../../middleware/Api"; import TextField from "@material-ui/core/TextField"; import { setModalsLoading, toggleSnackbar } from "../../redux/explorer"; +import { submitCompressTask } from "../../redux/explorer/action"; const useStyles = makeStyles((theme) => ({ contentFix: { @@ -55,6 +56,11 @@ export default function CompressDialog(props) { [dispatch] ); + const SubmitCompressTask = useCallback( + (name, path) => dispatch(submitCompressTask(name, path)), + [dispatch] + ); + const setMoveTarget = (folder) => { const path = folder.path === "/" @@ -70,25 +76,7 @@ export default function CompressDialog(props) { } SetModalsLoading(true); - const dirs = [], - items = []; - // eslint-disable-next-line - props.selected.map((value) => { - if (value.type === "dir") { - dirs.push(value.id); - } else { - items.push(value.id); - } - }); - - API.post("/file/compress", { - src: { - dirs: dirs, - items: items, - }, - name: fileName, - dst: selectedPath === "//" ? "/" : selectedPath, - }) + SubmitCompressTask(fileName, selectedPath) .then(() => { props.onClose(); ToggleSnackbar("top", "right", "压缩任务已创建", "success"); diff --git a/src/component/Modals/Decompress.js b/src/component/Modals/Decompress.js index 428c934..cbe42e6 100644 --- a/src/component/Modals/Decompress.js +++ b/src/component/Modals/Decompress.js @@ -14,6 +14,7 @@ import { useDispatch } from "react-redux"; import API from "../../middleware/Api"; import { filePath } from "../../utils"; import { setModalsLoading, toggleSnackbar } from "../../redux/explorer"; +import { submitDecompressTask } from "../../redux/explorer/action"; const useStyles = makeStyles((theme) => ({ contentFix: { @@ -49,6 +50,10 @@ export default function DecompressDialog(props) { }, [dispatch] ); + const SubmitDecompressTask = useCallback( + (path) => dispatch(submitDecompressTask(path)), + [dispatch] + ); const setMoveTarget = (folder) => { const path = @@ -64,10 +69,7 @@ export default function DecompressDialog(props) { e.preventDefault(); } SetModalsLoading(true); - API.post("/file/decompress", { - src: filePath(props.selected[0]), - dst: selectedPath === "//" ? "/" : selectedPath, - }) + SubmitDecompressTask(selectedPath) .then(() => { props.onClose(); ToggleSnackbar("top", "right", "解压缩任务已创建", "success"); diff --git a/src/config.ts b/src/config.ts index afac33c..a2474bc 100644 --- a/src/config.ts +++ b/src/config.ts @@ -17,7 +17,7 @@ export const msDocPreviewSuffix = [ "xls", ]; export const subtitleSuffix = ["ass", "srt", "vrr"]; -export const audioPreviewSuffix = ["mp3", "ogg", "flac","m4a"]; +export const audioPreviewSuffix = ["mp3", "ogg", "flac", "m4a"]; export const videoPreviewSuffix = ["mp4", "mkv", "webm", "avi", "m3u8", "mov"]; export const pdfPreviewSuffix = ["pdf"]; export const editSuffix = ["md", "txt"]; @@ -46,7 +46,7 @@ export const codePreviewSuffix = { yaml: "yaml", }; export const mediaType = { - audio: ["mp3", "flac", "ape", "wav", "acc", "ogg","m4a"], + audio: ["mp3", "flac", "ape", "wav", "acc", "ogg", "m4a"], video: ["mp4", "flv", "avi", "wmv", "mkv", "rm", "rmvb", "mov", "ogv"], image: ["bmp", "iff", "png", "gif", "jpg", "jpeg", "psd", "svg", "webp"], pdf: ["pdf"], @@ -104,7 +104,12 @@ export const isTorrent = (name: any) => { export const isCompressFile = (name: any) => { const suffix = name.split(".").pop().toLowerCase(); - return suffix !== "7z" && mediaType['zip'].indexOf(suffix) !== -1; + return suffix !== "7z" && mediaType["zip"].indexOf(suffix) !== -1; +}; + +export const encodingRequired = (name: any) => { + const suffix = name.split(".").pop().toLowerCase(); + return suffix === "zip"; }; const taskStatus = ["排队中", "处理中", "失败", "取消", "已完成"]; diff --git a/src/redux/explorer/action.ts b/src/redux/explorer/action.ts index 0e75b6c..213961e 100644 --- a/src/redux/explorer/action.ts +++ b/src/redux/explorer/action.ts @@ -6,13 +6,13 @@ import { Policy } from "../../component/Uploader/core/types"; import streamSaver from "streamsaver"; import "../../utils/zip"; import pathHelper from "../../utils/page"; -import { isMac } from "../../utils"; +import { filePath, isMac } from "../../utils"; import API, { getBaseURL } from "../../middleware/Api"; import { pathJoin, trimPrefix } from "../../component/Uploader/core/utils"; import { getPreviewPath, walk } from "../../utils/api"; import { askForOption } from "./async"; import Auth from "../../middleware/Auth"; -import { isPreviewable } from "../../config"; +import { encodingRequired, isPreviewable } from "../../config"; import { push } from "connected-react-router"; import { changeContextMenu, @@ -494,3 +494,117 @@ export const selectFile = (file: any, event: any, fileIndex: any) => { return dispatch(setSelectedTarget([file])); }; }; + +export const submitCompressTask = (fileName: string, path: string) => { + return async (dispatch: any, getState: any) => { + const { + explorer: { selected }, + } = getState(); + const dirs: string[] = [], + items: string[] = []; + // eslint-disable-next-line + selected.map((value) => { + if (value.type === "dir") { + dirs.push(value.id); + } else { + items.push(value.id); + } + }); + + return await API.post("/file/compress", { + src: { + dirs: dirs, + items: items, + }, + name: fileName, + dst: path === "//" ? "/" : path, + }); + }; +}; + +const encodings = [ + "ibm866", + "iso8859_2", + "iso8859_3", + "iso8859_4", + "iso8859_5", + "iso8859_6", + "iso8859_7", + "iso8859_8", + "iso8859_8I", + "iso8859_10", + "iso8859_13", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "koi8r", + "koi8u", + "macintosh", + "windows874", + "windows1250", + "windows1251", + "windows1252", + "windows1253", + "windows1254", + "windows1255", + "windows1256", + "windows1257", + "windows1258", + "macintoshcyrillic", + "gbk", + "big5", + "eucjp", + "iso2022jp", + "shiftjis", + "euckr", + "utf16be", + "utf16le", +]; + +export const submitDecompressTask = (path: string) => { + return async (dispatch: any, getState: any) => { + const { + explorer: { selected }, + } = getState(); + + let encoding = ""; + if (selected.length > 0 && encodingRequired(selected[0].name)) { + let option: any; + try { + const allOptions = encodings.map((e) => { + return { + key: e, + name: e.toUpperCase(), + }; + }); + option = await dispatch( + askForOption( + [ + { + key: "", + name: "缺省", + }, + { + key: "gb18030", + name: "GB18030", + description: "中文常见编码", + }, + ...allOptions, + ], + "选择 ZIP 文件特殊字符编码" + ) + ); + } catch (e) { + throw new Error("未选择编码方式"); + } + + encoding = option.key; + } + + return await API.post("/file/decompress", { + src: filePath(selected[0]), + dst: path === "//" ? "/" : path, + encoding: encoding, + }); + }; +}; diff --git a/src/utils/path.ts b/src/utils/path.ts new file mode 100644 index 0000000..dbe2d3f --- /dev/null +++ b/src/utils/path.ts @@ -0,0 +1,7 @@ +import { CloudreveFile } from "../types"; + +export function filePath(file: CloudreveFile): string { + return file.path === "/" + ? file.path + file.name + : file.path + "/" + file.name; +}