From fa961382dd3180eb416094120a28bbfe2f25a63e Mon Sep 17 00:00:00 2001 From: Sam Sartor Date: Fri, 28 Nov 2025 01:45:10 -0700 Subject: [PATCH] Use relative url for status --- common/src/lib.rs | 1 - gui/src/app.rs | 20 +------------- gui/src/imp/desktop.rs | 63 +++++++++++++++++++++++++++--------------- gui/src/imp/web.rs | 11 +++++++- proxy/src/main.rs | 8 +----- 5 files changed, 52 insertions(+), 51 deletions(-) diff --git a/common/src/lib.rs b/common/src/lib.rs index 87c3c72..0d520a5 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -3,7 +3,6 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct ClientConfig { pub proxy_url: Option, - pub status_url: Option, pub cert_hash: Option>, pub any_server: bool, } diff --git a/gui/src/app.rs b/gui/src/app.rs index f6f2f34..c6f6c78 100644 --- a/gui/src/app.rs +++ b/gui/src/app.rs @@ -545,33 +545,15 @@ pub fn ServerView(config: Resource) -> Element { ) } -async fn get_status( - client: &reqwest::Client, - status_url: &str, -) -> color_eyre::Result { - Ok(client - .get(status_url) - .send() - .await? - .json::() - .await?) -} - #[component] pub fn LoginView(config: Resource) -> Element { let net: Coroutine = use_coroutine_handle(); let last_status = use_signal(|| None::>); use_resource(move || async move { - let Some(config) = config.read().clone() else { - return; - }; - let Some(status_url) = config.status_url else { - return; - }; let client = reqwest::Client::new(); loop { - *last_status.write_unchecked() = Some(get_status(&client, &status_url).await); + *last_status.write_unchecked() = Some(imp::get_status(&client).await); imp::sleep(std::time::Duration::from_secs_f32(1.0)).await; } }); diff --git a/gui/src/imp/desktop.rs b/gui/src/imp/desktop.rs index 8e21adc..8337718 100644 --- a/gui/src/imp/desktop.rs +++ b/gui/src/imp/desktop.rs @@ -1,11 +1,11 @@ use crate::app::Command; use crate::effects::{AudioProcessor, AudioProcessorSender}; -use color_eyre::eyre::{eyre, Context, Error}; +use color_eyre::eyre::{bail, eyre, Context, Error}; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait as _}; use dioxus::hooks::UnboundedReceiver; use futures::io::{AsyncRead, AsyncWrite}; use mumble_protocol::control::ClientControlCodec; -use mumble_web2_common::ClientConfig; +use mumble_web2_common::{ClientConfig, ServerStatus}; use std::mem::replace; use std::net::ToSocketAddrs; use std::sync::Arc; @@ -64,26 +64,34 @@ impl AudioSystem { self.processors.store(Some(processor)) } - fn choose_config(&self, configs: impl Iterator) -> Result { + fn choose_config( + &self, + configs: impl Iterator, + ) -> Result { let mut supported_configs: Vec<_> = configs .filter_map(|cfg| cfg.try_with_sample_rate(cpal::SampleRate(SAMPLE_RATE))) .filter(|cfg| cfg.sample_format() == cpal::SampleFormat::I16) - .map(|cfg| { - cpal::StreamConfig { - buffer_size: cpal::BufferSize::Fixed(match *cfg.buffer_size() { - cpal::SupportedBufferSize::Range { min, max } => 480.clamp(min, max), - cpal::SupportedBufferSize::Unknown => 480, - }), - ..cfg.config() - } + .map(|cfg| cpal::StreamConfig { + buffer_size: cpal::BufferSize::Fixed(match *cfg.buffer_size() { + cpal::SupportedBufferSize::Range { min, max } => 480.clamp(min, max), + cpal::SupportedBufferSize::Unknown => 480, + }), + ..cfg.config() }) .collect(); supported_configs.sort_by(|a, b| { - let cpal::BufferSize::Fixed(a_buf) = a.buffer_size else { unreachable!() }; - let cpal::BufferSize::Fixed(b_buf) = b.buffer_size else { unreachable!() }; + let cpal::BufferSize::Fixed(a_buf) = a.buffer_size else { + unreachable!() + }; + let cpal::BufferSize::Fixed(b_buf) = b.buffer_size else { + unreachable!() + }; Ord::cmp(&a.channels, &b.channels).then(Ord::cmp(&a_buf, &b_buf)) }); - supported_configs.get(0).cloned().ok_or(eyre!("no supported stream configs")) + supported_configs + .get(0) + .cloned() + .ok_or(eyre!("no supported stream configs")) } pub fn start_recording( @@ -91,7 +99,11 @@ impl AudioSystem { mut each: impl FnMut(Vec) + Send + 'static, ) -> Result<(), Error> { let config = self.choose_config(self.input.supported_input_configs()?)?; - info!("creating recording on {:?} with {:#?}", self.input.name()?, config); + info!( + "creating recording on {:?} with {:#?}", + self.input.name()?, + config + ); let mut encoder = opus::Encoder::new(SAMPLE_RATE, opus::Channels::Mono, opus::Application::Voip)?; let mut current_processor = AudioProcessor::new_plain(); @@ -118,12 +130,10 @@ impl AudioSystem { } }; - match self.input.build_input_stream( - &config, - data_callback, - error_callback, - None, - ) { + match self + .input + .build_input_stream(&config, data_callback, error_callback, None) + { Ok(stream) => { stream.play()?; self.recording_stream = Some(stream); @@ -138,7 +148,11 @@ impl AudioSystem { pub fn create_player(&mut self) -> Result { let config = self.choose_config(self.input.supported_input_configs()?)?; - info!("creating player on {:?} with {:#?}", self.output.name().ok(), &config); + info!( + "creating player on {:?} with {:#?}", + self.output.name().ok(), + &config + ); let buffer = Arc::new(Mutex::new(dasp_ring_buffer::Bounded::from_raw_parts( 0, 0, @@ -311,12 +325,15 @@ pub fn load_username() -> Option { pub async fn load_config() -> color_eyre::Result { Ok(ClientConfig { proxy_url: None, - status_url: None, cert_hash: None, any_server: true, }) } +pub async fn get_status(client: &reqwest::Client) -> color_eyre::Result { + bail!("status not supported on desktop yet") +} + pub fn init_logging() { use tracing::level_filters::LevelFilter; use tracing_subscriber::filter::EnvFilter; diff --git a/gui/src/imp/web.rs b/gui/src/imp/web.rs index 9272158..297c323 100644 --- a/gui/src/imp/web.rs +++ b/gui/src/imp/web.rs @@ -6,7 +6,7 @@ use futures::{AsyncRead, AsyncWrite}; use gloo_timers::future::TimeoutFuture; use js_sys::Float32Array; use mumble_protocol::control::ClientControlCodec; -use mumble_web2_common::ClientConfig; +use mumble_web2_common::{ClientConfig, ServerStatus}; use reqwest::Url; use std::future::Future; use std::time::Duration; @@ -426,6 +426,15 @@ pub async fn load_config() -> color_eyre::Result { Ok(config) } +pub async fn get_status(client: &reqwest::Client) -> color_eyre::Result { + Ok(client + .get(absolute_url("status")?) + .send() + .await? + .json::() + .await?) +} + pub fn init_logging() { // copied from tracing_web example usage diff --git a/proxy/src/main.rs b/proxy/src/main.rs index 35031cf..90def5e 100644 --- a/proxy/src/main.rs +++ b/proxy/src/main.rs @@ -1,10 +1,6 @@ use color_eyre::eyre::{anyhow, bail, Context, Result}; -use color_eyre::owo_colors::OwoColorize; use mumble_web2_common::{ClientConfig, ServerStatus}; -use once_cell::sync::OnceCell; use rand::Rng; -use rcgen::date_time_ymd; -use rustls::server; use salvo::conn::rustls::{Keycert, RustlsConfig}; use salvo::cors::{AllowOrigin, Cors}; use salvo::logging::Logger; @@ -38,7 +34,6 @@ fn default_cert_alt_names() -> Vec { #[derive(Debug, Deserialize, Serialize)] struct Config { - public_url: Url, proxy_url: Option, https_listen_address: SocketAddr, http_listen_address: Option, @@ -85,9 +80,8 @@ async fn main() -> Result<()> { let mut client_config = ClientConfig { proxy_url: match &server_config.proxy_url { Some(url) => Some(url.to_string()), - None => Some(server_config.public_url.join("proxy")?.to_string()), + None => None, }, - status_url: Some(server_config.public_url.join("status")?.to_string()), cert_hash: None, any_server: false, };