diff options
Diffstat (limited to 'src/tui/accounts.rs')
-rw-r--r-- | src/tui/accounts.rs | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/tui/accounts.rs b/src/tui/accounts.rs new file mode 100644 index 0000000..a43028c --- /dev/null +++ b/src/tui/accounts.rs @@ -0,0 +1,169 @@ +use std::{cell::RefCell, rc::Rc}; + +use cursive::{ + view::Nameable, + views::{Button, Dialog, LinearLayout, SelectView, TextArea}, + Cursive, +}; + +use crate::ipc::{ + DeleteAccountRequest, GetAccountRequest, ListAccountsRequest, UpdateScopesRequest, +}; + +use super::{CursiveIpc, ToTextView, ViewExt}; + +pub fn show(siv: &mut Cursive) { + if let Some(accounts) = siv.ipc(ListAccountsRequest {}) { + siv.add_layer( + SelectView::new() + .autojump() + .with_all_str(accounts.names) + .on_submit(|siv, name: &str| { + manage_account(siv, name); + }) + .float("accounts"), + ); + } +} + +fn manage_account(siv: &mut Cursive, name: &str) { + let name = name.to_string(); + if let Some(_) = siv.ipc(GetAccountRequest { name: name.clone() }) { + siv.add_layer( + LinearLayout::vertical() + .child({ + let name = name.clone(); + enum SelectOption { + Back, + Scopes, + Delete, + } + SelectView::new() + .item("back", SelectOption::Back) + .item("scopes", SelectOption::Scopes) + .item("delete", SelectOption::Delete) + .on_submit(move |siv, opt| match opt { + SelectOption::Back => { + siv.pop_layer(); + } + SelectOption::Scopes => edit_scopes(siv, &name), + SelectOption::Delete => delete_account(siv, &name), + }) + }) + .float(&name), + ) + } +} + +fn edit_scopes(siv: &mut Cursive, name: &str) { + let name = name.to_string(); + let Some(account) = siv.ipc(GetAccountRequest { name: name.clone() }) else { + siv.pop_layer(); + return; // it was just there! + }; + let scopes = Rc::new(RefCell::new(account.scopes)); + enum SelectOption { + Scope(String), + Back, + Add, + } + siv.add_layer( + SelectView::new() + .autojump() + .item("back", SelectOption::Back) + .item("add", SelectOption::Add) + .with_all( + scopes + .clone() + .borrow() + .iter() + .map(|scope| (scope.to_string(), SelectOption::Scope(scope.clone()))), + ) + .on_submit(move |siv, opt| { + match opt { + SelectOption::Scope(scope) => { + let mut scopes = scopes.borrow_mut(); + let index = scopes + .iter() + .enumerate() + .find(|(_, check)| *check == scope) + .unwrap() + .0; + scopes.swap_remove(index); + ipc_update_scopes(siv, &name, &scopes); + siv.pop_layer(); + edit_scopes(siv, &name); + } + SelectOption::Back => { + siv.pop_layer(); + } + SelectOption::Add => add_scope(siv, name.clone(), scopes.clone()), + }; + }) + .float("edit scopes"), + ); +} + +fn add_scope(siv: &mut Cursive, name: String, scopes: Rc<RefCell<Vec<String>>>) { + siv.add_layer( + LinearLayout::vertical() + .child(TextArea::new().with_name("scope")) + .child(Button::new("add", { + move |siv| { + let text_area = siv.find_name::<TextArea>("scope").unwrap(); + let scope = text_area.get_content(); + if scope.is_empty() { + siv.pop_layer(); + return; + } + let mut scopes = scopes.borrow_mut(); + scopes.push(scope.to_string()); + ipc_update_scopes(siv, &name, &scopes); + siv.pop_layer(); + siv.pop_layer(); + edit_scopes(siv, &name); + } + })) + .float("add scope"), + ) +} + +fn ipc_update_scopes(siv: &mut Cursive, name: &str, scopes: &Vec<String>) { + siv.ipc(UpdateScopesRequest { + account: name.to_string(), + scopes: scopes.clone(), + }); +} + +fn delete_account(siv: &mut Cursive, name: &str) { + let name = name.to_string(); + siv.add_layer( + LinearLayout::vertical() + .child(format!("delete {name}?").text_view()) + .child(TextArea::new().with_name("confirm")) + .child(Button::new("submit", move |siv| { + if let Some(confirm) = siv.find_name::<TextArea>("confirm") { + if confirm.get_content() == "yes" { + if siv + .ipc(DeleteAccountRequest { name: name.clone() }) + .is_some() + { + siv.add_layer(Dialog::around("success".text_view()).button( + "ok", + |siv| { + // all the way back to the root + siv.pop_layer(); + siv.pop_layer(); + siv.pop_layer(); + siv.pop_layer(); + }, + )) + } + } else { + siv.pop_layer(); + } + } + })) + .float("are you sure"), + ); +} |