Skip to content

Commit dd6fa89

Browse files
Maselkovclaude
andauthored
Connect a computer: pick scripts with a row of toggle buttons (#197)
The three checkboxes, each with a hint line, pushed the command about 100px down. They're now one row of toggle buttons (aria-pressed, the range buttons' active look) with each hint as the button's tooltip; the installer still warns about a missing Adapter. Co-authored-by: Maselkov <25772111+Maselkov@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 429f588 commit dd6fa89

8 files changed

Lines changed: 42 additions & 25 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ The full list, including the OpenComputers config settings, is under
8484
there until its script reports). Check the address in the command is
8585
one the Minecraft server can reach (**Use a different address** changes
8686
it), then paste the command into that computer (each one, if you use
87-
several), after ticking the scripts that computer should run. It
87+
several), after picking the scripts that computer should run. It
8888
installs them, checks that the computer can reach the server, starts
8989
them on every boot and reboots. If it can't reach it, see
9090
[Scripts can't reach the server](#scripts-cant-reach-the-server).

‎docs/CONTEXT.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,9 +1647,11 @@ Connecting a computer: the Status dialog's "Connect a computer" builds
16471647
one line, `wget ... gcm.lua && /tmp/gcm.lua install <scripts>
16481648
--server=<url> --api-key=<key>` (OpenOS's shell chains with `&&`; checked
16491649
in game), from `/api/admin/connect` (the API key and `PUBLIC_URL`; the
1650-
page's own origin without it). The scripts are the ones ticked above it
1651-
(`CONNECT_SCRIPTS` in agents.js, which a JS test holds to
1652-
oc/manifest.lua's components; the ticks kept in localStorage); naming them
1650+
page's own origin without it). The scripts are the ones switched on above it,
1651+
a row of toggle buttons (`aria-pressed`) with each one's needed block as
1652+
its tooltip, to keep the section short (`CONNECT_SCRIPTS` in agents.js,
1653+
which a JS test holds to oc/manifest.lua's components; the choice kept in
1654+
localStorage); naming them
16531655
skips gcm's question for each. That gcm.lua comes from main, not a
16541656
release, so installer changes reach new computers on merge. Install asks
16551657
nothing else: it always enables the scripts and gcm_agent in rc and

‎docs/in-game.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,9 @@ wget -f https://raw.githubusercontent.com/Maselkov/gtnh-craft-monitor/main/oc/gc
173173

174174
**Settings (⚙) → Status → Connect a computer** on the web page shows
175175
both as one command, joined with `&&`, with this server's address and API
176-
key filled in, ready to copy. Tick the scripts this computer should run
177-
first (Crafts, Power, Network; the page remembers your choice), and the
176+
key filled in, ready to copy. First switch on the scripts this computer
177+
should run with the Crafts, Power and Network buttons above it (hover one
178+
to see which block it needs; the page remembers your choice), and the
178179
command names them, so the computer doesn't ask. Paste it into the
179180
computer with the middle mouse button or Insert.
180181
The address is the page's own unless `PUBLIC_URL` is set; if the

‎server/index.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ <h2>This base is private</h2>
510510
<div class="status-heading connect-heading">Connect a computer</div>
511511
<div class="connect-computer">
512512
<div class="modal-note">On an OpenComputers computer with an Internet Card, run this command: pick the scripts it installs, copy it and paste it into the computer with the middle mouse button or Insert.</div>
513-
<div id="connectScripts" class="agent-settings connect-scripts"></div>
513+
<div id="connectScripts" class="connect-scripts"></div>
514514
<div id="connectNoScripts" class="agent-line agent-command failed" style="display:none;">Pick at least one script to install.</div>
515515
<div id="connectAddress" hidden>
516516
<label class="modal-label" for="connectServerUrl">This server's address, as the Minecraft server reaches it</label>

‎server/static/app.css‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,16 @@ body.private-locked #networkTab {
13831383
margin-top: 16px;
13841384
}
13851385
.connect-scripts {
1386-
margin: 10px 0 0;
1386+
display: flex;
1387+
flex-wrap: wrap;
1388+
align-items: center;
1389+
gap: 6px;
1390+
margin-top: 8px;
1391+
font-size: 13px;
1392+
}
1393+
.connect-scripts-label {
1394+
color: var(--muted);
1395+
margin-right: 2px;
13871396
}
13881397
.connect-command {
13891398
display: flex;

‎server/static/js/agents.js‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,8 @@ const GCM_URL = 'https://raw.githubusercontent.com/Maselkov/gtnh-craft-monitor/m
276276
const LOCAL_HOST = /^(localhost|127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)/;
277277

278278
// The scripts the command installs, as oc/manifest.lua names them
279-
// (agents.test.js checks the two agree). Which are ticked is remembered
280-
// per browser.
279+
// (agents.test.js checks the two agree), as a row of toggle buttons; the
280+
// hint is each one's tooltip. Which are on is remembered per browser.
281281
export const CONNECT_SCRIPTS = [
282282
{ name: 'craft', label: 'Crafts', hint: 'Crafts tab and crafting from the page. Needs an Adapter touching an ME controller or interface.' },
283283
{ name: 'power', label: 'Power', hint: 'Power tab. Needs an Adapter touching a GregTech machine, e.g. the LSC.' },
@@ -313,10 +313,11 @@ export function connectCommand(serverUrl, apiKey, scripts = []) {
313313
}
314314

315315
export function connectScriptsHtml(chosen) {
316-
return CONNECT_SCRIPTS.map(s => `<label class="agent-setting">
317-
<input type="checkbox" data-script="${s.name}"${chosen.includes(s.name) ? ' checked' : ''}>
318-
<span>${escapeHtml(s.label)}<span class="agent-line">${escapeHtml(s.hint)}</span></span>
319-
</label>`).join('');
316+
return '<span class="connect-scripts-label">Install:</span>' + CONNECT_SCRIPTS.map((s) => {
317+
const on = chosen.includes(s.name);
318+
return `<button class="range-btn${on ? ' active' : ''}" data-action="toggle-connect-script"`
319+
+ ` data-script="${s.name}" aria-pressed="${on}" title="${escapeHtml(s.hint)}">${escapeHtml(s.label)}</button>`;
320+
}).join('');
320321
}
321322

322323
function savedConnectScripts() {
@@ -329,10 +330,13 @@ function savedConnectScripts() {
329330
}
330331

331332
function chosenScripts() {
332-
return [...document.querySelectorAll('#connectScripts input:checked')].map(box => box.dataset.script);
333+
return [...document.querySelectorAll('#connectScripts [aria-pressed="true"]')].map(btn => btn.dataset.script);
333334
}
334335

335-
function onConnectScriptsChange() {
336+
function toggleConnectScript(btn) {
337+
const on = btn.getAttribute('aria-pressed') !== 'true';
338+
btn.setAttribute('aria-pressed', String(on));
339+
btn.classList.toggle('active', on);
336340
try {
337341
localStorage.setItem(CONNECT_SCRIPTS_KEY, JSON.stringify(chosenScripts()));
338342
} catch (e) { /* per-viewer nicety only */ }
@@ -537,11 +541,10 @@ export function setupAgentsActions() {
537541
'copy-connect': () => copyConnect(),
538542
'edit-connect-address': () => editConnectAddress(),
539543
'toggle-connect-key': () => { connectKeyShown = !connectKeyShown; renderConnect(); },
544+
'toggle-connect-script': (el) => toggleConnectScript(el),
540545
});
541546
document.getElementById('connectServerUrl').addEventListener('input', renderConnect);
542-
const scripts = document.getElementById('connectScripts');
543-
scripts.innerHTML = connectScriptsHtml(savedConnectScripts());
544-
scripts.addEventListener('change', onConnectScriptsChange);
547+
document.getElementById('connectScripts').innerHTML = connectScriptsHtml(savedConnectScripts());
545548
for (const [key, id] of Object.entries(SETTING_TOGGLES)) {
546549
const box = document.getElementById(id);
547550
box.addEventListener('change', () => saveSetting(key, box));

‎server/tests/e2e/run.mjs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,9 +1927,11 @@ async function main() {
19271927
&& $('#connectCommand').textContent.startsWith('wget -f ')
19281928
&& $('#connectCommand').textContent.endsWith('/oc/gcm.lua /tmp/gcm.lua && ${install}' + location.origin + ' --api-key=' + '•'.repeat(12))
19291929
&& visible($('#connectLocalNote'))`);
1930-
// Unticked scripts drop out of the command; with none, nothing to copy.
1930+
// Scripts switched off drop out of the command; with none, nothing to copy.
19311931
await click(`$('#connectScripts [data-script="power"]')`);
1932-
await waitFor('power unpicked', `$('#connectCommand').textContent.includes('/tmp/gcm.lua install craft network --server=')`);
1932+
await waitFor('power unpicked', `$('#connectCommand').textContent.includes('/tmp/gcm.lua install craft network --server=')
1933+
&& $('#connectScripts [data-script="power"]').getAttribute('aria-pressed') === 'false'
1934+
&& !$('#connectScripts [data-script="power"]').classList.contains('active')`);
19331935
await click(`$('#connectScripts [data-script="craft"]')`);
19341936
await click(`$('#connectScripts [data-script="network"]')`);
19351937
await waitFor('none picked', `$('#connectCommand').textContent.includes('/tmp/gcm.lua install --server=')

‎server/tests/js/agents.test.js‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ test('connect scripts are the components oc/manifest.lua installs', () => {
131131
assert.deepEqual(CONNECT_SCRIPTS.map(s => s.name), names);
132132
});
133133

134-
test('connect scripts render a box each, ticked as chosen', () => {
134+
test('connect scripts render a toggle button each, pressed as chosen, the hint as tooltip', () => {
135135
const html = connectScriptsHtml(['power']);
136-
assert.equal((html.match(/type="checkbox"/g) || []).length, 3);
137-
assert.match(html, /data-script="power" checked>/);
138-
assert.match(html, /data-script="craft">/);
136+
assert.equal((html.match(/data-action="toggle-connect-script"/g) || []).length, 3);
137+
assert.match(html, /class="range-btn active"[^>]*data-script="power" aria-pressed="true" title="Power tab\. Needs an Adapter touching a GregTech machine/);
138+
assert.match(html, /class="range-btn"[^>]*data-script="craft" aria-pressed="false"/);
139139
});
140140

141141
test('local addresses are the ones OpenComputers blocks by default', () => {

0 commit comments

Comments
 (0)