Skip to content

Commit 520815a

Browse files
committed
feat: add control lock toggle to cyberpunk web interface
1 parent e291c6d commit 520815a

7 files changed

Lines changed: 88 additions & 5 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ neon logo that doubles as the SVG favicon ([`8d9725c`](../../commit/8d9725c)):
8282
| SD card capacity gauge in the files tab and the info dialog | [`a2b9f2b`](../../commit/a2b9f2b) |
8383
| FTP server can be stopped from the web interface (start button turns into a stop button) | [`f0906b4`](../../commit/f0906b4) |
8484
| Bluetooth modes can be stopped from the web interface; commands 143/144 switch modes directly via buttons | [`0c3edd0`](../../commit/0c3edd0) |
85+
| Button lock (Kindersicherung) toggle directly in the control tab of the web interface with visual lock status indicator | [`ae83116`](../../commit/ae83116) |
8586

8687
#### Feature highlights
8788

‎html/locales/de.json‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@
157157
"voldown": "Leiser",
158158
"volup": "Lauter",
159159
"current": "Aktueller Titel",
160-
"command": "Modifikation ausführen"
160+
"command": "Modifikation ausführen",
161+
"locked": "Gesperrt",
162+
"unlocked": "Entsperrt"
161163
},
162164
"files": {
163165
"title": "Dateien",

‎html/locales/en.json‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@
158158
"voldown": "Volume Down",
159159
"volup": "Volume Up",
160160
"current": "Current track",
161-
"command": "Execute Modification"
161+
"command": "Execute Modification",
162+
"locked": "Locked",
163+
"unlocked": "Unlocked"
162164
},
163165
"files": {
164166
"title": "Files",

‎html/locales/fr.json‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@
150150
"voldown": "Diminuer le volume",
151151
"volup": "Augmenter le volume",
152152
"current": "Piste actuelle",
153-
"command": "Exécuter la modification"
153+
"command": "Exécuter la modification",
154+
"locked": "Verrouillé",
155+
"unlocked": "Déverrouillé"
154156
},
155157
"files": {
156158
"title": "Fichiers",

‎html/management.html‎

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,45 @@
661661
box-shadow: 0 0 24px -4px rgba(255, 42, 109, .9);
662662
}
663663

664+
.cp-lock-button {
665+
font-family: "Rajdhani", sans-serif;
666+
font-weight: 600;
667+
text-transform: uppercase;
668+
letter-spacing: .1em;
669+
padding: 4px 10px;
670+
border-radius: 4px;
671+
font-size: 0.8rem;
672+
transition: all 0.3s ease;
673+
}
674+
675+
.cp-lock-button.unlocked {
676+
color: var(--cp-cyan);
677+
border: 1px solid rgba(0, 240, 255, .4);
678+
background: rgba(0, 240, 255, .05);
679+
box-shadow: 0 0 8px rgba(0, 240, 255, .1);
680+
}
681+
682+
.cp-lock-button.unlocked:hover {
683+
color: #021019;
684+
background: var(--cp-cyan);
685+
border-color: var(--cp-cyan);
686+
box-shadow: 0 0 12px rgba(0, 240, 255, .6);
687+
}
688+
689+
.cp-lock-button.locked {
690+
color: var(--cp-magenta);
691+
border: 1px solid rgba(255, 42, 109, .4);
692+
background: rgba(255, 42, 109, .05);
693+
box-shadow: 0 0 8px rgba(255, 42, 109, .1);
694+
}
695+
696+
.cp-lock-button.locked:hover {
697+
color: #021019;
698+
background: var(--cp-magenta);
699+
border-color: var(--cp-magenta);
700+
box-shadow: 0 0 12px rgba(255, 42, 109, .6);
701+
}
702+
664703
.volume-button {
665704
width: 60px;
666705
}
@@ -1573,7 +1612,13 @@ <h5 class="modal-title" data-i18n="tools.nvs.erase.title"></h5>
15731612
aria-labelledby="nav-control-tab">
15741613
<div class="container" id="navControl">
15751614
<div class="col-md-12">
1576-
<legend data-i18n="control.title"></legend>
1615+
<div class="d-flex justify-content-between align-items-center mb-1 pb-1" style="border-bottom: 1px solid var(--cp-border);">
1616+
<legend data-i18n="control.title" style="border-bottom: none; margin-bottom: 0; padding-bottom: 0;"></legend>
1617+
<button type="button" class="btn btn-sm cp-lock-button unlocked" id="btn-lock-controls" onclick="sendControl(100)" style="margin-bottom: 4px;">
1618+
<span id="ico-lock-controls" class="fas fa-lock-open me-1"></span>
1619+
<span id="lbl-lock-controls" data-i18n="control.unlocked">Unlocked</span>
1620+
</button>
1621+
</div>
15771622
<div class="mb-3 col-md-12">
15781623
<img src="/cover" class="coverimage-container" id="coverimg" alt="">
15791624
</div>
@@ -3689,6 +3734,9 @@ <h5 class="modal-title" data-i18n="tools.nvs.erase.title"></h5>
36893734
if (socketMsg.pong == 'pong') {
36903735
pong();
36913736
}
3737+
if ("controlsLocked" in socketMsg) {
3738+
updateLockControlsState(socketMsg.controlsLocked);
3739+
}
36923740
}
36933741
if ("opmode" in socketMsg) {
36943742
currentOpMode = socketMsg.opmode;
@@ -3709,6 +3757,9 @@ <h5 class="modal-title" data-i18n="tools.nvs.erase.title"></h5>
37093757
if ("trackinfo" in socketMsg) {
37103758
document.getElementById('track').innerHTML = socketMsg.trackinfo.name;
37113759
setTrackProgress(socketMsg.trackinfo);
3760+
if ("controlsLocked" in socketMsg.trackinfo) {
3761+
updateLockControlsState(socketMsg.trackinfo.controlsLocked);
3762+
}
37123763
var btnTrackPlayPause = document.getElementById('nav-btn-play');
37133764
if (socketMsg.trackinfo.pausePlay) {
37143765
btnTrackPlayPause.innerHTML = '<i id="ico-play-pause" class="fas fa-lg fa-play"></i>';
@@ -4471,6 +4522,25 @@ <h5 class="modal-title" data-i18n="tools.nvs.erase.title"></h5>
44714522
}
44724523
}
44734524

4525+
function updateLockControlsState(locked) {
4526+
const btn = document.getElementById('btn-lock-controls');
4527+
const ico = document.getElementById('ico-lock-controls');
4528+
const lbl = document.getElementById('lbl-lock-controls');
4529+
if (!btn || !ico || !lbl) return;
4530+
4531+
if (locked) {
4532+
btn.className = "btn btn-sm cp-lock-button locked";
4533+
ico.className = "fas fa-lock me-1";
4534+
lbl.setAttribute('data-i18n', 'control.locked');
4535+
lbl.innerHTML = i18next.t("control.locked");
4536+
} else {
4537+
btn.className = "btn btn-sm cp-lock-button unlocked";
4538+
ico.className = "fas fa-lock-open me-1";
4539+
lbl.setAttribute('data-i18n', 'control.unlocked');
4540+
lbl.innerHTML = i18next.t("control.unlocked");
4541+
}
4542+
}
4543+
44744544
async function mqttSettings(clickedId) {
44754545
lastIdclicked = clickedId;
44764546
var val;

‎src/System.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,15 @@ uint8_t System_GetSleepTimer(void) {
137137
}
138138

139139
void System_SetLockControls(bool value) {
140-
System_LockControls = value;
140+
if (System_LockControls != value) {
141+
System_LockControls = value;
142+
Web_SendWebsocketData(0, WebsocketCodeType::Pong);
143+
}
141144
}
142145

143146
void System_ToggleLockControls(void) {
144147
System_LockControls = !System_LockControls;
148+
Web_SendWebsocketData(0, WebsocketCodeType::Pong);
145149
}
146150

147151
bool System_AreControlsLocked(void) {

‎src/Web.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,7 @@ void Web_SendWebsocketData(uint32_t client, WebsocketCodeType code) {
19891989
} else if (code == WebsocketCodeType::Pong) {
19901990
object["pong"] = "pong";
19911991
object["rssi"] = Wlan_GetRssi();
1992+
object["controlsLocked"] = System_AreControlsLocked();
19921993
#ifdef BATTERY_MEASURE_ENABLE
19931994
JsonObject batteryObj = object["battery"].to<JsonObject>();
19941995
batteryObj["voltage"] = Battery_GetVoltage();
@@ -2006,6 +2007,7 @@ void Web_SendWebsocketData(uint32_t client, WebsocketCodeType code) {
20062007
entry["name"] = gPlayProperties.title;
20072008
entry["posPercent"] = gPlayProperties.currentRelPos;
20082009
entry["playMode"] = gPlayProperties.playMode;
2010+
entry["controlsLocked"] = System_AreControlsLocked();
20092011
} else if (code == WebsocketCodeType::CoverImg) {
20102012
object["coverimg"] = "coverimg";
20112013
} else if (code == WebsocketCodeType::Volume) {

0 commit comments

Comments
 (0)