better error handling
This commit is contained in:
parent
28ae313797
commit
bd829f23ad
@ -25,4 +25,8 @@ pub enum Error {
|
|||||||
/// error while handling requests
|
/// error while handling requests
|
||||||
#[error("reqwest error: {0}")]
|
#[error("reqwest error: {0}")]
|
||||||
Reqwest(#[from] reqwest::Error),
|
Reqwest(#[from] reqwest::Error),
|
||||||
|
|
||||||
|
/// error while sending to channel
|
||||||
|
#[error("sending to channel error: {0}")]
|
||||||
|
ChannelSendError(#[from] std::sync::mpsc::SendError<crate::ui::UiEvent>),
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@ use anyhow::Result;
|
|||||||
use crate::widget::service_switcher;
|
use crate::widget::service_switcher;
|
||||||
use crate::Opt;
|
use crate::Opt;
|
||||||
|
|
||||||
|
pub enum UiEvent {
|
||||||
|
Input(termion::event::Key),
|
||||||
|
RefreshOnNewData,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_ui(opt: &Opt) -> Result<()> {
|
pub fn create_ui(opt: &Opt) -> Result<()> {
|
||||||
let service_result = service_switcher::ServiceSwitcher::new(&opt.file);
|
let service_result = service_switcher::ServiceSwitcher::new(&opt.file);
|
||||||
match service_result {
|
match service_result {
|
||||||
|
@ -8,11 +8,11 @@ use tui::Terminal;
|
|||||||
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::{io, thread};
|
|
||||||
|
|
||||||
|
use super::UiEvent;
|
||||||
|
use crate::error::Error;
|
||||||
use crate::widget::async_tag_list::{self, TagList};
|
use crate::widget::async_tag_list::{self, TagList};
|
||||||
use crate::widget::info;
|
use crate::widget::{info, repo_entry};
|
||||||
use crate::widget::repo_entry;
|
|
||||||
use crate::Opt;
|
use crate::Opt;
|
||||||
|
|
||||||
pub struct Ui {
|
pub struct Ui {
|
||||||
@ -50,11 +50,6 @@ impl std::iter::Iterator for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum UiEvent {
|
|
||||||
Input(Key),
|
|
||||||
RefreshOnNewData,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DeferredEvent {
|
pub enum DeferredEvent {
|
||||||
Quit,
|
Quit,
|
||||||
NewRepo(String),
|
NewRepo(String),
|
||||||
@ -63,22 +58,21 @@ pub enum DeferredEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ui {
|
impl Ui {
|
||||||
/// create a thread for catching input and send them to core loop
|
/// catch input and send them to core loop
|
||||||
pub fn spawn_input_channel(sender: mpsc::Sender<UiEvent>) {
|
pub fn wait_for_input(sender: mpsc::Sender<UiEvent>) -> Result<(), Error> {
|
||||||
thread::spawn(move || loop {
|
let stdin = std::io::stdin();
|
||||||
let stdin = io::stdin();
|
for c in stdin.keys() {
|
||||||
for c in stdin.keys() {
|
sender.send(UiEvent::Input(c.unwrap()))?;
|
||||||
sender.send(UiEvent::Input(c.unwrap())).unwrap();
|
}
|
||||||
}
|
Ok(())
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
pub async fn work_requests(
|
pub async fn work_requests(
|
||||||
ui: Arc<Mutex<Ui>>,
|
ui: &Arc<Mutex<Ui>>,
|
||||||
events: mpsc::Receiver<DeferredEvent>,
|
events: mpsc::Receiver<DeferredEvent>,
|
||||||
sender: mpsc::Sender<UiEvent>,
|
sender: mpsc::Sender<UiEvent>,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
loop {
|
loop {
|
||||||
match events.recv() {
|
match events.recv() {
|
||||||
Ok(DeferredEvent::Quit) => break,
|
Ok(DeferredEvent::Quit) => break,
|
||||||
@ -86,7 +80,7 @@ impl Ui {
|
|||||||
{
|
{
|
||||||
let mut ui = ui.lock().unwrap();
|
let mut ui = ui.lock().unwrap();
|
||||||
ui.tags = TagList::with_status("fetching new tags...");
|
ui.tags = TagList::with_status("fetching new tags...");
|
||||||
sender.send(UiEvent::RefreshOnNewData).unwrap();
|
sender.send(UiEvent::RefreshOnNewData)?;
|
||||||
}
|
}
|
||||||
let list = async_tag_list::TagList::with_repo_name(name).await;
|
let list = async_tag_list::TagList::with_repo_name(name).await;
|
||||||
let mut ui = ui.lock().unwrap();
|
let mut ui = ui.lock().unwrap();
|
||||||
@ -102,7 +96,7 @@ impl Ui {
|
|||||||
let mut ui = ui.lock().unwrap();
|
let mut ui = ui.lock().unwrap();
|
||||||
if ui.tags.at_end_of_list() {
|
if ui.tags.at_end_of_list() {
|
||||||
ui.info.set_text("Fetching more tags...");
|
ui.info.set_text("Fetching more tags...");
|
||||||
sender.send(UiEvent::RefreshOnNewData).unwrap();
|
sender.send(UiEvent::RefreshOnNewData)?;
|
||||||
(true, ui.tags.clone())
|
(true, ui.tags.clone())
|
||||||
} else {
|
} else {
|
||||||
(false, ui.tags.clone())
|
(false, ui.tags.clone())
|
||||||
@ -121,8 +115,9 @@ impl Ui {
|
|||||||
ui.info.set_info(&e);
|
ui.info.set_info(&e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sender.send(UiEvent::RefreshOnNewData).unwrap();
|
sender.send(UiEvent::RefreshOnNewData)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(opt: &Opt) -> Result<()> {
|
pub fn run(opt: &Opt) -> Result<()> {
|
||||||
@ -142,16 +137,25 @@ impl Ui {
|
|||||||
let ui_clone = ui.clone();
|
let ui_clone = ui.clone();
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
Self::work_requests(ui_clone, deferred_receiver, sender2);
|
if let Err(e) = Self::work_requests(&ui_clone, deferred_receiver, sender2) {
|
||||||
|
let mut ui = ui_clone.lock().unwrap();
|
||||||
|
ui.info.set_info(&e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//setup tui
|
//setup tui
|
||||||
let stdout = io::stdout().into_raw_mode()?;
|
let stdout = std::io::stdout().into_raw_mode()?;
|
||||||
let backend = TermionBackend::new(stdout);
|
let backend = TermionBackend::new(stdout);
|
||||||
let mut terminal = Terminal::new(backend)?;
|
let mut terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
//setup input thread
|
//setup input thread
|
||||||
Self::spawn_input_channel(sender);
|
let ui_clone = ui.clone();
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
if let Err(e) = Self::wait_for_input(sender) {
|
||||||
|
let mut ui = ui_clone.lock().unwrap();
|
||||||
|
ui.info.set_info(&e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//core interaction loop
|
//core interaction loop
|
||||||
'core: loop {
|
'core: loop {
|
||||||
@ -190,48 +194,52 @@ impl Ui {
|
|||||||
let event = receiver.recv();
|
let event = receiver.recv();
|
||||||
let mut ui_data = ui.lock().unwrap();
|
let mut ui_data = ui.lock().unwrap();
|
||||||
match event {
|
match event {
|
||||||
Ok(UiEvent::Input(Key::Ctrl('q'))) | Ok(UiEvent::Input(Key::Ctrl('c'))) => {
|
Ok(UiEvent::Input(key)) => match key {
|
||||||
deferred_sender.send(DeferredEvent::Quit)?;
|
//quit without saving
|
||||||
break 'core; //quit program without saving
|
Key::Ctrl('q') | Key::Ctrl('c') => {
|
||||||
}
|
deferred_sender.send(DeferredEvent::Quit)?;
|
||||||
Ok(UiEvent::Input(Key::Char('\t'))) => {
|
break 'core; //quit program without saving
|
||||||
ui_data.state.next();
|
}
|
||||||
let state = ui_data.state.clone();
|
//cycle widgets
|
||||||
ui_data.info.set_info(&state);
|
Key::Char('\t') => {
|
||||||
}
|
ui_data.state.next();
|
||||||
Ok(UiEvent::Input(Key::Ctrl('r'))) => {
|
let state = ui_data.state.clone();
|
||||||
ui_data.repo.confirm();
|
ui_data.info.set_info(&state);
|
||||||
deferred_sender
|
}
|
||||||
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
//refresh repository
|
||||||
.unwrap();
|
Key::Ctrl('r') => {
|
||||||
}
|
ui_data.repo.confirm();
|
||||||
Ok(UiEvent::Input(Key::Char('\n'))) if ui_data.state == State::EditRepo => {
|
deferred_sender.send(DeferredEvent::NewRepo(ui_data.repo.get()))?;
|
||||||
ui_data.repo.confirm();
|
}
|
||||||
deferred_sender
|
//enter on selecting tags
|
||||||
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
Key::Char('\n') if ui_data.state == State::EditRepo => {
|
||||||
.unwrap();
|
ui_data.repo.confirm();
|
||||||
}
|
deferred_sender.send(DeferredEvent::NewRepo(ui_data.repo.get()))?;
|
||||||
Ok(UiEvent::Input(Key::Backspace)) if ui_data.state == State::EditRepo => {
|
}
|
||||||
ui_data.info.set_text("Editing Repository");
|
//delete last char on repository
|
||||||
ui_data.repo.handle_input(Key::Backspace);
|
Key::Backspace if ui_data.state == State::EditRepo => {
|
||||||
}
|
ui_data.info.set_text("Editing Repository");
|
||||||
Ok(UiEvent::Input(Key::Up)) | Ok(UiEvent::Input(Key::Char('k')))
|
ui_data.repo.handle_input(Key::Backspace);
|
||||||
if ui_data.state == State::SelectTag =>
|
}
|
||||||
{
|
//moving up on selecting tags
|
||||||
deferred_sender.send(DeferredEvent::TagPrevious).unwrap();
|
Key::Up | Key::Char('k') if ui_data.state == State::SelectTag => {
|
||||||
ui_data.details = ui_data.tags.create_detail_widget();
|
deferred_sender.send(DeferredEvent::TagPrevious)?;
|
||||||
}
|
ui_data.details = ui_data.tags.create_detail_widget();
|
||||||
Ok(UiEvent::Input(Key::Down)) | Ok(UiEvent::Input(Key::Char('j')))
|
}
|
||||||
if ui_data.state == State::SelectTag =>
|
//moving down on selecting tags
|
||||||
{
|
Key::Down | Key::Char('j') if ui_data.state == State::SelectTag => {
|
||||||
deferred_sender.send(DeferredEvent::TagNext).unwrap();
|
deferred_sender.send(DeferredEvent::TagNext)?;
|
||||||
ui_data.details = ui_data.tags.create_detail_widget();
|
ui_data.details = ui_data.tags.create_detail_widget();
|
||||||
}
|
}
|
||||||
Ok(UiEvent::Input(Key::Char(key))) if ui_data.state == State::EditRepo => {
|
//append character on editing repository
|
||||||
ui_data.info.set_text("Editing Repository");
|
Key::Char(key) if ui_data.state == State::EditRepo => {
|
||||||
ui_data.repo.handle_input(Key::Char(key));
|
ui_data.info.set_text("Editing Repository");
|
||||||
}
|
ui_data.repo.handle_input(Key::Char(key));
|
||||||
_ => {}
|
}
|
||||||
|
//ignore all else input
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Ok(UiEvent::RefreshOnNewData) | Err(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,13 +8,12 @@ use tui::Terminal;
|
|||||||
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::{io, thread};
|
|
||||||
|
|
||||||
|
use super::UiEvent;
|
||||||
|
use crate::error::Error;
|
||||||
use crate::repository;
|
use crate::repository;
|
||||||
use crate::widget::async_tag_list::{self, TagList};
|
use crate::widget::async_tag_list::{self, TagList};
|
||||||
use crate::widget::info;
|
use crate::widget::{info, repo_entry, service_switcher};
|
||||||
use crate::widget::repo_entry;
|
|
||||||
use crate::widget::service_switcher;
|
|
||||||
use crate::Opt;
|
use crate::Opt;
|
||||||
|
|
||||||
pub struct Ui {
|
pub struct Ui {
|
||||||
@ -56,11 +55,6 @@ impl std::iter::Iterator for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum UiEvent {
|
|
||||||
Input(Key),
|
|
||||||
RefreshOnNewData,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DeferredEvent {
|
pub enum DeferredEvent {
|
||||||
Quit,
|
Quit,
|
||||||
NewRepo(String),
|
NewRepo(String),
|
||||||
@ -69,22 +63,21 @@ pub enum DeferredEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ui {
|
impl Ui {
|
||||||
/// create a thread for catching input and send them to core loop
|
/// catch input and send them to core loop
|
||||||
pub fn spawn_input_channel(sender: mpsc::Sender<UiEvent>) {
|
pub fn wait_for_input(sender: mpsc::Sender<UiEvent>) -> Result<(), Error> {
|
||||||
thread::spawn(move || loop {
|
let stdin = std::io::stdin();
|
||||||
let stdin = io::stdin();
|
for c in stdin.keys() {
|
||||||
for c in stdin.keys() {
|
sender.send(UiEvent::Input(c.unwrap()))?;
|
||||||
sender.send(UiEvent::Input(c.unwrap())).unwrap();
|
}
|
||||||
}
|
Ok(())
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
pub async fn work_requests(
|
pub async fn work_requests(
|
||||||
ui: Arc<Mutex<Ui>>,
|
ui: &Arc<Mutex<Ui>>,
|
||||||
events: mpsc::Receiver<DeferredEvent>,
|
events: mpsc::Receiver<DeferredEvent>,
|
||||||
sender: mpsc::Sender<UiEvent>,
|
sender: mpsc::Sender<UiEvent>,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
loop {
|
loop {
|
||||||
match events.recv() {
|
match events.recv() {
|
||||||
Ok(DeferredEvent::Quit) => break,
|
Ok(DeferredEvent::Quit) => break,
|
||||||
@ -92,7 +85,7 @@ impl Ui {
|
|||||||
{
|
{
|
||||||
let mut ui = ui.lock().unwrap();
|
let mut ui = ui.lock().unwrap();
|
||||||
ui.tags = TagList::with_status("Fetching new tags...");
|
ui.tags = TagList::with_status("Fetching new tags...");
|
||||||
sender.send(UiEvent::RefreshOnNewData).unwrap();
|
sender.send(UiEvent::RefreshOnNewData)?;
|
||||||
}
|
}
|
||||||
let list = TagList::with_repo_name(name).await;
|
let list = TagList::with_repo_name(name).await;
|
||||||
let mut ui = ui.lock().unwrap();
|
let mut ui = ui.lock().unwrap();
|
||||||
@ -108,7 +101,7 @@ impl Ui {
|
|||||||
let mut ui = ui.lock().unwrap();
|
let mut ui = ui.lock().unwrap();
|
||||||
if ui.tags.at_end_of_list() {
|
if ui.tags.at_end_of_list() {
|
||||||
ui.info.set_text("Fetching more tags...");
|
ui.info.set_text("Fetching more tags...");
|
||||||
sender.send(UiEvent::RefreshOnNewData).unwrap();
|
sender.send(UiEvent::RefreshOnNewData)?;
|
||||||
(true, ui.tags.clone())
|
(true, ui.tags.clone())
|
||||||
} else {
|
} else {
|
||||||
(false, ui.tags.clone())
|
(false, ui.tags.clone())
|
||||||
@ -127,8 +120,9 @@ impl Ui {
|
|||||||
ui.info.set_info(&e);
|
ui.info.set_info(&e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sender.send(UiEvent::RefreshOnNewData).unwrap();
|
sender.send(UiEvent::RefreshOnNewData)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(opt: &Opt, switcher: service_switcher::ServiceSwitcher) -> Result<()> {
|
pub fn run(opt: &Opt, switcher: service_switcher::ServiceSwitcher) -> Result<()> {
|
||||||
@ -149,16 +143,25 @@ impl Ui {
|
|||||||
let ui_clone = ui.clone();
|
let ui_clone = ui.clone();
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
Self::work_requests(ui_clone, deferred_receiver, sender2);
|
if let Err(e) = Self::work_requests(&ui_clone, deferred_receiver, sender2) {
|
||||||
|
let mut ui = ui_clone.lock().unwrap();
|
||||||
|
ui.info.set_info(&e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//setup tui
|
//setup tui
|
||||||
let stdout = io::stdout().into_raw_mode()?;
|
let stdout = std::io::stdout().into_raw_mode()?;
|
||||||
let backend = TermionBackend::new(stdout);
|
let backend = TermionBackend::new(stdout);
|
||||||
let mut terminal = Terminal::new(backend)?;
|
let mut terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
//setup input thread
|
//setup input thread
|
||||||
Self::spawn_input_channel(sender);
|
let ui_clone = ui.clone();
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
if let Err(e) = Self::wait_for_input(sender) {
|
||||||
|
let mut ui = ui_clone.lock().unwrap();
|
||||||
|
ui.info.set_info(&e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//core interaction loop
|
//core interaction loop
|
||||||
'core: loop {
|
'core: loop {
|
||||||
@ -208,111 +211,122 @@ impl Ui {
|
|||||||
let event = receiver.recv();
|
let event = receiver.recv();
|
||||||
let mut ui_data = ui.lock().unwrap();
|
let mut ui_data = ui.lock().unwrap();
|
||||||
match event {
|
match event {
|
||||||
Ok(UiEvent::Input(Key::Ctrl('q'))) | Ok(UiEvent::Input(Key::Ctrl('c'))) => {
|
//handling input
|
||||||
deferred_sender.send(DeferredEvent::Quit)?;
|
Ok(UiEvent::Input(key)) => match key {
|
||||||
break 'core; //quit program without saving
|
//quit without saving
|
||||||
}
|
Key::Ctrl('q') | Key::Ctrl('c') => {
|
||||||
Ok(UiEvent::Input(Key::Char('\t'))) => {
|
deferred_sender.send(DeferredEvent::Quit)?;
|
||||||
ui_data.state.next();
|
break 'core; //quit program without saving
|
||||||
let state = ui_data.state.clone();
|
|
||||||
ui_data.info.set_info(&state);
|
|
||||||
}
|
|
||||||
Ok(UiEvent::Input(Key::Ctrl('s'))) => match ui_data.services.save() {
|
|
||||||
Err(e) => {
|
|
||||||
ui_data.info.set_info(&format!("{}", e));
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
Ok(_) => ui_data.info.set_text("Saved compose file"),
|
//cycle widgets
|
||||||
},
|
Key::Char('\t') => {
|
||||||
Ok(UiEvent::Input(Key::Ctrl('r'))) => {
|
ui_data.state.next();
|
||||||
ui_data.repo.confirm();
|
let state = ui_data.state.clone();
|
||||||
deferred_sender
|
ui_data.info.set_info(&state);
|
||||||
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
}
|
||||||
.unwrap();
|
//save file
|
||||||
}
|
Key::Ctrl('s') => match ui_data.services.save() {
|
||||||
Ok(UiEvent::Input(Key::Char('\n'))) if ui_data.state == State::SelectTag => {
|
|
||||||
let mut repo = ui_data.repo.get();
|
|
||||||
let tag = match ui_data.tags.get_selected() {
|
|
||||||
Err(async_tag_list::Error::NextPageSelected) => continue,
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
ui_data.info.set_info(&format!("{}", e));
|
ui_data.info.set_info(&format!("{}", e));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ok(tag) => tag,
|
Ok(_) => ui_data.info.set_text("Saved compose file"),
|
||||||
};
|
},
|
||||||
repo.push(':');
|
//refresh repository
|
||||||
repo.push_str(&tag);
|
Key::Ctrl('r') => {
|
||||||
ui_data.services.change_current_line(repo);
|
ui_data.repo.confirm();
|
||||||
}
|
deferred_sender
|
||||||
Ok(UiEvent::Input(Key::Char('\n'))) if ui_data.state == State::EditRepo => {
|
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
||||||
ui_data.repo.confirm();
|
.unwrap();
|
||||||
deferred_sender
|
}
|
||||||
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
//enter on selecting tags
|
||||||
.unwrap();
|
Key::Char('\n') if ui_data.state == State::SelectTag => {
|
||||||
}
|
let mut repo = ui_data.repo.get();
|
||||||
Ok(UiEvent::Input(Key::Backspace)) if ui_data.state == State::EditRepo => {
|
let tag = match ui_data.tags.get_selected() {
|
||||||
ui_data.info.set_text("Editing Repository");
|
Err(async_tag_list::Error::NextPageSelected) => continue,
|
||||||
ui_data.repo.handle_input(Key::Backspace);
|
Err(e) => {
|
||||||
}
|
ui_data.info.set_info(&format!("{}", e));
|
||||||
Ok(UiEvent::Input(Key::Up)) | Ok(UiEvent::Input(Key::Char('k')))
|
continue;
|
||||||
if ui_data.state == State::SelectService
|
}
|
||||||
&& ui_data.services.find_previous_match() =>
|
Ok(tag) => tag,
|
||||||
{
|
};
|
||||||
match ui_data.services.extract_repo() {
|
repo.push(':');
|
||||||
Err(e) => ui_data.info.set_info(&format!("{}", e)),
|
repo.push_str(&tag);
|
||||||
Ok(s) => {
|
ui_data.services.change_current_line(repo);
|
||||||
let repo = match repository::check_repo(&s) {
|
}
|
||||||
Err(e) => {
|
//enter on editing repository
|
||||||
ui_data.info.set_info(&format!("{}", e));
|
Key::Char('\n') if ui_data.state == State::EditRepo => {
|
||||||
continue;
|
ui_data.repo.confirm();
|
||||||
}
|
deferred_sender
|
||||||
Ok(s) => s,
|
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
||||||
};
|
.unwrap();
|
||||||
ui_data.repo.set(repo.to_string());
|
}
|
||||||
deferred_sender
|
//delete last char on repository
|
||||||
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
Key::Backspace if ui_data.state == State::EditRepo => {
|
||||||
.unwrap();
|
ui_data.info.set_text("Editing Repository");
|
||||||
|
ui_data.repo.handle_input(Key::Backspace);
|
||||||
|
}
|
||||||
|
//moving up on selecting service
|
||||||
|
Key::Up | Key::Char('k')
|
||||||
|
if ui_data.state == State::SelectService
|
||||||
|
&& ui_data.services.find_previous_match() =>
|
||||||
|
{
|
||||||
|
match ui_data.services.extract_repo() {
|
||||||
|
Err(e) => ui_data.info.set_info(&format!("{}", e)),
|
||||||
|
Ok(s) => {
|
||||||
|
let repo = match repository::check_repo(&s) {
|
||||||
|
Err(e) => {
|
||||||
|
ui_data.info.set_info(&format!("{}", e));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Ok(s) => s,
|
||||||
|
};
|
||||||
|
ui_data.repo.set(repo.to_string());
|
||||||
|
deferred_sender
|
||||||
|
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//moving down on selecting service
|
||||||
Ok(UiEvent::Input(Key::Down)) | Ok(UiEvent::Input(Key::Char('j')))
|
Key::Down | Key::Char('j')
|
||||||
if ui_data.state == State::SelectService
|
if ui_data.state == State::SelectService
|
||||||
&& ui_data.services.find_next_match() =>
|
&& ui_data.services.find_next_match() =>
|
||||||
{
|
{
|
||||||
match ui_data.services.extract_repo() {
|
match ui_data.services.extract_repo() {
|
||||||
Err(e) => ui_data.info.set_info(&format!("{}", e)),
|
Err(e) => ui_data.info.set_info(&format!("{}", e)),
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
let repo = match repository::check_repo(&s) {
|
let repo = match repository::check_repo(&s) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
ui_data.info.set_info(&format!("{}", e));
|
ui_data.info.set_info(&format!("{}", e));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
};
|
};
|
||||||
ui_data.repo.set(repo.to_string());
|
ui_data.repo.set(repo.to_string());
|
||||||
deferred_sender
|
deferred_sender
|
||||||
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
.send(DeferredEvent::NewRepo(ui_data.repo.get()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//moving up on selecting tags
|
||||||
Ok(UiEvent::Input(Key::Up)) | Ok(UiEvent::Input(Key::Char('k')))
|
Key::Up | Key::Char('k') if ui_data.state == State::SelectTag => {
|
||||||
if ui_data.state == State::SelectTag =>
|
deferred_sender.send(DeferredEvent::TagPrevious).unwrap();
|
||||||
{
|
}
|
||||||
deferred_sender.send(DeferredEvent::TagPrevious).unwrap();
|
//moving down on selecting tags
|
||||||
}
|
Key::Down | Key::Char('j') if ui_data.state == State::SelectTag => {
|
||||||
Ok(UiEvent::Input(Key::Down)) | Ok(UiEvent::Input(Key::Char('j')))
|
deferred_sender.send(DeferredEvent::TagNext).unwrap();
|
||||||
if ui_data.state == State::SelectTag =>
|
}
|
||||||
{
|
//append character on editing repository
|
||||||
deferred_sender.send(DeferredEvent::TagNext).unwrap();
|
Key::Char(key) if ui_data.state == State::EditRepo => {
|
||||||
}
|
ui_data.info.set_text("Editing Repository");
|
||||||
Ok(UiEvent::Input(Key::Char(key))) if ui_data.state == State::EditRepo => {
|
ui_data.repo.handle_input(Key::Char(key));
|
||||||
ui_data.info.set_text("Editing Repository");
|
}
|
||||||
ui_data.repo.handle_input(Key::Char(key));
|
//ignore all else input
|
||||||
}
|
_ => {}
|
||||||
Ok(UiEvent::Input(_)) => {}
|
},
|
||||||
Ok(UiEvent::RefreshOnNewData) => {}
|
Ok(UiEvent::RefreshOnNewData) | Err(_) => {}
|
||||||
Err(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,17 +160,14 @@ impl TagList {
|
|||||||
let next_page = self.lines.pop();
|
let next_page = self.lines.pop();
|
||||||
|
|
||||||
//add tags
|
//add tags
|
||||||
match &self.tags {
|
if let Some(tags) = &self.tags {
|
||||||
None => (),
|
for image in tags.get_tags().iter() {
|
||||||
Some(tags) => {
|
self.lines.push(Line::Image(image.clone()));
|
||||||
for image in tags.get_tags().iter() {
|
|
||||||
self.lines.push(Line::Image(image.clone()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//readd next page item
|
//readd next page item
|
||||||
if let Some(_) = self.tags.as_ref().unwrap().next_page().await {
|
if (self.tags.as_ref().unwrap().next_page().await).is_some() {
|
||||||
self.lines.push(next_page.unwrap());
|
self.lines.push(next_page.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user