created a new struct for a layout without opening a yaml file
This commit is contained in:
parent
a7f509b165
commit
47752720b4
@ -26,5 +26,5 @@ pub struct Opt {
|
||||
fn main() {
|
||||
//parse parameter
|
||||
let opt = Opt::from_args();
|
||||
ui::Ui::run(&opt);
|
||||
ui::create_ui(&opt);
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
use std::sync::mpsc;
|
||||
use std::{io, thread};
|
||||
|
||||
use crate::Opt;
|
||||
use termion::event::Key;
|
||||
use termion::input::TermRead;
|
||||
use termion::raw::IntoRawMode;
|
||||
use tui::backend::TermionBackend;
|
||||
use tui::layout::{Constraint, Direction, Layout};
|
||||
@ -12,7 +11,6 @@ use crate::widget::info;
|
||||
use crate::widget::repo_entry;
|
||||
use crate::widget::service_switcher;
|
||||
use crate::widget::tag_list;
|
||||
use crate::Opt;
|
||||
|
||||
pub struct Ui {
|
||||
state: State,
|
||||
@ -56,7 +54,7 @@ impl Ui {
|
||||
state: State::SelectService,
|
||||
repo: repo_entry::RepoEntry::new(repo_id),
|
||||
tags: tag_list::TagList::with_status("Tags are empty"),
|
||||
services: service_switcher::ServiceSwitcher::new(&opt.config),
|
||||
services: service_switcher::ServiceSwitcher::new(&opt.config).unwrap(),
|
||||
info: info::Info::new("Select image of edit Repository"),
|
||||
};
|
||||
|
||||
@ -70,7 +68,7 @@ impl Ui {
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
|
||||
//setup input thread
|
||||
let receiver = ui.spawn_stdin_channel();
|
||||
let receiver = super::spawn_stdin_channel();
|
||||
|
||||
//core interaction loop
|
||||
'core: loop {
|
||||
@ -212,18 +210,4 @@ impl Ui {
|
||||
|
||||
terminal.clear().unwrap();
|
||||
}
|
||||
|
||||
/// create a thread for catching input and send them to core loop
|
||||
pub fn spawn_stdin_channel(&self) -> mpsc::Receiver<termion::event::Key> {
|
||||
let (tx, rx) = mpsc::channel::<termion::event::Key>();
|
||||
|
||||
thread::spawn(move || loop {
|
||||
let stdin = io::stdin();
|
||||
for c in stdin.keys() {
|
||||
tx.send(c.unwrap()).unwrap();
|
||||
}
|
||||
});
|
||||
thread::sleep(std::time::Duration::from_millis(64));
|
||||
rx
|
||||
}
|
||||
}
|
32
src/ui/mod.rs
Normal file
32
src/ui/mod.rs
Normal file
@ -0,0 +1,32 @@
|
||||
mod default;
|
||||
mod no_yaml;
|
||||
|
||||
use std::sync::mpsc;
|
||||
use std::{io, thread};
|
||||
|
||||
use crate::Opt;
|
||||
use termion::input::TermRead;
|
||||
|
||||
use crate::widget::service_switcher;
|
||||
|
||||
pub fn create_ui(opt: &Opt) {
|
||||
let service_result = service_switcher::ServiceSwitcher::new(&opt.config);
|
||||
match service_result {
|
||||
None => no_yaml::NoYaml::run(opt),
|
||||
Some(_) => default::Ui::run(opt),
|
||||
}
|
||||
}
|
||||
|
||||
/// create a thread for catching input and send them to core loop
|
||||
pub fn spawn_stdin_channel() -> mpsc::Receiver<termion::event::Key> {
|
||||
let (tx, rx) = mpsc::channel::<termion::event::Key>();
|
||||
|
||||
thread::spawn(move || loop {
|
||||
let stdin = io::stdin();
|
||||
for c in stdin.keys() {
|
||||
tx.send(c.unwrap()).unwrap();
|
||||
}
|
||||
});
|
||||
thread::sleep(std::time::Duration::from_millis(64));
|
||||
rx
|
||||
}
|
138
src/ui/no_yaml.rs
Normal file
138
src/ui/no_yaml.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use std::{io, thread};
|
||||
|
||||
use termion::event::Key;
|
||||
use termion::raw::IntoRawMode;
|
||||
use tui::backend::TermionBackend;
|
||||
use tui::layout::{Constraint, Direction, Layout};
|
||||
use tui::Terminal;
|
||||
|
||||
use crate::widget::info;
|
||||
use crate::widget::repo_entry;
|
||||
use crate::widget::tag_list;
|
||||
use crate::Opt;
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
pub enum State {
|
||||
EditRepo,
|
||||
SelectTag,
|
||||
}
|
||||
|
||||
impl std::iter::Iterator for State {
|
||||
type Item = Self;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self {
|
||||
State::EditRepo => *self = State::SelectTag,
|
||||
State::SelectTag => *self = State::EditRepo,
|
||||
}
|
||||
Some(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NoYaml {
|
||||
state: State,
|
||||
repo: repo_entry::RepoEntry,
|
||||
tags: tag_list::TagList,
|
||||
info: info::Info,
|
||||
}
|
||||
|
||||
impl NoYaml {
|
||||
pub fn run(opt: &Opt) {
|
||||
let (repo, load_repo) = match &opt.repo {
|
||||
None => (
|
||||
repo_entry::RepoEntry::new(
|
||||
"enter a repository or select one from docker-compose.yml",
|
||||
),
|
||||
false,
|
||||
),
|
||||
Some(repo_id) => (repo_entry::RepoEntry::new(repo_id), true),
|
||||
};
|
||||
|
||||
let mut ui = NoYaml {
|
||||
state: State::EditRepo,
|
||||
repo,
|
||||
tags: tag_list::TagList::with_status("Tags are empty"),
|
||||
info: info::Info::new("edit the Repository widget to load tags"),
|
||||
};
|
||||
|
||||
// load tags if a repository was given thorugh paramter
|
||||
if load_repo {
|
||||
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
|
||||
}
|
||||
|
||||
//setup tui
|
||||
let stdout = io::stdout().into_raw_mode().unwrap();
|
||||
let backend = TermionBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
|
||||
//setup input thread
|
||||
let receiver = super::spawn_stdin_channel();
|
||||
|
||||
//core interaction loop
|
||||
'core: loop {
|
||||
//draw
|
||||
terminal
|
||||
.draw(|rect| {
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3),
|
||||
Constraint::Min(7),
|
||||
Constraint::Length(2),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(rect.size());
|
||||
|
||||
rect.render_widget(ui.repo.render(ui.state == State::EditRepo), chunks[0]);
|
||||
let (list, state) = ui.tags.render(ui.state == State::SelectTag);
|
||||
rect.render_stateful_widget(list, chunks[1], state);
|
||||
rect.render_widget(ui.info.render(), chunks[2]);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
//handle input
|
||||
match receiver.try_recv() {
|
||||
Ok(Key::Ctrl('q')) => break 'core,
|
||||
Ok(Key::Char('\t')) => {
|
||||
ui.state.next();
|
||||
}
|
||||
Ok(Key::Ctrl('r')) => {
|
||||
ui.repo.confirm();
|
||||
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
|
||||
}
|
||||
Ok(Key::Ctrl('n')) => match ui.tags.next_page() {
|
||||
Err(e) => ui.info.set_info(&format!("{}", e)),
|
||||
Ok(_) => (),
|
||||
},
|
||||
Ok(Key::Ctrl('p')) => match ui.tags.prev_page() {
|
||||
Err(e) => ui.info.set_info(&format!("{}", e)),
|
||||
Ok(_) => (),
|
||||
},
|
||||
Ok(Key::Char('\n')) => match ui.state {
|
||||
State::EditRepo => {
|
||||
ui.repo.confirm();
|
||||
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
Ok(Key::Char(key)) => match ui.state {
|
||||
State::EditRepo => {
|
||||
ui.info.set_info("Editing Repository");
|
||||
ui.repo.handle_input(Key::Char(key));
|
||||
}
|
||||
State::SelectTag => {
|
||||
ui.tags.handle_input(Key::Char(key));
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
||||
//sleep for 32ms (30 fps)
|
||||
thread::sleep(std::time::Duration::from_millis(32));
|
||||
}
|
||||
|
||||
terminal.clear().unwrap();
|
||||
}
|
||||
}
|
@ -3,8 +3,6 @@ use tui::layout::Alignment;
|
||||
use tui::style::{Color, Style};
|
||||
use tui::widgets::{Block, Borders, Paragraph};
|
||||
|
||||
use crate::ui::State;
|
||||
|
||||
pub struct RepoEntry {
|
||||
text: String,
|
||||
old_text: String,
|
||||
|
@ -9,7 +9,6 @@ use tui::style::{Color, Style};
|
||||
use tui::widgets::{Block, Borders, List, ListState};
|
||||
|
||||
use crate::repo;
|
||||
use crate::ui::State;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
@ -34,7 +33,7 @@ pub struct ServiceSwitcher {
|
||||
}
|
||||
|
||||
impl ServiceSwitcher {
|
||||
pub fn new(file: &Option<PathBuf>) -> Self {
|
||||
pub fn new(file: &Option<PathBuf>) -> Option<Self> {
|
||||
let mut file_list = vec![
|
||||
PathBuf::from("docker-compose.yml"),
|
||||
PathBuf::from("docker-compose.yaml"),
|
||||
@ -55,21 +54,16 @@ impl ServiceSwitcher {
|
||||
}
|
||||
};
|
||||
|
||||
return Self {
|
||||
return Some(Self {
|
||||
list,
|
||||
state: ListState::default(),
|
||||
changed: false,
|
||||
opened_file: file,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
//could not find docker-compose file
|
||||
Self {
|
||||
list: vec![format!("No docker-compose file found")],
|
||||
state: ListState::default(),
|
||||
changed: false,
|
||||
opened_file: PathBuf::new(),
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn render(&mut self, colored: bool) -> (List, &mut ListState) {
|
||||
|
@ -5,7 +5,6 @@ use tui::style::{Color, Style};
|
||||
use tui::widgets::{Block, Borders, List, ListState};
|
||||
|
||||
use crate::tags;
|
||||
use crate::ui::State;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
Loading…
Reference in New Issue
Block a user