This commit is contained in:
2026-03-22 09:31:18 +00:00
parent dfb0c1aede
commit b0ff4c748b
4 changed files with 67 additions and 19 deletions
+4 -4
View File
@@ -2,24 +2,24 @@ use std::time::{SystemTime, UNIX_EPOCH};
use rkyv::{Archive, Deserialize, Serialize}; use rkyv::{Archive, Deserialize, Serialize};
#[derive(Serialize, Deserialize, Archive)] #[derive(Serialize, Deserialize, Archive, Debug)]
pub struct Data { pub struct Data {
pub data_chunks: Vec<DataChunk>, pub data_chunks: Vec<DataChunk>,
pub data_static: BatteryStatic, pub data_static: BatteryStatic,
} }
#[derive(Serialize, Deserialize, Archive)] #[derive(Serialize, Deserialize, Archive, Debug)]
pub struct DataChunk { pub struct DataChunk {
pub timestamp: u64, pub timestamp: u64,
pub battery: BatteryMutable, pub battery: BatteryMutable,
} }
#[derive(Serialize, Deserialize, Archive)] #[derive(Serialize, Deserialize, Archive, Debug)]
pub struct BatteryMutable { pub struct BatteryMutable {
pub charge: i64, pub charge: i64,
} }
#[derive(Serialize, Deserialize, Archive)] #[derive(Serialize, Deserialize, Archive, Debug)]
pub struct BatteryStatic { pub struct BatteryStatic {
pub total_capacity: i64, pub total_capacity: i64,
} }
+42 -4
View File
@@ -1,6 +1,16 @@
use crate::component::Component; use crate::{
component::Component,
data_graph::{Graphable, SplitData},
};
use crossterm::event::Event; use crossterm::event::Event;
use ratatui::{layout::Rect, text::Text, Frame}; use data::{ArchivedData, Data};
use ratatui::{
layout::{Constraint, Layout, Rect},
text::Text,
widgets::{Axis, Chart, Dataset},
Frame,
};
use rkyv::{deserialize, rancor};
#[derive(Debug)] #[derive(Debug)]
pub enum MenuMsg { pub enum MenuMsg {
@@ -12,6 +22,8 @@ pub enum MenuMsg {
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Menu { pub struct Menu {
counter: i32, counter: i32,
split_data: Option<SplitData>,
data: Vec<(f64, f64)>,
} }
impl Component for Menu { impl Component for Menu {
type Msg = MenuMsg; type Msg = MenuMsg;
@@ -19,22 +31,48 @@ impl Component for Menu {
match msg { match msg {
MenuMsg::MoveUp => self.counter += 1, MenuMsg::MoveUp => self.counter += 1,
MenuMsg::MoveDown => self.counter -= 1, MenuMsg::MoveDown => self.counter -= 1,
MenuMsg::Select => self.get_data(),
_ => {} _ => {}
} }
} }
fn view(&self, f: &mut Frame) { fn view(&self, f: &mut Frame) {
let [text, graph] =
Layout::vertical([Constraint::Length(5), Constraint::Fill(1)]).areas(f.area());
let text_raw = format!("meow - {}", self.counter); let text_raw = format!("meow - {}", self.counter);
let text = Text::raw(text_raw); let text_widget = Text::raw(text_raw);
f.render_widget(text, f.area()); f.render_widget(text_widget, text);
let a = &self.data;
let data_set = Dataset::default().data(a).name("Battery");
let x_axis = Axis::default().title("timeframe");
let y_axis = Axis::default()
.title("Charge")
.labels(["0%", "50%", "100%"]);
let graph_widget = Chart::new(vec![data_set]);
f.render_widget(graph_widget, graph);
} }
fn handle_event(&mut self, event: Event) { fn handle_event(&mut self, event: Event) {
match event { match event {
Event::Key(x) => match x.code { Event::Key(x) => match x.code {
crossterm::event::KeyCode::Up => self.update(MenuMsg::MoveUp), crossterm::event::KeyCode::Up => self.update(MenuMsg::MoveUp),
crossterm::event::KeyCode::Down => self.update(MenuMsg::MoveDown), crossterm::event::KeyCode::Down => self.update(MenuMsg::MoveDown),
crossterm::event::KeyCode::Enter => self.update(MenuMsg::Select),
_ => {} _ => {}
}, },
_ => {} _ => {}
} }
} }
} }
impl Menu {
fn get_data(&mut self) {
let data = std::fs::read("./battery.data").unwrap();
let access_data: &ArchivedData =
rkyv::access::<ArchivedData, rkyv::rancor::Error>(&data).unwrap();
let data: data::Data = deserialize::<Data, rancor::Error>(access_data).unwrap();
let split_data = SplitData {
chunks: data.data_chunks,
};
self.data = split_data.timeframe(0, 999999999);
}
}
+4 -5
View File
@@ -1,8 +1,6 @@
use ratatui::widgets::Dataset;
use data::DataChunk; use data::DataChunk;
trait Graphable { pub trait Graphable {
fn timeframe(&self, start: u64, end: u64) -> Vec<(f64, f64)>; fn timeframe(&self, start: u64, end: u64) -> Vec<(f64, f64)>;
} }
@@ -24,6 +22,7 @@ impl Graphable for SplitData {
} }
} }
struct SplitData { #[derive(Debug)]
chunks: Vec<DataChunk>, pub struct SplitData {
pub chunks: Vec<DataChunk>,
} }
+16 -5
View File
@@ -19,6 +19,7 @@ use crate::{
mod component; mod component;
mod dashboard; mod dashboard;
mod data_graph;
// -- GLOBAL APP MESSAGE -- // -- GLOBAL APP MESSAGE --
enum AppMsg { enum AppMsg {
@@ -48,17 +49,25 @@ impl App {
} }
} }
// The "View" part of TEA
fn view(&self, f: &mut Frame) { fn view(&self, f: &mut Frame) {
// Centering logic we discussed earlier! match self.screen {
self.menu.view(f); Screen::Menu => self.menu.view(f),
}
} }
fn handle_event(&mut self, event: Event) { fn handle_event(&mut self, event: Event) {
match event {
Event::Key(x) => match x.code {
crossterm::event::KeyCode::Esc => self.update(AppMsg::GlobalQuit),
_ => {}
},
_ => {}
}
match self.screen { match self.screen {
Screen::Menu => self.menu.handle_event(event), Screen::Menu => self.menu.handle_event(event),
} }
} }
fn propagate_events(&mut self) { fn propagate_events(&mut self) {
if crossterm::event::poll(Duration::from_millis(100)).unwrap() { if crossterm::event::poll(Duration::from_millis(100)).unwrap() {
if let Ok(event) = crossterm::event::read() { if let Ok(event) = crossterm::event::read() {
@@ -70,8 +79,10 @@ impl App {
fn main() { fn main() {
let mut app: App = App::default(); let mut app: App = App::default();
ratatui::run(|terminal| loop { ratatui::run(|terminal| {
terminal.draw(|f| app.view(f)); while !app.should_quit {
terminal.draw(|f| app.view(f)).unwrap();
app.propagate_events(); app.propagate_events();
}
}); });
} }