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
+11
View File
@@ -151,10 +151,21 @@ pub fn room_users(ctx: &Ctx, room: &str, timeout: Duration) -> CliResult {
timeout.as_secs()
)));
};
// The stats ride along with the membership the server sent, so they are
// already here; a server that sent none leaves every field null rather
// than reporting a zero that reads like an answer.
let stats = session.client.room_member_stats(room);
for user in members {
let stat = stats.iter().find(|s| s.username == user);
ctx.out.emit(&RoomMemberRecord {
room: room.to_string(),
user,
status: stat.map(|s| s.status.to_string()),
average_speed: stat.map(|s| s.average_speed),
shared_files: stat.map(|s| s.shared_files),
shared_folders: stat.map(|s| s.shared_folders),
slots_free: stat.map(|s| s.slots_free),
country: stat.and_then(|s| s.country.clone()),
});
}
Ok(())