Skip to content

Commit 9b7a82b

Browse files
authored
Merge pull request #191 from Open-STEM/kq-bugs
Addressed issue 185 - FS renamed file
2 parents daaba9c + daab0f5 commit 9b7a82b

File tree

8 files changed

+134
-66
lines changed

8 files changed

+134
-66
lines changed

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.7
1+
# Version 2.0.8
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: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ type MonacoEditorProps = {
102102
/**
103103
* name of the editor container
104104
*/
105-
name: string;
105+
tabname: string;
106106
/**
107107
* Height of the editor container
108108
*/
@@ -126,7 +126,7 @@ type MonacoEditorProps = {
126126
};
127127

128128
const MonacoEditor = ({
129-
name,
129+
tabname,
130130
width,
131131
height,
132132
language = 'python',
@@ -139,6 +139,12 @@ const MonacoEditor = ({
139139
const editor = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
140140
const [childWidth, setChildWidth] = useState(width);
141141
const [childHeight, setChildHeight] = useState(height);
142+
const [name, setName] = useState<string>(tabname);
143+
const nameRef = useRef(name);
144+
145+
useEffect(() => {
146+
nameRef.current = name;
147+
}, [name]);
142148

143149
useEffect(() => {
144150
if (containerRef.current) {
@@ -166,20 +172,21 @@ const MonacoEditor = ({
166172
* SaveEditor save the current editor session to XRP
167173
* @param code
168174
*/
169-
function SaveEditor(code: string) {
175+
async function SaveEditor(code: string) {
176+
const currentName = nameRef.current;
170177
const activeTab = localStorage.getItem(StorageKeys.ACTIVETAB)?.replace(/^"|"$/g, '');
171-
if (activeTab === name) {
172-
EditorMgr.getInstance().saveEditor(name, code);
178+
if (activeTab === currentName) {
179+
await EditorMgr.getInstance().saveEditor(currentName, code);
173180
EditorMgr.getInstance().SaveToLocalStorage(
174-
EditorMgr.getInstance().getEditorSession(name) as EditorSession,
181+
EditorMgr.getInstance().getEditorSession(currentName) as EditorSession,
175182
code,
176183
);
177184
}
178185
}
179186

180187
if (
181-
EditorMgr.getInstance().hasEditorSession(name) &&
182-
!EditorMgr.getInstance().hasSubscription(name)
188+
EditorMgr.getInstance().hasEditorSession(nameRef.current) &&
189+
!EditorMgr.getInstance().hasSubscription(nameRef.current)
183190
) {
184191
AppMgr.getInstance().on(EventType.EVENT_THEME, (theme) => {
185192
console.log('Monaco set theme to ${selectedTheme}');
@@ -190,7 +197,7 @@ const MonacoEditor = ({
190197
AppMgr.getInstance().on(EventType.EVENT_EDITOR_LOAD, (content) => {
191198
console.log('Editor Content', content);
192199
const loadContent = JSON.parse(content);
193-
if (loadContent.name !== name) return;
200+
if (loadContent.name !== nameRef.current) return;
194201
if (editorRef.current && editor.current) {
195202
const model = monaco.editor.createModel(loadContent.content, languageId);
196203
editor.current.setModel(model);
@@ -203,17 +210,18 @@ const MonacoEditor = ({
203210
});
204211

205212
AppMgr.getInstance().on(EventType.EVENT_FONTCHANGE, (change) => {
213+
const currentName = nameRef.current;
206214
const activeTab = localStorage
207215
.getItem(StorageKeys.ACTIVETAB)
208216
?.replace(/^"|"$/g, '');
209-
if (activeTab !== name) return;
217+
if (activeTab !== currentName) return;
210218
if (change === FontSize.INCREASE) {
211-
const fontsize = EditorMgr.getInstance().getFontsize(name) + 1;
212-
EditorMgr.getInstance().setFontsize(name, fontsize);
219+
const fontsize = EditorMgr.getInstance().getFontsize(currentName) + 1;
220+
EditorMgr.getInstance().setFontsize(currentName, fontsize);
213221
editor.current?.updateOptions({ fontSize: fontsize });
214222
} else if (change === FontSize.DESCREASE) {
215-
const fontsize = EditorMgr.getInstance().getFontsize(name) - 1;
216-
EditorMgr.getInstance().setFontsize(name, fontsize);
223+
const fontsize = EditorMgr.getInstance().getFontsize(currentName) - 1;
224+
EditorMgr.getInstance().setFontsize(currentName, fontsize);
217225
editor.current?.updateOptions({ fontSize: fontsize });
218226
}
219227
});
@@ -225,8 +233,12 @@ const MonacoEditor = ({
225233
}
226234
});
227235

228-
EditorMgr.getInstance().setFontsize(name, Constants.DEFAULT_FONTSIZE);
229-
EditorMgr.getInstance().setSubscription(name);
236+
AppMgr.getInstance().on(EventType.EVENT_EDITOR_NAME_CHANGED, (newName) => {
237+
setName(newName);
238+
});
239+
240+
EditorMgr.getInstance().setFontsize(nameRef.current, Constants.DEFAULT_FONTSIZE);
241+
EditorMgr.getInstance().setSubscription(nameRef.current);
230242
}
231243

232244
if (editorRef.current) {
@@ -245,19 +257,20 @@ const MonacoEditor = ({
245257
console.log('Editor created', codeEditor.getId());
246258
});
247259

248-
const editorSession = EditorMgr.getInstance().getEditorSession(name);
260+
const editorSession = EditorMgr.getInstance().getEditorSession(nameRef.current);
249261
if (editorSession && editorSession.content) {
250262
const model = monaco.editor.createModel(editorSession.content, languageId);
251263
editor.current?.setModel(model);
252264
// Update live content with session content
253265
}
254266

255267
editor.current.onDidChangeModelContent(() => {
268+
const currentName = nameRef.current;
256269
const code = editor.current?.getValue();
257270
if (code) {
258-
EditorMgr.getInstance().updateEditorSessionChange(name, true);
271+
EditorMgr.getInstance().updateEditorSessionChange(currentName, true);
259272
EditorMgr.getInstance().SaveToLocalStorage(
260-
EditorMgr.getInstance().getEditorSession(name) as EditorSession,
273+
EditorMgr.getInstance().getEditorSession(currentName) as EditorSession,
261274
code,
262275
);
263276
}
@@ -287,7 +300,7 @@ const MonacoEditor = ({
287300
}
288301
}
289302
}
290-
}, [name, language, value, t, childWidth, childHeight]);
303+
}, [language, value, t, childWidth, childHeight]);
291304

292305
return (
293306
<>

src/components/blockly.tsx

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import BlocklyConfigs from '@components/blockly/xrp_blockly_configs';
55
import * as Blockly from 'blockly/core';
66
import { setBlocklyLocale } from '@/utils/blockly-locales';
77
import AppMgr, { EventType, Themes } from '@/managers/appmgr';
8-
import { useEffect, useState } from 'react';
8+
import { useCallback, useEffect, useRef, useState } from 'react';
99
import { useHotkeys } from 'react-hotkeys-hook';
1010
import { StorageKeys } from '@/utils/localstorage';
1111
import EditorMgr, { EditorSession } from '@/managers/editormgr';
@@ -122,17 +122,36 @@ const blocklyMpdernTheme = Blockly.Theme.defineTheme('modern', {
122122
});
123123

124124
interface BlocklyEditorProps {
125-
name: string;
125+
tabname: string;
126126
}
127127

128+
/**
129+
* blocklyToPython
130+
* @param ws
131+
* @returns
132+
*/
133+
function blocklyToPython(ws: Workspace) {
134+
const pythonCode = pythonGenerator
135+
.workspaceToCode(ws)
136+
.replace('from numbers import Number\n', 'Number = int\n');
137+
const blocklyCode = JSON.stringify(Blockly.serialization.workspaces.save(ws));
138+
const date = moment();
139+
const formatedDate = date.format('YYYY-MM-DD HH:MM:SS');
140+
const code = pythonCode + '\n\n\n## ' + formatedDate + '\n##XRPBLOCKS ' + blocklyCode;
141+
return code;
142+
}
143+
144+
128145
/**
129146
* BlocklyEditor component
130147
* @returns
131148
*/
132-
function BlocklyEditor({ name }: BlocklyEditorProps) {
149+
function BlocklyEditor({ tabname }: BlocklyEditorProps) {
133150
const [toolboxKey, setToolboxKey] = useState(0); // Force re-render when toolbox updates
134151
const [isLoading, setIsLoading] = useState<boolean>(true);
135152
const [isListenerSet, setIsListenerSet] = useState(false);
153+
const [name, setName] = useState<string>(tabname);
154+
const nameRef = useRef(name);
136155

137156
/**
138157
* handleOnInject
@@ -144,54 +163,46 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
144163
editorSession.workspace = ws;
145164
}
146165
}
147-
148-
/**
149-
* blocklyToPython
150-
* @param ws
151-
* @returns
152-
*/
153-
function blocklyToPython(ws: Workspace) {
154-
const pythonCode = pythonGenerator
155-
.workspaceToCode(ws)
156-
.replace('from numbers import Number\n', 'Number = int\n');
157-
const blocklyCode = JSON.stringify(Blockly.serialization.workspaces.save(ws));
158-
const date = moment();
159-
const formatedDate = date.format('YYYY-MM-DD HH:MM:SS');
160-
const code = pythonCode + '\n\n\n## ' + formatedDate + '\n##XRPBLOCKS ' + blocklyCode;
161-
return code;
162-
}
163166

164167
/**
165168
* saveEditor
166169
*/
167-
async function saveEditor() {
168-
const ws = EditorMgr.getInstance().getEditorSession(name)?.workspace;
170+
const saveEditor = useCallback(async () =>{
171+
const currentName = nameRef.current;
172+
const ws = EditorMgr.getInstance().getEditorSession(currentName)?.workspace;
169173
if (ws) {
170174
const activeTab = localStorage.getItem(StorageKeys.ACTIVETAB)?.replace(/^"|"$/g, '');
171-
if (activeTab === name) {
175+
if (activeTab === currentName) {
172176
const code = blocklyToPython(ws);
173177
console.log('Saving blockly', activeTab, code);
174-
await EditorMgr.getInstance().saveEditor(name, code);
178+
await EditorMgr.getInstance().saveEditor(currentName, code);
175179
EditorMgr.getInstance().SaveToLocalStorage(
176-
EditorMgr.getInstance().getEditorSession(name) as EditorSession,
180+
EditorMgr.getInstance().getEditorSession(currentName) as EditorSession,
177181
code
178182
);
179183
}
180184
}
181-
}
185+
}, []);
182186

183187
useHotkeys('ctrl+s, meta+s', (event) => {
184188
event.preventDefault();
185189
saveEditor();
186190
});
187191

192+
/**
193+
* useEffect - setup a reference to the editor name
194+
*/
195+
useEffect(() => {
196+
nameRef.current = name;
197+
}, [name]);
198+
188199
useEffect(() => {
189200
if (
190-
EditorMgr.getInstance().hasEditorSession(name) &&
191-
!EditorMgr.getInstance().hasSubscription(name)
201+
EditorMgr.getInstance().hasEditorSession(nameRef.current) &&
202+
!EditorMgr.getInstance().hasSubscription(nameRef.current)
192203
) {
193204
AppMgr.getInstance().on(EventType.EVENT_THEME, (theme) => {
194-
const ws = EditorMgr.getInstance().getEditorSession(name)?.workspace;
205+
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
195206

196207
if (ws) {
197208
// Not sure why the compiler complain but it works at runtime
@@ -203,9 +214,9 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
203214

204215
AppMgr.getInstance().on(EventType.EVENT_EDITOR_LOAD, (content) => {
205216
const loadContent = JSON.parse(content);
206-
if (loadContent.name !== name) return;
217+
if (loadContent.name !== nameRef.current) return;
207218

208-
const ws = EditorMgr.getInstance().getEditorSession(name)?.workspace;
219+
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
209220
if (ws) {
210221
Blockly.serialization.workspaces.load(JSON.parse(loadContent.content), ws);
211222
// @ts-expect-error - it is a valid function
@@ -222,7 +233,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
222233

223234
AppMgr.getInstance().on(EventType.EVENT_EDITOR, (type) => {
224235
if (type === EditorType.BLOCKLY) {
225-
const ws = EditorMgr.getInstance().getEditorSession(name)?.workspace;
236+
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
226237
if (ws) {
227238
console.log('rescrolling to center!')
228239
// @ts-expect-error - it is a valid function
@@ -237,7 +248,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
237248

238249
AppMgr.getInstance().on(EventType.EVENT_BLOCKLY_TOOLBOX_UPDATED, () => {
239250
// Force a re-render of the Blockly workspace to show new blocks
240-
const ws = EditorMgr.getInstance().getEditorSession(name)?.workspace;
251+
const ws = EditorMgr.getInstance().getEditorSession(nameRef.current)?.workspace;
241252
if (ws) {
242253
// Save current workspace content
243254
const content = Blockly.serialization.workspaces.save(ws);
@@ -260,7 +271,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
260271
});
261272

262273
AppMgr.getInstance().on(EventType.EVENT_GENPYTHON, (activeTab) => {
263-
if (name === activeTab) {
274+
if (nameRef.current === activeTab) {
264275
const session: EditorSession | undefined =
265276
EditorMgr.getInstance().getEditorSession(activeTab);
266277
if (session) {
@@ -277,10 +288,14 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
277288
saveEditor();
278289
});
279290

280-
EditorMgr.getInstance().setSubscription(name);
291+
AppMgr.getInstance().on(EventType.EVENT_EDITOR_NAME_CHANGED, (newName) => {
292+
setName(newName);
293+
});
294+
295+
EditorMgr.getInstance().setSubscription(nameRef.current);
281296

282297
} else {
283-
const editorSession = EditorMgr.getInstance().getEditorSession(name);
298+
const editorSession = EditorMgr.getInstance().getEditorSession(nameRef.current);
284299
if (editorSession && editorSession.content) {
285300
// There appears to be some timing issues in loading the content into the workspace
286301
// Set 100 ms delay to accommendate the timing issue
@@ -290,11 +305,11 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
290305
const loadContent = { name: name, content: blockContent };
291306
AppMgr.getInstance().emit(EventType.EVENT_EDITOR_LOAD, JSON.stringify(loadContent));
292307
};
293-
setTimeout(loadEditor, 100, name, editorSession.content);
308+
setTimeout(loadEditor, 100, nameRef.current, editorSession.content);
294309
}
295310
}
296311

297-
// Set up language based on stored preference
312+
// Set up language based on stored preference
298313
const setupLanguage = () => {
299314
const storedLanguage = localStorage.getItem(StorageKeys.LANGUAGE) || 'en';
300315
setBlocklyLocale(storedLanguage);
@@ -320,10 +335,10 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
320335
) { return; }
321336
if (event.type === Blockly.Events.VIEWPORT_CHANGE || event.isUiEvent) { return; }
322337
try {
323-
console.log('Workspace changed, saving session:', name);
324-
EditorMgr.getInstance().updateEditorSessionChange(name, true);
338+
console.log('Workspace changed, saving session:', nameRef.current);
339+
EditorMgr.getInstance().updateEditorSessionChange(nameRef.current, true);
325340
const code = blocklyToPython(ws);
326-
EditorMgr.getInstance().SaveToLocalStorage(EditorMgr.getInstance().getEditorSession(name) as EditorSession, code);
341+
EditorMgr.getInstance().SaveToLocalStorage(EditorMgr.getInstance().getEditorSession(nameRef.current) as EditorSession, code);
327342
} catch (e) {
328343
console.warn('Failed to serialize Blockly workspace:', e);
329344
}
@@ -351,7 +366,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
351366
ws.removeChangeListener(listener);
352367
}
353368
}
354-
});
369+
}, [isListenerSet, isLoading, saveEditor]);
355370

356371
return (
357372
<BlocklyWorkspace

src/components/dialogs/view-pythondlg.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +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-
name={t('python-untile')}
53+
tabname={t('python-untile')}
5454
width={'80vw'}
5555
height={'80vw'}
5656
/>

src/components/folder-tree.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ function FolderTree(treeProps: TreeProps) {
350350
await CommandToXRPMgr.getInstance().renameFile(found.path + '/' + found.name, name);
351351
}
352352

353+
EditorMgr.getInstance().RenameEditorTab(originalName, name);
354+
353355
// update the name field
354356
found.name = name;
355357
}

src/components/xrplayout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,13 @@ let layoutRef: React.RefObject<Layout> = {
104104
const factory = (node: TabNode) => {
105105
const component = node.getComponent();
106106
if (component == 'editor') {
107-
return <MonacoEditor name={node.getName()} width="100vw" height="100vh" />;
107+
return <MonacoEditor tabname={node.getName()} width="100vw" height="100vh" />;
108108
} else if (component == 'xterm') {
109109
return <XRPShell />;
110110
} else if (component == 'folders') {
111111
return <FolderTree treeData={null} theme="rct-dark" isHeader={true} />;
112112
} else if (component == 'blockly') {
113-
return <BlocklyEditor name={node.getName()} />;
113+
return <BlocklyEditor tabname={node.getName()} />;
114114
} else if (component == 'dashboard') {
115115
return <XRPDashboard />;
116116
} else if (component == 'aichat') {

0 commit comments

Comments
 (0)