mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 00:56:16 +00:00
refactor(web): remove legacy service-options table and Telnet URL Targets
The Plan card's per-field URL editor now drives both XML and Telnet
migrations via the same marge_url / stats_url / sw_update_url / bmx_url
options, so the two duplicate places that used to set those values are
gone:
- The XML method's "Service Implementations" table (#service-options)
with its self/proxied/original dropdowns. The legacy options keys
(marge / stats / sw_update / bmx) stay accepted by the backend's
applyProxyOptions for any direct API user, but the UI no longer
sets them.
- The "URL Targets" sub-pane inside #telnet-method-pane with its
parallel set of telnet-marge-url / etc. inputs and its own
Reset-to-defaults button. The Telnet pane retains its
explanatory header and limitations note (no CA install, pairing
panel below) — only the duplicate URL editor is gone.
Stripped the now-dead JS:
- showSummary's #service-options visibility toggle and
parsed_current_config-driven population of orig-marge etc.
- showSummary's reads of opt-marge / opt-stats / opt-sw_update /
opt-bmx in the summary query string.
- migrate's reads of those same fields in the migrate query string.
- fillTelnetURLInputs / readTelnetURLOptions /
resetTelnetURLsToDefaults / defaultTelnetURLs entirely.
- renderTelnetPreflight entirely (its writes were all into the
removed elements; the state card and Plan card now own all the
surfaces it used to populate).
- toggleMigrationMethod's serviceOptions branches.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
3dd3e3eaef
commit
670252b230
@@ -967,84 +967,6 @@
|
||||
streaming work.
|
||||
</p>
|
||||
|
||||
<h4 style="margin: 15px 0 5px 0">URL Targets</h4>
|
||||
<p style="margin: 0 0 8px 0; font-size: 0.9em; color: #555">
|
||||
Pre-filled from the target URL above. Most users leave
|
||||
these as-is. If you redirect to a fork like
|
||||
<a href="https://github.com/deborahgu/soundcork">soundcork</a>
|
||||
that mounts marge under <code>/marge</code>, append the
|
||||
suffix here — the matching <code>envswitch boseurls set</code>
|
||||
argument is derived automatically.
|
||||
</p>
|
||||
<table style="width: 100%; border-collapse: collapse">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: left; padding: 4px 6px">Field</th>
|
||||
<th style="text-align: left; padding: 4px 6px">Current on Device</th>
|
||||
<th style="text-align: left; padding: 4px 6px">Target URL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding: 4px 6px">Marge</td>
|
||||
<td id="telnet-current-marge" style="padding: 4px 6px; font-family: monospace; font-size: 0.85em; color: #555">—</td>
|
||||
<td style="padding: 4px 6px">
|
||||
<input
|
||||
type="text"
|
||||
id="telnet-marge-url"
|
||||
style="width: 100%; font-family: monospace; font-size: 0.9em; box-sizing: border-box"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px 6px">Stats</td>
|
||||
<td id="telnet-current-stats" style="padding: 4px 6px; font-family: monospace; font-size: 0.85em; color: #555">—</td>
|
||||
<td style="padding: 4px 6px">
|
||||
<input
|
||||
type="text"
|
||||
id="telnet-stats-url"
|
||||
style="width: 100%; font-family: monospace; font-size: 0.9em; box-sizing: border-box"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px 6px">Software Update</td>
|
||||
<td id="telnet-current-sw_update" style="padding: 4px 6px; font-family: monospace; font-size: 0.85em; color: #555">—</td>
|
||||
<td style="padding: 4px 6px">
|
||||
<input
|
||||
type="text"
|
||||
id="telnet-sw_update-url"
|
||||
style="width: 100%; font-family: monospace; font-size: 0.9em; box-sizing: border-box"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px 6px">BMX Registry</td>
|
||||
<td id="telnet-current-bmx" style="padding: 4px 6px; font-family: monospace; font-size: 0.85em; color: #555">—</td>
|
||||
<td style="padding: 4px 6px">
|
||||
<input
|
||||
type="text"
|
||||
id="telnet-bmx-url"
|
||||
style="width: 100%; font-family: monospace; font-size: 0.9em; box-sizing: border-box"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="margin-top: 8px">
|
||||
<button
|
||||
type="button"
|
||||
onclick="resetTelnetURLsToDefaults()"
|
||||
style="font-size: 0.85em"
|
||||
>
|
||||
Reset to defaults
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="telnet-probe-error"
|
||||
style="display: none; margin-top: 10px; padding: 6px 10px; background-color: #ffebee; border-left: 4px solid #c62828; font-size: 0.9em"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -1101,100 +1023,6 @@
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="service-options"
|
||||
style="margin-bottom: 20px; display: none"
|
||||
>
|
||||
<h4>Service Implementations</h4>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Service</th>
|
||||
<th>Original URL</th>
|
||||
<th>Implementation</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Marge (Streaming)</td>
|
||||
<td id="orig-marge">loading...</td>
|
||||
<td>
|
||||
<select
|
||||
id="opt-marge"
|
||||
onchange="refreshSummary()"
|
||||
>
|
||||
<option value="self">
|
||||
AfterTouch (Local Service)
|
||||
</option>
|
||||
<option value="proxied">
|
||||
Proxied (via local service)
|
||||
</option>
|
||||
<option value="original">
|
||||
Original (keep Bose URL)
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stats</td>
|
||||
<td id="orig-stats">loading...</td>
|
||||
<td>
|
||||
<select
|
||||
id="opt-stats"
|
||||
onchange="refreshSummary()"
|
||||
>
|
||||
<option value="self">
|
||||
AfterTouch (Local Service)
|
||||
</option>
|
||||
<option value="proxied">
|
||||
Proxied (via local service)
|
||||
</option>
|
||||
<option value="original">
|
||||
Original (keep Bose URL)
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Software Update</td>
|
||||
<td id="orig-sw_update">loading...</td>
|
||||
<td>
|
||||
<select
|
||||
id="opt-sw_update"
|
||||
onchange="refreshSummary()"
|
||||
>
|
||||
<option value="self">
|
||||
AfterTouch (Local Service)
|
||||
</option>
|
||||
<option value="proxied">
|
||||
Proxied (via local service)
|
||||
</option>
|
||||
<option value="original">
|
||||
Original (keep Bose URL)
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>BMX (Registry)</td>
|
||||
<td id="orig-bmx">loading...</td>
|
||||
<td>
|
||||
<select
|
||||
id="opt-bmx"
|
||||
onchange="refreshSummary()"
|
||||
>
|
||||
<option value="self">
|
||||
AfterTouch (Local Service)
|
||||
</option>
|
||||
<option value="proxied">
|
||||
Proxied (via local service)
|
||||
</option>
|
||||
<option value="original">
|
||||
Original (keep Bose URL)
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="diff-container">
|
||||
<div id="xml-diff-pane" class="diff-pane">
|
||||
<span class="config-header"
|
||||
|
||||
@@ -1697,12 +1697,10 @@ async function showSummary(deviceId) {
|
||||
}
|
||||
const targetUrl = document.getElementById("target-domain").value;
|
||||
|
||||
const opts = {
|
||||
marge: document.getElementById("opt-marge").value,
|
||||
stats: document.getElementById("opt-stats").value,
|
||||
sw_update: document.getElementById("opt-sw_update").value,
|
||||
bmx: document.getElementById("opt-bmx").value,
|
||||
};
|
||||
// Per-field URL overrides (Plan card). The summary endpoint uses
|
||||
// these to render the planned-config diff so the user sees the
|
||||
// exact XML that the migration will write.
|
||||
const opts = readPlanURLOptions();
|
||||
|
||||
const statusDiv = document.getElementById("status");
|
||||
statusDiv.style.display = "block";
|
||||
@@ -1761,9 +1759,7 @@ async function showSummary(deviceId) {
|
||||
renderMigrationState(summary);
|
||||
renderPlan(summary);
|
||||
renderPlanCurrentURLs(summary);
|
||||
renderTelnetPreflight(summary);
|
||||
renderPreflightWarnings(summary);
|
||||
fillTelnetURLInputs(defaultTelnetURLs(targetUrl));
|
||||
|
||||
// Mirror the global target URL into the Plan card's input.
|
||||
// Reset the "saved" feedback to the persisted value so a
|
||||
@@ -1791,16 +1787,6 @@ async function showSummary(deviceId) {
|
||||
migrationStatus.style.color = summary.is_migrated ? "green" : "red";
|
||||
migrationStatus.style.fontWeight = "bold";
|
||||
|
||||
if (summary.parsed_current_config) {
|
||||
document.getElementById("service-options").style.display = "block";
|
||||
document.getElementById("orig-marge").innerText = summary.parsed_current_config.margeServerUrl;
|
||||
document.getElementById("orig-stats").innerText = summary.parsed_current_config.statsServerUrl;
|
||||
document.getElementById("orig-sw_update").innerText = summary.parsed_current_config.swUpdateUrl;
|
||||
document.getElementById("orig-bmx").innerText = summary.parsed_current_config.bmxRegistryUrl;
|
||||
} else {
|
||||
document.getElementById("service-options").style.display = "none";
|
||||
}
|
||||
|
||||
// Trust CA Now button now lives inside the state card's CA / TLS
|
||||
// cell. Show only when SSH is reachable AND the CA isn't already
|
||||
// trusted on the device.
|
||||
@@ -2127,27 +2113,11 @@ async function migrate(deviceId, ip) {
|
||||
return;
|
||||
}
|
||||
|
||||
const opts = {};
|
||||
|
||||
// Legacy XML mode dropdowns (self/proxied/original) — only read if
|
||||
// the elements still exist. They're being removed in the next
|
||||
// iteration; until then a literal *_url override from the Plan
|
||||
// card wins anyway via assignment order below + the backend's
|
||||
// applyURLOverrides taking precedence over applyProxyOptions.
|
||||
const optMarge = document.getElementById("opt-marge");
|
||||
const optStats = document.getElementById("opt-stats");
|
||||
const optSwUpdate = document.getElementById("opt-sw_update");
|
||||
const optBmx = document.getElementById("opt-bmx");
|
||||
if (optMarge) opts.marge = optMarge.value;
|
||||
if (optStats) opts.stats = optStats.value;
|
||||
if (optSwUpdate) opts.sw_update = optSwUpdate.value;
|
||||
if (optBmx) opts.bmx = optBmx.value;
|
||||
|
||||
// Per-field URL overrides from the Plan card apply to any method
|
||||
// (XML or Telnet). Telnet pane's URL Targets table is now
|
||||
// redundant for the Plan-driven flow but is kept under Customize
|
||||
// for the next iteration's cleanup.
|
||||
Object.assign(opts, readPlanURLOptions());
|
||||
// Per-field URL overrides from the Plan card. The backend's
|
||||
// applyURLOverrides honors these for both XML and Telnet
|
||||
// migrations. Empty inputs are omitted so the canonical-default
|
||||
// fallback runs server-side.
|
||||
const opts = readPlanURLOptions();
|
||||
|
||||
const summaryDiv = document.getElementById("migration-summary");
|
||||
summaryDiv.style.display = "none";
|
||||
@@ -2416,63 +2386,6 @@ async function testDNSRedirection(deviceId) {
|
||||
}
|
||||
}
|
||||
|
||||
// defaultTelnetURLs returns the canonical four URLs derived from a
|
||||
// service base URL. Mirrors setup.defaultTelnetURLs (Go) — keep them in
|
||||
// sync if either side changes.
|
||||
function defaultTelnetURLs(targetUrl) {
|
||||
const base = (targetUrl || "").replace(/\/+$/, "");
|
||||
return {
|
||||
marge: base,
|
||||
stats: base,
|
||||
sw_update: base + "/updates/soundtouch",
|
||||
bmx: base + "/bmx/registry/v1/services",
|
||||
};
|
||||
}
|
||||
|
||||
// fillTelnetURLInputs writes the given URL set into the four input
|
||||
// fields, but only when the field is empty (so a user's edit is never
|
||||
// clobbered by a refresh).
|
||||
function fillTelnetURLInputs(urls, {force = false} = {}) {
|
||||
const fields = [
|
||||
["telnet-marge-url", urls.marge],
|
||||
["telnet-stats-url", urls.stats],
|
||||
["telnet-sw_update-url", urls.sw_update],
|
||||
["telnet-bmx-url", urls.bmx],
|
||||
];
|
||||
for (const [id, value] of fields) {
|
||||
const el = document.getElementById(id);
|
||||
if (!el) continue;
|
||||
if (force || !el.value) el.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// resetTelnetURLsToDefaults wipes any user edits and reapplies the
|
||||
// canonical defaults. Wired to the "Reset to defaults" button in the
|
||||
// telnet pane.
|
||||
function resetTelnetURLsToDefaults() {
|
||||
const targetUrl = document.getElementById("target-domain").value;
|
||||
fillTelnetURLInputs(defaultTelnetURLs(targetUrl), {force: true});
|
||||
}
|
||||
|
||||
// readTelnetURLOptions returns the four per-field URL overrides as the
|
||||
// query-parameter map the handler expects (marge_url / stats_url /
|
||||
// sw_update_url / bmx_url). Empty fields are omitted so the service
|
||||
// layer's "fall back to canonical default" path is exercised.
|
||||
function readTelnetURLOptions() {
|
||||
const out = {};
|
||||
const pairs = [
|
||||
["marge_url", "telnet-marge-url"],
|
||||
["stats_url", "telnet-stats-url"],
|
||||
["sw_update_url", "telnet-sw_update-url"],
|
||||
["bmx_url", "telnet-bmx-url"],
|
||||
];
|
||||
for (const [optKey, elemId] of pairs) {
|
||||
const el = document.getElementById(elemId);
|
||||
if (el && el.value) out[optKey] = el.value;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// onPlanTargetURLChange mirrors the migration tab's plan-target-url
|
||||
// input back into the canonical #target-domain input on the Settings
|
||||
// tab. Keeps the rest of the migration flow (which still reads
|
||||
@@ -3085,52 +2998,6 @@ function remoteServicesVerdict(summary) {
|
||||
return {icon: "✅", text: "Persistent", note: ""};
|
||||
}
|
||||
|
||||
// renderTelnetPreflight surfaces TelnetReachable / TelnetBanner /
|
||||
// TelnetProbeError on the migration summary, and populates the "Current
|
||||
// on Device" column from TelnetVerifiedConfig when the device answered.
|
||||
function renderTelnetPreflight(summary) {
|
||||
const statusEl = document.getElementById("telnet-status");
|
||||
if (statusEl) {
|
||||
if (summary.telnet_reachable) {
|
||||
statusEl.innerText = "✅ Reachable";
|
||||
statusEl.style.color = "green";
|
||||
} else if (summary.telnet_probe_error) {
|
||||
statusEl.innerText = "❌ Unreachable";
|
||||
statusEl.style.color = "red";
|
||||
} else {
|
||||
statusEl.innerText = "❓ Unknown";
|
||||
statusEl.style.color = "gray";
|
||||
}
|
||||
}
|
||||
|
||||
const bannerEl = document.getElementById("telnet-banner");
|
||||
if (bannerEl) {
|
||||
bannerEl.innerText = summary.telnet_banner ? `(${summary.telnet_banner})` : "";
|
||||
}
|
||||
|
||||
const errorEl = document.getElementById("telnet-probe-error");
|
||||
if (errorEl) {
|
||||
if (summary.telnet_probe_error && !summary.telnet_reachable) {
|
||||
errorEl.innerText = "Probe error: " + summary.telnet_probe_error;
|
||||
errorEl.style.display = "block";
|
||||
} else {
|
||||
errorEl.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
const live = parseTelnetVerifiedConfig(summary.telnet_verified_config || "");
|
||||
const cells = [
|
||||
["telnet-current-marge", live.margeServerUrl],
|
||||
["telnet-current-stats", live.statsServerUrl],
|
||||
["telnet-current-sw_update", live.swUpdateUrl],
|
||||
["telnet-current-bmx", live.bmxRegistryUrl],
|
||||
];
|
||||
for (const [id, value] of cells) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.innerText = value || "—";
|
||||
}
|
||||
}
|
||||
|
||||
// parseTelnetVerifiedConfig extracts field values from the device's
|
||||
// `getpdo CurrentSystemConfiguration` reply. Mirrors
|
||||
// setup.parseGetpdoConfig (Go); supports both the protobuf-text-like
|
||||
@@ -3213,7 +3080,6 @@ async function toggleMigrationMethod() {
|
||||
const plannedHostsPane = document.getElementById("planned-hosts-pane");
|
||||
const plannedResolvPane = document.getElementById("planned-resolv-pane");
|
||||
const currentResolvPane = document.getElementById("current-resolv-pane");
|
||||
const serviceOptions = document.getElementById("service-options");
|
||||
const hostsTestPane = document.getElementById("hosts-redirection-test");
|
||||
const dnsTestPane = document.getElementById("dns-redirection-test");
|
||||
const telnetPane = document.getElementById("telnet-method-pane");
|
||||
@@ -3228,7 +3094,6 @@ async function toggleMigrationMethod() {
|
||||
plannedHostsPane.style.display = "none";
|
||||
plannedResolvPane.style.display = "none";
|
||||
currentResolvPane.style.display = "none";
|
||||
serviceOptions.style.display = "none";
|
||||
hostsTestPane.style.display = "none";
|
||||
dnsTestPane.style.display = "none";
|
||||
if (dnsWarning) dnsWarning.style.display = "none";
|
||||
@@ -3238,7 +3103,6 @@ async function toggleMigrationMethod() {
|
||||
plannedHostsPane.style.display = "block";
|
||||
plannedResolvPane.style.display = "none";
|
||||
currentResolvPane.style.display = "none";
|
||||
serviceOptions.style.display = "none";
|
||||
hostsTestPane.style.display = "block";
|
||||
dnsTestPane.style.display = "none";
|
||||
if (dnsWarning) dnsWarning.style.display = "none";
|
||||
@@ -3248,7 +3112,6 @@ async function toggleMigrationMethod() {
|
||||
plannedHostsPane.style.display = "none";
|
||||
plannedResolvPane.style.display = "block";
|
||||
currentResolvPane.style.display = "none";
|
||||
serviceOptions.style.display = "none";
|
||||
hostsTestPane.style.display = "none";
|
||||
dnsTestPane.style.display = "block";
|
||||
|
||||
@@ -3298,11 +3161,6 @@ async function toggleMigrationMethod() {
|
||||
currentResolvPane.style.display = "none";
|
||||
hostsTestPane.style.display = "none";
|
||||
dnsTestPane.style.display = "none";
|
||||
// Only show service options if we have a parsed config
|
||||
const currentConfig = document.getElementById("current-config").innerText;
|
||||
if (currentConfig && !currentConfig.startsWith("Error") && currentConfig !== "loading...") {
|
||||
serviceOptions.style.display = "block";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user