Add threaded ui model
This commit is contained in:
parent
c542b10738
commit
861391f7d8
File diff suppressed because it is too large
Load Diff
|
|
@ -1,2 +1,2 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["crabidy-core"]
|
members = ["crabidy-core", "cbd-tui"]
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crossterm = "0.26.1"
|
crossterm = "0.26.1"
|
||||||
cynic = { version = "3.0.0-beta.3", features = ["http-reqwest"] }
|
cynic = { version = "3.0.0-beta.3", features = ["http-reqwest"] }
|
||||||
|
flume = "0.10.14"
|
||||||
ratatui = "0.20.1"
|
ratatui = "0.20.1"
|
||||||
reqwest = { version = "0.11", features = ["json"] }
|
reqwest = { version = "0.11", features = ["json"] }
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use crossterm::{
|
||||||
execute,
|
execute,
|
||||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||||
};
|
};
|
||||||
|
use flume::{Receiver, Sender};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
backend::{Backend, CrosstermBackend},
|
backend::{Backend, CrosstermBackend},
|
||||||
layout::{Alignment, Constraint, Corner, Direction, Layout},
|
layout::{Alignment, Constraint, Corner, Direction, Layout},
|
||||||
|
|
@ -15,7 +16,7 @@ use ratatui::{
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
io, println,
|
io, println, thread,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
vec,
|
vec,
|
||||||
};
|
};
|
||||||
|
|
@ -134,39 +135,57 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
enum Message {
|
||||||
async fn main() {
|
Quit,
|
||||||
task::spawn_blocking(run_ui).await.unwrap();
|
LibraryData(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ui() {
|
#[tokio::main]
|
||||||
// let operation = graphql::queries::AllFilmsQuery::build(());
|
async fn main() {
|
||||||
//
|
let (ui_tx, rx): (Sender<Message>, Receiver<Message>) = flume::unbounded();
|
||||||
// let client = reqwest::Client::new();
|
let (tx, ui_rx): (Sender<Message>, Receiver<Message>) = flume::unbounded();
|
||||||
//
|
|
||||||
// let response = client
|
|
||||||
// .post("https://swapi-graphql.netlify.app/.netlify/functions/index")
|
|
||||||
// .run_graphql(operation)
|
|
||||||
// .await
|
|
||||||
// .unwrap();
|
|
||||||
//
|
|
||||||
// if let Some(data) = response.data {
|
|
||||||
// if let Some(films) = data.all_films {
|
|
||||||
// if let Some(list) = films.films {
|
|
||||||
// list.iter().for_each(|mut f| {
|
|
||||||
// if let Some(film) = f {
|
|
||||||
// if let Some(title) = &film.title {
|
|
||||||
// app.library.items.push(ListNode {
|
|
||||||
// name: title.to_string(),
|
|
||||||
// children: None,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
thread::spawn(|| {
|
||||||
|
run_ui(ui_tx, ui_rx);
|
||||||
|
});
|
||||||
|
|
||||||
|
// FIXME: move into some request function
|
||||||
|
let operation = graphql::queries::AllFilmsQuery::build(());
|
||||||
|
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("https://swapi-graphql.netlify.app/.netlify/functions/index")
|
||||||
|
.run_graphql(operation)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if let Some(data) = response.data {
|
||||||
|
if let Some(films) = data.all_films {
|
||||||
|
if let Some(list) = films.films {
|
||||||
|
// FIXME: Collect into array/vector instead and send it all over at once
|
||||||
|
list.iter().for_each(|mut f| {
|
||||||
|
if let Some(film) = f {
|
||||||
|
if let Some(title) = &film.title {
|
||||||
|
tx.send(Message::LibraryData(title.to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match rx.recv() {
|
||||||
|
Ok(Message::Quit) => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_ui(tx: Sender<Message>, rx: Receiver<Message>) {
|
||||||
// setup terminal
|
// setup terminal
|
||||||
enable_raw_mode().unwrap();
|
enable_raw_mode().unwrap();
|
||||||
let mut stdout = io::stdout();
|
let mut stdout = io::stdout();
|
||||||
|
|
@ -176,14 +195,33 @@ fn run_ui() {
|
||||||
|
|
||||||
// create app and run it
|
// create app and run it
|
||||||
let mut app = App::new();
|
let mut app = App::new();
|
||||||
|
let tick_rate = Duration::from_millis(100);
|
||||||
|
let mut last_tick = Instant::now();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
for message in rx.try_iter() {
|
||||||
|
if let Message::LibraryData(title) = message {
|
||||||
|
app.library.items.push(ListNode {
|
||||||
|
name: title,
|
||||||
|
children: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
terminal.draw(|f| ui(f, &mut app)).unwrap();
|
terminal.draw(|f| ui(f, &mut app)).unwrap();
|
||||||
|
|
||||||
|
let timeout = tick_rate
|
||||||
|
.checked_sub(last_tick.elapsed())
|
||||||
|
.unwrap_or_else(|| Duration::from_secs(0));
|
||||||
|
|
||||||
|
if crossterm::event::poll(timeout).unwrap() {
|
||||||
if let Event::Key(key) = event::read().unwrap() {
|
if let Event::Key(key) = event::read().unwrap() {
|
||||||
if key.kind == KeyEventKind::Press {
|
if key.kind == KeyEventKind::Press {
|
||||||
match key.code {
|
match key.code {
|
||||||
KeyCode::Char('q') => break,
|
KeyCode::Char('q') => {
|
||||||
|
tx.send(Message::Quit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
KeyCode::Char('j') => {
|
KeyCode::Char('j') => {
|
||||||
if app.library.is_focused() {
|
if app.library.is_focused() {
|
||||||
app.library.next();
|
app.library.next();
|
||||||
|
|
@ -205,6 +243,11 @@ fn run_ui() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if last_tick.elapsed() >= tick_rate {
|
||||||
|
last_tick = Instant::now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// restore terminal
|
// restore terminal
|
||||||
disable_raw_mode().unwrap();
|
disable_raw_mode().unwrap();
|
||||||
execute!(
|
execute!(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue