Skip to content

Commit 26bd958

Browse files
authored
fix: improve close group in editor (#267)
1 parent 3d10746 commit 26bd958

File tree

2 files changed

+80
-32
lines changed

2 files changed

+80
-32
lines changed

src/services/workbench/editorService.ts

+79-32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'reflect-metadata';
22
import { singleton, container } from 'tsyringe';
3-
3+
import cloneDeep from 'lodash/cloneDeep';
44
import { Component } from 'mo/react';
55
import {
66
EditorModel,
@@ -104,8 +104,11 @@ export class EditorService
104104
});
105105
}
106106

107-
public isOpened(tabId: string): boolean {
108-
const { groups = [] } = this.state;
107+
public isOpened(
108+
tabId: string,
109+
filterGroups?: IEditorGroup<any, any>[]
110+
): boolean {
111+
const groups = filterGroups || this.state.groups || [];
109112
return groups.some((group) => this.getTabById(tabId, group));
110113
}
111114

@@ -207,6 +210,8 @@ export class EditorService
207210
const nextGroups = [...groups];
208211
const nextGroup = nextGroups[groupIndex];
209212
const tabIndex = nextGroup.data!.findIndex(searchById(tabId));
213+
214+
const tab = cloneDeep(nextGroup.data![tabIndex]);
210215
if (tabIndex === -1) return;
211216

212217
if (nextGroup.data!.length === 1 && tabIndex === 0) {
@@ -215,14 +220,19 @@ export class EditorService
215220
const activeGroup =
216221
nextGroups[groupIndex + 1] || nextGroups[groupIndex - 1];
217222

218-
// the model of closed tab should be disposed after closing
219-
this.disposeModel(nextGroup.data![tabIndex]);
220223
nextGroups.splice(groupIndex, 1);
221224

222-
this.setState({
223-
groups: nextGroups,
224-
current: nextGroups?.length === 0 ? undefined : activeGroup,
225-
});
225+
this.setState(
226+
{
227+
groups: nextGroups,
228+
current: nextGroups?.length === 0 ? undefined : activeGroup,
229+
},
230+
() => {
231+
const isOpened = this.isOpened(tabId);
232+
// the model of closed tab should be disposed after closing
233+
!isOpened && this.disposeModel(tab);
234+
}
235+
);
226236
return;
227237
}
228238

@@ -235,15 +245,19 @@ export class EditorService
235245
nextGroup.activeTab = nextTab?.id;
236246
}
237247

238-
this.disposeModel(nextGroup.data![tabIndex]);
239-
240248
nextGroup.data!.splice(tabIndex, 1);
241249
nextGroups[groupIndex] = nextGroup;
242250

243-
this.setState({
244-
current: nextGroup,
245-
groups: nextGroups,
246-
});
251+
this.setState(
252+
{
253+
current: nextGroup,
254+
groups: nextGroups,
255+
},
256+
() => {
257+
const isOpened = this.isOpened(tabId);
258+
!isOpened && this.disposeModel(tab);
259+
}
260+
);
247261
}
248262

249263
public closeOthers(tab: IEditorTab, groupId: number) {
@@ -258,14 +272,23 @@ export class EditorService
258272

259273
const updateTabs = nextTabData!.filter(searchById(tabId));
260274
// tab data is unlikely to be large enough to affect exec time, so we filter twice for maintainability
261-
const removedTabs = nextTabData!.filter((item) => item.id !== tabId);
262-
263-
this.disposeModel(removedTabs);
275+
const removedTabs = cloneDeep(
276+
nextTabData!.filter(
277+
(item) =>
278+
item.id !== tabId &&
279+
!this.isOpened(
280+
item.id!,
281+
nextGroups.filter((g) => g.id !== groupId)
282+
)
283+
)
284+
);
264285

265286
this.updateGroup(groupId, {
266287
data: updateTabs,
267288
});
268289
this.setActive(groupId, tabId!);
290+
291+
this.disposeModel(removedTabs);
269292
}
270293

271294
public closeToRight(tab: IEditorTab, groupId: number) {
@@ -282,14 +305,21 @@ export class EditorService
282305
if (tabIndex <= -1) return;
283306

284307
const updateTabs = nextTabData?.slice(0, tabIndex + 1);
285-
const removedTabs = nextTabData?.slice(tabIndex + 1);
286-
287-
removedTabs && this.disposeModel(removedTabs);
308+
const removedTabs = cloneDeep(
309+
nextTabData?.slice(tabIndex + 1).filter(
310+
(item) =>
311+
!this.isOpened(
312+
item.id!,
313+
nextGroups.filter((g) => g.id !== groupId)
314+
)
315+
)
316+
);
288317

289318
this.updateGroup(groupId, {
290319
data: updateTabs,
291320
});
292321
this.setActive(groupId, tabId!);
322+
this.disposeModel(removedTabs || []);
293323
}
294324

295325
public closeToLeft(tab: IEditorTab, groupId: number) {
@@ -306,14 +336,21 @@ export class EditorService
306336
if (tabIndex <= -1) return;
307337

308338
const updateTabs = nextTabData?.slice(tabIndex, nextTabData.length);
309-
const removedTabs = nextTabData?.slice(0, tabIndex);
310-
311-
this.disposeModel(removedTabs || []);
339+
const removedTabs = cloneDeep(
340+
nextTabData?.slice(0, tabIndex).filter(
341+
(item) =>
342+
!this.isOpened(
343+
item.id!,
344+
nextGroups.filter((g) => g.id !== groupId)
345+
)
346+
)
347+
);
312348

313349
this.updateGroup(groupId, {
314350
data: updateTabs,
315351
});
316352
this.setActive(groupId, tabId!);
353+
this.disposeModel(removedTabs || []);
317354
}
318355

319356
public getGroupById(groupId: number): IEditorGroup | undefined {
@@ -426,19 +463,29 @@ export class EditorService
426463
const nextGroups = [...groups];
427464
let nextCurrentGroup = current;
428465

429-
// dispose all models in specific group
430-
this.disposeModel(nextGroups[groupIndex].data || []);
466+
const removedGroup = nextGroups.splice(groupIndex, 1);
431467

432-
nextGroups.splice(groupIndex, 1);
468+
const removed = cloneDeep(
469+
removedGroup[0].data?.filter(
470+
(item) => !this.isOpened(item.id!, nextGroups)
471+
) || []
472+
);
433473

434474
if (current && current.id === groupId) {
435-
nextCurrentGroup = groups[groupIndex - 1];
475+
nextCurrentGroup =
476+
groups[groupIndex + 1] || groups[groupIndex - 1];
436477
}
437478

438-
this.setState({
439-
groups: nextGroups,
440-
current: nextCurrentGroup,
441-
});
479+
this.setState(
480+
{
481+
groups: nextGroups,
482+
current: nextCurrentGroup,
483+
},
484+
() => {
485+
// dispose all models in specific group
486+
this.disposeModel(removed);
487+
}
488+
);
442489
}
443490
}
444491

src/workbench/editor/group.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export function EditorGroup(props: IEditorGroupProps & IEditorController) {
9494
)
9595
) : (
9696
<MonacoEditor
97+
key={tab.id}
9798
options={{
9899
value: tab.data?.value,
99100
language: tab.data?.language,

0 commit comments

Comments
 (0)