Expanded TUI: Lemmy Info + Post History
This commit is contained in:
parent
877c7ef324
commit
007570c2e3
2 changed files with 60 additions and 39 deletions
|
@ -144,6 +144,7 @@ impl Config {
|
||||||
post_history[idx].last_post_url = item.url.clone();
|
post_history[idx].last_post_url = item.url.clone();
|
||||||
}
|
}
|
||||||
None => post_history.push(PrevPost {
|
None => post_history.push(PrevPost {
|
||||||
|
id: feed.id,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
last_post_url: item.url.clone(),
|
last_post_url: item.url.clone(),
|
||||||
}),
|
}),
|
||||||
|
@ -163,6 +164,7 @@ pub_struct!(RedditConfig {
|
||||||
});
|
});
|
||||||
|
|
||||||
pub_struct!(FeedSetting {
|
pub_struct!(FeedSetting {
|
||||||
|
id: usize,
|
||||||
feed_url: String,
|
feed_url: String,
|
||||||
communities: FeedCommunities,
|
communities: FeedCommunities,
|
||||||
reddit: FeedRedditSettings,
|
reddit: FeedRedditSettings,
|
||||||
|
@ -190,6 +192,7 @@ pub_struct!(FeedRedditSettings {
|
||||||
|
|
||||||
// Posts structs
|
// Posts structs
|
||||||
pub_struct!(PrevPost {
|
pub_struct!(PrevPost {
|
||||||
|
id: usize,
|
||||||
title: String,
|
title: String,
|
||||||
last_post_url: String,
|
last_post_url: String,
|
||||||
});
|
});
|
||||||
|
|
96
src/main.rs
96
src/main.rs
|
@ -10,9 +10,9 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use reqwest::{blocking::Client, StatusCode};
|
use reqwest::{blocking::Client, StatusCode};
|
||||||
use tui::{backend::{CrosstermBackend, Backend}, Terminal, widgets::{Block, Borders, Cell, Row, Table}, layout::{Layout, Constraint, Direction}, Frame, style::{Style, Modifier, Color}};
|
use tui::{backend::{CrosstermBackend, Backend}, Terminal, widgets::{Block, Borders, Cell, Row, Table, Paragraph, Wrap}, layout::{Layout, Constraint, Direction, Alignment}, Frame, style::{Style, Modifier, Color}, text::{Span, Spans}};
|
||||||
use crossterm::{event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},};
|
use crossterm::{event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},};
|
||||||
use std::{thread::{sleep, self}, time::{self, Duration}, io};
|
use std::{thread::{sleep, self}, time::{self, Duration}, io, vec};
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
|
@ -94,12 +94,13 @@ impl Bot {
|
||||||
println!("Posting: {}", post.name);
|
println!("Posting: {}", post.name);
|
||||||
self.post(post.clone());
|
self.post(post.clone());
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn idle(&self) {
|
||||||
while Utc::now().time() - self.start_time.time() < chrono::Duration::seconds(60) {
|
while Utc::now().time() - self.start_time.time() < chrono::Duration::seconds(60) {
|
||||||
sleep(time::Duration::from_secs(10));
|
sleep(time::Duration::from_secs(10));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_posts(auth: &Sensitive<String>, base: String) -> GetPostsResponse {
|
fn list_posts(auth: &Sensitive<String>, base: String) -> GetPostsResponse {
|
||||||
|
@ -121,55 +122,85 @@ fn list_posts(auth: &Sensitive<String>, base: String) -> GetPostsResponse {
|
||||||
return serde_json::from_str(&res).unwrap();
|
return serde_json::from_str(&res).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_bot() {
|
fn run_bot(mut terminal: Terminal<CrosstermBackend<&io::Stdout>>) {
|
||||||
// Get all needed auth tokens at the start
|
// Get all needed auth tokens at the start
|
||||||
let mut old = Utc::now().time();
|
let mut old = Utc::now().time();
|
||||||
let mut this = Bot::new();
|
let mut this = Bot::new();
|
||||||
println!("{}", this.secrets.lemmy.username);
|
|
||||||
this.login();
|
this.login();
|
||||||
this.community_ids.load(&this.auth, &this.config.instance);
|
this.community_ids.load(&this.auth, &this.config.instance);
|
||||||
|
|
||||||
// Create empty eTag list
|
|
||||||
println!("TODO: Etag list");
|
|
||||||
|
|
||||||
// Enter a loop (not for debugging)
|
// Enter a loop (not for debugging)
|
||||||
loop {
|
loop {
|
||||||
this.run_once(old);
|
this.run_once(old);
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
terminal.draw(|f| {
|
||||||
|
ui(f, &this);
|
||||||
|
}).unwrap();
|
||||||
|
|
||||||
|
thread::sleep(Duration::from_secs(5));
|
||||||
|
|
||||||
|
disable_raw_mode().unwrap();
|
||||||
|
execute!(
|
||||||
|
terminal.backend_mut(),
|
||||||
|
LeaveAlternateScreen,
|
||||||
|
DisableMouseCapture
|
||||||
|
).unwrap();
|
||||||
|
terminal.show_cursor().unwrap();
|
||||||
|
|
||||||
|
this.idle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui<B: Backend>(f: &mut Frame<B>) {
|
fn ui<B: Backend>(f: &mut Frame<B>, state: &Bot) {
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(1)
|
.margin(1)
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Percentage(10),
|
Constraint::Percentage(15),
|
||||||
Constraint::Percentage(90),
|
Constraint::Percentage(90),
|
||||||
].as_ref()
|
].as_ref()
|
||||||
)
|
)
|
||||||
.split(f.size());
|
.split(f.size());
|
||||||
|
|
||||||
|
// Account Infos
|
||||||
|
|
||||||
let block = Block::default()
|
let account_info = vec![
|
||||||
.title("Block")
|
Row::new(vec![
|
||||||
.borders(Borders::ALL);
|
Cell::from(format!("Lemmy Username: {} |", state.secrets.lemmy.username)),
|
||||||
|
Cell::from(format!("Lemmy Instance: {} |", state.config.instance))
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
let block = Table::new(account_info)
|
||||||
|
.block(Block::default().title("Account info").borders(Borders::ALL))
|
||||||
|
.widths(&[
|
||||||
|
Constraint::Percentage(15),
|
||||||
|
Constraint::Percentage(20),
|
||||||
|
Constraint::Percentage(20),
|
||||||
|
Constraint::Percentage(20),
|
||||||
|
Constraint::Percentage(20),
|
||||||
|
]);
|
||||||
f.render_widget(block, chunks[0]);
|
f.render_widget(block, chunks[0]);
|
||||||
|
|
||||||
|
|
||||||
|
// Post Table
|
||||||
|
|
||||||
let selected_style = Style::default().add_modifier(Modifier::REVERSED);
|
let selected_style = Style::default().add_modifier(Modifier::REVERSED);
|
||||||
let normal_style = Style::default().bg(Color::Blue);
|
let normal_style = Style::default().bg(Color::Blue);
|
||||||
let header_cells = ["Series", "Community", "Last Post"]
|
let header_cells = ["Series", "Community", "Reddit", "Discord", "Last Post"]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|h| Cell::from(*h).style(Style::default().fg(Color::Red)));
|
.map(|h| Cell::from(*h).style(Style::default().fg(Color::Red)));
|
||||||
let header = Row::new(header_cells)
|
let header = Row::new(header_cells)
|
||||||
.style(normal_style)
|
.style(normal_style)
|
||||||
.height(1)
|
.height(1)
|
||||||
.bottom_margin(1);
|
.bottom_margin(1);
|
||||||
let rows = [
|
let rows = state.post_history.iter().map(|post| {
|
||||||
Row::new([Cell::from("a1"), Cell::from("a2"), Cell::from("a3")]).height(1 as u16).bottom_margin(1),
|
let config = &state.config.feeds[post.id];
|
||||||
Row::new([Cell::from("b1"), Cell::from("b2"), Cell::from("b3")]).height(1 as u16).bottom_margin(1),
|
Row::new([Cell::from(post.title.clone()), Cell::from(format!("{}", config.communities.chapter)), Cell::from(format!("{}", config.reddit.enabled as u8)), Cell::from("0"), Cell::from(post.last_post_url.clone())]).height(1 as u16).bottom_margin(1)
|
||||||
Row::new([Cell::from("unicorn"), Cell::from("c2"), Cell::from("c3")]).height(2 as u16).bottom_margin(1)
|
});
|
||||||
];
|
|
||||||
|
|
||||||
let t = Table::new(rows)
|
let t = Table::new(rows)
|
||||||
.header(header)
|
.header(header)
|
||||||
|
@ -177,9 +208,11 @@ fn ui<B: Backend>(f: &mut Frame<B>) {
|
||||||
.highlight_style(selected_style)
|
.highlight_style(selected_style)
|
||||||
.highlight_symbol(">> ")
|
.highlight_symbol(">> ")
|
||||||
.widths(&[
|
.widths(&[
|
||||||
|
Constraint::Percentage(30),
|
||||||
|
Constraint::Percentage(10),
|
||||||
|
Constraint::Percentage(5),
|
||||||
|
Constraint::Percentage(5),
|
||||||
Constraint::Percentage(50),
|
Constraint::Percentage(50),
|
||||||
Constraint::Length(30),
|
|
||||||
Constraint::Min(10),
|
|
||||||
]);
|
]);
|
||||||
f.render_widget(t, chunks[1]);
|
f.render_widget(t, chunks[1]);
|
||||||
}
|
}
|
||||||
|
@ -187,23 +220,8 @@ fn ui<B: Backend>(f: &mut Frame<B>) {
|
||||||
fn main() -> Result<(), io::Error> {
|
fn main() -> Result<(), io::Error> {
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
let backend = CrosstermBackend::new(&stdout);
|
let backend = CrosstermBackend::new(&stdout);
|
||||||
let mut terminal = Terminal::new(backend)?;
|
let terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
terminal.draw(|f| {
|
run_bot(terminal);
|
||||||
ui(f);
|
|
||||||
})?;
|
|
||||||
|
|
||||||
thread::sleep(Duration::from_secs(5));
|
|
||||||
|
|
||||||
disable_raw_mode()?;
|
|
||||||
execute!(
|
|
||||||
terminal.backend_mut(),
|
|
||||||
LeaveAlternateScreen,
|
|
||||||
DisableMouseCapture
|
|
||||||
)?;
|
|
||||||
terminal.show_cursor()?;
|
|
||||||
|
|
||||||
|
|
||||||
run_bot();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue