Skip to content

Commit

Permalink
Merge pull request #34 from dantleech/traits
Browse files Browse the repository at this point in the history
Traits
  • Loading branch information
dantleech committed Sep 22, 2023
2 parents 218d185 + fd01771 commit 2186e01
Show file tree
Hide file tree
Showing 13 changed files with 402 additions and 390 deletions.
72 changes: 47 additions & 25 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,29 @@ use std::{
use tokio::sync::mpsc::{Receiver, Sender};
use tui::{
backend::{Backend, CrosstermBackend},
widgets::TableState,
Frame, Terminal,
widgets::TableState, Terminal,
};
use tui_input::Input;

use crate::{
component::activity_list::{ActivityListMode, ActivityListState, ActivityViewState},
event::{input::EventSender, util::{table_state_prev, table_state_next}},
input::InputEvent,
store::{activity::{ActivityStore, Activities, SortBy, SortOrder}},
};
use crate::{
component::{activity_list, activity_view, unit_formatter::UnitFormatter},
event::keymap::{map_key, MappedKey},
component::{activity_list, unit_formatter::UnitFormatter},
event::keymap::{map_key},
store::activity::Activity,
ui,
};
use crate::{
component::{
activity_list::{ActivityList, ActivityListMode, ActivityListState, ActivityViewState},
activity_view::ActivityView,
View,
},
event::{
input::EventSender,
util::{table_state_next, table_state_prev},
},
input::InputEvent,
store::activity::{Activities, ActivityStore, SortBy, SortOrder},
};

pub struct ActivityFilters {
pub sort_by: SortBy,
Expand Down Expand Up @@ -151,13 +157,18 @@ impl App<'_> {
&mut self,
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
) -> Result<(), anyhow::Error> {
terminal.clear()?;
loop {
if self.quit {
break;
}
terminal.draw(|f| {
self.draw(f).expect("Could not draw frame");
})?;

let mut view: Box<dyn View> = match self.active_page {
ActivePage::ActivityList => Box::new(ActivityList::new()),
ActivePage::Activity => Box::new(ActivityView{}),
};

self.render(terminal, view.as_mut())?;

if let Some(message) = &self.info_message {
if message.has_expired() {
Expand All @@ -180,7 +191,7 @@ impl App<'_> {
match event {
InputEvent::Input(k) => {
let key = map_key(k);
self.handle(key);
view.handle(self, key);
}
InputEvent::InfoMessage(message) => {
self.info_message = Some(Notification::new(message));
Expand Down Expand Up @@ -215,17 +226,6 @@ impl App<'_> {
self.activities.clone()
}

fn draw<B: Backend>(&mut self, f: &mut Frame<B>) -> Result<(), anyhow::Error> {
ui::draw(self, f)
}

fn handle(&mut self, key: MappedKey) {
match self.active_page {
ActivePage::ActivityList => activity_list::handle(self, key),
ActivePage::Activity => activity_view::handle(self, key),
}
}

pub fn send(&mut self, event: InputEvent) {
self.event_queue.push(event);
}
Expand Down Expand Up @@ -272,4 +272,26 @@ impl App<'_> {
}
}
}

fn render(
&mut self,
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
view: &mut dyn View
) -> Result<(), anyhow::Error> {
let area = terminal.size().expect("Could not determine terminal size'");
let buffer = terminal.current_buffer_mut();
ui::draw(self, buffer, area, view);

match view.cursor_position() {
None => terminal.hide_cursor()?,
Some((x, y)) => {
terminal.show_cursor()?;
terminal.set_cursor(x, y)?;
}
}
terminal.flush()?;
terminal.swap_buffers();
terminal.backend_mut().flush()?;
Ok(())
}
}
19 changes: 8 additions & 11 deletions src/component/activity_list/chart.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use chrono::NaiveDateTime;
use tui::{
backend::Backend,
layout::Constraint,
style::{Color, Style},
symbols::Marker,
text::Span,
widgets::{Axis, Block, Borders, Chart, Dataset, GraphType},
Frame,
widgets::{Axis, Block, Borders, Chart, Dataset, GraphType, Widget},
prelude::Buffer,
};

use crate::{
Expand All @@ -16,11 +15,11 @@ use crate::{
};

pub fn handle(_app: &mut App, _key: MappedKey) {}
pub fn draw<B: Backend>(
pub fn draw(
app: &mut App,
f: &mut Frame<B>,
f: &mut Buffer,
area: tui::layout::Rect,
) -> Result<(), anyhow::Error> {
) {
let activities = &app
.activities()
.sort(&SortBy::Date, &SortOrder::Asc);
Expand All @@ -31,12 +30,12 @@ pub fn draw<B: Backend>(
let pmax = paces.iter().max();
let pmin = paces.iter().min();
if tmax.is_none() || tmin.is_none() {
return Ok(());
return;
}
let pdiff = pmax.unwrap() - pmin.unwrap();
let tdiff = tmax.unwrap() - tmin.unwrap();
if pmin.is_none() || pmax.is_none() {
return Ok(());
return;
}
let pmin = pmin.unwrap();
let pmax = pmax.unwrap();
Expand Down Expand Up @@ -115,7 +114,5 @@ pub fn draw<B: Backend>(
.collect(),
),
);
f.render_widget(chart, area);

Ok(())
chart.render(area, f);
}
143 changes: 4 additions & 139 deletions src/component/activity_list/list.rs
Original file line number Diff line number Diff line change
@@ -1,152 +1,18 @@
use crossterm::event::Event;

use tui::{
backend::Backend,
layout::Constraint,
style::{Color, Modifier, Style},
text::Span,
widgets::{Block, Borders, Cell, Clear, Row, Table, Paragraph},
Frame,
widgets::{Cell, Row, Table},
};
use tui_input::backend::crossterm::EventHandler;


use crate::{
app::App,
event::{
keymap::{MappedKey, StravaEvent}, input::InputEvent,
},
store::activity::{Activities, SortOrder},
ui::{centered_rect_absolute, color::ColorTheme}, component::{table_status_select_current},
store::activity::{Activities},
};

use super::{sort_dialog, rank_dialog};

pub fn handle(app: &mut App, key: MappedKey) {
if app.activity_list.filter_dialog {
let matched = match key.strava_event {
StravaEvent::Enter => {
app.filters.filter =
app.activity_list.filter_text_area.value().to_string();
app.activity_list.filter_dialog = false;
app.activity_list.table_state().select(Some(0));
app.send(InputEvent::Reload);
true
}
_ => false,
};
if matched {
return;
}

app.activity_list.filter_text_area.handle_event(&Event::Key(key.key_event));
return;
}

if app.activity_list.sort_dialog {
sort_dialog::handle(app, key);

return;
}
if app.activity_list.rank_dialog {
rank_dialog::handle(app, key);

return;
}
match key.strava_event {
StravaEvent::Quit => app.quit = true,
StravaEvent::ToggleUnitSystem => {
app.unit_formatter = app.unit_formatter.toggle();
}
StravaEvent::ToggleSortOrder => {
app.filters.sort_order = match app.filters.sort_order {
SortOrder::Asc => SortOrder::Desc,
SortOrder::Desc => SortOrder::Asc,
};
app.send(InputEvent::Reload);
}
StravaEvent::Down => app.next_activity(),
StravaEvent::Up => app.previous_activity(),
StravaEvent::Filter => toggle_filter(app),
StravaEvent::Sort => toggle_sort(app),
StravaEvent::Rank => toggle_rank(app),
StravaEvent::Enter => table_status_select_current(app),
StravaEvent::Refresh => app.send(InputEvent::Sync),
StravaEvent::IncreaseTolerance => {
app.filters.anchor_tolerance_add(0.01);
app.send(InputEvent::Reload)
}
StravaEvent::DecreaseTolerance => {
app.filters.anchor_tolerance_add(-0.01);
app.send(InputEvent::Reload);
},
StravaEvent::Anchor => {
app.anchor_selected();
app.send(InputEvent::Reload);
}
_ => (),
}
}

fn toggle_filter(app: &mut App) {
app.activity_list.filter_dialog = !app.activity_list.filter_dialog;
}

fn toggle_sort(app: &mut App) {
app.activity_list.sort_dialog = !app.activity_list.sort_dialog;
}
fn toggle_rank(app: &mut App) {
app.activity_list.rank_dialog = !app.activity_list.rank_dialog;
}

pub fn draw<B: Backend>(
app: &mut App,
f: &mut Frame<B>,
area: tui::layout::Rect,
) -> Result<(), anyhow::Error> {
let activities = &app.activities();

if app.activity_list.table_state().selected().is_none() && !activities.is_empty() {
app.activity_list.table_state().select(Some(0));
}

f.render_stateful_widget(
activity_list_table(app, activities),
area,
app.activity_list.table_state(),
);

if app.activity_list.filter_dialog {
let rect = centered_rect_absolute(64, 3, f.size());
let p = Paragraph::new(app.activity_list.filter_text_area.value())
.block(Block::default()
.borders(Borders::ALL)
.title("Filter")
.border_style(Style::default().fg(ColorTheme::Dialog.to_color()))
);

f.set_cursor(
1 + rect.x + app.activity_list.filter_text_area.visual_cursor() as u16,
rect.y + 1,
);

f.render_widget(Clear, rect);
f.render_widget(p, rect);

return Ok(());
}

if app.activity_list.sort_dialog {
sort_dialog::draw(app, f, f.size())?;

return Ok(());
}
if app.activity_list.rank_dialog {
rank_dialog::draw(app, f, f.size())?;

return Ok(());
}

Ok(())
}

pub fn activity_list_table<'a>(app: &App, activities: &'a Activities) -> Table<'a> {
let mut rows = vec![];
Expand Down Expand Up @@ -210,4 +76,3 @@ pub fn activity_list_table<'a>(app: &App, activities: &'a Activities) -> Table<'
Constraint::Percentage(10),
])
}

0 comments on commit 2186e01

Please sign in to comment.