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>>) { siv.add_layer( LinearLayout::vertical() .child(TextArea::new().with_name("scope")) .child(Button::new("add", { move |siv| { let text_area = siv.find_name::