Skip to content

Commit 67a542c

Browse files
committed
updated with editor bugfix
1 parent 0e07e02 commit 67a542c

File tree

2 files changed

+55
-37
lines changed

2 files changed

+55
-37
lines changed

frontend/public/config.generated.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
server:
2-
numImageProcessors: 8 # number of concurrent image processing jobs used to create previews, default is number of cpu cores available.
2+
numImageProcessors: 14 # number of concurrent image processing jobs used to create previews, default is number of cpu cores available.
33
socket: "" # socket to listen on
44
tlsKey: "" # path to TLS key
55
tlsCert: "" # path to TLS cert

frontend/src/views/files/Editor.vue

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import { eventBus } from "@/store/eventBus";
99
import { state, getters, mutations } from "@/store";
1010
import { filesApi } from "@/api";
11+
// Assuming 'notify' is a utility you have for showing notifications
12+
import { notify } from "@/notify";
1113
import ace, { version as ace_version } from "ace-builds";
1214
import modelist from "ace-builds/src-noconflict/ext-modelist";
1315
import "ace-builds/src-min-noconflict/theme-chrome";
@@ -18,27 +20,35 @@ export default {
1820
data: function () {
1921
return {
2022
editor: null, // The editor instance
23+
// Initialize filename from the route it's created with
24+
filename: "",
2125
};
2226
},
2327
computed: {
2428
isDarkMode() {
2529
return getters.isDarkMode();
2630
},
2731
},
28-
watch: {
29-
$route() {
30-
if (this.editor) {
31-
this.editor.destroy();
32-
this.editor = null;
33-
}
34-
// Wait for the DOM to update after the route change
35-
this.$nextTick(() => {
36-
this.setupEditor();
37-
});
38-
},
32+
// Use beforeRouteUpdate to react to file changes
33+
beforeRouteUpdate(to, from, next) {
34+
35+
// Destroy the old editor instance to ensure a clean state
36+
if (this.editor) {
37+
this.editor.destroy();
38+
this.editor = null;
39+
}
40+
41+
// Call setupEditor on the next DOM update cycle
42+
this.$nextTick(() => {
43+
this.setupEditor();
44+
});
45+
46+
// Continue with the navigation
47+
next();
3948
},
4049
created() {
4150
window.addEventListener("keydown", this.keyEvent);
51+
eventBus.on("handleEditorValueRequest", this.handleEditorValueRequest);
4252
},
4353
beforeUnmount() {
4454
window.removeEventListener("keydown", this.keyEvent);
@@ -47,53 +57,61 @@ export default {
4757
}
4858
},
4959
mounted: function () {
50-
mutations.resetSelected();
51-
mutations.addSelected({
52-
name: state.req.name,
53-
path: state.req.path,
54-
size: state.req.size,
55-
type: state.req.type,
56-
source: state.req.source,
57-
url: state.req.url,
58-
});
59-
// Wait for the initial DOM render to complete
60-
this.$nextTick(() => {
61-
this.setupEditor();
62-
});
63-
eventBus.on("handleEditorValueRequest", this.handleEditorValueRequest);
60+
// This will run only when the component is first added to the page
61+
this.setupEditor();
6462
},
6563
methods: {
66-
setupEditor() {
64+
setupEditor(attempt = 1) {
65+
this.filename = decodeURIComponent(this.$route.path.split("/").pop())
66+
// Safety Check 1: Use the component's 'filename' data property for comparison
67+
if (state.req.name !== this.filename) {
68+
if (attempt < 5) {
69+
console.warn(
70+
`[Attempt ${attempt}/5] State filename ("${state.req.name}") does not match route filename ("${this.filename}"). Retrying in 500ms...`
71+
);
72+
setTimeout(() => this.setupEditor(attempt + 1), 500);
73+
} else {
74+
const errorMsg = `[FATAL] Failed to sync state with the route for "${this.filename}" after 5 attempts. Aborting editor setup to prevent data corruption.`;
75+
console.error(errorMsg);
76+
notify.showError(errorMsg); // Using the custom notifier
77+
}
78+
return;
79+
}
80+
81+
console.log(
82+
"State and route are in sync. Proceeding with editor setup for",
83+
this.filename
84+
);
6785
const editorEl = document.getElementById("editor");
6886
if (!editorEl) {
69-
console.warn(
70-
"Editor component mounted, but #editor div was not found in the DOM. Aborting setup."
71-
);
7287
return;
7388
}
7489
7590
ace.config.set(
7691
"basePath",
7792
`https://cdn.jsdelivr.net/npm/ace-builds@${ace_version}/src-min-noconflict/`
7893
);
79-
8094
const fileContent =
8195
state.req.content == "empty-file-x6OlSil" ? "" : state.req.content || "";
82-
8396
this.editor = ace.edit(editorEl, {
8497
mode: modelist.getModeForPath(state.req.name).mode,
8598
value: fileContent,
8699
showPrintMargin: false,
87-
theme: "ace/theme/chrome",
100+
theme: this.isDarkMode ? "ace/theme/twilight" : "ace/theme/chrome",
88101
readOnly: state.req.type === "textImmutable",
89102
wrap: false,
90103
});
91-
92-
if (this.isDarkMode) {
93-
this.editor.setTheme("ace/theme/twilight");
94-
}
104+
this.filename = decodeURIComponent(this.$route.path.split("/").pop())
95105
},
96106
handleEditorValueRequest() {
107+
// Safety Check 2: Final verification before saving
108+
if (state.req.name !== this.filename) {
109+
// Corrected the error message to be more accurate
110+
const errorMsg = `CRITICAL: Save operation aborted. The application's active file ("${state.req.name}") does not match the file you are trying to save ("${this.filename}").`;
111+
notify.showError(errorMsg);
112+
return;
113+
}
114+
97115
if (this.editor) {
98116
filesApi.put(state.req.path, state.req.source, this.editor.getValue());
99117
}

0 commit comments

Comments
 (0)