Skip to content

Commit 8e719b2

Browse files
authored
Merge pull request #193 from Open-STEM/kq-bugs
Addressed the non unique editor session ID issue
2 parents 6e92dab + f9fe578 commit 8e719b2

16 files changed

Lines changed: 322 additions & 127 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"homepage": "https://experientialrobotics.org/",
55
"license": "GPL-2.0-only",
66
"private": true,
7-
"version": "2.0.0",
7+
"version": "2.0.9",
88
"type": "module",
99
"scripts": {
1010
"dev": "vite",

public/CHANGELOG.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Version 2.0.8
1+
# Version 2.0.9
22

33
#### Bluetooth support
44
<img height="10%" width="10%" src="src/assets/images/Bluetooth_FM_Black.png"/></img>

src/components/MonacoEditor.tsx

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ const extension = {
9999
registerExtension(extension, ExtensionHostKind.LocalProcess);
100100

101101
type MonacoEditorProps = {
102+
/**
103+
* id of the editor container
104+
*/
105+
tabId: string;
102106
/**
103107
* name of the editor container
104108
*/
@@ -126,6 +130,7 @@ type MonacoEditorProps = {
126130
};
127131

128132
const MonacoEditor = ({
133+
tabId,
129134
tabname,
130135
width,
131136
height,
@@ -173,20 +178,19 @@ const MonacoEditor = ({
173178
* @param code
174179
*/
175180
async function SaveEditor(code: string) {
176-
const currentName = nameRef.current;
177181
const activeTab = localStorage.getItem(StorageKeys.ACTIVETAB)?.replace(/^"|"$/g, '');
178-
if (activeTab === currentName) {
179-
await EditorMgr.getInstance().saveEditor(currentName, code);
182+
if (activeTab === tabId) {
183+
await EditorMgr.getInstance().saveEditor(tabId, code);
180184
EditorMgr.getInstance().SaveToLocalStorage(
181-
EditorMgr.getInstance().getEditorSession(currentName) as EditorSession,
185+
EditorMgr.getInstance().getEditorSession(tabId) as EditorSession,
182186
code,
183187
);
184188
}
185189
}
186190

187191
if (
188-
EditorMgr.getInstance().hasEditorSession(nameRef.current) &&
189-
!EditorMgr.getInstance().hasSubscription(nameRef.current)
192+
EditorMgr.getInstance().hasEditorSession(tabId) &&
193+
!EditorMgr.getInstance().hasSubscription(tabId)
190194
) {
191195
AppMgr.getInstance().on(EventType.EVENT_THEME, (theme) => {
192196
console.log('Monaco set theme to ${selectedTheme}');
@@ -196,32 +200,31 @@ const MonacoEditor = ({
196200

197201
AppMgr.getInstance().on(EventType.EVENT_EDITOR_LOAD, (content) => {
198202
console.log('Editor Content', content);
203+
const session: EditorSession | undefined =
204+
EditorMgr.getInstance().getEditorSession(tabId);
199205
const loadContent = JSON.parse(content);
200-
if (loadContent.name !== nameRef.current) return;
206+
if (loadContent.name !== nameRef.current || loadContent.path !== session?.path) return;
201207
if (editorRef.current && editor.current) {
202208
const model = monaco.editor.createModel(loadContent.content, languageId);
203209
editor.current.setModel(model);
204210
}
205-
const session: EditorSession | undefined =
206-
EditorMgr.getInstance().getEditorSession(loadContent.name);
207211
if (session) {
208212
EditorMgr.getInstance().SaveToLocalStorage(session, loadContent.content);
209213
}
210214
});
211215

212216
AppMgr.getInstance().on(EventType.EVENT_FONTCHANGE, (change) => {
213-
const currentName = nameRef.current;
214217
const activeTab = localStorage
215218
.getItem(StorageKeys.ACTIVETAB)
216219
?.replace(/^"|"$/g, '');
217-
if (activeTab !== currentName) return;
220+
if (activeTab !== tabId) return;
218221
if (change === FontSize.INCREASE) {
219-
const fontsize = EditorMgr.getInstance().getFontsize(currentName) + 1;
220-
EditorMgr.getInstance().setFontsize(currentName, fontsize);
222+
const fontsize = EditorMgr.getInstance().getFontsize(tabId) + 1;
223+
EditorMgr.getInstance().setFontsize(tabId, fontsize);
221224
editor.current?.updateOptions({ fontSize: fontsize });
222225
} else if (change === FontSize.DESCREASE) {
223-
const fontsize = EditorMgr.getInstance().getFontsize(currentName) - 1;
224-
EditorMgr.getInstance().setFontsize(currentName, fontsize);
226+
const fontsize = EditorMgr.getInstance().getFontsize(tabId) - 1;
227+
EditorMgr.getInstance().setFontsize(tabId, fontsize);
225228
editor.current?.updateOptions({ fontSize: fontsize });
226229
}
227230
});
@@ -233,12 +236,14 @@ const MonacoEditor = ({
233236
}
234237
});
235238

236-
AppMgr.getInstance().on(EventType.EVENT_EDITOR_NAME_CHANGED, (newName) => {
237-
setName(newName);
239+
AppMgr.getInstance().on(EventType.EVENT_EDITOR_NAME_CHANGED, (names) => {
240+
const newNames = JSON.parse(names);
241+
if (newNames.oldId !== nameRef.current) return;
242+
setName(newNames.newId);
238243
});
239244

240-
EditorMgr.getInstance().setFontsize(nameRef.current, Constants.DEFAULT_FONTSIZE);
241-
EditorMgr.getInstance().setSubscription(nameRef.current);
245+
EditorMgr.getInstance().setFontsize(tabId, Constants.DEFAULT_FONTSIZE);
246+
EditorMgr.getInstance().setSubscription(tabId);
242247
}
243248

244249
if (editorRef.current) {
@@ -257,20 +262,19 @@ const MonacoEditor = ({
257262
console.log('Editor created', codeEditor.getId());
258263
});
259264

260-
const editorSession = EditorMgr.getInstance().getEditorSession(nameRef.current);
265+
const editorSession = EditorMgr.getInstance().getEditorSession(tabId);
261266
if (editorSession && editorSession.content) {
262267
const model = monaco.editor.createModel(editorSession.content, languageId);
263268
editor.current?.setModel(model);
264269
// Update live content with session content
265270
}
266271

267272
editor.current.onDidChangeModelContent(() => {
268-
const currentName = nameRef.current;
269273
const code = editor.current?.getValue();
270274
if (code) {
271-
EditorMgr.getInstance().updateEditorSessionChange(currentName, true);
275+
EditorMgr.getInstance().updateEditorSessionChange(tabId, true);
272276
EditorMgr.getInstance().SaveToLocalStorage(
273-
EditorMgr.getInstance().getEditorSession(currentName) as EditorSession,
277+
EditorMgr.getInstance().getEditorSession(tabId) as EditorSession,
274278
code,
275279
);
276280
}
@@ -300,7 +304,7 @@ const MonacoEditor = ({
300304
}
301305
}
302306
}
303-
}, [language, value, t, childWidth, childHeight]);
307+
}, [language, value, t, childWidth, childHeight, tabId]);
304308

305309
return (
306310
<>

src/components/blockly.tsx

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ const blocklyMpdernTheme = Blockly.Theme.defineTheme('modern', {
122122
});
123123

124124
interface BlocklyEditorProps {
125-
tabname: string;
125+
tabId: string;
126+
tabName: string;
126127
}
127128

128129
/**
@@ -146,19 +147,19 @@ function blocklyToPython(ws: Workspace) {
146147
* BlocklyEditor component
147148
* @returns
148149
*/
149-
function BlocklyEditor({ tabname }: BlocklyEditorProps) {
150+
function BlocklyEditor({ tabId, tabName }: BlocklyEditorProps) {
150151
const [toolboxKey, setToolboxKey] = useState(0); // Force re-render when toolbox updates
151152
const [isLoading, setIsLoading] = useState<boolean>(true);
152153
const [isListenerSet, setIsListenerSet] = useState(false);
153-
const [name, setName] = useState<string>(tabname);
154+
const [name, setName] = useState<string>(tabName);
154155
const nameRef = useRef(name);
155156

156157
/**
157158
* handleOnInject
158159
*/
159160
function handleOnInject(ws: Workspace) {
160161
// save the ws for this editor session
161-
const editorSession = EditorMgr.getInstance().getEditorSession(name);
162+
const editorSession = EditorMgr.getInstance().getEditorSession(tabId);
162163
if (editorSession) {
163164
editorSession.workspace = ws;
164165
}
@@ -168,16 +169,15 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
168169
* saveEditor
169170
*/
170171
const saveEditor = useCallback(async () =>{
171-
const currentName = nameRef.current;
172-
const ws = EditorMgr.getInstance().getEditorSession(currentName)?.workspace;
172+
const ws = EditorMgr.getInstance().getEditorSession(tabId)?.workspace;
173173
if (ws) {
174174
const activeTab = localStorage.getItem(StorageKeys.ACTIVETAB)?.replace(/^"|"$/g, '');
175-
if (activeTab === currentName) {
175+
if (activeTab === tabId) {
176176
const code = blocklyToPython(ws);
177177
console.log('Saving blockly', activeTab, code);
178-
await EditorMgr.getInstance().saveEditor(currentName, code);
178+
await EditorMgr.getInstance().saveEditor(tabId, code);
179179
EditorMgr.getInstance().SaveToLocalStorage(
180-
EditorMgr.getInstance().getEditorSession(currentName) as EditorSession,
180+
EditorMgr.getInstance().getEditorSession(tabId) as EditorSession,
181181
code
182182
);
183183
}
@@ -198,11 +198,11 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
198198

199199
useEffect(() => {
200200
if (
201-
EditorMgr.getInstance().hasEditorSession(nameRef.current) &&
202-
!EditorMgr.getInstance().hasSubscription(nameRef.current)
201+
EditorMgr.getInstance().hasEditorSession(tabId) &&
202+
!EditorMgr.getInstance().hasSubscription(tabId)
203203
) {
204204
AppMgr.getInstance().on(EventType.EVENT_THEME, (theme) => {
205-
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
205+
const ws = EditorMgr.getInstance().getEditorSession(tabId)?.workspace;
206206

207207
if (ws) {
208208
// Not sure why the compiler complain but it works at runtime
@@ -214,26 +214,26 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
214214

215215
AppMgr.getInstance().on(EventType.EVENT_EDITOR_LOAD, (content) => {
216216
const loadContent = JSON.parse(content);
217-
if (loadContent.name !== nameRef.current) return;
217+
const session: EditorSession | undefined =
218+
EditorMgr.getInstance().getEditorSession(tabId);
219+
if (loadContent.name !== nameRef.current || loadContent.path !== session?.path) return;
218220

219-
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
221+
const ws = EditorMgr.getInstance().getEditorSession(tabId)?.workspace;
220222
if (ws) {
221223
Blockly.serialization.workspaces.load(JSON.parse(loadContent.content), ws);
222224
// @ts-expect-error - it is a valid function
223225
ws.scrollCenter();
224226
// @ts-expect-error - it is a valid function
225227
ws.zoomToFit();
226228
}
227-
const session: EditorSession | undefined =
228-
EditorMgr.getInstance().getEditorSession(loadContent.name);
229229
if (session) {
230230
EditorMgr.getInstance().SaveToLocalStorage(session, loadContent.content);
231231
}
232232
});
233233

234234
AppMgr.getInstance().on(EventType.EVENT_EDITOR, (type) => {
235235
if (type === EditorType.BLOCKLY) {
236-
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
236+
const ws = EditorMgr.getInstance().getEditorSession(tabId)?.workspace;
237237
if (ws) {
238238
console.log('rescrolling to center!')
239239
// @ts-expect-error - it is a valid function
@@ -248,7 +248,7 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
248248

249249
AppMgr.getInstance().on(EventType.EVENT_BLOCKLY_TOOLBOX_UPDATED, () => {
250250
// Force a re-render of the Blockly workspace to show new blocks
251-
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
251+
const ws = EditorMgr.getInstance().getEditorSession(tabId)?.workspace;
252252
if (ws) {
253253
// Save current workspace content
254254
const content = Blockly.serialization.workspaces.save(ws);
@@ -271,7 +271,7 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
271271
});
272272

273273
AppMgr.getInstance().on(EventType.EVENT_GENPYTHON, (activeTab) => {
274-
if (nameRef.current === activeTab) {
274+
if (tabId === activeTab) {
275275
const session: EditorSession | undefined =
276276
EditorMgr.getInstance().getEditorSession(activeTab);
277277
if (session) {
@@ -288,21 +288,23 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
288288
saveEditor();
289289
});
290290

291-
AppMgr.getInstance().on(EventType.EVENT_EDITOR_NAME_CHANGED, (newName) => {
292-
setName(newName);
291+
AppMgr.getInstance().on(EventType.EVENT_EDITOR_NAME_CHANGED, (names) => {
292+
const newNames = JSON.parse(names);
293+
if (newNames.oldId !== nameRef.current) return;
294+
setName(newNames.newId);
293295
});
294296

295-
EditorMgr.getInstance().setSubscription(nameRef.current);
297+
EditorMgr.getInstance().setSubscription(tabId);
296298

297299
} else {
298-
const editorSession = EditorMgr.getInstance().getEditorSession(nameRef.current);
300+
const editorSession = EditorMgr.getInstance().getEditorSession(tabId);
299301
if (editorSession && editorSession.content) {
300302
// There appears to be some timing issues in loading the content into the workspace
301303
// Set 100 ms delay to accommendate the timing issue
302304
const loadEditor = (name: string, content: string) => {
303305
const lines: string[] | undefined = content.split('##XRPBLOCKS ');
304306
const blockContent = lines.length > 1 ? lines[1] : lines[0];
305-
const loadContent = { name: name, content: blockContent };
307+
const loadContent = { name: name, path: editorSession.path, content: blockContent };
306308
AppMgr.getInstance().emit(EventType.EVENT_EDITOR_LOAD, JSON.stringify(loadContent));
307309
};
308310
setTimeout(loadEditor, 100, nameRef.current, editorSession.content);
@@ -336,9 +338,9 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
336338
if (event.type === Blockly.Events.VIEWPORT_CHANGE || event.isUiEvent) { return; }
337339
try {
338340
console.log('Workspace changed, saving session:', nameRef.current);
339-
EditorMgr.getInstance().updateEditorSessionChange(nameRef.current, true);
341+
EditorMgr.getInstance().updateEditorSessionChange(tabId, true);
340342
const code = blocklyToPython(ws);
341-
EditorMgr.getInstance().SaveToLocalStorage(EditorMgr.getInstance().getEditorSession(nameRef.current) as EditorSession, code);
343+
EditorMgr.getInstance().SaveToLocalStorage(EditorMgr.getInstance().getEditorSession(tabId) as EditorSession, code);
342344
} catch (e) {
343345
console.warn('Failed to serialize Blockly workspace:', e);
344346
}
@@ -366,7 +368,7 @@ function BlocklyEditor({ tabname }: BlocklyEditorProps) {
366368
ws.removeChangeListener(listener);
367369
}
368370
}
369-
}, [isListenerSet, isLoading, saveEditor]);
371+
}, [isListenerSet, isLoading, saveEditor, tabId]);
370372

371373
return (
372374
<BlocklyWorkspace

src/components/dialogs/newfiledlg.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ function NewFileDlg(newFileProps: NewFileProps) {
115115
const filename = e.target.value + (filetype === 1 ? '.blocks' : '.py');
116116
const isValid = Constants.REGEX_FILENAME.test(filename);
117117
const parts = selectedFolder.split('/').filter((part) => part !== '');
118-
const foldername = parts[parts.length - 1];
118+
const foldername = parts.length > 0 ? parts[parts.length - 1] : selectedFolder;
119119
if (!isValid || AppMgr.getInstance().IsFileExists(foldername,filename)) {
120120
setIsFileExists(true);
121121
setIsOkayToSubmit(false);

src/components/dialogs/view-pythondlg.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export default function ViewPythonDlg({ code, toggleDlg, clearDlg }: ViewPythonD
5050
<hr className="w-full border-mountain-mist-600" />
5151
<MonacoEditor
5252
value={code}
53+
tabId={t('python-untile')}
5354
tabname={t('python-untile')}
5455
width={'80vw'}
5556
height={'80vw'}

0 commit comments

Comments
 (0)