fix: auto codec, force-ping button, relay delete button
Some checks failed
Mirror to GitHub / mirror (push) Failing after 36s
Build Release Binaries / build-amd64 (push) Failing after 1m57s

1. Auto codec: new "Auto" position on quality slider (JNI index 7).
   When selected, the engine uses the relay's chosen_profile from
   CallAnswer instead of the local preference. Slider now has 8
   positions: Studio 64k → Auto → Codec2 1.2k.

2. Force ping: added refresh button (↻) in Manage Relays dialog
   header. Calls pingAllServers() to re-check all relays on demand.

3. Delete relay fix: the X button was inside a Surface(onClick=...)
   which swallowed the touch event. Replaced with a separate Surface
   that properly intercepts the click.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-07 21:22:24 +04:00
parent c8bcc5c974
commit d06cf66538
4 changed files with 65 additions and 30 deletions

View File

@@ -38,6 +38,8 @@ fn frame_samples_for(profile: &QualityProfile) -> usize {
/// Configuration to start a call.
pub struct CallStartConfig {
pub profile: QualityProfile,
/// When true, use the relay's chosen_profile from CallAnswer instead of local profile.
pub auto_profile: bool,
pub relay_addr: String,
pub room: String,
pub auth_token: Vec<u8>,
@@ -49,6 +51,7 @@ impl Default for CallStartConfig {
fn default() -> Self {
Self {
profile: QualityProfile::GOOD,
auto_profile: false,
relay_addr: String::new(),
room: String::new(),
auth_token: Vec::new(),
@@ -126,6 +129,7 @@ impl WzpEngine {
let room = config.room.clone();
let identity_seed = config.identity_seed;
let profile = config.profile;
let auto_profile = config.auto_profile;
let alias = config.alias.clone();
let state = self.state.clone();
@@ -134,7 +138,7 @@ impl WzpEngine {
let state_clone = state.clone();
runtime.block_on(async move {
if let Err(e) = run_call(relay_addr, &room, &identity_seed, profile, alias.as_deref(), state_clone).await
if let Err(e) = run_call(relay_addr, &room, &identity_seed, profile, auto_profile, alias.as_deref(), state_clone).await
{
error!("call failed: {e}");
}
@@ -277,6 +281,7 @@ async fn run_call(
room: &str,
identity_seed: &[u8; 32],
profile: QualityProfile,
auto_profile: bool,
alias: Option<&str>,
state: Arc<EngineState>,
) -> Result<(), anyhow::Error> {
@@ -328,8 +333,8 @@ async fn run_call(
.await?
.ok_or_else(|| anyhow::anyhow!("connection closed before CallAnswer"))?;
let relay_ephemeral_pub = match answer {
SignalMessage::CallAnswer { ephemeral_pub, .. } => ephemeral_pub,
let (relay_ephemeral_pub, chosen_profile) = match answer {
SignalMessage::CallAnswer { ephemeral_pub, chosen_profile, .. } => (ephemeral_pub, chosen_profile),
other => {
return Err(anyhow::anyhow!(
"expected CallAnswer, got {:?}",
@@ -338,8 +343,16 @@ async fn run_call(
}
};
// Auto mode: use the relay's chosen profile instead of the local preference
let profile = if auto_profile {
info!(chosen = ?chosen_profile.codec, "auto mode: using relay's chosen profile");
chosen_profile
} else {
profile
};
let _session = kx.derive_session(&relay_ephemeral_pub)?;
info!("handshake complete, call active");
info!(codec = ?profile.codec, "handshake complete, call active");
{
let mut stats = state.stats.lock().unwrap();

View File

@@ -21,6 +21,9 @@ unsafe fn handle_ref(handle: jlong) -> &'static mut EngineHandle {
unsafe { &mut *(handle as *mut EngineHandle) }
}
/// 7 = auto (use relay's chosen profile)
const PROFILE_AUTO: jint = 7;
fn profile_from_int(value: jint) -> QualityProfile {
match value {
0 => QualityProfile::GOOD, // Opus 24k
@@ -35,7 +38,7 @@ fn profile_from_int(value: jint) -> QualityProfile {
4 => QualityProfile::STUDIO_32K, // Opus 32k
5 => QualityProfile::STUDIO_48K, // Opus 48k
6 => QualityProfile::STUDIO_64K, // Opus 64k
_ => QualityProfile::GOOD,
_ => QualityProfile::GOOD, // auto falls back to GOOD
}
}
@@ -122,6 +125,7 @@ pub unsafe extern "system" fn Java_com_wzp_engine_WzpEngine_nativeStartCall(
let config = CallStartConfig {
profile: profile_from_int(profile_j),
auto_profile: profile_j == PROFILE_AUTO,
relay_addr,
room,
auth_token: if token.is_empty() { Vec::new() } else { token.into_bytes() },