Skip to content

Commit 87b028b

Browse files
committed
fix #4252 -- closing a file that is being opened may result in that file still opening
- was mostly fixed, but just put in more checks
1 parent f5d427f commit 87b028b

File tree

1 file changed

+38
-21
lines changed

1 file changed

+38
-21
lines changed

src/packages/frontend/project/open-file.ts

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,12 @@ export async function open_file(
9393
return;
9494
}
9595

96-
let store = actions.get_store();
97-
if (store == undefined) {
98-
return;
99-
}
100-
10196
// ensure the project is opened -- otherwise the modal to start the project won't appear.
10297
redux.getActions("projects").open_project({ project_id: actions.project_id });
10398

104-
let open_files = store.get("open_files");
105-
const alreadyOpened = open_files.has(opts.path);
99+
const tabIsOpened = () =>
100+
!!actions.get_store()?.get("open_files")?.has(opts.path);
101+
const alreadyOpened = tabIsOpened();
106102

107103
if (!alreadyOpened) {
108104
// Make the visible tab itself appear ASAP (just the tab at the top,
@@ -140,6 +136,9 @@ export async function open_file(
140136
}
141137

142138
const intl = await getIntl();
139+
if (!tabIsOpened()) {
140+
return;
141+
}
143142
const what = intl.formatMessage(dialogs.project_open_file_what, {
144143
path: opts.path,
145144
});
@@ -149,6 +148,9 @@ export async function open_file(
149148
actions.open_files.delete(opts.path);
150149
return;
151150
}
151+
if (!tabIsOpened()) {
152+
return;
153+
}
152154

153155
try {
154156
// Unfortunately (it adds a roundtrip to the server), we **have** to do this
@@ -160,6 +162,9 @@ export async function open_file(
160162
project_id: actions.project_id,
161163
path: opts.path,
162164
});
165+
if (!tabIsOpened()) {
166+
return;
167+
}
163168
if (opts.path != realpath) {
164169
if (!actions.open_files) return; // closed
165170
alert_message({
@@ -176,35 +181,36 @@ export async function open_file(
176181
}
177182
let ext = opts.ext ?? filename_extension_notilde(opts.path).toLowerCase();
178183

179-
// Returns true if the project is closed or the file tab is now closed.
180-
function is_closed(): boolean {
181-
const store = actions.get_store();
182-
// if store isn't defined (so project closed) *or*
183-
// open_files doesn't have path in since tab got closed
184-
// (see https://github.com/sagemathinc/cocalc/issues/4692):
185-
return store?.getIn(["open_files", opts.path]) == null;
186-
}
187-
188184
// Next get the group.
189185
let group: string;
190186
try {
191187
group = await get_my_group(actions.project_id);
192-
if (is_closed()) return;
188+
if (!tabIsOpened()) {
189+
return;
190+
}
193191
} catch (err) {
194192
actions.set_activity({
195193
id: uuid(),
196194
error: `opening file '${opts.path}' (error getting group) -- ${err}`,
197195
});
198196
return;
199197
}
198+
199+
let store = actions.get_store();
200+
if (store == null) {
201+
return;
202+
}
203+
200204
const is_public = group === "public";
201205

202206
if (!is_public) {
203207
// Check if have capability to open this file. Important
204208
// to only do this if not public, since again, if public we
205209
// are not even using the project (it is all client side).
206210
const can_open_file = await store.can_open_file_ext(ext, actions);
207-
if (is_closed()) return;
211+
if (!tabIsOpened()) {
212+
return;
213+
}
208214
if (!can_open_file) {
209215
const site_name =
210216
redux.getStore("customize").get("site_name") || SITE_NAME;
@@ -223,14 +229,19 @@ export async function open_file(
223229
// know anything about the state of the project).
224230
try {
225231
await callback(actions._ensure_project_is_open.bind(actions));
232+
if (!tabIsOpened()) {
233+
return;
234+
}
226235
} catch (err) {
227236
actions.set_activity({
228237
id: uuid(),
229238
error: `Error opening file '${opts.path}' (error ensuring project is open) -- ${err}`,
230239
});
231240
return;
232241
}
233-
if (is_closed()) return;
242+
if (!tabIsOpened()) {
243+
return;
244+
}
234245
}
235246

236247
if (!is_public && (ext === "sws" || ext.slice(0, 4) === "sws~")) {
@@ -244,12 +255,14 @@ export async function open_file(
244255
}
245256

246257
store = actions.get_store(); // because async stuff happened above.
247-
if (store == undefined) return;
258+
if (store == undefined) {
259+
return;
260+
}
248261

249262
// Only generate the editor component if we don't have it already
250263
// Also regenerate if view type (public/not-public) changes.
251264
// (TODO: get rid of that change code since public is deprecated)
252-
open_files = store.get("open_files");
265+
const open_files = store.get("open_files");
253266
if (open_files == null || actions.open_files == null) {
254267
// project is closing
255268
return;
@@ -277,6 +290,7 @@ export async function open_file(
277290
}
278291

279292
actions.open_files.set(opts.path, "fragmentId", opts.fragmentId ?? "");
293+
280294
if ((opts.compute_server_id != null || opts.explicit) && !alreadyOpened) {
281295
let path = opts.path;
282296
if (path.endsWith(".term")) {
@@ -298,6 +312,9 @@ export async function open_file(
298312
return;
299313
}
300314
}
315+
if (!tabIsOpened()) {
316+
return;
317+
}
301318

302319
if (opts.foreground) {
303320
actions.foreground_project(opts.change_history);

0 commit comments

Comments
 (0)