// The local/remote server URL //var ROBOT_SERVER = "10.42.0.1"; var ROBOT_SERVER = "ws.achex.ca:4010"; // The sumorobot object var sumorobot = null; // The sumorobot state var sumostart = false; // Disable / enable coding mode var codingEnabled = false; // Disable / enable live stream var liveStreamVisible = false; // Where Blockly Python code is shown var readOnlyCodingEditor = null; // Last hightlighted block id var lastHighlighted = ""; // Block highlight WebSocket var blockHighlight = null; window.addEventListener("load", function() { $("#robot-id").val(getLocalStorageItem("sumorobot.robotId")); // Load read only ace editor readOnlyCodingEditor = ace.edit("readOnlyBlocklyCode"); // Set the style readOnlyCodingEditor.setTheme("ace/theme/textmate"); readOnlyCodingEditor.session.setMode("ace/mode/python"); readOnlyCodingEditor.session.setTabSize(2); // Make as read only readOnlyCodingEditor.setReadOnly(true); // Disable scrolling warning readOnlyCodingEditor.$blockScrolling = Infinity; // Load ace editor var codingEditor = ace.edit("blocklyCode"); // Set the style codingEditor.setTheme("ace/theme/textmate"); codingEditor.session.setMode("ace/mode/python"); codingEditor.session.setTabSize(2); // Disable scrolling warning codingEditor.$blockScrolling = Infinity; // Enable autocomplete ace.require("ace/ext/language_tools"); codingEditor.setOptions({ enableSnippets: true, enableLiveAutocompletion: true, enableBasicAutocompletion: true }); // Add autocomplete keywords codingEditor.completers.push({ getCompletions: function(editor, session, pos, prefix, callback) { callback(null, [ {value: "STOP", score: 1000, meta: "sumorobot"}, {value: "LEFT", score: 1000, meta: "sumorobot"}, {value: "RIGHT", score: 1000, meta: "sumorobot"}, {value: "SEARCH", score: 1000, meta: "sumorobot"}, {value: "FORWARD", score: 1000, meta: "sumorobot"}, {value: "BACKWARD", score: 1000, meta: "sumorobot"}, {value: "STATUS", score: 1000, meta: "sumorobot"}, {value: "LEFT_LINE", score: 1000, meta: "sumorobot"}, {value: "RIGHT_LINE", score: 1000, meta: "sumorobot"}, {value: "sumorobot", score: 1000, meta: "sumorobot"}, {value: "move", score: 1000, meta: "sumorobot"}, {value: "sleep", score: 1000, meta: "sumorobot"}, {value: "set_led", score: 1000, meta: "sumorobot"}, {value: "is_line", score: 1000, meta: "sumorobot"}, {value: "get_line", score: 1000, meta: "sumorobot"}, {value: "set_servo", score: 1000, meta: "sumorobot"}, {value: "is_opponent", score: 1000, meta: "sumorobot"}, {value: "calibrate_line", score: 1000, meta: "sumorobot"}, {value: "get_battery_voltage", score: 1000, meta: "sumorobot"}, {value: "get_opponent_distance", score: 1000, meta: "sumorobot"} ]); } }); // Set the code to the saved code from local storage or empty codingEditor.setValue(getLocalStorageItem("sumorobot.code") || ""); // Clear the selection after setting the value codingEditor.clearSelection(); // Add an change listener for the code editor codingEditor.on("change", function() { // When change occurs, save the new code to the localstorage setLocalStorageItem("sumorobot.code", codingEditor.getValue()) }); // Key down event $(document).keydown(function(e) { // When the alt key is not pressed, don't process hotkeys if (e.altKey == false) return; // Prevent typing in textfields e.preventDefault(); // Select the hotkey switch(e.which) { case 32: // space bar sumostart = !sumostart; if (sumostart) { $(".btn-start").addClass("hover"); $(".btn-start").click(); } else { $(".btn-stop").addClass("hover"); $(".btn-stop").click(); } break; case 37: // left sumorobot.send("left"); break; case 38: // up sumorobot.send("forward"); break; case 39: // right sumorobot.send("right"); break; case 40: // down sumorobot.send("backward"); break; case 67: // c $("#panel").toggle(); break; case 76: // l // No live stream if cookies are disabled if (!cookiesEnabled) { // TODO: Open the cookie consent popup return; } // Load the Mixer stream if ($("#stream").is(':empty')) { $("#stream").html(''); } $("#stream").toggle(); // Toggle live steam visible liveStreamVisible = !liveStreamVisible; // If not in coding mode if (codingEnabled == false) { $("#readOnlyBlocklyCode").toggle(); } break; case 80: // p $("#blocklyDiv").toggle(); $("#blocklyArea").toggle(); $("#blocklyCode").toggle(); if (liveStreamVisible == false) { $("#readOnlyBlocklyCode").toggle(); } // Toggle coding enabled codingEnabled = !codingEnabled; if (codingEnabled) { // Resize the coding editor codingEditor.resize(); // Focus, so the user can start coding codingEditor.focus(); } break; case 82: // r // Implement something break; case 83: // s $(".btn-stop").addClass("hover"); $(".btn-stop").click(); break; case 84: // t sumorobot.send("calibrate_line"); break; case 87: // w $(".btn-start").addClass("hover"); $(".btn-start").click(); break; } }); // Key up event $(document).keyup(function(e) { // When the alt key is not pressed, don't process hotkeys if (e.altKey == false) return; // Remove hover from buttons $('.btn').removeClass('hover'); // If arrow keys were pressed if (e.which == 37 || e.which == 38 || e.which == 39 || e.which == 40) { sumorobot.send("stop"); } }); // Start button listener $(".btn-start").click(function() { sumostart = true; // When we are in coding mode if (codingEnabled) { var parsedCode = codingEditor.getValue().replace(/"/g, '\\"').replace(/\n/g, ';;'); // Send the code from the textarea to the SumoRobot sumorobot.send("code", parsedCode); // Otherwise when we are in Blockly mode } else { // Send the code from the blocks to the SumoRobot var parsedCode = sumorobot.getBlocklyCode().replace(/"/g, '\\"').replace(/\n/g, ';;'); sumorobot.send("code", parsedCode); } }); // Stop button listener $(".btn-stop").click(function() { sumostart = false; sumorobot.send("stop"); //workspace.highlightBlock(lastHighlighted, false); }); // Enter listener on robot ID field $("#robot-id").keypress(function(e) { if (e.which == 13) { // Simulate robot GO button click $(".btn-robot-go").click(); } }); // Robot number button listener $(".btn-robot-go").click(function() { // Extract and validate the selected robot ID var robotId = $("#robot-id").val().trim(); if (robotId === "" || /^([a-f0-9]{6})$/.test(robotId) == false) { $("#robot-id, #robot-label").addClass("has-error"); return; } else { $("#robot-id, #robot-label").removeClass("has-error"); } // Update robot IDs in local storage setLocalStorageItem("sumorobot.robotId", robotId); // In case there is a open connection if (sumorobot/* && blockHighlight*/) { // Close the connections sumorobot.close(); //blockHighlight.close(); } // Connect to the selected robots WebSocket sumorobot = new Sumorobot(`ws://${ROBOT_SERVER}`, robotId); // connect to the other block highlight WebSocket //blockHighlight = new WebSocket("ws://" + robotServer + ":80/p2p/browser/" + robotId + "-highlight/"); // when there is a message from the WebSocket /*blockHighlight.onmessage = function(evt) { // when scope is received if (evt.data.length == 20 && sumostart) { workspace.highlightBlock(evt.data); lastHighlighted = evt.data; } };*/ // Hide the configuration panel $("#panel").hide(); }); });