Add key binding to change rooms sort order

This commit is contained in:
Joscha 2022-08-27 14:37:34 +02:00
parent c9eee7f1d0
commit ac13f4b490
3 changed files with 49 additions and 11 deletions

View file

@ -21,6 +21,7 @@ Procedure when bumping the version number:
- `euph.rooms.<name>.username` config option - `euph.rooms.<name>.username` config option
- `euph.rooms.<name>.force_username` config option - `euph.rooms.<name>.force_username` config option
- `euph.rooms.<name>.password` config option - `euph.rooms.<name>.password` config option
- Key binding to change rooms sort order
## v0.3.0 - 2022-08-22 ## v0.3.0 - 2022-08-22

View file

@ -47,6 +47,15 @@ pub enum RoomStatus {
Connected(Status), Connected(Status),
} }
impl RoomStatus {
pub fn connecting_or_connected(&self) -> bool {
match self {
Self::NoRoom | Self::Stopped => false,
Self::Connecting | Self::Connected(_) => true,
}
}
}
pub struct EuphRoom { pub struct EuphRoom {
config: config::EuphRoom, config: config::EuphRoom,

View file

@ -33,6 +33,11 @@ enum State {
Connect(EditorState), Connect(EditorState),
} }
enum Order {
Alphabet,
Importance,
}
pub struct Rooms { pub struct Rooms {
config: &'static Config, config: &'static Config,
@ -42,6 +47,7 @@ pub struct Rooms {
state: State, state: State,
list: ListState<String>, list: ListState<String>,
order: Order,
euph_rooms: HashMap<String, EuphRoom>, euph_rooms: HashMap<String, EuphRoom>,
} }
@ -57,6 +63,7 @@ impl Rooms {
ui_event_tx, ui_event_tx,
state: State::ShowList, state: State::ShowList,
list: ListState::new(), list: ListState::new(),
order: Order::Alphabet,
euph_rooms: HashMap::new(), euph_rooms: HashMap::new(),
} }
} }
@ -169,8 +176,8 @@ impl Rooms {
result.join(" ") result.join(" ")
} }
async fn format_status(room: &EuphRoom) -> Option<String> { fn format_status(status: RoomStatus) -> Option<String> {
match room.status().await { match status {
RoomStatus::NoRoom | RoomStatus::Stopped => None, RoomStatus::NoRoom | RoomStatus::Stopped => None,
RoomStatus::Connecting => Some("connecting".to_string()), RoomStatus::Connecting => Some("connecting".to_string()),
RoomStatus::Connected(Status::Joining(j)) if j.bounce.is_some() => { RoomStatus::Connected(Status::Joining(j)) if j.bounce.is_some() => {
@ -181,8 +188,7 @@ impl Rooms {
} }
} }
async fn format_unseen_msgs(room: &EuphRoom) -> Option<String> { fn format_unseen_msgs(unseen: usize) -> Option<String> {
let unseen = room.unseen_msgs_count().await;
if unseen == 0 { if unseen == 0 {
None None
} else { } else {
@ -190,11 +196,11 @@ impl Rooms {
} }
} }
async fn format_room_info(room: &EuphRoom) -> Styled { fn format_room_info(status: RoomStatus, unseen: usize) -> Styled {
let unseen_style = ContentStyle::default().bold().green(); let unseen_style = ContentStyle::default().bold().green();
let status = Self::format_status(room).await; let status = Self::format_status(status);
let unseen = Self::format_unseen_msgs(room).await; let unseen = Self::format_unseen_msgs(unseen);
match (status, unseen) { match (status, unseen) {
(None, None) => Styled::default(), (None, None) => Styled::default(),
@ -210,6 +216,15 @@ impl Rooms {
} }
} }
fn sort_rooms(&self, rooms: &mut [(&String, RoomStatus, usize)]) {
match self.order {
Order::Alphabet => rooms.sort_unstable_by_key(|(n, _, _)| *n),
Order::Importance => {
rooms.sort_unstable_by_key(|(n, s, u)| (!s.connecting_or_connected(), *u == 0, *n))
}
}
}
async fn render_rows(&self, list: &mut List<String>) { async fn render_rows(&self, list: &mut List<String>) {
if self.euph_rooms.is_empty() { if self.euph_rooms.is_empty() {
list.add_unsel(Text::new(( list.add_unsel(Text::new((
@ -218,16 +233,21 @@ impl Rooms {
))) )))
} }
let mut rooms = self.euph_rooms.iter().collect::<Vec<_>>(); let mut rooms = vec![];
rooms.sort_by_key(|(n, _)| *n); for (name, room) in &self.euph_rooms {
for (name, room) in rooms { let status = room.status().await;
let unseen = room.unseen_msgs_count().await;
rooms.push((name, status, unseen));
}
self.sort_rooms(&mut rooms);
for (name, status, unseen) in rooms {
let room_style = ContentStyle::default().bold().blue(); let room_style = ContentStyle::default().bold().blue();
let room_sel_style = ContentStyle::default().bold().black().on_white(); let room_sel_style = ContentStyle::default().bold().black().on_white();
let mut normal = Styled::new(format!("&{name}"), room_style); let mut normal = Styled::new(format!("&{name}"), room_style);
let mut selected = Styled::new(format!("&{name}"), room_sel_style); let mut selected = Styled::new(format!("&{name}"), room_sel_style);
let info = Self::format_room_info(room).await; let info = Self::format_room_info(status, unseen);
normal = normal.and_then(info.clone()); normal = normal.and_then(info.clone());
selected = selected.and_then(info); selected = selected.and_then(info);
@ -265,6 +285,8 @@ impl Rooms {
bindings.binding("C", "connect to new room"); bindings.binding("C", "connect to new room");
bindings.binding("d", "disconnect from selected room"); bindings.binding("d", "disconnect from selected room");
bindings.binding("D", "delete room"); bindings.binding("D", "delete room");
bindings.empty();
bindings.binding("s", "change sort order");
} }
State::ShowRoom(name) => { State::ShowRoom(name) => {
// Key bindings for leaving the room are a part of the room's // Key bindings for leaving the room are a part of the room's
@ -333,6 +355,12 @@ impl Rooms {
self.vault.euph(name.clone()).delete(); self.vault.euph(name.clone()).delete();
} }
} }
key!('s') => {
self.order = match self.order {
Order::Alphabet => Order::Importance,
Order::Importance => Order::Alphabet,
};
}
_ => return false, _ => return false,
}, },
State::ShowRoom(name) => { State::ShowRoom(name) => {