chore: restore product scaffold to rollback baseline

This commit is contained in:
Edison Jwa
2026-05-29 14:02:04 +09:00
parent 2896f14ec9
commit fe6e07353e
434 changed files with 27278 additions and 63230 deletions
+117 -13
View File
@@ -355,8 +355,6 @@ pub struct BridgeChannel {
pub struct BridgeClient {
/// Stable client id.
pub id: u64,
/// Stable TeamSpeak unique identifier.
pub uid: String,
/// Channel id the client is currently in.
pub channel: u64,
/// Nickname.
@@ -375,6 +373,61 @@ pub struct BridgeClient {
pub talk_power_granted: bool,
}
/// Rich profile and live connection details for one online client.
#[derive(Debug, Clone)]
pub struct BridgeClientProfile {
/// Stable online client id.
pub id: u64,
/// Channel the client is currently in.
pub channel: u64,
/// Nickname.
pub name: String,
/// TeamSpeak unique id.
pub unique_id: String,
/// Stable TeamSpeak database id, when visible.
pub database_id: Option<u64>,
/// ISO country code, when visible.
pub country_code: String,
/// User description, when visible.
pub description: String,
/// Client version string.
pub version: String,
/// Client platform string.
pub platform: String,
/// Account creation time as Unix seconds.
pub created_unix_seconds: Option<i64>,
/// Last connection time as Unix seconds.
pub last_connected_unix_seconds: Option<i64>,
/// Total historical connections.
pub connections_total: Option<u64>,
/// Current online duration in seconds.
pub online_seconds: Option<i64>,
/// Current idle time in milliseconds.
pub idle_milliseconds: Option<i64>,
/// Current ping in milliseconds.
pub ping_milliseconds: Option<i64>,
/// Client address. Empty when permission-gated.
pub client_address: String,
/// Resolved server group names.
pub server_groups: Vec<String>,
/// Resolved channel group name.
pub channel_group: String,
/// TeamSpeak avatar file path suffix.
pub avatar_path: String,
/// Downloaded bytes this month.
pub bytes_downloaded_month: Option<u64>,
/// Uploaded bytes this month.
pub bytes_uploaded_month: Option<u64>,
/// Downloaded bytes across all time.
pub bytes_downloaded_total: Option<u64>,
/// Uploaded bytes across all time.
pub bytes_uploaded_total: Option<u64>,
/// Client-to-server total packet loss ratio.
pub packet_loss_client_to_server_total: Option<f32>,
/// Server-to-client total packet loss ratio.
pub packet_loss_server_to_client_total: Option<f32>,
}
/// Server snapshot as seen by Dart.
#[derive(Debug, Clone)]
pub struct BridgeSnapshot {
@@ -396,6 +449,38 @@ pub struct BridgeSnapshot {
pub own_client_id: u64,
}
impl From<chanora_core::ClientProfile> for BridgeClientProfile {
fn from(profile: chanora_core::ClientProfile) -> Self {
Self {
id: profile.id.0,
channel: profile.channel.0,
name: profile.name,
unique_id: profile.unique_id,
database_id: profile.database_id,
country_code: profile.country_code,
description: profile.description,
version: profile.version,
platform: profile.platform,
created_unix_seconds: profile.created_unix_seconds,
last_connected_unix_seconds: profile.last_connected_unix_seconds,
connections_total: profile.connections_total,
online_seconds: profile.online_seconds,
idle_milliseconds: profile.idle_milliseconds,
ping_milliseconds: profile.ping_milliseconds,
client_address: profile.client_address,
server_groups: profile.server_groups,
channel_group: profile.channel_group,
avatar_path: profile.avatar_path,
bytes_downloaded_month: profile.bytes_downloaded_month,
bytes_uploaded_month: profile.bytes_uploaded_month,
bytes_downloaded_total: profile.bytes_downloaded_total,
bytes_uploaded_total: profile.bytes_uploaded_total,
packet_loss_client_to_server_total: profile.packet_loss_client_to_server_total,
packet_loss_server_to_client_total: profile.packet_loss_server_to_client_total,
}
}
}
impl From<chanora_core::ServerSnapshot> for BridgeSnapshot {
fn from(s: chanora_core::ServerSnapshot) -> Self {
Self {
@@ -420,7 +505,6 @@ impl From<chanora_core::ServerSnapshot> for BridgeSnapshot {
.into_iter()
.map(|c| BridgeClient {
id: c.id.0,
uid: c.uid,
channel: c.channel.0,
name: c.name,
input_muted: c.input_muted,
@@ -459,6 +543,7 @@ pub async fn connect(
},
identity: None,
ready_timeout: Duration::from_secs(15),
resolved_address: None,
};
let snap = match runtime()
.spawn(async move { session().connect(cfg).await })
@@ -475,6 +560,17 @@ pub async fn connect(
Ok(snap.into())
}
/// Warm server address resolution for the active host field. This is
/// intentionally fire-and-forget from the UI perspective: it schedules
/// Rust-side prefetch work and never opens a TS3 session.
pub async fn prefetch_server(host: String) -> Result<(), BridgeError> {
runtime()
.spawn(async move { session().prefetch_server(host).await })
.await
.map_err(|e| task_join_error("prefetch_server", e))??;
Ok(())
}
/// Re-fetch a fresh snapshot from the active connection.
pub async fn snapshot() -> Result<BridgeSnapshot, BridgeError> {
let snap = runtime()
@@ -484,6 +580,15 @@ pub async fn snapshot() -> Result<BridgeSnapshot, BridgeError> {
Ok(snap.into())
}
/// Fetch richer profile and live connection details for one online client.
pub async fn client_profile(client_id: u64) -> Result<BridgeClientProfile, BridgeError> {
let profile = runtime()
.spawn(async move { session().client_profile(client_id).await })
.await
.map_err(|e| task_join_error("client_profile", e))??;
Ok(profile.into())
}
/// Disconnect from the server. No-op if not connected.
pub async fn disconnect() -> Result<(), BridgeError> {
runtime()
@@ -816,9 +921,10 @@ pub async fn set_input_muted(muted: bool) -> Result<(), BridgeError> {
Ok(())
}
/// Toggle self output-mute (speaker). Mutes locally, informs the
/// server, and clamps local microphone transmit while speaker mute
/// is active so the user cannot continue talking while deafened.
/// Toggle self output-mute (speaker). Mutes locally *and* informs
/// the server. The server uses this for the channel icon next to
/// the client name; the local mute kicks in immediately even
/// before the server acknowledges.
pub async fn set_output_muted(muted: bool) -> Result<(), BridgeError> {
runtime()
.spawn(async move { session().set_self_muted(None, Some(muted)).await })
@@ -1229,7 +1335,8 @@ impl From<chanora_core::AudioProcessingStats> for BridgeAudioProcessingStats {
/// On non-Android targets or before a voice session opens the
/// section is omitted. Per SDD-090 every field in that section is
/// a device-side technical scalar — no PII admitted.
pub async fn export_diagnostics() -> String {
#[frb(sync)]
pub fn export_diagnostics() -> String {
let metadata = vec![
(
"crate_version".to_string(),
@@ -1245,15 +1352,12 @@ pub async fn export_diagnostics() -> String {
// diagnostics snapshot from the process-global slot published
// by AndroidVoiceUnit::open(). Returns None on non-Android and
// before any voice session has opened.
#[cfg(target_os = "android")]
let android_audio_yaml =
chanora_audio::mobile_voice_backend::current_android_audio_diagnostics()
.map(|d| d.to_yaml_fragment());
#[cfg(not(target_os = "android"))]
let android_audio_yaml: Option<String> = None;
let audio_health = session().audio_processing_stats().await.ok();
let network_info = session().network_diagnostics_summary().await;
let protocol_events = session().drain_protocol_events().await;
let audio_health = session().audio_processing_stats_if_ready();
let network_info = runtime().block_on(async { session().network_diagnostics_summary().await });
let protocol_events = runtime().block_on(async { session().protocol_events_snapshot().await });
let android_audio_yaml = android_audio_yaml.map(|mut yaml| {
if let Some(stats) = audio_health {
yaml.push_str(&format!(