#208 — stale binary executes after compile error EditorToolbar.handleCompile: on failed compile, clear the active board's compiledProgram so a subsequent Run can't silently execute the previous successful build (which doesn't match the editor any more). The Run gate already short-circuits on !compiledProgram and forces a fresh compile. #209 — compile terminal kept stale messages across runs EditorToolbar.handleCompile: setCompileLogs([]) at the top of the handler. Previously logs from the prior compile lingered, making it hard to tell new errors / warnings apart from old ones. #210 — desktop File > New Project did nothing desktop/menu.ts: the menu action used to dispatch a CustomEvent nobody listened to. Replaced with a real `newProject()` function that stops the running simulation, removes every board (also drops the bridges + wires touching them), clears components / wires, loads the default Blink sketch into the editor, clears project metadata, and wipes the compile output. Confirms first if there's unsaved work on the canvas. #211 — deleting the only board made every other component unresponsive (wires still worked) SimulatorCanvas.tsx::interactionRunning: the old expression treated boards.length === 0 as "boardless electrical mode is running" — which suppressed the property dialog on click and made non-sensor components look frozen. Fixed by also requiring useElectricalStore.submittedNetlist !== '' before flipping to the boardless-running branch. SPICE has to have actually solved at least once for the mode to engage. #212 — ESP32 Support 404 with no actionable message desktop/Esp32QemuPrompt.tsx: catch the raw "download HTTP 404" / "not found" upstream error and reword it to "ESP32 support is not yet available for your platform. The Velxio team is preparing this build - try again in a few days, or use Arduino/RP2040 boards in the meantime." The real fix is server-side (the velxio team needs to publish a qemu-xtensa.tar.gz for the user's platform into the asset bucket and update esp32-qemu/latest.json). Tracked in project/desktop-agent-v040/ follow-ups. All five fixes verified with `tsc --noEmit` clean and the existing 25-test vitest suite green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d64eebc200
commit
145710561a
|
|
@ -163,6 +163,10 @@ export const EditorToolbar = ({
|
|||
setCompiling(true);
|
||||
setMessage(null);
|
||||
setConsoleOpen(true);
|
||||
// Wipe the previous build's output before we append anything new.
|
||||
// Issue #209: lingering logs from prior compiles made it impossible
|
||||
// to tell the latest errors / warnings apart from stale ones.
|
||||
setCompileLogs([]);
|
||||
trackCompileCode();
|
||||
|
||||
// ── Chip-program path ───────────────────────────────────────────────
|
||||
|
|
@ -380,6 +384,13 @@ export const EditorToolbar = ({
|
|||
} else {
|
||||
const errText = result.error || result.stderr || 'Compile failed';
|
||||
setMessage({ type: 'error', text: errText });
|
||||
// Issue #208: drop the previous successful program from this
|
||||
// board so a subsequent Run cannot silently execute stale code
|
||||
// that doesn't match the editor any more. The Run button gates
|
||||
// on `!compiledProgram` and will refuse + force a re-compile.
|
||||
if (activeBoardId) {
|
||||
updateBoard(activeBoardId, { compiledProgram: null });
|
||||
}
|
||||
// Detect missing library errors — common patterns:
|
||||
// "No such file or directory" for #include, "fatal error: XXX.h"
|
||||
const looksLikeMissingLib =
|
||||
|
|
|
|||
|
|
@ -259,9 +259,16 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
|
|||
// their own state on click instead of opening the property dialog.
|
||||
// We treat board-less + un-paused as "interaction-running" so the same
|
||||
// gating logic that suppresses the dialog for MCU-running mode also
|
||||
// covers board-less circuits.
|
||||
// covers board-less circuits — BUT only when SPICE has actually
|
||||
// engaged (submittedNetlist != ''). Without that extra check, deleting
|
||||
// the only board on a normal Arduino+LED circuit dropped boards to 0
|
||||
// and silently flipped every remaining component to "running" mode,
|
||||
// which suppresses the property dialog and makes them appear
|
||||
// unresponsive to clicks (issue #211).
|
||||
const electricalPaused = useElectricalStore((s) => s.paused);
|
||||
const interactionRunning = running || (boards.length === 0 && !electricalPaused);
|
||||
const electricalEngaged = useElectricalStore((s) => s.submittedNetlist !== '');
|
||||
const interactionRunning =
|
||||
running || (boards.length === 0 && electricalEngaged && !electricalPaused);
|
||||
|
||||
// Refs that mirror state/props for use inside touch event closures
|
||||
// (touch listeners are added imperatively and can't access current React state)
|
||||
|
|
|
|||
|
|
@ -104,7 +104,22 @@ export const Esp32QemuPrompt = () => {
|
|||
setStatus(fresh);
|
||||
if (fresh.installed) setOpen(false);
|
||||
} catch (e) {
|
||||
setErr(e instanceof Error ? e.message : String(e));
|
||||
// Issue #212: the backend returns 404 when the velxio team
|
||||
// hasn't published an ESP32 QEMU build for the user's platform
|
||||
// yet (Windows / Linux x86_64 / macOS aarch64). The raw
|
||||
// "download HTTP 404" string is opaque - reword to something
|
||||
// the user can actually act on (or at least understand isn't
|
||||
// their fault).
|
||||
const raw = e instanceof Error ? e.message : String(e);
|
||||
if (/HTTP\s*404|not found/i.test(raw)) {
|
||||
setErr(
|
||||
'ESP32 support is not yet available for your platform. ' +
|
||||
'The Velxio team is preparing this build - try again in a ' +
|
||||
'few days, or use Arduino/RP2040 boards in the meantime.',
|
||||
);
|
||||
} else {
|
||||
setErr(raw);
|
||||
}
|
||||
} finally {
|
||||
setInstalling(false);
|
||||
setProgress(null);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ import { listen } from './tauriBridge';
|
|||
import { dlog } from './log';
|
||||
import { triggerDownloadVlx, importVlxFile } from '../utils/vlxFile';
|
||||
import { useSimulatorStore } from '../store/useSimulatorStore';
|
||||
import { useEditorStore } from '../store/useEditorStore';
|
||||
import { useProjectStore } from '../store/useProjectStore';
|
||||
import { useCompileLogsStore } from '../store/useCompileLogsStore';
|
||||
import { switchLocale } from '../i18n/path';
|
||||
import { LOCALES, type Locale } from '../i18n/config';
|
||||
|
||||
|
|
@ -74,6 +77,8 @@ async function handle(action: MenuAction, payload?: MenuEventPayload): Promise<v
|
|||
useSimulatorStore.getState().toggleSerialMonitor();
|
||||
return;
|
||||
case 'new-project':
|
||||
newProject();
|
||||
return;
|
||||
case 'find-in-editor':
|
||||
case 'toggle-file-explorer':
|
||||
window.dispatchEvent(new CustomEvent(`velxio:menu:${action}`));
|
||||
|
|
@ -152,6 +157,74 @@ function pickAndImportVlx(): void {
|
|||
input.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe the current workspace and start from the default Blink sketch +
|
||||
* empty canvas. Issue #210: the menu action used to just dispatch a
|
||||
* CustomEvent that nobody listened to.
|
||||
*
|
||||
* Confirms first if the user has unsaved changes (any modified file
|
||||
* or any component on the canvas). The Tauri-side menu can't show a
|
||||
* confirm dialog cheaply, so we use the browser-native `confirm()`
|
||||
* here — fine for the desktop bundle where it renders as a modal.
|
||||
*/
|
||||
function newProject(): void {
|
||||
const sim = useSimulatorStore.getState();
|
||||
const editor = useEditorStore.getState();
|
||||
const project = useProjectStore.getState();
|
||||
const compileLogs = useCompileLogsStore.getState();
|
||||
|
||||
const hasWork =
|
||||
sim.boards.length > 0 ||
|
||||
sim.components.length > 0 ||
|
||||
sim.wires.length > 0 ||
|
||||
editor.files.some((f) => f.modified) ||
|
||||
project.currentProject !== null;
|
||||
|
||||
if (hasWork) {
|
||||
// eslint-disable-next-line no-alert
|
||||
const ok = window.confirm(
|
||||
'Start a new project? Any unsaved changes will be lost.',
|
||||
);
|
||||
if (!ok) return;
|
||||
}
|
||||
|
||||
// Stop any running simulation first so workers / bridges shut down
|
||||
// cleanly. Idempotent — no-op if nothing is running.
|
||||
if (sim.running) {
|
||||
sim.stopSimulation();
|
||||
}
|
||||
|
||||
// Drop every board (also disconnects its bridges + removes wires
|
||||
// touching it). Iterate over a snapshot copy since removeBoard
|
||||
// mutates the array.
|
||||
for (const board of [...sim.boards]) {
|
||||
sim.removeBoard(board.id);
|
||||
}
|
||||
|
||||
// Any non-board components + wires that weren't connected to a
|
||||
// board still need to go.
|
||||
sim.setComponents([]);
|
||||
sim.setWires([]);
|
||||
|
||||
// Reset the editor to the default Blink sketch. loadFiles takes
|
||||
// a {name, content}[] and rebuilds the file list, picking the
|
||||
// first .ino as active.
|
||||
editor.loadFiles([
|
||||
{
|
||||
name: 'sketch.ino',
|
||||
content:
|
||||
'// Arduino Blink Example\nvoid setup() {\n pinMode(LED_BUILTIN, OUTPUT);\n}\n\nvoid loop() {\n digitalWrite(LED_BUILTIN, HIGH);\n delay(1000);\n digitalWrite(LED_BUILTIN, LOW);\n delay(1000);\n}\n',
|
||||
},
|
||||
]);
|
||||
|
||||
// Drop project metadata so the next Save .vlx doesn't reuse the
|
||||
// previous project's slug / name.
|
||||
project.clearCurrentProject();
|
||||
|
||||
// Clear the compile output panel so old build logs don't carry over.
|
||||
compileLogs.clear();
|
||||
}
|
||||
|
||||
async function checkForUpdates(): Promise<void> {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
|
|
|||
Loading…
Reference in New Issue