Merge branch 'alatiera/move-update-notif' into 'master'
Move the update indication into an In-app Notification Closes #72 See merge request World/podcasts!60
This commit is contained in:
commit
646439d86a
@ -271,41 +271,5 @@ Tobias Bernard
|
|||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkBox" id="update_notification">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="no_show_all">True</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSpinner" id="update_spinner">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="padding">6</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="update_label">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="label" translatable="yes">Fetching new episodes</property>
|
|
||||||
<property name="ellipsize">end</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
|||||||
@ -53,20 +53,12 @@ Tobias Bernard
|
|||||||
<property name="margin_end">3</property>
|
<property name="margin_end">3</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="text">
|
<object class="GtkSpinner" id="spinner">
|
||||||
<property name="width_request">150</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="margin_start">12</property>
|
|
||||||
<property name="margin_end">12</property>
|
|
||||||
<property name="label" translatable="yes">An in-app action notification</property>
|
|
||||||
<property name="ellipsize">start</property>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
@ -97,10 +89,27 @@ Tobias Bernard
|
|||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="text">
|
||||||
|
<property name="width_request">150</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="margin_start">12</property>
|
||||||
|
<property name="margin_end">12</property>
|
||||||
|
<property name="label" translatable="yes">An in-app action notification</property>
|
||||||
|
<property name="ellipsize">start</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="undo">
|
<object class="GtkButton" id="undo">
|
||||||
<property name="label" translatable="yes">Undo</property>
|
<property name="label" translatable="yes">Undo</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="halign">center</property>
|
<property name="halign">center</property>
|
||||||
@ -113,7 +122,7 @@ Tobias Bernard
|
|||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="pack_type">end</property>
|
<property name="pack_type">end</property>
|
||||||
<property name="position">2</property>
|
<property name="position">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|||||||
@ -17,10 +17,11 @@ use settings::{self, WindowGeometry};
|
|||||||
use stacks::{Content, PopulatedState};
|
use stacks::{Content, PopulatedState};
|
||||||
use utils;
|
use utils;
|
||||||
use widgets::about_dialog;
|
use widgets::about_dialog;
|
||||||
use widgets::appnotif::{InAppNotification, UndoState};
|
use widgets::appnotif::{InAppNotification, SpinnerState, State};
|
||||||
use widgets::player;
|
use widgets::player;
|
||||||
use widgets::show_menu::{mark_all_notif, remove_show_notif, ShowMenu};
|
use widgets::show_menu::{mark_all_notif, remove_show_notif, ShowMenu};
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -57,9 +58,8 @@ pub(crate) enum Action {
|
|||||||
ShowShowsAnimated,
|
ShowShowsAnimated,
|
||||||
HeaderBarShowTile(String),
|
HeaderBarShowTile(String),
|
||||||
HeaderBarNormal,
|
HeaderBarNormal,
|
||||||
HeaderBarShowUpdateIndicator,
|
|
||||||
HeaderBarHideUpdateIndicator,
|
|
||||||
MarkAllPlayerNotification(Arc<Show>),
|
MarkAllPlayerNotification(Arc<Show>),
|
||||||
|
ShowUpdateNotif(Receiver<bool>),
|
||||||
RemoveShow(Arc<Show>),
|
RemoveShow(Arc<Show>),
|
||||||
ErrorNotification(String),
|
ErrorNotification(String),
|
||||||
InitEpisode(i32),
|
InitEpisode(i32),
|
||||||
@ -75,6 +75,7 @@ pub(crate) struct App {
|
|||||||
content: Rc<Content>,
|
content: Rc<Content>,
|
||||||
headerbar: Rc<Header>,
|
headerbar: Rc<Header>,
|
||||||
player: Rc<player::PlayerWidget>,
|
player: Rc<player::PlayerWidget>,
|
||||||
|
updater: RefCell<Option<InAppNotification>>,
|
||||||
sender: Sender<Action>,
|
sender: Sender<Action>,
|
||||||
receiver: Receiver<Action>,
|
receiver: Receiver<Action>,
|
||||||
}
|
}
|
||||||
@ -130,6 +131,8 @@ impl App {
|
|||||||
// Add the player to the main Box
|
// Add the player to the main Box
|
||||||
wrap.add(&player.action_bar);
|
wrap.add(&player.action_bar);
|
||||||
|
|
||||||
|
let updater = RefCell::new(None);
|
||||||
|
|
||||||
window.add(&wrap);
|
window.add(&wrap);
|
||||||
|
|
||||||
let app = App {
|
let app = App {
|
||||||
@ -140,6 +143,7 @@ impl App {
|
|||||||
headerbar: header,
|
headerbar: header,
|
||||||
content,
|
content,
|
||||||
player,
|
player,
|
||||||
|
updater,
|
||||||
sender,
|
sender,
|
||||||
receiver,
|
receiver,
|
||||||
};
|
};
|
||||||
@ -293,8 +297,6 @@ impl App {
|
|||||||
}
|
}
|
||||||
Action::HeaderBarShowTile(title) => self.headerbar.switch_to_back(&title),
|
Action::HeaderBarShowTile(title) => self.headerbar.switch_to_back(&title),
|
||||||
Action::HeaderBarNormal => self.headerbar.switch_to_normal(),
|
Action::HeaderBarNormal => self.headerbar.switch_to_normal(),
|
||||||
Action::HeaderBarShowUpdateIndicator => self.headerbar.show_update_notification(),
|
|
||||||
Action::HeaderBarHideUpdateIndicator => self.headerbar.hide_update_notification(),
|
|
||||||
Action::MarkAllPlayerNotification(pd) => {
|
Action::MarkAllPlayerNotification(pd) => {
|
||||||
let notif = mark_all_notif(pd, &self.sender);
|
let notif = mark_all_notif(pd, &self.sender);
|
||||||
notif.show(&self.overlay);
|
notif.show(&self.overlay);
|
||||||
@ -305,10 +307,38 @@ impl App {
|
|||||||
}
|
}
|
||||||
Action::ErrorNotification(err) => {
|
Action::ErrorNotification(err) => {
|
||||||
error!("An error notification was triggered: {}", err);
|
error!("An error notification was triggered: {}", err);
|
||||||
let callback = || glib::Continue(false);
|
let callback = |revealer: gtk::Revealer| {
|
||||||
let notif = InAppNotification::new(&err, callback, || {}, UndoState::Hidden);
|
revealer.set_reveal_child(false);
|
||||||
|
glib::Continue(false)
|
||||||
|
};
|
||||||
|
let undo_cb: Option<fn()> = None;
|
||||||
|
let notif = InAppNotification::new(&err, 6000, callback, undo_cb);
|
||||||
notif.show(&self.overlay);
|
notif.show(&self.overlay);
|
||||||
}
|
}
|
||||||
|
Action::ShowUpdateNotif(receiver) => {
|
||||||
|
let sender = self.sender.clone();
|
||||||
|
let callback = move |revealer: gtk::Revealer| {
|
||||||
|
if let Some(_) = receiver.try_recv() {
|
||||||
|
revealer.set_reveal_child(false);
|
||||||
|
sender.send(Action::RefreshAllViews);
|
||||||
|
return glib::Continue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::Continue(true)
|
||||||
|
};
|
||||||
|
let txt = i18n("Fetching new episodes");
|
||||||
|
let undo_cb: Option<fn()> = None;
|
||||||
|
let updater = InAppNotification::new(&txt, 250, callback, undo_cb);
|
||||||
|
updater.set_close_state(State::Hidden);
|
||||||
|
updater.set_spinner_state(SpinnerState::Active);
|
||||||
|
|
||||||
|
let old = self.updater.replace(Some(updater));
|
||||||
|
old.map(|i| i.destroy());
|
||||||
|
self.updater
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.map(|i| i.show(&self.overlay));
|
||||||
|
}
|
||||||
Action::InitEpisode(rowid) => {
|
Action::InitEpisode(rowid) => {
|
||||||
let res = self.player.initialize_episode(rowid);
|
let res = self.player.initialize_episode(rowid);
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
|
|||||||
@ -26,34 +26,10 @@ pub(crate) struct Header {
|
|||||||
back: gtk::Button,
|
back: gtk::Button,
|
||||||
show_title: gtk::Label,
|
show_title: gtk::Label,
|
||||||
hamburger: gtk::MenuButton,
|
hamburger: gtk::MenuButton,
|
||||||
updater: UpdateIndicator,
|
|
||||||
add: AddPopover,
|
add: AddPopover,
|
||||||
dots: gtk::MenuButton,
|
dots: gtk::MenuButton,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
struct UpdateIndicator {
|
|
||||||
container: gtk::Box,
|
|
||||||
text: gtk::Label,
|
|
||||||
spinner: gtk::Spinner,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpdateIndicator {
|
|
||||||
fn show(&self) {
|
|
||||||
self.spinner.start();
|
|
||||||
self.spinner.show();
|
|
||||||
self.container.show();
|
|
||||||
self.text.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hide(&self) {
|
|
||||||
self.spinner.stop();
|
|
||||||
self.spinner.hide();
|
|
||||||
self.container.hide();
|
|
||||||
self.text.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct AddPopover {
|
struct AddPopover {
|
||||||
container: gtk::Popover,
|
container: gtk::Popover,
|
||||||
@ -158,16 +134,6 @@ impl Default for Header {
|
|||||||
// The 3 dots secondary menu
|
// The 3 dots secondary menu
|
||||||
let dots = builder.get_object("secondary_menu").unwrap();
|
let dots = builder.get_object("secondary_menu").unwrap();
|
||||||
|
|
||||||
let update_box = builder.get_object("update_notification").unwrap();
|
|
||||||
let update_label = builder.get_object("update_label").unwrap();
|
|
||||||
let update_spinner = builder.get_object("update_spinner").unwrap();
|
|
||||||
|
|
||||||
let updater = UpdateIndicator {
|
|
||||||
container: update_box,
|
|
||||||
text: update_label,
|
|
||||||
spinner: update_spinner,
|
|
||||||
};
|
|
||||||
|
|
||||||
let add_toggle = builder.get_object("add_toggle").unwrap();
|
let add_toggle = builder.get_object("add_toggle").unwrap();
|
||||||
let add_popover = builder.get_object("add_popover").unwrap();
|
let add_popover = builder.get_object("add_popover").unwrap();
|
||||||
let new_url = builder.get_object("new_url").unwrap();
|
let new_url = builder.get_object("new_url").unwrap();
|
||||||
@ -187,7 +153,6 @@ impl Default for Header {
|
|||||||
back,
|
back,
|
||||||
show_title,
|
show_title,
|
||||||
hamburger,
|
hamburger,
|
||||||
updater,
|
|
||||||
add,
|
add,
|
||||||
dots,
|
dots,
|
||||||
}
|
}
|
||||||
@ -248,14 +213,6 @@ impl Header {
|
|||||||
self.show_title.set_text(title)
|
self.show_title.set_text(title)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn show_update_notification(&self) {
|
|
||||||
self.updater.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn hide_update_notification(&self) {
|
|
||||||
self.updater.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn open_menu(&self) {
|
pub(crate) fn open_menu(&self) {
|
||||||
self.hamburger.clicked();
|
self.hamburger.clicked();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use gtk::prelude::*;
|
|||||||
use gtk::{IsA, Widget};
|
use gtk::{IsA, Widget};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use crossbeam_channel::{unbounded, Sender};
|
use crossbeam_channel::{bounded, unbounded, Sender};
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use fragile::Fragile;
|
use fragile::Fragile;
|
||||||
use rayon;
|
use rayon;
|
||||||
@ -200,7 +200,8 @@ fn refresh_feed<S>(source: Option<S>, sender: Sender<Action>) -> Result<(), Erro
|
|||||||
where
|
where
|
||||||
S: IntoIterator<Item = Source> + Send + 'static,
|
S: IntoIterator<Item = Source> + Send + 'static,
|
||||||
{
|
{
|
||||||
sender.send(Action::HeaderBarShowUpdateIndicator);
|
let (up_sender, up_receiver) = bounded(1);
|
||||||
|
sender.send(Action::ShowUpdateNotif(up_receiver));
|
||||||
|
|
||||||
rayon::spawn(move || {
|
rayon::spawn(move || {
|
||||||
if let Some(s) = source {
|
if let Some(s) = source {
|
||||||
@ -218,8 +219,7 @@ where
|
|||||||
.ok();
|
.ok();
|
||||||
};
|
};
|
||||||
|
|
||||||
sender.send(Action::HeaderBarHideUpdateIndicator);
|
up_sender.send(true);
|
||||||
sender.send(Action::RefreshAllViews);
|
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,17 +6,26 @@ use std::cell::RefCell;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub(crate) enum UndoState {
|
#[allow(dead_code)]
|
||||||
|
pub(crate) enum State {
|
||||||
Shown,
|
Shown,
|
||||||
Hidden,
|
Hidden,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) enum SpinnerState {
|
||||||
|
Active,
|
||||||
|
Stopped,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct InAppNotification {
|
pub(crate) struct InAppNotification {
|
||||||
revealer: gtk::Revealer,
|
revealer: gtk::Revealer,
|
||||||
text: gtk::Label,
|
text: gtk::Label,
|
||||||
undo: gtk::Button,
|
undo: gtk::Button,
|
||||||
close: gtk::Button,
|
close: gtk::Button,
|
||||||
|
spinner: gtk::Spinner,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InAppNotification {
|
impl Default for InAppNotification {
|
||||||
@ -27,37 +36,54 @@ impl Default for InAppNotification {
|
|||||||
let text: gtk::Label = builder.get_object("text").unwrap();
|
let text: gtk::Label = builder.get_object("text").unwrap();
|
||||||
let undo: gtk::Button = builder.get_object("undo").unwrap();
|
let undo: gtk::Button = builder.get_object("undo").unwrap();
|
||||||
let close: gtk::Button = builder.get_object("close").unwrap();
|
let close: gtk::Button = builder.get_object("close").unwrap();
|
||||||
|
let spinner = builder.get_object("spinner").unwrap();
|
||||||
|
|
||||||
InAppNotification {
|
InAppNotification {
|
||||||
revealer,
|
revealer,
|
||||||
text,
|
text,
|
||||||
undo,
|
undo,
|
||||||
close,
|
close,
|
||||||
|
spinner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Timer should be in milliseconds
|
||||||
impl InAppNotification {
|
impl InAppNotification {
|
||||||
pub(crate) fn new<F, U>(
|
pub(crate) fn new<F, U>(
|
||||||
text: &str,
|
text: &str,
|
||||||
|
timer: u32,
|
||||||
mut callback: F,
|
mut callback: F,
|
||||||
undo_callback: U,
|
undo_callback: Option<U>,
|
||||||
show_undo: UndoState,
|
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut() -> glib::Continue + 'static,
|
F: FnMut(gtk::Revealer) -> glib::Continue + 'static,
|
||||||
U: Fn() + 'static,
|
U: Fn() + 'static,
|
||||||
{
|
{
|
||||||
let notif = InAppNotification::default();
|
let notif = InAppNotification::default();
|
||||||
notif.text.set_text(&text);
|
notif.text.set_text(&text);
|
||||||
|
|
||||||
let revealer = notif.revealer.clone();
|
let revealer_weak = notif.revealer.downgrade();
|
||||||
let id = timeout_add_seconds(6, move || {
|
let mut time = 0;
|
||||||
revealer.set_reveal_child(false);
|
let id = timeout_add(250, move || {
|
||||||
callback()
|
if time < timer {
|
||||||
|
time += 250;
|
||||||
|
return glib::Continue(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
let revealer = match revealer_weak.upgrade() {
|
||||||
|
Some(r) => r,
|
||||||
|
None => return glib::Continue(false),
|
||||||
|
};
|
||||||
|
|
||||||
|
callback(revealer)
|
||||||
});
|
});
|
||||||
let id = Rc::new(RefCell::new(Some(id)));
|
let id = Rc::new(RefCell::new(Some(id)));
|
||||||
|
|
||||||
|
if undo_callback.is_some() {
|
||||||
|
notif.set_undo_state(State::Shown)
|
||||||
|
};
|
||||||
|
|
||||||
// Cancel the callback
|
// Cancel the callback
|
||||||
let revealer = notif.revealer.clone();
|
let revealer = notif.revealer.clone();
|
||||||
notif.undo.connect_clicked(move |_| {
|
notif.undo.connect_clicked(move |_| {
|
||||||
@ -66,23 +92,25 @@ impl InAppNotification {
|
|||||||
glib::source::source_remove(id);
|
glib::source::source_remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
undo_callback();
|
if let Some(ref f) = undo_callback {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
// Hide the notification
|
// Hide the notification
|
||||||
revealer.set_reveal_child(false);
|
revealer.set_reveal_child(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Hide the revealer when the close button is clicked
|
// Hide the revealer when the close button is clicked
|
||||||
let revealer = notif.revealer.clone();
|
let revealer_weak = notif.revealer.downgrade();
|
||||||
notif.close.connect_clicked(move |_| {
|
notif.close.connect_clicked(move |_| {
|
||||||
|
let revealer = match revealer_weak.upgrade() {
|
||||||
|
Some(r) => r,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
revealer.set_reveal_child(false);
|
revealer.set_reveal_child(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
match show_undo {
|
|
||||||
UndoState::Shown => (),
|
|
||||||
UndoState::Hidden => notif.undo.hide(),
|
|
||||||
}
|
|
||||||
|
|
||||||
notif
|
notif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,4 +124,35 @@ impl InAppNotification {
|
|||||||
// so there will be a nice animation.
|
// so there will be a nice animation.
|
||||||
self.revealer.set_reveal_child(true);
|
self.revealer.set_reveal_child(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_undo_state(&self, state: State) {
|
||||||
|
match state {
|
||||||
|
State::Shown => self.undo.show(),
|
||||||
|
State::Hidden => self.undo.hide(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_close_state(&self, state: State) {
|
||||||
|
match state {
|
||||||
|
State::Shown => self.close.show(),
|
||||||
|
State::Hidden => self.close.hide(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_spinner_state(&self, state: SpinnerState) {
|
||||||
|
match state {
|
||||||
|
SpinnerState::Active => {
|
||||||
|
self.spinner.start();
|
||||||
|
self.spinner.show();
|
||||||
|
}
|
||||||
|
SpinnerState::Stopped => {
|
||||||
|
self.spinner.stop();
|
||||||
|
self.spinner.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn destroy(self) {
|
||||||
|
self.revealer.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use podcasts_data::Show;
|
|||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
use utils;
|
use utils;
|
||||||
use widgets::appnotif::{InAppNotification, UndoState};
|
use widgets::appnotif::InAppNotification;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -137,15 +137,18 @@ fn mark_all_watched(pd: &Show, sender: &Sender<Action>) -> Result<(), Error> {
|
|||||||
|
|
||||||
pub(crate) fn mark_all_notif(pd: Arc<Show>, sender: &Sender<Action>) -> InAppNotification {
|
pub(crate) fn mark_all_notif(pd: Arc<Show>, sender: &Sender<Action>) -> InAppNotification {
|
||||||
let id = pd.id();
|
let id = pd.id();
|
||||||
let callback = clone!(sender => move || {
|
let sender_ = sender.clone();
|
||||||
let res = mark_all_watched(&pd, &sender);
|
let callback = move |revealer: gtk::Revealer| {
|
||||||
|
let res = mark_all_watched(&pd, &sender_);
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
|
|
||||||
|
revealer.set_reveal_child(false);
|
||||||
glib::Continue(false)
|
glib::Continue(false)
|
||||||
});
|
};
|
||||||
|
|
||||||
let undo_callback = clone!(sender => move || sender.send(Action::RefreshWidgetIfSame(id)));
|
let undo_callback = clone!(sender => move || sender.send(Action::RefreshWidgetIfSame(id)));
|
||||||
let text = i18n("Marked all episodes as listened");
|
let text = i18n("Marked all episodes as listened");
|
||||||
InAppNotification::new(&text, callback, undo_callback, UndoState::Shown)
|
InAppNotification::new(&text, 6000, callback, Some(undo_callback))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove_show_notif(pd: Arc<Show>, sender: Sender<Action>) -> InAppNotification {
|
pub(crate) fn remove_show_notif(pd: Arc<Show>, sender: Sender<Action>) -> InAppNotification {
|
||||||
@ -154,21 +157,25 @@ pub(crate) fn remove_show_notif(pd: Arc<Show>, sender: Sender<Action>) -> InAppN
|
|||||||
let res = utils::ignore_show(pd.id());
|
let res = utils::ignore_show(pd.id());
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
|
|
||||||
let callback = clone!(pd, sender => move || {
|
let sender_ = sender.clone();
|
||||||
let res = utils::uningore_show(pd.id());
|
let pd_ = pd.clone();
|
||||||
|
let callback = move |revealer: gtk::Revealer| {
|
||||||
|
let res = utils::uningore_show(pd_.id());
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
|
|
||||||
// Spawn a thread so it won't block the ui.
|
// Spawn a thread so it won't block the ui.
|
||||||
rayon::spawn(clone!(pd, sender => move || {
|
rayon::spawn(clone!(pd_, sender_ => move || {
|
||||||
delete_show(&pd)
|
delete_show(&pd_)
|
||||||
.map_err(|err| error!("Error: {}", err))
|
.map_err(|err| error!("Error: {}", err))
|
||||||
.map_err(|_| error!("Failed to delete {}", pd.title()))
|
.map_err(|_| error!("Failed to delete {}", pd_.title()))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
sender.send(Action::RefreshEpisodesView);
|
sender_.send(Action::RefreshEpisodesView);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
revealer.set_reveal_child(false);
|
||||||
glib::Continue(false)
|
glib::Continue(false)
|
||||||
});
|
};
|
||||||
|
|
||||||
let undo_callback = move || {
|
let undo_callback = move || {
|
||||||
let res = utils::uningore_show(pd.id());
|
let res = utils::uningore_show(pd.id());
|
||||||
@ -177,5 +184,5 @@ pub(crate) fn remove_show_notif(pd: Arc<Show>, sender: Sender<Action>) -> InAppN
|
|||||||
sender.send(Action::RefreshEpisodesView);
|
sender.send(Action::RefreshEpisodesView);
|
||||||
};
|
};
|
||||||
|
|
||||||
InAppNotification::new(&text, callback, undo_callback, UndoState::Shown)
|
InAppNotification::new(&text, 6000, callback, Some(undo_callback))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user