Skip to content

Commit c79f29e

Browse files
committed
VSCode editor bugfixes
1 parent 3d78451 commit c79f29e

File tree

12 files changed

+462
-369
lines changed

12 files changed

+462
-369
lines changed

packages/app/src/app/components/CodeEditor/VSCode/index.js

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
9999
transpilationListener: ?Function;
100100
sizeProbeInterval: ?number;
101101

102+
modelSelectionListener: {
103+
dispose: Function,
104+
};
105+
modelContentChangedListener: {
106+
dispose: Function,
107+
};
108+
102109
constructor(props: Props) {
103110
super(props);
104111
this.state = {
@@ -160,16 +167,19 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
160167
window.removeEventListener('resize', this.resizeEditor);
161168
// Make sure that everything has run before disposing, to prevent any inconsistensies
162169

163-
// if (this.editor) {
164-
// this.editor.dispose();
165-
// }
166170
if (this.lintWorker) {
167171
this.lintWorker.terminate();
168172
}
169173
if (this.transpilationListener) {
170174
this.transpilationListener();
171175
}
172176
clearInterval(this.sizeProbeInterval);
177+
if (this.modelContentChangedListener) {
178+
this.modelContentChangedListener.dispose();
179+
}
180+
if (this.modelSelectionListener) {
181+
this.modelSelectionListener.dispose();
182+
}
173183

174184
if (this.disposeInitializer) {
175185
this.disposeInitializer();
@@ -274,22 +284,20 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
274284
monaco: this.monaco,
275285
};
276286

277-
let modelContentChangedListener;
278-
let modelSelectionListener;
279287
editor.editorService.onDidActiveEditorChange(() => {
280-
if (modelContentChangedListener) {
281-
modelContentChangedListener.dispose();
288+
if (this.modelContentChangedListener) {
289+
this.modelContentChangedListener.dispose();
282290
}
283-
if (modelSelectionListener) {
284-
modelSelectionListener.dispose();
291+
if (this.modelSelectionListener) {
292+
this.modelSelectionListener.dispose();
285293
}
286294

287295
const activeEditor = editor.getActiveCodeEditor();
288296

289297
if (activeEditor) {
290298
activeEditor.updateOptions({ readOnly: this.props.readOnly });
291299

292-
modelContentChangedListener = activeEditor.onDidChangeModelContent(
300+
this.modelContentChangedListener = activeEditor.onDidChangeModelContent(
293301
e => {
294302
const { isLive, sendTransforms } = this.props;
295303

@@ -301,7 +309,7 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
301309
}
302310
);
303311

304-
modelSelectionListener = activeEditor.onDidChangeCursorSelection(
312+
this.modelSelectionListener = activeEditor.onDidChangeCursorSelection(
305313
selectionChange => {
306314
// TODO: add another debounced action to send the current data. So we can
307315
// have the correct cursor pos no matter what
@@ -718,6 +726,12 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
718726
dependencies: $PropertyType<Props, 'dependencies'>
719727
): Promise<null> =>
720728
new Promise(resolve => {
729+
if (this.modelContentChangedListener) {
730+
this.modelContentChangedListener.dispose();
731+
}
732+
if (this.modelSelectionListener) {
733+
this.modelSelectionListener.dispose();
734+
}
721735
this.sandbox = newSandbox;
722736
this.currentModule = newCurrentModule;
723737
this.dependencies = dependencies;
@@ -859,7 +873,7 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
859873
.map(error => {
860874
if (error) {
861875
return {
862-
severity: this.monaco.Severity.Error,
876+
severity: this.monaco.MarkerSeverity.Error,
863877
startColumn: 1,
864878
startLineNumber: error.line,
865879
endColumn: error.column,
@@ -898,8 +912,8 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
898912
return {
899913
severity:
900914
correction.severity === 'warning'
901-
? this.monaco.Severity.Warning
902-
: this.monaco.Severity.Notice,
915+
? this.monaco.MarkerSeverity.Warning
916+
: this.monaco.MarkerSeverity.Notice,
903917
startColumn: correction.column,
904918
startLineNumber: correction.line,
905919
endColumn: 1,

packages/app/src/app/store/actions.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ export function callVSCodeCallback({ props }) {
2929
}
3030
}
3131

32+
export function callVSCodeCallbackError({ props }) {
33+
const { cbID } = props;
34+
if (cbID) {
35+
if (window.cbs && window.cbs[cbID]) {
36+
const errorMessage =
37+
props.message || 'Something went wrong while saving the file.';
38+
window.cbs[cbID](new Error(errorMessage), undefined);
39+
delete window.cbs[cbID];
40+
}
41+
}
42+
}
43+
3244
export function setWorkspace({ state, props }) {
3345
state.set('workspace.project.title', props.sandbox.title || '');
3446
state.set('workspace.project.description', props.sandbox.description || '');

packages/app/src/app/store/modules/editor/actions.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ export function updateTemplateIfSSE({ state, api }) {
480480
}
481481
}
482482

483-
export function saveModuleCode({ props, state, api, recover }) {
483+
export function saveModuleCode({ props, state, api, recover, path }) {
484484
const sandbox = state.get('editor.currentSandbox');
485485
const moduleToSave = sandbox.modules.find(
486486
module => module.shortid === props.moduleShortid
@@ -504,6 +504,14 @@ export function saveModuleCode({ props, state, api, recover }) {
504504
);
505505

506506
if (index > -1) {
507+
state.set(
508+
`editor.sandboxes.${newSandbox.id}.modules.${index}.insertedAt`,
509+
x.insertedAt
510+
);
511+
state.set(
512+
`editor.sandboxes.${newSandbox.id}.modules.${index}.updatedAt`,
513+
x.updatedAt
514+
);
507515
if (newModuleToSave.code === codeToSave) {
508516
state.set(
509517
`editor.sandboxes.${newSandbox.id}.modules.${index}.savedCode`,
@@ -515,14 +523,20 @@ export function saveModuleCode({ props, state, api, recover }) {
515523
`editor.sandboxes.${newSandbox.id}.modules.${index}.savedCode`,
516524
x.code
517525
);
518-
throw new Error(
519-
`The code of '${title}' changed while saving, will ignore the save now. Please try again with saving.`
520-
);
526+
527+
return path.codeOutdated({
528+
message: `The code of '${title}' changed while saving. Please try again with saving.`,
529+
});
521530
}
522531
}
523532

524-
return x;
525-
});
533+
return path.success(x);
534+
})
535+
.catch(e =>
536+
path.error({
537+
message: e.message,
538+
})
539+
);
526540
}
527541

528542
export function getCurrentModuleId({ state }) {
@@ -624,3 +638,19 @@ export function getSavedCode({ props, state }) {
624638

625639
return {};
626640
}
641+
642+
export function touchFile({ props, state }) {
643+
const sandbox = state.get('editor.currentSandbox');
644+
const moduleIndex = sandbox.modules.findIndex(
645+
m => m.shortid === props.moduleShortid
646+
);
647+
648+
if (moduleIndex > -1) {
649+
state.set(
650+
`editor.currentSandbox.modules.${moduleIndex}.updatedAt`,
651+
new Date().toString()
652+
);
653+
}
654+
655+
return {};
656+
}

packages/app/src/app/store/modules/editor/model.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ const Directory = types.model({
3434
shortid: types.string,
3535
sourceId: types.string,
3636
title: types.string,
37+
insertedAt: types.string,
38+
updatedAt: types.string,
3739
});
3840

3941
const Module = types.model({
@@ -45,6 +47,8 @@ const Module = types.model({
4547
shortid: types.string,
4648
sourceId: types.string,
4749
title: types.string,
50+
insertedAt: types.string,
51+
updatedAt: types.string,
4852
});
4953

5054
const Git = types.model({

packages/app/src/app/store/modules/editor/sequences.js

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { set, when, equals, toggle, increment } from 'cerebral/operators';
22
import { state, props } from 'cerebral/tags';
33
import * as actions from './actions';
4-
import { closeTabByIndex, callVSCodeCallback } from '../../actions';
4+
import {
5+
closeTabByIndex,
6+
callVSCodeCallback,
7+
callVSCodeCallbackError,
8+
} from '../../actions';
59
import { renameModule } from '../files/sequences';
610
import {
711
sendModuleSaved,
@@ -203,30 +207,40 @@ export const saveCode = [
203207
},
204208

205209
actions.saveModuleCode,
206-
actions.setModuleSaved,
207-
callVSCodeCallback,
208-
when(state`editor.currentSandbox.originalGit`),
209210
{
210-
true: [
211-
when(state`workspace.openedWorkspaceItem`, item => item === 'github'),
211+
success: [
212+
actions.setModuleSaved,
213+
callVSCodeCallback,
214+
when(state`editor.currentSandbox.originalGit`),
212215
{
213-
true: fetchGitChanges,
216+
true: [
217+
when(state`workspace.openedWorkspaceItem`, item => item === 'github'),
218+
{
219+
true: fetchGitChanges,
220+
false: [],
221+
},
222+
],
214223
false: [],
215224
},
225+
sendModuleSaved,
226+
227+
actions.updateTemplateIfSSE,
216228
],
217-
false: [],
218-
},
219-
sendModuleSaved,
220229

221-
actions.updateTemplateIfSSE,
230+
error: [callVSCodeCallbackError],
231+
codeOutdated: [
232+
addNotification(props`message`, 'warning'),
233+
callVSCodeCallbackError,
234+
],
235+
},
222236
];
223237

224238
export const discardModuleChanges = [
225239
track('Code Discarded', {}),
226240
actions.getSavedCode,
227241
when(props`code`),
228242
{
229-
true: [changeCode],
243+
true: [changeCode, actions.touchFile],
230244
false: [],
231245
},
232246
];

packages/app/src/app/store/modules/files/actions.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ export function createOptimisticModule({ state, props, utils }) {
191191
shortid: utils.createOptimisticId(),
192192
isBinary: props.isBinary === undefined ? false : props.isBinary,
193193
sourceId: state.get('editor.currentSandbox.sourceId'),
194+
insertedAt: new Date().toString(),
195+
updatedAt: new Date().toString(),
194196
};
195197

196198
return { optimisticModule };
@@ -203,6 +205,8 @@ export function createOptimisticDirectory({ state, props, utils }) {
203205
directoryShortid: props.directoryShortid || null,
204206
shortid: utils.createOptimisticId(),
205207
sourceId: state.get('editor.currentSandbox.sourceId'),
208+
insertedAt: new Date().toString(),
209+
updatedAt: new Date().toString(),
206210
};
207211

208212
return { optimisticDirectory };

packages/app/src/app/store/modules/files/sequences.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { push, set, concat } from 'cerebral/operators';
22
import { state, props } from 'cerebral/tags';
33
import { ensureOwnedEditable, closeModal } from '../../sequences';
44
import { setCurrentModule, addNotification } from '../../factories';
5-
import { closeTabByIndex, setModal, callVSCodeCallback } from '../../actions';
5+
import {
6+
closeTabByIndex,
7+
setModal,
8+
callVSCodeCallback,
9+
callVSCodeCallbackError,
10+
} from '../../actions';
611
import {
712
sendModuleCreated,
813
sendModuleDeleted,
@@ -55,7 +60,7 @@ export const massCreateModules = [
5560
sendMassModuleCreated,
5661
callVSCodeCallback,
5762
],
58-
error: [],
63+
error: [callVSCodeCallbackError],
5964
},
6065
];
6166

standalone-packages/codesandbox-browserfs/src/backend/CodeSandboxEditorFS.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { ErrorCode, ApiError } from '../core/api_error';
1414
export interface IModule {
1515
path: string;
1616
code: string | undefined;
17+
updatedAt: string;
18+
insertedAt: string;
1719
}
1820

1921
export interface IManager {
@@ -159,7 +161,11 @@ export default class CodeSandboxEditorFS extends SynchronousFileSystem
159161

160162
const stats = new Stats(
161163
FileType.FILE,
162-
(moduleInfo.code || '').length
164+
(moduleInfo.code || '').length,
165+
undefined,
166+
new Date(),
167+
new Date(moduleInfo.updatedAt),
168+
new Date(moduleInfo.insertedAt)
163169
);
164170

165171
return stats;
@@ -178,7 +184,7 @@ export default class CodeSandboxEditorFS extends SynchronousFileSystem
178184

179185
const { code = '' } = moduleInfo;
180186
const buffer = Buffer.from(code || '');
181-
const stats = new Stats(FileType.FILE, buffer.length);
187+
const stats = new Stats(FileType.FILE, buffer.length, undefined, new Date(), new Date(moduleInfo.updatedAt), new Date(moduleInfo.insertedAt));
182188

183189
return new CodeSandboxFile(this, p, flag, stats, buffer);
184190
}

standalone-packages/monaco-typescript/src/fetchDependencyTypings.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ const getFileTypes = (
307307

308308
if (fetchedPaths[virtualPath]) return null;
309309

310+
console.log(`${depUrl}${depPath}`);
310311
return doFetch(`${depUrl}${depPath}`).then(typings => {
311312
if (fetchedPaths[virtualPath]) return null;
312313

@@ -388,8 +389,8 @@ function fetchFromMeta(dependency, version, fetchedPaths) {
388389
}
389390

390391
function fetchFromTypings(dependency, version, fetchedPaths) {
391-
const depUrl = `${ROOT_URL}${dependency}@${version}`;
392-
return doFetch(`${depUrl}/package.json`)
392+
const depUrl = `${ROOT_URL}${dependency}@${version}/`;
393+
return doFetch(`${depUrl}package.json`)
393394
.then(response => JSON.parse(response))
394395
.then(packageJSON => {
395396
const types = packageJSON.typings || packageJSON.types;

standalone-packages/vscode-editor/release/min/vs/editor/codesandbox.editor.main.js

Lines changed: 317 additions & 314 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)