feat(http-frontend): add rig and owner header lines
This commit is contained in:
@@ -238,6 +238,7 @@ async fn async_init() -> DynResult<AppState> {
|
||||
.callsign
|
||||
.clone()
|
||||
.or_else(|| cfg.general.callsign.clone());
|
||||
frontend_runtime.owner_callsign = callsign.clone();
|
||||
|
||||
info!(
|
||||
"Starting trx-client (remote: {}, frontends: {})",
|
||||
|
||||
@@ -153,6 +153,8 @@ pub struct FrontendRuntimeContext {
|
||||
pub remote_active_rig_id: Arc<Mutex<Option<String>>>,
|
||||
/// Cached remote rig list from GetRigs polling.
|
||||
pub remote_rigs: Arc<Mutex<Vec<RemoteRigEntry>>>,
|
||||
/// Owner callsign from trx-client config/CLI for frontend display.
|
||||
pub owner_callsign: Option<String>,
|
||||
}
|
||||
|
||||
impl FrontendRuntimeContext {
|
||||
@@ -180,6 +182,7 @@ impl FrontendRuntimeContext {
|
||||
http_auth_cookie_same_site: "Lax".to_string(),
|
||||
remote_active_rig_id: Arc::new(Mutex::new(None)),
|
||||
remote_rigs: Arc::new(Mutex::new(Vec::new())),
|
||||
owner_callsign: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,6 +285,8 @@ const swrValue = document.getElementById("swr-value");
|
||||
const loadingEl = document.getElementById("loading");
|
||||
const contentEl = document.getElementById("content");
|
||||
const serverSubtitle = document.getElementById("server-subtitle");
|
||||
const rigSubtitle = document.getElementById("rig-subtitle");
|
||||
const ownerSubtitle = document.getElementById("owner-subtitle");
|
||||
const loadingTitle = document.getElementById("loading-title");
|
||||
const loadingSub = document.getElementById("loading-sub");
|
||||
const headerSigCanvas = document.getElementById("header-sig-canvas");
|
||||
@@ -297,7 +299,6 @@ const headerRigSwitchBtn = document.getElementById("header-rig-switch-btn");
|
||||
let lastControl;
|
||||
let lastTxEn = null;
|
||||
let lastRendered = null;
|
||||
let rigName = "Rig";
|
||||
let hintTimer = null;
|
||||
let sigMeasuring = false;
|
||||
let sigLastSUnits = null;
|
||||
@@ -729,6 +730,8 @@ function setDisabled(disabled) {
|
||||
let serverVersion = null;
|
||||
let serverBuildDate = null;
|
||||
let serverCallsign = null;
|
||||
let ownerCallsign = null;
|
||||
let rigDisplayName = null;
|
||||
let serverLat = null;
|
||||
let serverLon = null;
|
||||
|
||||
@@ -741,17 +744,20 @@ function updateFooterBuildInfo() {
|
||||
}
|
||||
|
||||
function updateTitle() {
|
||||
let title = rigName || "Rig";
|
||||
if (serverCallsign) title = `${serverCallsign}'s ${title}`;
|
||||
document.getElementById("rig-title").textContent = title;
|
||||
document.getElementById("rig-title").textContent = originalTitle;
|
||||
}
|
||||
|
||||
function render(update) {
|
||||
if (!update) return;
|
||||
if (update.info && update.info.model) rigName = update.info.model;
|
||||
if (update.info && typeof update.info.model === "string" && update.info.model.length > 0) {
|
||||
rigDisplayName = update.info.model;
|
||||
}
|
||||
if (update.server_version) serverVersion = update.server_version;
|
||||
if (update.server_build_date) serverBuildDate = update.server_build_date;
|
||||
if (update.server_callsign) serverCallsign = update.server_callsign;
|
||||
if (typeof update.owner_callsign === "string" && update.owner_callsign.length > 0) {
|
||||
ownerCallsign = update.owner_callsign;
|
||||
}
|
||||
if (update.server_latitude != null) serverLat = update.server_latitude;
|
||||
if (update.server_longitude != null) serverLon = update.server_longitude;
|
||||
updateTitle();
|
||||
@@ -786,17 +792,21 @@ function render(update) {
|
||||
if (contentEl) contentEl.style.display = "";
|
||||
}
|
||||
// Server subtitle: "trx-server vX.Y.Z hosted by CALL"
|
||||
if (update.server_version || update.server_callsign) {
|
||||
let parts = "trx-server";
|
||||
if (update.server_version) parts += ` v${update.server_version}`;
|
||||
if (update.server_callsign) {
|
||||
const cs = update.server_callsign;
|
||||
serverSubtitle.innerHTML = `${parts} hosted by <a href="https://www.qrzcq.com/call/${encodeURIComponent(cs)}" target="_blank" rel="noopener">${cs}</a>`;
|
||||
document.title = `${cs} - ${originalTitle}`;
|
||||
} else {
|
||||
serverSubtitle.textContent = parts;
|
||||
if (serverSubtitle) {
|
||||
if (update.server_version && update.server_callsign) {
|
||||
serverSubtitle.textContent = `trx-server v${update.server_version} hosted by ${update.server_callsign}`;
|
||||
} else if (update.server_version) {
|
||||
serverSubtitle.textContent = `trx-server v${update.server_version}`;
|
||||
} else if (update.server_callsign) {
|
||||
serverSubtitle.textContent = `trx-server hosted by ${update.server_callsign}`;
|
||||
}
|
||||
}
|
||||
if (rigSubtitle) {
|
||||
rigSubtitle.textContent = `Rig: ${rigDisplayName || "--"}`;
|
||||
}
|
||||
if (ownerSubtitle) {
|
||||
ownerSubtitle.textContent = `Owner: ${ownerCallsign || "--"}`;
|
||||
}
|
||||
setDisabled(false);
|
||||
if (update.info && update.info.capabilities && Array.isArray(update.info.capabilities.supported_modes)) {
|
||||
const modes = update.info.capabilities.supported_modes.map(normalizeMode).filter(Boolean);
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
<div class="header-text">
|
||||
<div class="title"><span id="rig-title">trx-rs</span></div>
|
||||
<div class="subtitle" id="server-subtitle"></div>
|
||||
<div class="subtitle">{pkg} v{ver}</div>
|
||||
<div class="subtitle" id="rig-subtitle">Rig: --</div>
|
||||
<div class="subtitle" id="owner-subtitle">Owner: --</div>
|
||||
</div>
|
||||
<div class="header-signal-wrap" aria-hidden="true">
|
||||
<canvas id="header-sig-canvas"></canvas>
|
||||
|
||||
@@ -32,9 +32,23 @@ const REQUEST_TIMEOUT: Duration = Duration::from_secs(15);
|
||||
#[get("/status")]
|
||||
pub async fn status_api(
|
||||
state: web::Data<watch::Receiver<RigState>>,
|
||||
clients: web::Data<Arc<AtomicUsize>>,
|
||||
context: web::Data<Arc<FrontendRuntimeContext>>,
|
||||
) -> Result<impl Responder, Error> {
|
||||
let state = wait_for_view(state.get_ref().clone()).await?;
|
||||
Ok(HttpResponse::Ok().json(state))
|
||||
let json = serde_json::to_string(&state).map_err(actix_web::error::ErrorInternalServerError)?;
|
||||
let json = inject_frontend_meta(
|
||||
&json,
|
||||
clients.load(Ordering::Relaxed),
|
||||
context.rigctl_clients.load(Ordering::Relaxed),
|
||||
rigctl_addr_from_context(context.get_ref().as_ref()),
|
||||
active_rig_id_from_context(context.get_ref().as_ref()),
|
||||
rig_ids_from_context(context.get_ref().as_ref()),
|
||||
owner_callsign_from_context(context.get_ref().as_ref()),
|
||||
);
|
||||
Ok(HttpResponse::Ok()
|
||||
.insert_header((header::CONTENT_TYPE, "application/json"))
|
||||
.body(json))
|
||||
}
|
||||
|
||||
/// Inject `"clients": N` into a JSON object string.
|
||||
@@ -45,6 +59,7 @@ fn inject_frontend_meta(
|
||||
rigctl_addr: Option<String>,
|
||||
active_rig_id: Option<String>,
|
||||
rig_ids: Vec<String>,
|
||||
owner_callsign: Option<String>,
|
||||
) -> String {
|
||||
let mut value: serde_json::Value = match serde_json::from_str(json) {
|
||||
Ok(v) => v,
|
||||
@@ -66,6 +81,9 @@ fn inject_frontend_meta(
|
||||
map.insert("active_rig_id".to_string(), serde_json::json!(rig_id));
|
||||
}
|
||||
map.insert("rig_ids".to_string(), serde_json::json!(rig_ids));
|
||||
if let Some(owner) = owner_callsign {
|
||||
map.insert("owner_callsign".to_string(), serde_json::json!(owner));
|
||||
}
|
||||
|
||||
serde_json::to_string(&value).unwrap_or_else(|_| json.to_string())
|
||||
}
|
||||
@@ -96,6 +114,10 @@ fn rig_ids_from_context(context: &FrontendRuntimeContext) -> Vec<String> {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn owner_callsign_from_context(context: &FrontendRuntimeContext) -> Option<String> {
|
||||
context.owner_callsign.clone()
|
||||
}
|
||||
|
||||
#[get("/events")]
|
||||
pub async fn events(
|
||||
state: web::Data<watch::Receiver<RigState>>,
|
||||
@@ -117,6 +139,7 @@ pub async fn events(
|
||||
rigctl_addr_from_context(context.get_ref().as_ref()),
|
||||
active_rig_id_from_context(context.get_ref().as_ref()),
|
||||
rig_ids_from_context(context.get_ref().as_ref()),
|
||||
owner_callsign_from_context(context.get_ref().as_ref()),
|
||||
);
|
||||
let initial_stream =
|
||||
once(async move { Ok::<Bytes, Error>(Bytes::from(format!("data: {initial_json}\n\n"))) });
|
||||
@@ -136,6 +159,7 @@ pub async fn events(
|
||||
rigctl_addr_from_context(context.as_ref()),
|
||||
active_rig_id_from_context(context.as_ref()),
|
||||
rig_ids_from_context(context.as_ref()),
|
||||
owner_callsign_from_context(context.as_ref()),
|
||||
);
|
||||
Ok::<Bytes, Error>(Bytes::from(format!("data: {json}\n\n")))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user