#[cfg(feature = "serve")]
use std::net::SocketAddr;
#[cfg(feature = "serve")]
use futures_util::SinkExt;
#[cfg(feature = "serve")]
use tokio_tungstenite::tungstenite::Message;
use crate::{
Result,
view::{View, component, view},
};
#[cfg(feature = "serve")]
pub async fn notify_ready(addr: Option<SocketAddr>) {
let Ok(base) = std::env::var("TOPCOAT_DEV_URL") else {
return;
};
let ws_url = http_to_ws(&base) + "/ws";
let Ok((mut ws, _)) = tokio_tungstenite::connect_async(&ws_url).await else {
eprintln!("topcoat dev: failed to connect to {ws_url}");
return;
};
let text = match addr {
Some(addr) => format!("ready {addr}"),
None => "ready".to_owned(),
};
let _ = ws.send(Message::Text(text.into())).await;
let _ = ws.close(None).await;
}
#[cfg(feature = "serve")]
fn http_to_ws(url: &str) -> String {
if let Some(rest) = url.strip_prefix("http://") {
format!("ws://{rest}")
} else if let Some(rest) = url.strip_prefix("https://") {
format!("wss://{rest}")
} else {
url.to_string()
}
}
#[component]
pub async fn script(#[default(true)] status_indicator: bool) -> Result<impl View> {
let src = std::env::var("TOPCOAT_DEV_URL")
.ok()
.map(|base| format!("{base}/dev.js"));
let indicator_off = (!status_indicator).then_some("false");
Ok(view! {
if let Some(src) = src {
<script src=(src) data-status-indicator=(indicator_off)></script>
}
})
}