feat(daemon): publish room member statistics over RPC and the CLI

The statistics parsed from the JoinRoom reply were reachable only from the
library. They answer the question `room users` already exists to ask -- who
is in here, and are they worth downloading from -- so they belong on its
output rather than behind a second call.

- proto: room.member_stats, with a RoomUserStatsDto carrying status, share
  counts, free slots and country
- SessionApi::room_member_stats, so local and remote sessions stay
  interchangeable; the status word is decoded through one shared helper
  rather than a third copy of the match
- `room users` now emits status, average_speed, shared_files,
  shared_folders, slots_free and country, each null when the server said
  nothing, documented in SKILL.md
- docs/openrpc.json regenerated from the wire types
This commit is contained in:
Michel de Graaf
2026-08-28 13:27:09 +00:00
parent fa49ebd2eb
commit 60f7100e30
12 changed files with 288 additions and 27 deletions
+19 -2
View File
@@ -370,16 +370,33 @@ impl Record for UserRecord {
}
}
/// One member of a chat room.
/// One member of a chat room, with the server's description of them.
///
/// The statistics come from the reply that named the members, and are `None`
/// for a server that sent none — so a consumer never reads "shares nothing"
/// from a missing answer.
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct RoomMemberRecord {
pub room: String,
pub user: String,
/// `online`, `away`, or `offline`.
pub status: Option<String>,
pub average_speed: Option<u32>,
pub shared_files: Option<u32>,
pub shared_folders: Option<u32>,
pub slots_free: Option<u32>,
pub country: Option<String>,
}
impl Record for RoomMemberRecord {
fn text(&self) -> String {
sanitize(&self.user)
let unknown = || "-".to_string();
format!(
"{}\t{}\t{}",
sanitize(&self.user),
self.status.clone().unwrap_or_else(unknown),
self.shared_files.map_or_else(unknown, |v| v.to_string())
)
}
}