use std::cell::RefCell;
use std::rc::Rc;
use common::dateutil;
use cursive::event::Key;
use cursive::view::Nameable;
use cursive::view::View;
use cursive::views::Dialog;
use cursive::views::EditView;
use cursive::views::LinearLayout;
use cursive::views::OnEventView;
use cursive::views::TextView;
use cursive::Cursive;
use store::Advance;
use store::Direction;
use crate::ViewState;
pub fn advance_helper(
adv: &Rc<RefCell<Advance>>,
direction: Direction,
c: &mut Cursive,
input: &str,
) {
if input.trim().starts_with('0') {
view_warn!(c, "Time value should not start with 0");
return;
}
match (input.parse::<humantime::Duration>(), direction) {
(Ok(d), Direction::Forward) => {
if let Some(data) = adv.borrow_mut().jump_sample_forward(d) {
c.user_data::<ViewState>()
.expect("No user data set")
.update(data)
} else {
}
}
(Ok(d), Direction::Reverse) => {
if let Some(data) = adv.borrow_mut().jump_sample_backward(d) {
c.user_data::<ViewState>()
.expect("No user data set")
.update(data)
} else {
}
}
_ => match dateutil::HgTime::parse_time_of_day(input) {
Some(time_of_day) => {
let view_time = c
.user_data::<ViewState>()
.expect("user data not set")
.timestamp;
match dateutil::HgTime::time_of_day_relative_to_system_time(view_time, time_of_day)
{
Some(timestamp) => match adv.borrow_mut().jump_sample_to(timestamp) {
Some(data) => c
.user_data::<ViewState>()
.expect("No user data set")
.update(data),
None => view_warn!(c, "Cannot find available data sample"),
},
None => {
view_warn!(c, "Failed to parse time of day value: {}", input);
return;
}
}
}
None => {
match dateutil::HgTime::parse(input) {
Some(pt) => {
let timestamp =
std::time::UNIX_EPOCH + std::time::Duration::from_secs(pt.unixtime);
match adv.borrow_mut().jump_sample_to(timestamp) {
Some(data) => c
.user_data::<ViewState>()
.expect("No user data set")
.update(data),
None => view_warn!(c, "Cannot find available data sample"),
}
}
None => {
view_warn!(c, "Failed to parse time value: {}", input);
return;
}
}
}
},
};
crate::refresh(c);
}
pub fn new(adv: Rc<RefCell<Advance>>, direction: Direction) -> impl View {
let title = match direction {
Direction::Forward => "How far forward should we advance?",
Direction::Reverse => "How far backward should we advance?",
};
OnEventView::new(
Dialog::new()
.title(title)
.padding_lrtb(1, 1, 1, 0)
.content(
LinearLayout::vertical()
.child(
EditView::new()
.on_submit(move |c, input| {
advance_helper(&adv, direction, c, input);
c.pop_layer();
})
.with_name("jump_popup"),
)
.child(TextView::new("e.g:"))
.child(TextView::new(" Relative Time: 10s or 3h5m or 2d"))
.child(TextView::new(" Absolute time: 01/01/1970 11:59PM"))
.child(TextView::new(" Time Of Day: 10:00am")),
)
.dismiss_button("Close"),
)
.on_event(Key::Esc, |s| {
s.pop_layer();
})
}