Skip to content

Commit 49518cd

Browse files
authored
Make the opening of files deterministic.
2 parents ee6f5c1 + a38f1fb commit 49518cd

File tree

5 files changed

+211
-121
lines changed

5 files changed

+211
-121
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"url": "git+https://github.com/opencor/webapp.git"
2424
},
2525
"type": "module",
26-
"version": "0.20260325.1",
26+
"version": "0.20260325.2",
2727
"engines": {
2828
"bun": ">=1.2.0"
2929
},

src/renderer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
},
4343
"./style.css": "./dist/opencor.css"
4444
},
45-
"version": "0.20260325.1",
45+
"version": "0.20260325.2",
4646
"scripts": {
4747
"build": "vite build && bun scripts/generate.version.js",
4848
"build:lib": "vite build --config vite.lib.config.ts && bunx --bun vue-tsc --project tsconfig.lib.types.json",

src/renderer/src/common/common.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,17 @@ export const fileName = (filePath: string): string => {
212212
// A method to sleep for a number of milliseconds.
213213

214214
export const sleep = (ms: number): Promise<void> => {
215-
return new Promise((resolve) => setTimeout(resolve, ms));
215+
return new Promise((resolve) => {
216+
setTimeout(resolve, ms);
217+
});
218+
};
219+
220+
// A method to wait for the next animation frame.
221+
222+
export const waitForNextAnimationFrame = (): Promise<number> => {
223+
return new Promise((resolve: FrameRequestCallback) => {
224+
requestAnimationFrame(resolve);
225+
});
216226
};
217227

218228
// Some constants related to simulation data values.

src/renderer/src/components/ContentsComponent.vue

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,44 +113,66 @@ const hasFiles = (): boolean => {
113113
return fileTabs.value.length > 0;
114114
};
115115
116-
const selectFile = (filePath: string): void => {
116+
const waitForTabsUpdate = async (): Promise<void> => {
117+
// Wait a bit to ensure that the file tabs are properly updated.
118+
// Note: although a bit of a hack, this is needed when opening multiple files. Indeed, without this, the file tab may
119+
// not be fully initialised when opening the next file. This means that when we select the file tab, it may try
120+
// to finish initialising itself and, when it comes to our simulation experiment view, this means resizing the
121+
// plots.
122+
123+
await vue.nextTick();
124+
125+
for (let i = 0; i < 3; ++i) {
126+
await common.waitForNextAnimationFrame();
127+
}
128+
};
129+
130+
const selectFile = async (filePath: string, wait: boolean = false): Promise<void> => {
117131
activeFile.value = filePath;
132+
133+
if (wait) {
134+
await waitForTabsUpdate();
135+
}
118136
};
119137
120-
const selectNextFile = (): void => {
138+
const selectNextFile = async (): Promise<void> => {
121139
const fileTabIndex = fileTabs.value.findIndex((fileTab) => fileTab.file.path() === activeFile.value);
122140
const fileTabName = fileTabs.value[(fileTabIndex + 1) % fileTabs.value.length]?.file.path() || '';
123141
124142
if (fileTabName !== '') {
125-
selectFile(fileTabName);
143+
await selectFile(fileTabName);
126144
}
127145
};
128146
129-
const selectPreviousFile = (): void => {
147+
const selectPreviousFile = async (): Promise<void> => {
130148
const fileTabIndex = fileTabs.value.findIndex((fileTab) => fileTab.file.path() === activeFile.value);
131149
const fileTabName =
132150
fileTabs.value[(fileTabIndex - 1 + fileTabs.value.length) % fileTabs.value.length]?.file.path() || '';
133151
134152
if (fileTabName !== '') {
135-
selectFile(fileTabName);
153+
await selectFile(fileTabName);
136154
}
137155
};
138156
139-
const openFile = (file: locApi.File): void => {
157+
const openFile = async (file: locApi.File, wait: boolean = false): Promise<void> => {
140158
const filePath = file.path();
141159
const prevActiveFile = activeFile.value;
142160
143-
selectFile(filePath);
161+
await selectFile(filePath);
144162
145163
fileTabs.value.splice(fileTabs.value.findIndex((fileTab) => fileTab.file.path() === prevActiveFile) + 1, 0, {
146164
file: file,
147165
uiJson: file.uiJson()
148166
});
149167
150168
electronApi?.fileOpened(filePath);
169+
170+
if (wait) {
171+
await waitForTabsUpdate();
172+
}
151173
};
152174
153-
const closeFile = (filePath: string): void => {
175+
const closeFile = async (filePath: string): Promise<void> => {
154176
locApi.fileManager.unmanage(filePath);
155177
156178
const fileTabIndex = fileTabs.value.findIndex((fileTab) => fileTab.file.path() === filePath);
@@ -161,20 +183,20 @@ const closeFile = (filePath: string): void => {
161183
const nextFileTab = fileTabs.value[Math.min(fileTabIndex, fileTabs.value.length - 1)];
162184
163185
if (nextFileTab) {
164-
selectFile(nextFileTab.file.path());
186+
await selectFile(nextFileTab.file.path());
165187
}
166188
}
167189
168190
electronApi?.fileClosed(filePath);
169191
};
170192
171-
const closeCurrentFile = (): void => {
172-
closeFile(activeFile.value);
193+
const closeCurrentFile = async (): Promise<void> => {
194+
await closeFile(activeFile.value);
173195
};
174196
175-
const closeAllFiles = (): void => {
197+
const closeAllFiles = async (): Promise<void> => {
176198
while (fileTabs.value.length) {
177-
closeCurrentFile();
199+
await closeCurrentFile();
178200
}
179201
};
180202

0 commit comments

Comments
 (0)