fix(android): clarify channel and voice status icons

This commit is contained in:
Edison Jwa
2026-05-20 14:52:34 +09:00
parent 34121b2eb7
commit b21fc16ee6
8 changed files with 154 additions and 21 deletions
+15 -3
View File
@@ -17,7 +17,7 @@
//! * Disconnect is requested via a `oneshot`; the task drains
//! `tsclientlib`'s outbound events and exits.
use std::time::Duration;
use std::time::{Duration, Instant};
use futures::prelude::*;
use std::collections::HashMap;
@@ -36,6 +36,8 @@ use tsproto_types::ClientType;
use crate::dto::{ChannelId, ChannelInfo, ClientId, ClientInfo, ServerSnapshot};
use crate::ProtocolError;
const SPEAKING_ACTIVITY_WINDOW: Duration = Duration::from_millis(750);
/// Pick the TeamSpeak `client_version`/platform/signature triple
/// (sourced from `ReSpeak/tsdeclarations/Versions.csv`, baked into
/// `tsproto-types` at vendor-time) that best matches the *runtime*
@@ -509,6 +511,7 @@ async fn connection_task(
std::time::Instant,
),
> = HashMap::new();
let mut voice_activity: HashMap<u64, Instant> = HashMap::new();
// Main loop: pump events, service requests, forward voice.
loop {
@@ -530,6 +533,7 @@ async fn connection_task(
StreamItem::Audio(buf) => {
let from = packet_sender_id(&buf);
if let Some(from) = from {
voice_activity.insert(from, Instant::now());
if voice_in_tx
.try_send(InboundVoice {
from_client: from,
@@ -612,7 +616,7 @@ async fn connection_task(
// 3. Service at most one control request (non-blocking).
match rx.try_recv() {
Ok(Request::Snapshot(reply)) => {
let snap = build_snapshot(&con);
let snap = build_snapshot(&con, &voice_activity);
let _ = reply.send(snap);
}
Ok(Request::MoveToChannel {
@@ -826,7 +830,10 @@ fn emit_subtree<'a, T>(
}
}
fn build_snapshot(con: &Connection) -> Result<ServerSnapshot, ProtocolError> {
fn build_snapshot(
con: &Connection,
voice_activity: &HashMap<u64, Instant>,
) -> Result<ServerSnapshot, ProtocolError> {
let state: &data::Connection = con
.get_state()
.map_err(|e| ProtocolError::Backend(format!("get_state: {e}")))?;
@@ -874,6 +881,11 @@ fn build_snapshot(con: &Connection) -> Result<ServerSnapshot, ProtocolError> {
id: ClientId(c.id.0 as u64),
channel: ChannelId(c.channel.0),
name: sanitize(&c.name),
input_muted: c.input_muted,
output_muted: c.output_muted || c.output_only_muted,
is_speaking: voice_activity
.get(&(c.id.0 as u64))
.is_some_and(|last| last.elapsed() <= SPEAKING_ACTIVITY_WINDOW),
is_server_query: is_server_query_client_type(&c.client_type),
})
.collect();
+6
View File
@@ -36,6 +36,12 @@ pub struct ClientInfo {
pub channel: ChannelId,
/// Nickname, preserved verbatim per ADR-008.
pub name: String,
/// True when this client has muted microphone/input capture.
pub input_muted: bool,
/// True when this client has muted speaker/output audio.
pub output_muted: bool,
/// True when recent inbound voice activity was observed for this client.
pub is_speaking: bool,
/// True for TeamSpeak ServerQuery clients.
pub is_server_query: bool,
}