feat(wavelog): link to the Wavelog instance next to the API key field
Show an "Open Wavelog" link beside the Wavelog API Key heading in the OpenWebRX panel. The URL comes from the runtime WAVELOG_BASE_URL (exposed via GET /v1/me and the OpenWebRX session response), so the private hostname is never hardcoded in this public repo. The link is hidden when no base URL is configured. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -138,6 +138,7 @@ const els = {
|
|||||||
wavelogKeyInput: document.getElementById("wavelogKeyInput"),
|
wavelogKeyInput: document.getElementById("wavelogKeyInput"),
|
||||||
wavelogKeySaveBtn: document.getElementById("wavelogKeySaveBtn"),
|
wavelogKeySaveBtn: document.getElementById("wavelogKeySaveBtn"),
|
||||||
wavelogKeyMessage: document.getElementById("wavelogKeyMessage"),
|
wavelogKeyMessage: document.getElementById("wavelogKeyMessage"),
|
||||||
|
wavelogInstanceLink: document.getElementById("wavelogInstanceLink"),
|
||||||
openwebrxTxStatePill: document.getElementById("openwebrxTxStatePill"),
|
openwebrxTxStatePill: document.getElementById("openwebrxTxStatePill"),
|
||||||
rotorCurrent: document.getElementById("rotorCurrent"),
|
rotorCurrent: document.getElementById("rotorCurrent"),
|
||||||
rotorCompass: document.getElementById("rotorCompass"),
|
rotorCompass: document.getElementById("rotorCompass"),
|
||||||
@@ -1505,6 +1506,7 @@ async function refreshCurrentUser() {
|
|||||||
const result = await api("/v1/me", { authRequired: true });
|
const result = await api("/v1/me", { authRequired: true });
|
||||||
state.user = result.user;
|
state.user = result.user;
|
||||||
state.wavelogApiKey = typeof result.wavelogApiKey === "string" ? result.wavelogApiKey : "";
|
state.wavelogApiKey = typeof result.wavelogApiKey === "string" ? result.wavelogApiKey : "";
|
||||||
|
state.wavelogBaseUrl = typeof result.wavelogBaseUrl === "string" ? result.wavelogBaseUrl : "";
|
||||||
applyWavelogKeyToInput();
|
applyWavelogKeyToInput();
|
||||||
renderUserSettingsAuthMethods();
|
renderUserSettingsAuthMethods();
|
||||||
await ensureLanguageFromUserPreference();
|
await ensureLanguageFromUserPreference();
|
||||||
@@ -1698,6 +1700,16 @@ function applyWavelogKeyToInput() {
|
|||||||
if (els.wavelogKeyInput) {
|
if (els.wavelogKeyInput) {
|
||||||
els.wavelogKeyInput.value = String(state.wavelogApiKey || "");
|
els.wavelogKeyInput.value = String(state.wavelogApiKey || "");
|
||||||
}
|
}
|
||||||
|
if (els.wavelogInstanceLink) {
|
||||||
|
const url = String(state.wavelogBaseUrl || "").trim();
|
||||||
|
if (url) {
|
||||||
|
els.wavelogInstanceLink.href = url;
|
||||||
|
els.wavelogInstanceLink.hidden = false;
|
||||||
|
} else {
|
||||||
|
els.wavelogInstanceLink.removeAttribute("href");
|
||||||
|
els.wavelogInstanceLink.hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveWavelogKey() {
|
async function saveWavelogKey() {
|
||||||
@@ -1723,6 +1735,9 @@ async function openOpenWebRxSession() {
|
|||||||
const session = result && result.session ? result.session : null;
|
const session = result && result.session ? result.session : null;
|
||||||
if (result && typeof result.wavelogApiKey === "string") {
|
if (result && typeof result.wavelogApiKey === "string") {
|
||||||
state.wavelogApiKey = result.wavelogApiKey;
|
state.wavelogApiKey = result.wavelogApiKey;
|
||||||
|
if (typeof result.wavelogBaseUrl === "string") {
|
||||||
|
state.wavelogBaseUrl = result.wavelogBaseUrl;
|
||||||
|
}
|
||||||
applyWavelogKeyToInput();
|
applyWavelogKeyToInput();
|
||||||
}
|
}
|
||||||
const sessionTicket = session && session.ticket ? String(session.ticket) : "";
|
const sessionTicket = session && session.ticket ? String(session.ticket) : "";
|
||||||
@@ -1752,6 +1767,9 @@ async function openOpenWebRxExternal() {
|
|||||||
const session = result && result.session ? result.session : null;
|
const session = result && result.session ? result.session : null;
|
||||||
if (result && typeof result.wavelogApiKey === "string") {
|
if (result && typeof result.wavelogApiKey === "string") {
|
||||||
state.wavelogApiKey = result.wavelogApiKey;
|
state.wavelogApiKey = result.wavelogApiKey;
|
||||||
|
if (typeof result.wavelogBaseUrl === "string") {
|
||||||
|
state.wavelogBaseUrl = result.wavelogBaseUrl;
|
||||||
|
}
|
||||||
applyWavelogKeyToInput();
|
applyWavelogKeyToInput();
|
||||||
}
|
}
|
||||||
const sessionTicket = session && session.ticket ? String(session.ticket) : "";
|
const sessionTicket = session && session.ticket ? String(session.ticket) : "";
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
"Key speichern": "Key speichern",
|
"Key speichern": "Key speichern",
|
||||||
"Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.": "Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.",
|
"Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.": "Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.",
|
||||||
"Wavelog API Key gespeichert.": "Wavelog API Key gespeichert.",
|
"Wavelog API Key gespeichert.": "Wavelog API Key gespeichert.",
|
||||||
|
"Wavelog öffnen": "Wavelog öffnen",
|
||||||
"Reservierungen": "Reservierungen",
|
"Reservierungen": "Reservierungen",
|
||||||
"Naechsten Slot reservieren": "Naechsten Slot reservieren",
|
"Naechsten Slot reservieren": "Naechsten Slot reservieren",
|
||||||
"SWR Uebersicht": "SWR Uebersicht",
|
"SWR Uebersicht": "SWR Uebersicht",
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
"Key speichern": "Save key",
|
"Key speichern": "Save key",
|
||||||
"Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.": "The station's frequency and mode are sent to your Wavelog logbook on band change.",
|
"Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.": "The station's frequency and mode are sent to your Wavelog logbook on band change.",
|
||||||
"Wavelog API Key gespeichert.": "Wavelog API key saved.",
|
"Wavelog API Key gespeichert.": "Wavelog API key saved.",
|
||||||
|
"Wavelog öffnen": "Open Wavelog",
|
||||||
"Reservierungen": "Reservations",
|
"Reservierungen": "Reservations",
|
||||||
"Naechsten Slot reservieren": "Reserve next slot",
|
"Naechsten Slot reservieren": "Reserve next slot",
|
||||||
"SWR Uebersicht": "SWR Overview",
|
"SWR Uebersicht": "SWR Overview",
|
||||||
|
|||||||
@@ -167,7 +167,10 @@
|
|||||||
<p class="muted">Session Key (Ticket): <code id="openwebrxSessionTicket">-</code></p>
|
<p class="muted">Session Key (Ticket): <code id="openwebrxSessionTicket">-</code></p>
|
||||||
</div>
|
</div>
|
||||||
<div id="wavelogKeyBox" class="stack">
|
<div id="wavelogKeyBox" class="stack">
|
||||||
|
<div class="section-head">
|
||||||
<label for="wavelogKeyInput">Wavelog API Key (Rig-Key)</label>
|
<label for="wavelogKeyInput">Wavelog API Key (Rig-Key)</label>
|
||||||
|
<a id="wavelogInstanceLink" target="_blank" rel="noopener noreferrer" hidden>Wavelog öffnen</a>
|
||||||
|
</div>
|
||||||
<input id="wavelogKeyInput" type="text" autocomplete="off" spellcheck="false" placeholder="Wavelog API Key" />
|
<input id="wavelogKeyInput" type="text" autocomplete="off" spellcheck="false" placeholder="Wavelog API Key" />
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button id="wavelogKeySaveBtn" type="button" class="ghost-btn">Key speichern</button>
|
<button id="wavelogKeySaveBtn" type="button" class="ghost-btn">Key speichern</button>
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ async function routeRequest(req, res) {
|
|||||||
if (method === "GET" && url.pathname === "/v1/me") {
|
if (method === "GET" && url.pathname === "/v1/me") {
|
||||||
const auth = requireAuth(req, res);
|
const auth = requireAuth(req, res);
|
||||||
if (!auth) return;
|
if (!auth) return;
|
||||||
return sendJson(res, 200, { user: sanitizeUser(auth.user), wavelogApiKey: auth.user.wavelogApiKey || "", capabilities: userCapabilities(auth.user) });
|
return sendJson(res, 200, { user: sanitizeUser(auth.user), wavelogApiKey: auth.user.wavelogApiKey || "", wavelogBaseUrl: wavelogBaseUrlPublic(), capabilities: userCapabilities(auth.user) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method === "GET" && url.pathname === "/v1/auth/session/diag") {
|
if (method === "GET" && url.pathname === "/v1/auth/session/diag") {
|
||||||
@@ -3641,7 +3641,8 @@ async function handleOpenWebRxSessionIssue(res, user) {
|
|||||||
return sendJson(res, 200, {
|
return sendJson(res, 200, {
|
||||||
ok: true,
|
ok: true,
|
||||||
session: result,
|
session: result,
|
||||||
wavelogApiKey: user.wavelogApiKey || ""
|
wavelogApiKey: user.wavelogApiKey || "",
|
||||||
|
wavelogBaseUrl: wavelogBaseUrlPublic()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3719,6 +3720,12 @@ async function handleOpenWebRxBandSelect(res, user, body) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Public Wavelog base URL (for the UI link). Comes from runtime env only, so the
|
||||||
|
// private hostname is never baked into this (public) repo.
|
||||||
|
function wavelogBaseUrlPublic() {
|
||||||
|
return String(process.env.WAVELOG_BASE_URL || "").trim().replace(/\/+$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
// Push a frequency/mode to the active operator's Wavelog logbook (CAT API).
|
// Push a frequency/mode to the active operator's Wavelog logbook (CAT API).
|
||||||
// Best-effort: never throws into the caller's flow.
|
// Best-effort: never throws into the caller's flow.
|
||||||
async function sendWavelogCat(user, frequencyHz, mode) {
|
async function sendWavelogCat(user, frequencyHz, mode) {
|
||||||
|
|||||||
Reference in New Issue
Block a user