From 583046dcbf307792ae051263e4029c5d4086434f Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sat, 20 Aug 2022 23:36:20 -0700 Subject: Auto close success/error message --- src/tui/app.rs | 14 +++++++------- src/tui/views.rs | 28 +++++++++++++++++++++------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/tui/app.rs b/src/tui/app.rs index 0aa7840..6658f16 100644 --- a/src/tui/app.rs +++ b/src/tui/app.rs @@ -1,3 +1,8 @@ +use std::collections::HashMap; +use std::io; +use std::io::Write; +use std::sync::Arc; + use cursive::event::{Event, Key}; use cursive::theme::{BaseColor, Color, Effect, Style}; use cursive::traits::{Nameable, Scrollable}; @@ -6,23 +11,18 @@ use cursive::utils::span::SpannedString; use cursive::views::{Dialog, TextView, ViewRef}; use cursive::Cursive; use cursive::XY; -use std::collections::HashMap; -use std::io; -use std::io::Write; -use std::sync::Arc; use super::markdown; use super::markdown::Markdown; use super::views::{ LayoutView, ListView, MdView, Name, TempView, Vimable, NAME_ANSWER_LIST, NAME_ANSWER_VIEW, - NAME_FULL_LAYOUT, NAME_QUESTION_LIST, NAME_QUESTION_VIEW, + NAME_FULL_LAYOUT, NAME_QUESTION_LIST, NAME_QUESTION_VIEW, NAME_TEMP_MSG, }; use crate::config::Config; use crate::error::Result; use crate::stackexchange::{Answer, Question}; pub const NAME_HELP_VIEW: &str = "help_view"; -pub const NAME_TEMP_MSG: &str = "tmp_msg_view"; // TODO an Arc app state that gets auto updated with new selections would // be convenient @@ -225,7 +225,7 @@ pub fn temp_feedback_msg(siv: &mut Cursive, msg: io::Result) { let content = msg.unwrap_or_else(|e| format!("error: {}", e)); let styled_content = SpannedString::styled(content, style); let layer = Dialog::around(TextView::new(styled_content)); - let temp = TempView::new(layer).with_name(NAME_TEMP_MSG); + let temp = TempView::new(layer, siv.cb_sink().clone()); siv.add_layer(temp); } diff --git a/src/tui/views.rs b/src/tui/views.rs index af015ef..0e7971d 100644 --- a/src/tui/views.rs +++ b/src/tui/views.rs @@ -1,3 +1,8 @@ +use std::fmt::Display; +use std::rc::Rc; +use std::time::Duration; +use std::{fmt, thread}; + use cursive::event::{Callback, Event, EventResult, Key}; use cursive::traits::{Finder, Nameable, Resizable, Scrollable}; use cursive::utils::markup::StyledString; @@ -6,10 +11,7 @@ use cursive::views::{ HideableView, LinearLayout, NamedView, PaddedView, Panel, ResizedView, ScrollView, SelectView, TextView, }; -use cursive::{Cursive, Vec2, XY}; -use std::fmt; -use std::fmt::Display; -use std::rc::Rc; +use cursive::{CbSink, Cursive, Vec2, XY}; use super::markdown::Markdown; @@ -18,6 +20,7 @@ pub const NAME_ANSWER_LIST: &str = "answer_list"; pub const NAME_QUESTION_VIEW: &str = "question_view"; pub const NAME_ANSWER_VIEW: &str = "answer_view"; pub const NAME_FULL_LAYOUT: &str = "full_layout"; +pub const NAME_TEMP_MSG: &str = "tmp_msg_view"; // TODO this seems pointless; probably should be removed pub enum Name { @@ -647,19 +650,30 @@ pub struct TempView { view: T, } -// TODO figure out how to auto close this in 3-5s impl ViewWrapper for TempView { cursive::wrap_impl!(self.view: T); fn wrap_on_event(&mut self, _event: Event) -> EventResult { + // close this view on any input EventResult::with_cb(|s| { s.pop_layer(); }) } } -impl TempView { - pub fn new(view: T) -> Self { +impl TempView> { + pub fn new(inner: V, cb_sink: CbSink) -> Self { + thread::spawn(move || { + thread::sleep(Duration::from_secs(2)); + cb_sink + .send(Box::new(|s| { + if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_TEMP_MSG) { + s.screen_mut().remove_layer(pos); + } + })) + .expect("failed to send fn to cursive cb sink"); + }); + let view = inner.with_name(NAME_TEMP_MSG); Self { view } } } -- cgit v1.2.3