Extract list key bindings to util
Also refactors the Rooms event handling code a bit
This commit is contained in:
parent
30276fcbbf
commit
c16ad024ed
2 changed files with 157 additions and 102 deletions
203
src/ui/rooms.rs
203
src/ui/rooms.rs
|
|
@ -313,14 +313,9 @@ impl Rooms {
|
||||||
c.is_ascii_alphanumeric() || c == '_'
|
c.is_ascii_alphanumeric() || c == '_'
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
fn list_showlist_key_bindings(bindings: &mut KeyBindingsList) {
|
||||||
match &self.state {
|
|
||||||
State::ShowList => {
|
|
||||||
bindings.heading("Rooms");
|
bindings.heading("Rooms");
|
||||||
bindings.binding("j/k, ↓/↑", "move cursor up/down");
|
util::list_list_key_bindings(bindings);
|
||||||
bindings.binding("g, home", "move cursor to top");
|
|
||||||
bindings.binding("G, end", "move cursor to bottom");
|
|
||||||
bindings.binding("ctrl+y/e", "scroll up/down");
|
|
||||||
bindings.empty();
|
bindings.empty();
|
||||||
bindings.binding("enter", "enter selected room");
|
bindings.binding("enter", "enter selected room");
|
||||||
bindings.binding("c", "connect to selected room");
|
bindings.binding("c", "connect to selected room");
|
||||||
|
|
@ -334,6 +329,96 @@ impl Rooms {
|
||||||
bindings.empty();
|
bindings.empty();
|
||||||
bindings.binding("s", "change sort order");
|
bindings.binding("s", "change sort order");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_showlist_input_event(&mut self, event: &InputEvent) -> bool {
|
||||||
|
if util::handle_list_input_event(&mut self.list, event) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match event {
|
||||||
|
key!(Enter) => {
|
||||||
|
if let Some(name) = self.list.cursor() {
|
||||||
|
self.state = State::ShowRoom(name);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('c') => {
|
||||||
|
if let Some(name) = self.list.cursor() {
|
||||||
|
if let Some(room) = self.euph_rooms.get_mut(&name) {
|
||||||
|
room.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('C') => {
|
||||||
|
for room in self.euph_rooms.values_mut() {
|
||||||
|
room.connect();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('d') => {
|
||||||
|
if let Some(name) = self.list.cursor() {
|
||||||
|
if let Some(room) = self.euph_rooms.get_mut(&name) {
|
||||||
|
room.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('D') => {
|
||||||
|
for room in self.euph_rooms.values_mut() {
|
||||||
|
room.disconnect();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('a') => {
|
||||||
|
for (name, options) in &self.config.euph.rooms {
|
||||||
|
if options.autojoin {
|
||||||
|
self.get_or_insert_room(name.clone()).connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('A') => {
|
||||||
|
for (name, room) in &mut self.euph_rooms {
|
||||||
|
let autojoin = self
|
||||||
|
.config
|
||||||
|
.euph
|
||||||
|
.rooms
|
||||||
|
.get(name)
|
||||||
|
.map(|r| r.autojoin)
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !autojoin {
|
||||||
|
room.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('n') => {
|
||||||
|
self.state = State::Connect(EditorState::new());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('X') => {
|
||||||
|
if let Some(name) = self.list.cursor() {
|
||||||
|
self.state = State::Delete(name, EditorState::new());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
key!('s') => {
|
||||||
|
self.order = match self.order {
|
||||||
|
Order::Alphabet => Order::Importance,
|
||||||
|
Order::Importance => Order::Alphabet,
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn list_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
||||||
|
match &self.state {
|
||||||
|
State::ShowList => Self::list_showlist_key_bindings(bindings),
|
||||||
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
|
||||||
// list_key_bindings function since they may be shadowed by the
|
// list_key_bindings function since they may be shadowed by the
|
||||||
|
|
@ -372,78 +457,11 @@ impl Rooms {
|
||||||
self.stabilize_rooms().await;
|
self.stabilize_rooms().await;
|
||||||
|
|
||||||
match &self.state {
|
match &self.state {
|
||||||
State::ShowList => match event {
|
State::ShowList => {
|
||||||
key!('k') | key!(Up) => self.list.move_cursor_up(),
|
if self.handle_showlist_input_event(event) {
|
||||||
key!('j') | key!(Down) => self.list.move_cursor_down(),
|
return true;
|
||||||
key!('g') | key!(Home) => self.list.move_cursor_to_top(),
|
|
||||||
key!('G') | key!(End) => self.list.move_cursor_to_bottom(),
|
|
||||||
key!(Ctrl + 'y') => self.list.scroll_up(1),
|
|
||||||
key!(Ctrl + 'e') => self.list.scroll_down(1),
|
|
||||||
|
|
||||||
key!(Enter) => {
|
|
||||||
if let Some(name) = self.list.cursor() {
|
|
||||||
self.state = State::ShowRoom(name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key!('c') => {
|
|
||||||
if let Some(name) = self.list.cursor() {
|
|
||||||
if let Some(room) = self.euph_rooms.get_mut(&name) {
|
|
||||||
room.connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key!('C') => {
|
|
||||||
for room in self.euph_rooms.values_mut() {
|
|
||||||
room.connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key!('d') => {
|
|
||||||
if let Some(name) = self.list.cursor() {
|
|
||||||
if let Some(room) = self.euph_rooms.get_mut(&name) {
|
|
||||||
room.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key!('D') => {
|
|
||||||
for room in self.euph_rooms.values_mut() {
|
|
||||||
room.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key!('a') => {
|
|
||||||
for (name, options) in &self.config.euph.rooms {
|
|
||||||
if options.autojoin {
|
|
||||||
self.get_or_insert_room(name.clone()).connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key!('A') => {
|
|
||||||
for (name, room) in &mut self.euph_rooms {
|
|
||||||
let autojoin = self
|
|
||||||
.config
|
|
||||||
.euph
|
|
||||||
.rooms
|
|
||||||
.get(name)
|
|
||||||
.map(|r| r.autojoin)
|
|
||||||
.unwrap_or(false);
|
|
||||||
if !autojoin {
|
|
||||||
room.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key!('n') => self.state = State::Connect(EditorState::new()),
|
|
||||||
key!('X') => {
|
|
||||||
if let Some(name) = self.list.cursor() {
|
|
||||||
self.state = State::Delete(name, EditorState::new());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key!('s') => {
|
|
||||||
self.order = match self.order {
|
|
||||||
Order::Alphabet => Order::Importance,
|
|
||||||
Order::Importance => Order::Alphabet,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
_ => return false,
|
|
||||||
},
|
|
||||||
State::ShowRoom(name) => {
|
State::ShowRoom(name) => {
|
||||||
if let Some(room) = self.euph_rooms.get_mut(name) {
|
if let Some(room) = self.euph_rooms.get_mut(name) {
|
||||||
if room
|
if room
|
||||||
|
|
@ -458,39 +476,46 @@ impl Rooms {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
State::Connect(ed) => match event {
|
State::Connect(ed) => match event {
|
||||||
key!(Esc) => self.state = State::ShowList,
|
key!(Esc) => {
|
||||||
|
self.state = State::ShowList;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
key!(Enter) => {
|
key!(Enter) => {
|
||||||
let name = ed.text();
|
let name = ed.text();
|
||||||
if !name.is_empty() {
|
if !name.is_empty() {
|
||||||
self.get_or_insert_room(name.clone()).connect();
|
self.get_or_insert_room(name.clone()).connect();
|
||||||
self.state = State::ShowRoom(name);
|
self.state = State::ShowRoom(name);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if util::handle_editor_input_event(ed, terminal, event, Self::room_char) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => return util::handle_editor_input_event(ed, terminal, event, Self::room_char),
|
|
||||||
},
|
},
|
||||||
State::Delete(name, editor) => match event {
|
State::Delete(name, editor) => match event {
|
||||||
key!(Esc) => self.state = State::ShowList,
|
key!(Esc) => {
|
||||||
|
self.state = State::ShowList;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
key!(Enter) if editor.text() == *name => {
|
key!(Enter) if editor.text() == *name => {
|
||||||
self.euph_rooms.remove(name);
|
self.euph_rooms.remove(name);
|
||||||
self.vault.euph().delete(name.clone());
|
self.vault.euph().delete(name.clone());
|
||||||
self.state = State::ShowList;
|
self.state = State::ShowList;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return util::handle_editor_input_event(
|
if util::handle_editor_input_event(editor, terminal, event, Self::room_char) {
|
||||||
editor,
|
return true;
|
||||||
terminal,
|
}
|
||||||
event,
|
|
||||||
Self::room_char,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_euph_room_event(&mut self, name: String, event: EuphRoomEvent) -> bool {
|
pub fn handle_euph_room_event(&mut self, name: String, event: EuphRoomEvent) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use toss::terminal::Terminal;
|
||||||
|
|
||||||
use super::input::{key, InputEvent, KeyBindingsList};
|
use super::input::{key, InputEvent, KeyBindingsList};
|
||||||
use super::widgets::editor::EditorState;
|
use super::widgets::editor::EditorState;
|
||||||
|
use super::widgets::list::ListState;
|
||||||
|
|
||||||
pub fn prompt(
|
pub fn prompt(
|
||||||
terminal: &mut Terminal,
|
terminal: &mut Terminal,
|
||||||
|
|
@ -23,6 +24,35 @@ pub fn prompt(
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////
|
||||||
|
// List //
|
||||||
|
//////////
|
||||||
|
|
||||||
|
pub fn list_list_key_bindings(bindings: &mut KeyBindingsList) {
|
||||||
|
bindings.binding("j/k, ↓/↑", "move cursor up/down");
|
||||||
|
bindings.binding("g, home", "move cursor to top");
|
||||||
|
bindings.binding("G, end", "move cursor to bottom");
|
||||||
|
bindings.binding("ctrl+y/e", "scroll up/down");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_list_input_event<Id: Clone>(list: &mut ListState<Id>, event: &InputEvent) -> bool {
|
||||||
|
match event {
|
||||||
|
key!('k') | key!(Up) => list.move_cursor_up(),
|
||||||
|
key!('j') | key!(Down) => list.move_cursor_down(),
|
||||||
|
key!('g') | key!(Home) => list.move_cursor_to_top(),
|
||||||
|
key!('G') | key!(End) => list.move_cursor_to_bottom(),
|
||||||
|
key!(Ctrl + 'y') => list.scroll_up(1),
|
||||||
|
key!(Ctrl + 'e') => list.scroll_down(1),
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////
|
||||||
|
// Editor //
|
||||||
|
////////////
|
||||||
|
|
||||||
fn list_editor_editing_key_bindings(
|
fn list_editor_editing_key_bindings(
|
||||||
bindings: &mut KeyBindingsList,
|
bindings: &mut KeyBindingsList,
|
||||||
char_filter: impl Fn(char) -> bool,
|
char_filter: impl Fn(char) -> bool,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue