sumorobot-web/assets/js/main.js

249 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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('<iframe src="https://mixer.com/embed/player/14551694"></iframe>');
}
$("#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();
});
});