show file changed dialog

This commit is contained in:
codetypes committed 2024-11-21 10:35:03 +08:00
1 parent cf1c33891f
commit 78ee7bcc76
6 files changed
+97 -20

No files matched your search

+1
View File
@@ -64,6 +64,7 @@
"workspace.saveAllOnClose": "Do you want to save the changes to the following {{count}} files?", "workspace.saveAllOnClose": "Do you want to save the changes to the following {{count}} files?",
"workspace.saveOnClose": "Do you want to save the changes you made to '{{name}}'?", "workspace.saveOnClose": "Do you want to save the changes you made to '{{name}}'?",
"workspace.reloadFile": "'{{name}}' has changed, do you want to reload now?",
"explorer.deleteFile": "Are you sure you want delete '{{name}}'?", "explorer.deleteFile": "Are you sure you want delete '{{name}}'?",
"explorer.deleteFolder": "Are you sure you want delete '{{name}}' and its contents?", "explorer.deleteFolder": "Are you sure you want delete '{{name}}' and its contents?",
+1
View File
@@ -64,6 +64,7 @@
"workspace.saveAllOnClose": "你需要保存对以下 {{count}} 个文件的修改吗?", "workspace.saveAllOnClose": "你需要保存对以下 {{count}} 个文件的修改吗?",
"workspace.saveOnClose": "你需要保存对文件 {{name}} 的修改吗?", "workspace.saveOnClose": "你需要保存对文件 {{name}} 的修改吗?",
"workspace.reloadFile": "文件 {{name}} 发生改变,你需要重新加载吗?",
"explorer.deleteFile": "你确定要删除文件 '{{name}}'?", "explorer.deleteFile": "你确定要删除文件 '{{name}}'?",
"explorer.deleteFolder": "你确定要删除目录 '{{name}}'?", "explorer.deleteFolder": "你确定要删除目录 '{{name}}'?",
+10 -2
View File
@@ -11,7 +11,7 @@ import { message } from "@/misc/hooks";
import i18n from "@/misc/i18n"; import i18n from "@/misc/i18n";
import { Hotkey, isMacos, useKeyDown } from "@/misc/keys"; import { Hotkey, isMacos, useKeyDown } from "@/misc/keys";
import Path from "@/misc/path"; import Path from "@/misc/path";
import { mergeClassNames } from "@/misc/util"; import { mergeClassNames, readJson } from "@/misc/util";
import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined } from "@ant-design/icons"; import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined } from "@ant-design/icons";
import G6, { G6GraphEvent, Item, TreeGraph } from "@antv/g6"; import G6, { G6GraphEvent, Item, TreeGraph } from "@antv/g6";
import { dialog } from "@electron/remote"; import { dialog } from "@electron/remote";
@@ -330,6 +330,7 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
const refresh = () => { const refresh = () => {
const rootData = findDataById("1"); const rootData = findDataById("1");
const rootNode = b3util.createNode(rootData); const rootNode = b3util.createNode(rootData);
editor.modifiedTime = fs.statSync(editor.path).mtimeMs;
editor.data = b3util.createTreeData(rootNode); editor.data = b3util.createTreeData(rootNode);
editor.autoId = b3util.refreshTreeDataId(editor.data); editor.autoId = b3util.refreshTreeDataId(editor.data);
editor.graph.changeData(editor.data); editor.graph.changeData(editor.data);
@@ -337,7 +338,14 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
restoreViewport(); restoreViewport();
}; };
const reload = () => {}; const reload = () => {
const file = readJson(editor.path) as TreeModel;
editor.data = b3util.createTreeData(file.root);
editor.autoId = b3util.refreshTreeDataId(editor.data);
editor.graph.changeData(editor.data);
editor.graph.layout();
restoreViewport();
};
const checkSubtree = () => { const checkSubtree = () => {
if (editor.graph) { if (editor.graph) {
+69 -13
View File
@@ -28,6 +28,7 @@ export const Workspace: FC = () => {
edit: useWorkspace((state) => state.edit), edit: useWorkspace((state) => state.edit),
editing: useWorkspace((state) => state.editing), editing: useWorkspace((state) => state.editing),
editors: useWorkspace((state) => state.editors), editors: useWorkspace((state) => state.editors),
modifiedEditors: useWorkspace((state) => state.modifiedEditors),
fileTree: useWorkspace((state) => state.fileTree), fileTree: useWorkspace((state) => state.fileTree),
find: useWorkspace((state) => state.find), find: useWorkspace((state) => state.find),
init: useWorkspace((state) => state.init), init: useWorkspace((state) => state.init),
@@ -39,7 +40,7 @@ export const Workspace: FC = () => {
const settings = { const settings = {
recent: useSetting((state) => state.recent), recent: useSetting((state) => state.recent),
}; };
const [isShowingSave, setShowingSave] = useState(false); const [isShowingAlert, setShowingAlert] = useState(false);
const { t } = useTranslation(); const { t } = useTranslation();
const forceUpdate = useForceUpdate(); const forceUpdate = useForceUpdate();
const { width = 0, height = 0 } = useWindowSize(); const { width = 0, height = 0 } = useWindowSize();
@@ -88,16 +89,71 @@ export const Workspace: FC = () => {
}); });
useEffect(() => { useEffect(() => {
if (!workspace.isShowingSearch && !isShowingSave) { if (!workspace.isShowingSearch && !isShowingAlert) {
keysRef.current?.focus(); keysRef.current?.focus();
} }
}, [workspace.isShowingSearch]); }, [workspace.isShowingSearch]);
useEffect(() => {
const editor = workspace.editing;
if (editor && workspace.modifiedEditors.includes(editor)) {
if (isShowingAlert) {
return;
}
setShowingAlert(true);
const modifiedEditors = workspace.modifiedEditors.filter((v) => v !== editor);
console.log(
"modified:",
editor.path,
modifiedEditors.map((v) => v.path)
);
const alert = modal.confirm({
centered: true,
content: (
<Flex vertical gap="middle">
<div>
<FaExclamationTriangle style={{ fontSize: "60px", color: "#FADB14" }} />
</div>
<div>{t("workspace.reloadFile", { name: Path.basename(editor.path) })}</div>
</Flex>
),
footer: (
<Flex vertical gap="middle" style={{ paddingTop: "30px" }}>
<Flex vertical gap="6px">
<Button
type="primary"
onClick={() => {
editor.dispatch("reload");
alert.destroy();
keysRef.current?.focus();
setShowingAlert(false);
useWorkspace.setState({ modifiedEditors: modifiedEditors });
}}
>
{t("reload")}
</Button>
<Button
onClick={() => {
alert.destroy();
keysRef.current?.focus();
setShowingAlert(false);
useWorkspace.setState({ modifiedEditors: modifiedEditors });
}}
>
{t("cancel")}
</Button>
</Flex>
</Flex>
),
});
}
}, [workspace.modifiedEditors, workspace.editing]);
const showSaveDialog = (editor: EditorStore) => { const showSaveDialog = (editor: EditorStore) => {
if (isShowingSave) { if (isShowingAlert) {
return; return;
} }
setShowingSave(true); setShowingAlert(true);
const alert = modal.confirm({ const alert = modal.confirm({
centered: true, centered: true,
content: ( content: (
@@ -118,7 +174,7 @@ export const Workspace: FC = () => {
workspace.close(editor.path); workspace.close(editor.path);
alert.destroy(); alert.destroy();
keysRef.current?.focus(); keysRef.current?.focus();
setShowingSave(false); setShowingAlert(false);
}} }}
> >
{t("save")} {t("save")}
@@ -129,7 +185,7 @@ export const Workspace: FC = () => {
workspace.close(editor.path); workspace.close(editor.path);
alert.destroy(); alert.destroy();
keysRef.current?.focus(); keysRef.current?.focus();
setShowingSave(false); setShowingAlert(false);
}} }}
> >
{t("donotSave")} {t("donotSave")}
@@ -139,7 +195,7 @@ export const Workspace: FC = () => {
onClick={() => { onClick={() => {
alert.destroy(); alert.destroy();
keysRef.current?.focus(); keysRef.current?.focus();
setShowingSave(false); setShowingAlert(false);
}} }}
> >
{t("cancel")} {t("cancel")}
@@ -150,10 +206,10 @@ export const Workspace: FC = () => {
}; };
const showSaveAllDialog = (unsaves: EditorStore[]) => { const showSaveAllDialog = (unsaves: EditorStore[]) => {
if (isShowingSave) { if (isShowingAlert) {
return; return;
} }
setShowingSave(true); setShowingAlert(true);
const alert = modal.confirm({ const alert = modal.confirm({
centered: true, centered: true,
content: ( content: (
@@ -169,7 +225,7 @@ export const Workspace: FC = () => {
<div>{t("workspace.saveAllOnClose", { count: unsaves.length })}</div> <div>{t("workspace.saveAllOnClose", { count: unsaves.length })}</div>
<Flex vertical style={{ fontSize: "12px" }}> <Flex vertical style={{ fontSize: "12px" }}>
{unsaves.map((editor) => ( {unsaves.map((editor) => (
<div>{Path.basename(editor.path)}</div> <div key={editor.path}>{Path.basename(editor.path)}</div>
))} ))}
</Flex> </Flex>
</> </>
@@ -185,7 +241,7 @@ export const Workspace: FC = () => {
unsaves.forEach((editor) => editor.dispatch("save")); unsaves.forEach((editor) => editor.dispatch("save"));
alert.destroy(); alert.destroy();
window.close(); window.close();
setShowingSave(false); setShowingAlert(false);
}} }}
> >
{unsaves.length > 1 ? t("saveAll") : t("save")} {unsaves.length > 1 ? t("saveAll") : t("save")}
@@ -196,7 +252,7 @@ export const Workspace: FC = () => {
workspace.editors.length = 0; workspace.editors.length = 0;
alert.destroy(); alert.destroy();
window.close(); window.close();
setShowingSave(false); setShowingAlert(false);
}} }}
> >
{t("donotSave")} {t("donotSave")}
@@ -205,7 +261,7 @@ export const Workspace: FC = () => {
<Button <Button
onClick={() => { onClick={() => {
alert.destroy(); alert.destroy();
setShowingSave(false); setShowingAlert(false);
}} }}
> >
{t("cancel")} {t("cancel")}
+15 -4
View File
@@ -130,6 +130,7 @@ export type WorkspaceStore = {
allFiles: Map<string, FileMeta>; allFiles: Map<string, FileMeta>;
fileTree?: FileTreeType; fileTree?: FileTreeType;
editors: EditorStore[]; editors: EditorStore[];
modifiedEditors: EditorStore[];
editing?: EditorStore; editing?: EditorStore;
isShowingSearch: boolean; isShowingSearch: boolean;
@@ -213,6 +214,7 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
allFiles: new Map(), allFiles: new Map(),
fileTree: undefined, fileTree: undefined,
editors: [], editors: [],
modifiedEditors: [],
workdir: "", workdir: "",
path: "", path: "",
@@ -498,10 +500,19 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
} else { } else {
const fullpath = fs.realpathSync(`${workspace.workdir}/${filename}`); const fullpath = fs.realpathSync(`${workspace.workdir}/${filename}`);
const editor = workspace.find(fullpath); const editor = workspace.find(fullpath);
if (editor) { if (
console.log(filename, editor, editor.modifiedTime, fs.statSync(fullpath).mtimeMs); editor &&
if (editor.modifiedTime + 500 < fs.statSync(fullpath).mtimeMs) { editor.modifiedTime + 500 < fs.statSync(fullpath).mtimeMs &&
console.log("reload", filename); !workspace.modifiedEditors.includes(editor)
) {
if (editor.unsave) {
const modifiedEditors = workspace.modifiedEditors;
console.log("modified1:", editor.path, modifiedEditors);
modifiedEditors.push(editor);
set({ modifiedEditors: modifiedEditors });
console.log("modified2:", editor.path, modifiedEditors);
} else {
editor.dispatch("reload");
} }
} }
} }