Skip to content

Commit

Permalink
feat: extend Script history panel with new functions (#758)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dotneteer committed Apr 23, 2024
1 parent 97e3c00 commit b0d0ede
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 106 deletions.
2 changes: 1 addition & 1 deletion src/common/ksx/script-runner.ts
Expand Up @@ -40,7 +40,7 @@ export function concludeScript (
time = script.endTime.getTime() - script.startTime.getTime();
}
outputFn?.(
`Script ${script.scriptFileName} with ID ${script.id} ${script.status} in ${time}ms.`,
`Script ${script.scriptFileName} with ID ${script.id} ${script.status} after ${time}ms.`,
{
color: cancelled ? "yellow" : "green"
}
Expand Down
4 changes: 4 additions & 0 deletions src/common/utils/script-utils.ts
Expand Up @@ -8,3 +8,7 @@ export function isScriptCompleted (status: ScriptStatus): boolean {
status === "execError"
);
}

export function scriptDocumentId (scriptId: number): string {
return `ScriptOutput-${scriptId}`;
}
8 changes: 2 additions & 6 deletions src/renderer/appIde/DocumentArea/DocumentsHeader.tsx
Expand Up @@ -272,15 +272,11 @@ const BuildRootCommandBar = () => {
clicked={async () => {
const buildPane =
outputPaneService.getOutputPaneBuffer(PANE_ID_BUILD);
const commandResult = await ideCommandsService.executeCommand(
await ideCommandsService.executeCommand(
"run-build-function buildCode",
buildPane
);
console.log("commandResult", commandResult);
await delay(100);
await ideCommandsService.executeCommand(
`script-output ${commandResult.value}`, buildPane
);
await ideCommandsService.executeCommand(`outp ${PANE_ID_BUILD}`);
}}
/>
<TabButtonSpace />
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/appIde/DocumentArea/ScriptingCommandBar.tsx
Expand Up @@ -36,7 +36,7 @@ const ScriptingCommandBar = ({ path }: Props) => {
if (scriptId > 0) {
setScriptEverStarted(true);
}
}, [scriptsInfo]);
}, [scriptsInfo, path]);

return (
<>
Expand Down
13 changes: 9 additions & 4 deletions src/renderer/appIde/MainToIdeProcessor.ts
Expand Up @@ -23,6 +23,7 @@ import {
ProjectStructure,
ProjectTreeNode
} from "@main/ksx-runner/ProjectStructure";
import { CompositeOutputBuffer } from "./ToolArea/CompositeOutputBuffer";

/**
* Process the messages coming from the emulator to the main process
Expand Down Expand Up @@ -101,12 +102,16 @@ export async function processMainToIdeMessages (
}

case "IdeExecuteCommand": {
const pane = /*message.scriptId
? scriptService.getScriptOutputBuffer(message.scriptId)
: */outputPaneService.getOutputPaneBuffer(PANE_ID_BUILD);
const buildOutput = outputPaneService.getOutputPaneBuffer(PANE_ID_BUILD);
const scriptOutput = message.scriptId ? scriptService.getScriptOutputBuffer(message.scriptId) : undefined;
const buffers = [ buildOutput ];
if (scriptOutput) {
buffers.push(scriptOutput);
}
console.log("Executing command: " + message.commandText, buffers);
const response = await ideCommandsService.executeCommand(
message.commandText,
pane
new CompositeOutputBuffer(buffers)
);
return {
type: "IdeExecuteCommandResponse",
Expand Down
Expand Up @@ -6,7 +6,6 @@
flex-direction: column;
user-select: none;
font-family: var(--monospace-font);
font-size: 0.8em;
padding: 4px 0;

.center {
Expand All @@ -25,6 +24,7 @@
flex-grow: 1;
width: calc(100% - 8px);
padding: 4px;
font-size: 0.8em;

&.selected {
background-color: var(--bgcolor-explorer-focused-selected);
Expand Down Expand Up @@ -55,5 +55,12 @@
width: 80px;
}



.header {
display: flex;
flex-shrink: 0;
flex-grow: 0;
align-items: center;
height: 24px;
gap: 8px;
padding: 0 8px;
}
229 changes: 140 additions & 89 deletions src/renderer/appIde/SiteBarPanels/ScriptingHistoryPanel.tsx
Expand Up @@ -5,113 +5,164 @@ import { LabelSeparator } from "@renderer/controls/Labels";
import { Icon } from "@renderer/controls/Icon";
import classnames from "@renderer/utils/classnames";
import { ScriptRunInfo } from "@abstractions/ScriptRunInfo";
import { useSelector } from "@renderer/core/RendererProvider";
import { useDispatch, useSelector } from "@renderer/core/RendererProvider";
import { useAppServices } from "../services/AppServicesProvider";
import { TabButton } from "@renderer/controls/TabButton";
import {
isScriptCompleted,
scriptDocumentId
} from "@common/utils/script-utils";
import { setScriptsStatusAction } from "@common/state/actions";
import { Text } from "@renderer/controls/generic/Text";

const ScriptingHistoryPanel = () => {
const { ideCommandsService } = useAppServices();
const dispatch = useDispatch();
const { ideCommandsService, projectService } = useAppServices();
const scriptsInState = useSelector(state => state.scripts);
const scripts = scriptsInState.slice().reverse();
const [scripts, setScripts] = useState<ScriptRunInfo[]>([]);
const [selectedScript, setSelectedScript] = useState<ScriptRunInfo>();
const [version, setVersion] = useState(1);
const [showBuildScripts, setShowBuildScripts] = useState(true);
const refreshing = useRef(false);


useEffect(() => {
setScripts(
scriptsInState
.filter(
script =>
(script.specialScript !== "build" && !showBuildScripts) ||
showBuildScripts
)
.reverse()
);
}, [scriptsInState, showBuildScripts]);

// --- Refresh script information regularly
useEffect(() => {
(async() => {
(async () => {
if (refreshing.current) return;
refreshing.current = true;
await new Promise(resolve => setTimeout(resolve, 5000));
setVersion(version + 1);
refreshing.current = false;
})()
})
})();
});

return (
<div className={styles.panel}>
{scripts.length === 0 && (
<div className={styles.center}>No scripts started</div>
)}
{scripts.length > 0 && (
<VirtualizedListView
items={scripts}
approxSize={24}
fixItemHeight={true}
itemRenderer={idx => {
const script = scripts[idx];
console;
let icon = "";
let color = "";
const from = script.startTime;
let to = new Date();
{scripts.length >= 0 && (
<div className={styles.panel}>
<div className={styles.header}>
<TabButton
iconName='clear-all'
title='Clear completed scripts'
clicked={() => {
const removed = scripts.filter(scr =>
isScriptCompleted(scr.status)
);
const cleared = scripts.filter(
scr => !isScriptCompleted(scr.status)
);
dispatch(setScriptsStatusAction(cleared));
const hub = projectService.getActiveDocumentHubService();
removed.forEach(async scr => {
await hub.closeDocument(scriptDocumentId(scr.id));
});
}}
/>
<TabButton
iconName='combine'
title={`${showBuildScripts ? "Hide" : "Show"} build scripts`}
fill={showBuildScripts ? "--color-button-focused" : undefined}
clicked={() => {
setShowBuildScripts(!showBuildScripts);
}}
/>
<Text text={`Scripts displayed: ${scripts.length}`} />
</div>
<div className={styles.panel}>
<VirtualizedListView
items={scripts}
approxSize={24}
fixItemHeight={true}
itemRenderer={idx => {
const script = scripts[idx];
console;
let icon = "";
let color = "";
const from = script.startTime;
let to = new Date();

// --- Set the task icon
let taskIcon = script.runsInEmu ? "vm" : "tools";
let taskIconColor = "--color-command-icon";
let taskName = script.scriptFileName;
if (script.specialScript === "build" ) {
taskIcon = "combine";
taskIconColor = "--console-ansi-bright-cyan";
taskName = "build";
taskName = script.scriptFunction;
}
// --- Set the task icon
let taskIcon = script.runsInEmu ? "vm" : "tools";
let taskIconColor = "--color-command-icon";
let taskName = script.scriptFileName;
if (script.specialScript === "build") {
taskIcon = "combine";
taskIconColor = "--console-ansi-bright-cyan";
taskName = "build";
taskName = script.scriptFunction;
}

// --- Set the status icon
switch (script.status) {
case "pending":
icon = "play";
color = "--console-ansi-bright-cyan";
break;
case "completed":
icon = "check";
color = "--console-ansi-bright-green";
to = script.endTime;
break;
case "execError":
icon = "close";
color = "--console-ansi-bright-red";
to = script.endTime;
break;
case "compileError":
icon = "circle-slash";
color = "--console-ansi-bright-red";
to = script.endTime;
break;
case "stopped":
icon = "stop";
color = "--console-ansi-yellow";
to = script.stopTime;
break;
}
to ??= new Date();
const duration = to.getTime() - from.getTime();
return (
<div
key = {1000 * version + idx}
className={classnames(styles.itemWrapper, {
[styles.selected]: selectedScript?.id === script.id
})}
onClick={async () => {
setSelectedScript(script);
await ideCommandsService.executeCommand(
`script-output ${script.id}`
);
}}
>
<LabelSeparator width={4} />
<Icon
iconName={taskIcon}
fill={taskIconColor}
width={16}
height={16}
/>
<LabelSeparator width={4} />
<Icon iconName={icon} fill={color} width={16} height={16} />
<div className={styles.itemText}>{taskName}</div>
<div className={styles.itemTime}>{`${duration}ms`}</div>
</div>
);
}}
/>
// --- Set the status icon
switch (script.status) {
case "pending":
icon = "play";
color = "--console-ansi-bright-cyan";
break;
case "completed":
icon = "check";
color = "--console-ansi-bright-green";
to = script.endTime;
break;
case "execError":
icon = "close";
color = "--console-ansi-bright-red";
to = script.endTime;
break;
case "compileError":
icon = "circle-slash";
color = "--console-ansi-bright-red";
to = script.endTime;
break;
case "stopped":
icon = "stop";
color = "--console-ansi-yellow";
to = script.stopTime;
break;
}
to ??= new Date();
const duration = to.getTime() - from.getTime();
return (
<div
key={1000 * version + idx}
className={classnames(styles.itemWrapper, {
[styles.selected]: selectedScript?.id === script.id
})}
onClick={async () => {
setSelectedScript(script);
await ideCommandsService.executeCommand(
`script-output ${script.id}`
);
}}
>
<LabelSeparator width={4} />
<Icon
iconName={taskIcon}
fill={taskIconColor}
width={16}
height={16}
/>
<LabelSeparator width={4} />
<Icon iconName={icon} fill={color} width={16} height={16} />
<div className={styles.itemText}>{taskName}</div>
<div className={styles.itemTime}>{`${duration}ms`}</div>
</div>
);
}}
/>
</div>
</div>
)}
</div>
);
Expand Down

0 comments on commit b0d0ede

Please sign in to comment.