From e080b78aa77aee142d941b4b1974d27469247a71 Mon Sep 17 00:00:00 2001 From: sommermorgentraum <24917424+zxkmm@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:37:18 +0800 Subject: [PATCH] simple script support (#73) * simple script * remove css that probably is AI added * fix typo that catch by gull, thx * Add script running state management and display status message * Update layout styles in Controller component for improved responsiveness --------- Co-authored-by: jLynx --- public/script_demo_record.ppsc | 5 + src/components/Controller/Controller.tsx | 114 +++++++++++++++++++++-- 2 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 public/script_demo_record.ppsc diff --git a/public/script_demo_record.ppsc b/public/script_demo_record.ppsc new file mode 100644 index 0000000..43e5a0b --- /dev/null +++ b/public/script_demo_record.ppsc @@ -0,0 +1,5 @@ +-- Mayhem script go to capture, set freq to 433.92 and capture +-- This is Lua syntax but based on regex, so no Lua run time support yet +write("appstart capture",true,true) +write("setfreq 433920000",true,true) +write("touch 7 57",true,true) diff --git a/src/components/Controller/Controller.tsx b/src/components/Controller/Controller.tsx index 06e7529..5496ed1 100644 --- a/src/components/Controller/Controller.tsx +++ b/src/components/Controller/Controller.tsx @@ -11,6 +11,7 @@ import { faCheckCircle, faPaperPlane, faCircleXmark, + faCode, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import React, { ChangeEvent, useEffect, useRef, useState } from "react"; @@ -48,6 +49,11 @@ const Controller = () => { const canvasRef = useRef(null); const fileInputRef = useRef(null); const firmwareFileInputRef = useRef(null); + const scriptFileInputRef = useRef(null); + const [scriptStatus, setScriptStatus] = useState( + "Type single command above or pick a script" + ); + const [scriptRunning, setScriptRunning] = useState(false); const started = useRef(false); @@ -302,6 +308,69 @@ const Controller = () => { // } }; + const onScriptFileChange = (event: ChangeEvent) => { + const fileList = event.target.files; + if (!fileList) return; + + let file = fileList[0]; + setScriptStatus(`Picked script: ${file.name}`); + + let reader = new FileReader(); + + reader.onloadend = async () => { + setScriptRunning(true); + const content = reader.result; + if (typeof content === "string") { + const lines = content.split(/\r?\n/); // split lines + + for (let lineNumber = 0; lineNumber < lines.length; lineNumber++) { + await new Promise((resolve) => setTimeout(resolve, 1000)); // the await for write func seems is still too fast. TODO + const line = lines[lineNumber]; + const trimmedLine = line.trim(); + if (trimmedLine.startsWith("--") || trimmedLine === "") { + continue; + } + const writeMatch = trimmedLine.match(/^write\((.*)\);?$/); // match write command + if (writeMatch) { + const argsString = writeMatch[1]; + const argsRegex = + /["'](.+?)["']\s*,\s*(true|false)\s*,\s*(true|false)/; + /* ^match str surronded by' and " + ^ match bool ^ match bool */ + const argsMatch = argsString.match(argsRegex); + if (argsMatch) { + const command = argsMatch[1]; + const updateFrame = argsMatch[2] === "true"; //cast to bool + const awaitResponse = argsMatch[3] === "true"; // cast to bool + + setScriptStatus(`sending: ${command}`); + await write(command, updateFrame, awaitResponse); + } else { + setScriptStatus(`script syntax invalid: line ${lineNumber + 1}`); + break; + } + } else { + setScriptStatus(`script syntax invalid: line ${lineNumber + 1}`); + break; + } + } + setScriptStatus("script execution completed"); + } else { + setScriptStatus("failed to read script file"); + } + setScriptRunning(false); + }; + + reader.onerror = () => { + setScriptStatus("error reading script file"); + setScriptRunning(false); + }; + + if (file) { + reader.readAsText(file); + } + }; + return ( <> {setupComplete ? ( @@ -477,8 +546,8 @@ const Controller = () => { ) : ( <> -
-
+
+
{ onFirmwareFileChange(e, selectedUploadFolder); }} /> -
+ { + if (scriptFileInputRef.current) { + scriptFileInputRef.current.value = ""; + } + }} + onChange={(e) => { + onScriptFileChange(e); + }} + /> +
{