diff --git a/applications/system/js_app/examples/apps/Scripts/interactive.js b/applications/system/js_app/examples/apps/Scripts/interactive.js index d346552e2..63db6c5e0 100644 --- a/applications/system/js_app/examples/apps/Scripts/interactive.js +++ b/applications/system/js_app/examples/apps/Scripts/interactive.js @@ -1,21 +1,56 @@ -let dialog = require("dialog"); -let keyboard = require("keyboard"); +let eventLoop = require("event_loop"); +let gui = require("gui"); +let dialog = require("gui/dialog"); +let textInput = require("gui/text_input"); +let loading = require("gui/loading"); let storage = require("storage"); -// Need to run code from file, and filename must be unique -let tmp_template = "/ext/apps_data/js_app/.interactive.tmp."; -let tmp_number = 0; +// No eval() or exec() so need to run code from file, and filename must be unique +storage.makeDirectory("/ext/.tmp"); +storage.makeDirectory("/ext/.tmp/js"); +storage.rmrf("/ext/.tmp/js/repl") +storage.makeDirectory("/ext/.tmp/js/repl") +let ctx = { + tmp_template: "/ext/.tmp/js/repl/", + tmp_number: 0, +}; -let result = "Run JavaScript Code"; -while (dialog.message("Interactive Console", result)) { - keyboard.setHeader("Type JavaScript Code"); - let input = keyboard.text(256); - if (!input) break; +let views = { + dialog: dialog.makeWith({ + header: "Interactive Console", + text: "Press OK to Start", + center: "Run Some JS" + }), + textInput: textInput.makeWith({ + header: "Type JavaScript Code:", + defaultText: "2+2", + defaultTextClear: true, + // Props for makeWith() are passed in reverse order, so maxLength must be after defaultText + minLength: 0, + maxLength: 256, + }), + loading: loading.make(), +}; - let path = tmp_template + toString(tmp_number++); - storage.write(path, "({run:function(){return " + input + ";},})"); - result = load(path).run(); +eventLoop.subscribe(views.dialog.input, function (_sub, button, gui, views) { + if (button === "center") { + gui.viewDispatcher.switchTo(views.textInput); + } +}, gui, views); + +eventLoop.subscribe(views.textInput.input, function (_sub, text, gui, views, ctx) { + gui.viewDispatcher.switchTo(views.loading); + + let path = ctx.tmp_template + toString(ctx.tmp_number++); + let file = storage.openFile(path, "w", "create_always"); + file.write("({run:function(){return " + text + ";},})"); + file.close(); + + // Hide GUI before running, we want to see console and avoid deadlock if code fails + gui.viewDispatcher.sendTo("back"); + let result = load(path).run(); storage.remove(path); + gui.viewDispatcher.sendTo("front"); // Must convert to string explicitly if (typeof result === "number") { @@ -27,4 +62,16 @@ while (dialog.message("Interactive Console", result)) { } else if (typeof result === "object") { result = JSON.stringify(result); } -} + + views.dialog.set("header", "JS Returned:"); + views.dialog.set("text", result); + gui.viewDispatcher.switchTo(views.dialog); + views.textInput.set("defaultText", text); +}, gui, views, ctx); + +eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _, eventLoop) { + eventLoop.stop(); +}, eventLoop); + +gui.viewDispatcher.switchTo(views.dialog); +eventLoop.run();