Skip to content

Instantly share code, notes, and snippets.

@maclyn
Last active July 8, 2024 21:04
Show Gist options
  • Save maclyn/9b1059469c5b46bea7097c965fd42033 to your computer and use it in GitHub Desktop.
Save maclyn/9b1059469c5b46bea7097c965fd42033 to your computer and use it in GitHub Desktop.
Macro Deck web client patch for car thing (applies on top of commit with tag v2.5.1, d6310947bffb32830826d7c490d5d9eb7e98b396)
From cb7f26f9496a33e502bdfd25e11d413338efdb5c Mon Sep 17 00:00:00 2001
From: Maclyn Brandwein <maclyn@maclyn.me>
Date: Sun, 29 Jan 2023 14:14:29 -0500
Subject: [PATCH] Simple Car Thing patch
---
css/style.css | 17 +++++++-
index.html | 14 ++++---
js/client.js | 107 +++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 129 insertions(+), 9 deletions(-)
diff --git a/css/style.css b/css/style.css
index c89ea32..a11eca7 100644
--- a/css/style.css
+++ b/css/style.css
@@ -27,12 +27,27 @@ p, h1, h2, h3, h4, h5, h6, label , .text-w
}
.bg-dark {
- background-color: #2d2d2d!important;
+ background-color: #000!important;
}
.btn-secondary{
background-color: #eeeeee !important;
}
+
+#simple-car-thing-overlay {
+ background-color: #000;
+ color: #b0b0b0;
+ font-size: 2em;
+ text-align: center;
+ position: absolute;
+ margin: auto;
+ padding-top: 2em;
+ top: 50%;
+ left: 50%;
+ width: 100%;
+ height: 100%;
+ transform: translate(-50%, -50%);
+}
.bg-dark .btn-secondary {
background-color: #232323!important;
diff --git a/index.html b/index.html
index 2751454..2a6b9fb 100644
--- a/index.html
+++ b/index.html
@@ -72,7 +72,7 @@
<button class="btn btn-danger d-none" id="btn-back" onclick="back()">Back</button>
<button class="btn btn-success" id="btn-fullscreen" onclick="openFullscreen()">Fullscreen</button>
<button class="btn btn-success" id="btn-dark" onclick="toggleDark()">Light</button>
- <div class="connect-container container-fluid animate__animated animate__fadeIn" id="connect-container">
+ <div class="connect-container container-fluid" id="connect-container">
<div class="text-center text-w m-3">
<div class="text-center p-0 m-0">
<div class="row justify-content-md-center container-fluid">
@@ -101,11 +101,11 @@
<div class="row">
<div class="col">
<label for="inputHost" class="sr-only">IP address/hostname</label>
- <input type="text" name="inputHost" id="inputHost" class="form-control" placeholder="IP address/hostname" required="" autofocus="">
+ <input type="text" name="inputHost" id="inputHost" class="form-control" placeholder="IP address/hostname" required="">
</div>
<div class="col-auto">
<label for="inputPort" class="sr-only">Port</label>
- <input style="width: 80px;" type="text" name="inputPort" id="inputPort" class="form-control" placeholder="Port" required="" autofocus="" value="8191">
+ <input style="width: 80px;" type="text" name="inputPort" id="inputPort" class="form-control" placeholder="Port" required="" value="8191">
</div>
</div>
<button class="btn btn-primary mt-2 w-100" type="submit">
@@ -154,11 +154,13 @@
</div>
</div>
-
-
+ <div id="simple-car-thing-overlay"></div>
<script src="js/bootstrap.js"></script>
<script src="js/client.js"></script>
- <script src="js/cookiealert.js"></script>
+ <!--
+ Removed for Car Thing, which doesn't support persistent cookie storage
+ <script src="js/cookiealert.js"></script>
+ -->
</body>
</html>
diff --git a/js/client.js b/js/client.js
index a48156b..faeeb38 100644
--- a/js/client.js
+++ b/js/client.js
@@ -18,6 +18,32 @@ var buttonsGenerated = false;
var apiVersion = 20;
var version = "2.5.1";
+// Car thing specific customizations
+const TRY_AUTOCONNECT = true;
+const USE_FIXED_CLIENT_ID = true;
+const HIDE_BUTTONS = true;
+const MAP_HW_BUTTONS = true;
+const SIMPLE_CONNECTION_SCREEN = true;
+// THe values here can be changed as desired
+const FIXED_CLIENT_ID = '8gp3utc97';
+const AUTOCONNECT_URL = 'ws://127.0.0.1:8191/';
+const HW_KEY_TO_COL_ROW = {
+ // Presets
+ '1': { row: 0, col: 0 },
+ '2': { row: 0, col: 1 },
+ '3': { row: 0, col: 2 },
+ '4': { row: 0, col: 3 },
+ // Menu
+ 'M': { row: 0, col: 4 },
+ // Back (String.fromCharCode(27))
+ '\u001b': { row: 2, col: 4 },
+ // Dial
+ 'scroll_down': { row: 1, col: 0 },
+ 'scroll_up': { row: 1, col: 4},
+ // Dial button
+ '\r': { row: 1, col: 2 }
+};
+
function back() {
disconnect();
window.location.reload(false);
@@ -93,6 +119,12 @@ $(document).ready(function () {
clientId = Math.random().toString(36).substr(2, 9);
setCookie("clientId", clientId, 365);
}
+
+ if (USE_FIXED_CLIENT_ID) {
+ // Read only FS on CarThing = get/setCookie won't work, so overwrite
+ // whatever the fetched value is with a constant
+ clientId = FIXED_CLIENT_ID;
+ }
document.getElementById("labelVersion").innerHTML = version;
@@ -146,11 +178,48 @@ $(document).ready(function () {
document.getElementById("recent-connections").appendChild(recentConnectionItemRow);
}
}
+
+ if (MAP_HW_BUTTONS) {
+ $(window).keydown(function(event) {
+ const character = String.fromCharCode(event.which);
+ const target = HW_KEY_TO_COL_ROW[character];
+ if (target != null) {
+ buttonPress(target.row + "_" + target.col);
+ }
+ });
+ $(window).keyup(function(event) {
+ const character = String.fromCharCode(event.which);
+ const target = HW_KEY_TO_COL_ROW[character];
+ if (target != null) {
+ buttonPressRelease(target.row + "_" + target.col);
+ }
+ });
+ document.addEventListener('wheel', function(event) {
+ const character = event.wheelDelta < 0 ? 'scroll_up' : 'scroll_down';
+ const target = HW_KEY_TO_COL_ROW[character];
+ buttonPress(target.row + "_" + target.col);
+ setTimeout(function() {
+ buttonPressRelease(target.row + "_" + target.col);
+ }, 0);
+ });
+ }
+
+ if (TRY_AUTOCONNECT) {
+ const connectionScreenOverlay = document.getElementById("simple-car-thing-overlay");
+ if (SIMPLE_CONNECTION_SCREEN) {
+ connectionScreenOverlay.innerHTML = "Connecting to " + AUTOCONNECT_URL + "...";
+ } else {
+ connectionScreenOverlay.style.visibility = "hidden";
+ }
+ autoconnect();
+ }
});
function connect(url) {
if (connected) return;
- document.getElementById("button-connect-spinner").classList.toggle("d-none", false);
+ if (!(TRY_AUTOCONNECT && SIMPLE_CONNECTION_SCREEN)) {
+ document.getElementById("button-connect-spinner").classList.toggle("d-none", false);
+ }
if (websocket != null) {
disconnect();
@@ -163,6 +232,7 @@ function connect(url) {
document.getElementById("button-container").innerHTML = "";
document.getElementById("connect-container").innerHTML = '<div class="d-flex align-items-center justify-content-center" style="height: 500px;"><h1>Waiting for accepting the connection... <span class="spinner-border spinner-border-lg" role="status" aria-hidden="true"></span></h1></div>';
+ document.getElementById("simple-car-thing-overlay").style.visibility = "hidden";
var jsonObj = { "Method" : JsonMethod.CONNECTED, "Client-Id" : clientId, "API" : apiVersion, "Device-Type": "Web" }
doSend(JSON.stringify(jsonObj));
@@ -171,7 +241,16 @@ function connect(url) {
websocket.onclose = function (e) {
connected = false;
console.log("Connection closed");
- window.location.reload(false);
+ if (!TRY_AUTOCONNECT) {
+ window.location.reload(false);
+ }
+ if (TRY_AUTOCONNECT) {
+ // Continue trying to automatically connect without reloading
+ const connectionScreenOverlay = document.getElementById("simple-car-thing-overlay");
+ connectionScreenOverlay.style.visibility = "visible";
+ buttonsGenerated = false;
+ autoconnect();
+ }
};
websocket.onmessage = function (e) {
@@ -352,6 +431,12 @@ function connect(url) {
}
}
};
+
+ if (TRY_AUTOCONNECT) {
+ // Don't set the error handler when autoconnect is active, since we
+ // don't want to be blocked by the dialog
+ return;
+ }
websocket.onerror = function (e) {
document.getElementById("button-connect-spinner").classList.toggle("d-none", true);
@@ -418,11 +503,22 @@ function autoSize() {
var btnFullscreen = document.getElementById("btn-fullscreen");
+ if (HIDE_BUTTONS) {
+ document.getElementById("btn-fullscreen").style.visibility = "hidden";
+ document.getElementById("btn-back").style.visibility = "hidden";
+ document.getElementById("btn-dark").style.visibility = "hidden";
+ }
+
var offset = 0;
if (!document.fullscreenElement) {
offset = 30 + btnFullscreen.offsetHeight * 2;
}
+ if (HIDE_BUTTONS) {
+ // Don't use extra vertical padding ever
+ offset = 15;
+ }
+
var buttonSize = 100;
var rowsCount = rows.length;
var columnsCount = (divs.length / rows.length);
@@ -539,6 +635,13 @@ function IsTouchDevice() {
return 'ontouchstart' in window || navigator.msMaxTouchPoints;
}
+function autoconnect() {
+ setTimeout(function() {
+ if (connected) return;
+ connect(AUTOCONNECT_URL);
+ }, 1000);
+}
+
var JsonMethod = {
CONNECTED: "CONNECTED",
GET_CONFIG: "GET_CONFIG",
--
2.37.3.windows.1
@maclyn
Copy link
Author

maclyn commented Jan 29, 2023

The version at the bottom is Git, but it does seems like at some point it stopped applying cleanly to the main branch -- updated it so if you pull main it'll apply cleanly on top of v2.5.1

@RubenChavez04
Copy link

do i just push this after i push the main with adb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment