Skip to content

Commit

Permalink
fix: 修复自定义数据存储路径时偶尔报错的问题 (#607)
Browse files Browse the repository at this point in the history
  • Loading branch information
ayangweb authored Sep 29, 2024
1 parent 23a86e2 commit 1cc4404
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 44 deletions.
50 changes: 45 additions & 5 deletions src-tauri/src/plugins/backup.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use super::fs_extra::{get_file_name, preview_path};
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
use fs_extra::dir::{move_dir, CopyOptions};
use fs_extra::{
dir::{ls, CopyOptions, DirEntryAttr, DirEntryValue},
move_items,
};
use std::{
fs::{read_dir, File},
collections::HashSet,
fs::{create_dir_all, read_dir, remove_dir, File},
path::PathBuf,
};
use tar::Archive;
Expand Down Expand Up @@ -61,7 +65,41 @@ async fn import_data(dst_dir: PathBuf, path: String) -> tauri::Result<bool> {
}

#[command]
async fn move_data(from: PathBuf, to: PathBuf) -> Result<String, String> {
async fn move_data(from: PathBuf, to: PathBuf) -> Result<PathBuf, String> {
create_dir_all(to.clone()).map_err(|err| err.to_string())?;

let mut config = HashSet::new();
config.insert(DirEntryAttr::Path);

let ls_result = ls(&from, &config).unwrap();

let mut from_items = Vec::new();

for item in ls_result.items {
if let Some(path) = item.get(&DirEntryAttr::Path) {
if let &DirEntryValue::String(ref path) = path {
let path = PathBuf::from(path);
let is_dir = path.is_dir();
let is_file = path.is_file();
let file_name = get_file_name(path.clone());

// 忽略主题插件和窗口状态插件生成的的文件,无法修改存储路径
let skip_files = ["tauri-plugin-theme", ".window-state"];
if is_file && skip_files.contains(&file_name.as_str()) {
continue;
}

// 忽略日志插件生成的目录,无法修改存储路径
let skip_dirs = ["logs"];
if is_dir && skip_dirs.contains(&file_name.as_str()) {
continue;
}

from_items.push(path);
}
}
}

let options = CopyOptions {
overwrite: true,
skip_exist: false,
Expand All @@ -71,9 +109,11 @@ async fn move_data(from: PathBuf, to: PathBuf) -> Result<String, String> {
depth: 0,
};

move_dir(&from, &to, &options).map_err(|err| err.to_string())?;
move_items(&from_items, &to, &options).map_err(|err| err.to_string())?;

let _ = remove_dir(from);

Ok(get_file_name(from))
Ok(to)
}

pub fn init() -> TauriPlugin<Wry> {
Expand Down
7 changes: 4 additions & 3 deletions src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,16 @@
}
},
"data_backup": {
"storage_path": {
"storage_settings": {
"title": "Storage Settings",
"label": {
"storage_path": "Data Storage Directory"
"data_storage_path": "Data Storage Path",
"log_storage_path": "Log Storage Path"
},
"hints": {
"custom_path": "Custom",
"default_path": "Restore Default",
"save_success": "Changes Saved Successfully"
"change_success": "Changed successfully"
}
},
"import_export": {
Expand Down
11 changes: 6 additions & 5 deletions src/locales/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,16 @@
}
},
"data_backup": {
"storage_path": {
"title": "保存設定",
"storage_settings": {
"title": "ストレージ設定",
"label": {
"storage_path": "データ保存パス"
"data_storage_path": "データ保存パス",
"log_storage_path": "ログ保存パス"
},
"hints": {
"custom_path": "カスタム",
"custom_path": "カスタマイズ",
"default_path": "デフォルトに戻す",
"save_success": "変更に成功しました"
"change_success": "変更成功"
}
},
"import_export": {
Expand Down
7 changes: 4 additions & 3 deletions src/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,16 @@
}
},
"data_backup": {
"storage_path": {
"storage_settings": {
"title": "存储设置",
"label": {
"storage_path": "数据存储路径"
"data_storage_path": "数据存储路径",
"log_storage_path": "日志存储路径"
},
"hints": {
"custom_path": "自定义",
"default_path": "恢复默认",
"save_success": "更改成功"
"change_success": "更改成功"
}
},
"import_export": {
Expand Down
7 changes: 4 additions & 3 deletions src/locales/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,16 @@
}
},
"data_backup": {
"storage_path": {
"storage_settings": {
"title": "存儲設定",
"label": {
"storage_path": "數據存儲路徑"
"data_storage_path": "資料存儲路徑",
"log_storage_path": "日誌存儲路徑"
},
"hints": {
"custom_path": "自訂",
"default_path": "恢復預設",
"save_success": "更改成功"
"change_success": "更改成功"
}
},
"import_export": {
Expand Down
72 changes: 47 additions & 25 deletions src/pages/Backup/components/SavePath/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,83 @@ import ProListItem from "@/components/ProListItem";
import { NodeIndexOutlined, ReloadOutlined } from "@ant-design/icons";
import { open } from "@tauri-apps/api/dialog";
import { emit } from "@tauri-apps/api/event";
import { dataDir as tauriDataDir } from "@tauri-apps/api/path";
import { appLogDir, dataDir as tauriDataDir } from "@tauri-apps/api/path";
import { Button, Space, Tooltip, message } from "antd";
import { isString } from "antd/es/button";
import { isEqual } from "lodash-es";
import { isEqual, isString } from "lodash-es";
import type { FC } from "react";
import type { State } from "../..";

const SavePath: FC<{ state: State }> = (props) => {
const { state } = props;
const { t } = useTranslation();
const [dataDir, setDataDir] = useState("");
const [logDir, setLogDir] = useState("");

useMount(async () => {
setDataDir(await tauriDataDir());
setLogDir(await appLogDir());
});

const handleChange = async (isDefault = false) => {
try {
const nextDir = isDefault ? dataDir : await open({ directory: true });
const dstDir = isDefault ? dataDir : await open({ directory: true });

if (!isString(nextDir) || isEqualPath(nextDir)) return;
if (!isString(dstDir) || isEqualPath(dstDir)) return;

state.spinning = true;
const dstPath = joinPath(dstDir, getSaveDataDirName());

const dirName = await moveData(getSaveDataDir(), nextDir);
state.spinning = true;

if (!dirName) return;
await moveData(getSaveDataDir(), dstPath);

globalStore.env.saveDataDir = joinPath(nextDir, dirName);
globalStore.env.saveDataDir = dstPath;

state.spinning = false;
await wait();

emit(LISTEN_KEY.REFRESH_CLIPBOARD_LIST);

message.success(
t("preference.data_backup.storage_path.hints.save_success"),
t("preference.data_backup.storage_settings.hints.change_success"),
);

state.spinning = false;
} catch (error: any) {
state.spinning = false;

message.error(error);
}
};

const isEqualPath = (nextDir = dataDir) => {
return isEqual(joinPath(nextDir, getSaveDataDirName()), getSaveDataDir());
const isEqualPath = (dstDir = dataDir) => {
const dstPath = joinPath(dstDir, getSaveDataDirName());

return isEqual(dstPath, getSaveDataDir());
};

const description = (path = getSaveDataDir()) => {
return (
<span
className="hover:color-primary cursor-pointer break-all transition"
onMouseDown={() => previewPath(path)}
>
{joinPath(path)}
</span>
);
};

return (
<ProList header={t("preference.data_backup.storage_path.title")}>
<ProList header={t("preference.data_backup.storage_settings.title")}>
<ProListItem
title={t("preference.data_backup.storage_path.label.storage_path")}
description={
<span
className="hover:color-primary cursor-pointer break-all transition"
onMouseDown={() => previewPath(getSaveDataDir())}
>
{getSaveDataDir()}
</span>
}
title={t(
"preference.data_backup.storage_settings.label.data_storage_path",
)}
description={description()}
>
<Space.Compact>
<Tooltip
title={t("preference.data_backup.storage_path.hints.custom_path")}
title={t(
"preference.data_backup.storage_settings.hints.custom_path",
)}
>
<Button
icon={<NodeIndexOutlined />}
Expand All @@ -75,7 +88,9 @@ const SavePath: FC<{ state: State }> = (props) => {
</Tooltip>

<Tooltip
title={t("preference.data_backup.storage_path.hints.default_path")}
title={t(
"preference.data_backup.storage_settings.hints.default_path",
)}
>
<Button
disabled={isEqualPath()}
Expand All @@ -85,6 +100,13 @@ const SavePath: FC<{ state: State }> = (props) => {
</Tooltip>
</Space.Compact>
</ProListItem>

<ProListItem
title={t(
"preference.data_backup.storage_settings.label.log_storage_path",
)}
description={description(logDir)}
/>
</ProList>
);
};
Expand Down
7 changes: 7 additions & 0 deletions src/utils/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* 延迟执行
* @param delay 延迟时间
*/
export const wait = (delay = 100) => {
return new Promise((resolve) => setTimeout(resolve, delay));
};

0 comments on commit 1cc4404

Please sign in to comment.