Skip to content

Commit 475ef5b

Browse files
authored
Merge pull request #105 from Open-STEM/kq-bugs
Addressed folder tree interaction during run state
2 parents e8e66e9 + 046c48e commit 475ef5b

File tree

4 files changed

+57
-15
lines changed

4 files changed

+57
-15
lines changed

src/components/folder-header.tsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import AppMgr, { EventType } from '@/managers/appmgr';
12
import { StorageKeys } from '@/utils/localstorage';
23
import { ModeType } from '@/utils/types';
4+
import { useEffect, useState } from 'react';
35
import { useTranslation } from 'react-i18next';
46
import { AiOutlineFileAdd } from "react-icons/ai";
57
import { AiOutlineFolderAdd } from "react-icons/ai";
@@ -18,6 +20,20 @@ interface FolderHeaderProps {
1820
function FolderHeader({ storageCapacity, openFolderCallback, closeFolderCallback, newFolderCallback, newFileCallback }: FolderHeaderProps) {
1921
const { t } = useTranslation();
2022
const modeType = useReadLocalStorage(StorageKeys.MODESETTING);
23+
const [isRunning, setIsRunning] = useState<boolean>(false);
24+
25+
useEffect(() => {
26+
const appMgr = AppMgr.getInstance();
27+
28+
appMgr.on(EventType.EVENT_ISRUNNING, (running: string) => {
29+
if (running === 'running') {
30+
setIsRunning(true);
31+
} else if (running === 'stopped') {
32+
setIsRunning(false);
33+
}
34+
});
35+
}, []);
36+
2137
return (
2238
<div className="flex flex-row items-center justify-between bg-mountain-mist-100 p-1 text-sm dark:bg-mountain-mist-800">
2339
<div className="flex flex-row">
@@ -26,18 +42,18 @@ function FolderHeader({ storageCapacity, openFolderCallback, closeFolderCallback
2642
<div className="flex flex-row gap-1">
2743
{modeType === ModeType.SYSTEM && (
2844
<>
29-
<button title={t('openFolder')} onClick={openFolderCallback}>
30-
<FaRegFolderOpen size={'1.5em'} />
45+
<button title={t('openFolder')} onClick={openFolderCallback} disabled={isRunning}>
46+
<FaRegFolderOpen className={`${isRunning ? 'opacity-50' : 'opacity-100'}`} size={'1.5em'} />
3147
</button>
32-
<button title={t('closeFolder')} onClick={closeFolderCallback}>
33-
<FaRegFolderClosed size={'1.2em'} />
48+
<button title={t('closeFolder')} onClick={closeFolderCallback} disabled={isRunning}>
49+
<FaRegFolderClosed className={`${isRunning ? 'opacity-50' : 'opacity-100'}`} size={'1.2em'} />
3450
</button>
3551
</>
3652
)}
37-
<button title={t('newFolder')} onClick={newFolderCallback}>
38-
<AiOutlineFolderAdd size={'1.5em'} />
53+
<button title={t('newFolder')} onClick={newFolderCallback} disabled={isRunning}>
54+
<AiOutlineFolderAdd className={`${isRunning ? 'opacity-50' : 'opacity-100'}`} size={'1.5em'} />
3955
</button>
40-
<button title={t('newFile')} onClick={newFileCallback}>
56+
<button title={t('newFile')} className={`${isRunning ? 'opacity-50' : 'opacity-100'}`} onClick={newFileCallback} disabled={isRunning}>
4157
<AiOutlineFileAdd size={'1.4em'} />
4258
</button>
4359
</div>

src/components/folder-tree.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ function FolderTree(treeProps: TreeProps) {
3737
const [capacity, setCapacity] = useState<string>('0/0');
3838
const [treeData, setTreeData] = useState<FolderItem[] | undefined>(undefined);
3939
const [selectedItems, setSelectedItems] = useState<FolderItem[] | undefined>(undefined);
40+
const [isRunning, setIsRunning] = useState<boolean>(false);
4041
const appMgrRef = useRef<AppMgr>();
4142
const treeRef = useRef(null);
4243
const { ref, width, height } = useResizeObserver();
@@ -57,11 +58,19 @@ function FolderTree(treeProps: TreeProps) {
5758

5859
setConnected(appMgrRef.current.getConnection()?.isConnected() ?? false);
5960

60-
AppMgr.getInstance().on(EventType.EVENT_CONNECTION_STATUS, (state: string) => {
61+
appMgrRef.current.on(EventType.EVENT_CONNECTION_STATUS, (state: string) => {
6162
if (state === ConnectionState.Connected.toString()) {
6263
setConnected(true);
6364
}
6465
});
66+
67+
appMgrRef.current.on(EventType.EVENT_ISRUNNING, (running: string) => {
68+
if (running === 'running') {
69+
setIsRunning(true);
70+
} else if (running === 'stopped') {
71+
setIsRunning(false);
72+
}
73+
});
6574

6675
appMgrRef.current.on(EventType.EVENT_FILESYS, (filesysJson: string) => {
6776
try {
@@ -150,10 +159,10 @@ function FolderTree(treeProps: TreeProps) {
150159
<div
151160
ref={dragHandle}
152161
style={style}
153-
className={`group flex flex-row items-center justify-between hover:bg-matisse-400 dark:hover:bg-shark-500 ${node.isSelected ? 'bg-curious-blue-300 dark:bg-shark-400' : ''}`}
162+
className={`group flex flex-row items-center justify-between hover:bg-matisse-400 dark:hover:bg-shark-500 ${node.isSelected ? 'bg-curious-blue-300 dark:bg-shark-400' : ''} ${isRunning ? 'opacity-50 pointer-events-none' : 'opacity-100 pointer-events-auto'}}`}
154163
onClick={(e) => {
155164
if (node.isInternal) node.toggle();
156-
if (!(e.detail % 2)) {
165+
if (!(e.detail % 2) && !isRunning) {
157166
if (node.children === null) {
158167
const filePath =
159168
node.data.path === '/'
@@ -180,10 +189,10 @@ function FolderTree(treeProps: TreeProps) {
180189
</div>
181190
{!treeProps.onSelected && (
182191
<div className="invisible flex flex-row items-center gap-1 px-2 group-hover:visible">
183-
<button onClick={() => node.edit()} title={t('rename')}>
192+
<button className={`${isRunning ? 'opacity-50 pointer-events-none' : 'opacity-100 pointer-events-auto'}`} onClick={() => node.edit()} title={t('rename')}>
184193
<MdEdit size={'1.5em'} />
185194
</button>
186-
<button
195+
<button className={`${isRunning ? 'opacity-50 pointer-events-none' : 'opacity-100 pointer-events-auto'}`}
187196
onClick={() => {
188197
tree.delete(node.id);
189198
}}

src/components/navbar.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,14 @@ function NavBar({ layoutref }: NavBarProps) {
621621
toggleDialog();
622622
}
623623

624+
/**
625+
* boadcastRunningState - broadcast the running state to the app manager
626+
* @param running
627+
*/
628+
function broadcastRunningState(running: boolean) {
629+
AppMgr.getInstance().emit(EventType.EVENT_ISRUNNING, running ? 'running' : 'stopped');
630+
}
631+
624632
/**
625633
* onRunBtnClicked
626634
*/
@@ -653,6 +661,7 @@ function NavBar({ layoutref }: NavBarProps) {
653661
}
654662

655663
setRunning(true);
664+
broadcastRunningState(true);
656665

657666
// Check battery voltage && version
658667
await CommandToXRPMgr.getInstance()
@@ -694,9 +703,11 @@ function NavBar({ layoutref }: NavBarProps) {
694703
});
695704
}
696705
setRunning(false);
706+
broadcastRunningState(false);
697707
}
698708
} else {
699709
setRunning(false);
710+
broadcastRunningState(false);
700711
CommandToXRPMgr.getInstance().stopProgram();
701712
}
702713
}

src/managers/appmgr.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export enum EventType {
4040
EVENT_BLOCKLY_TOOLBOX_UPDATED = 'blockly-toolbox-updated', // Blockly toolbox has been updated
4141
EVENT_GAMEPAD_STATUS = 'gamepad-status', // Gamepad status on/off
4242
EVENT_ALERT = 'alert', // Alert dialog event
43+
EVENT_ISRUNNING = 'is-running', // XRP is running user code
4344
}
4445

4546
type Events = {
@@ -71,6 +72,7 @@ type Events = {
7172
[EventType.EVENT_BLOCKLY_TOOLBOX_UPDATED]: string;
7273
[EventType.EVENT_GAMEPAD_STATUS]: string;
7374
[EventType.EVENT_ALERT]: string;
75+
[EventType.EVENT_ISRUNNING]: string;
7476
};
7577

7678
/**
@@ -184,10 +186,14 @@ export default class AppMgr {
184186
}
185187

186188
/**
187-
* Remove all listeners for a given event
189+
* Remove listeners for a given event or all listeners if no event is provided
188190
*/
189-
public off(): void {
190-
this._emitter.all.clear();
191+
public off(eventName?: EventType): void {
192+
if (eventName) {
193+
this._emitter.off(eventName);
194+
} else {
195+
this._emitter.all.clear();
196+
}
191197
}
192198

193199
/**

0 commit comments

Comments
 (0)