List pagination and html tables
This commit is contained in:
parent
0328932c54
commit
5443768b5c
1 changed files with 59 additions and 14 deletions
|
@ -33,6 +33,8 @@ use crate::{
|
|||
|
||||
use super::pdu::PduBuilder;
|
||||
|
||||
const PAGE_SIZE: usize = 100;
|
||||
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
#[derive(Parser)]
|
||||
#[command(name = "@conduit:server.name:", version = env!("CARGO_PKG_VERSION"))]
|
||||
|
@ -164,7 +166,9 @@ enum UserCommand {
|
|||
#[derive(Subcommand)]
|
||||
enum RoomCommand {
|
||||
/// List all rooms the server knows about
|
||||
List,
|
||||
List {
|
||||
page: Option<usize>,
|
||||
},
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Manage rooms' aliases
|
||||
|
@ -227,7 +231,9 @@ enum RoomDirectoryCommand {
|
|||
|
||||
/// List rooms that are published
|
||||
// TODO: is this really necessary?
|
||||
List,
|
||||
List {
|
||||
page: Option<usize>,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
|
@ -733,26 +739,46 @@ impl Service {
|
|||
},
|
||||
}
|
||||
AdminCommand::Room(command) => match command {
|
||||
RoomCommand::List => {
|
||||
RoomCommand::List { page } => {
|
||||
// TODO: i know there's a way to do this with clap, but i can't seem to find it
|
||||
let page = page.unwrap_or(1);
|
||||
let mut rooms = services().rooms.metadata.iter_ids()
|
||||
.filter_map(|r| r.ok())
|
||||
.map(|id| (
|
||||
id.clone(),
|
||||
services().rooms.state_accessor.get_name(&id).ok().flatten().unwrap_or(id.to_string()),
|
||||
services().rooms.state_cache.room_joined_count(&id).ok().flatten().unwrap_or(0),
|
||||
services().rooms.state_accessor.get_name(&id).ok().flatten().unwrap_or(id.to_string()),
|
||||
))
|
||||
.collect::<Vec<_>>();
|
||||
rooms.sort_by_key(|r| r.2);
|
||||
rooms.sort_by_key(|r| r.1);
|
||||
rooms.reverse();
|
||||
let output = format!(
|
||||
|
||||
let slice_start = page.saturating_sub(1) * PAGE_SIZE;
|
||||
let Some(rooms) = rooms.get(slice_start..slice_start + PAGE_SIZE) else {
|
||||
return Ok(RoomMessageEventContent::text_plain("No more rooms."));
|
||||
};
|
||||
|
||||
let output_plain = format!(
|
||||
"Rooms:\n{}",
|
||||
rooms
|
||||
.iter()
|
||||
.map(|(id, name, members)| format!("{id}\tName: {name}\tMembers: {members}"))
|
||||
.map(|(id, members, name)| format!("{id}\tMembers: {members}\tName: {name}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
);
|
||||
RoomMessageEventContent::text_plain(output)
|
||||
let output_html = format!(
|
||||
"<table><caption>Room list - page {page}</caption>\n<tr><th>id</th>\t<th>name</th>\t<th>members</th></tr>\n{}</table>",
|
||||
rooms
|
||||
.iter()
|
||||
.map(|(id, members, name)| format!(
|
||||
"<tr><td>{}</td>\t<td>{}</td>\t<td>{}</td></tr>\n",
|
||||
escape_html(&id.to_string()),
|
||||
members,
|
||||
escape_html(name),
|
||||
))
|
||||
.collect::<String>()
|
||||
);
|
||||
RoomMessageEventContent::text_html(output_plain, output_html)
|
||||
}
|
||||
// TODO: clean up and deduplicate code
|
||||
RoomCommand::Alias(command) => {
|
||||
|
@ -853,26 +879,45 @@ impl Service {
|
|||
Ok(()) => RoomMessageEventContent::text_plain("Room unpublished"),
|
||||
Err(err) => RoomMessageEventContent::text_plain(&format!("Unable to update room: {}", err)),
|
||||
}
|
||||
RoomDirectoryCommand::List => {
|
||||
RoomDirectoryCommand::List { page } => {
|
||||
let page = page.unwrap_or(1);
|
||||
let mut rooms = services().rooms.directory.public_rooms()
|
||||
.filter_map(|r| r.ok())
|
||||
.map(|id| (
|
||||
id.clone(),
|
||||
services().rooms.state_accessor.get_name(&id).ok().flatten().unwrap_or(id.to_string()),
|
||||
services().rooms.state_cache.room_joined_count(&id).ok().flatten().unwrap_or(0),
|
||||
services().rooms.state_accessor.get_name(&id).ok().flatten().unwrap_or(id.to_string()),
|
||||
))
|
||||
.collect::<Vec<_>>();
|
||||
rooms.sort_by_key(|r| r.2);
|
||||
rooms.sort_by_key(|r| r.1);
|
||||
rooms.reverse();
|
||||
let output = format!(
|
||||
|
||||
let slice_start = page.saturating_sub(1) * PAGE_SIZE;
|
||||
let Some(rooms) = rooms.get(slice_start..slice_start + PAGE_SIZE) else {
|
||||
return Ok(RoomMessageEventContent::text_plain("No more rooms."));
|
||||
};
|
||||
|
||||
let output_plain = format!(
|
||||
"Rooms:\n{}",
|
||||
rooms
|
||||
.iter()
|
||||
.map(|(id, name, members)| format!("{id}\tName: {name}\tMembers: {members}"))
|
||||
.map(|(id, members, name)| format!("{id}\tMembers: {members}\tName: {name}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
);
|
||||
RoomMessageEventContent::text_plain(output)
|
||||
let output_html = format!(
|
||||
"<table><caption>Room directory - page {page}</caption>\n<tr><th>id</th>\t<th>name</th>\t<th>members</th></tr>\n{}</table>",
|
||||
rooms
|
||||
.iter()
|
||||
.map(|(id, members, name)| format!(
|
||||
"<tr><td>{}</td>\t<td>{}</td>\t<td>{}</td></tr>\n",
|
||||
escape_html(&id.to_string()),
|
||||
members,
|
||||
escape_html(name),
|
||||
))
|
||||
.collect::<String>()
|
||||
);
|
||||
RoomMessageEventContent::text_html(output_plain, output_html)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue