Wired up refresh button.
This commit is contained in:
parent
fa33138d66
commit
ddb195db3c
@ -33,58 +33,9 @@ impl Content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn new_initialized() -> Content {
|
pub fn update(&mut self) {
|
||||||
// let ct = Content::new();
|
self.shows.update();
|
||||||
// ct.init();
|
self.episodes.update();
|
||||||
// ct
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn init(&self) {
|
|
||||||
// self.podcasts.init();
|
|
||||||
// if self.podcasts.flowbox.get_children().is_empty() {
|
|
||||||
// self.stack.set_visible_child_name("empty");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// self.stack.set_visible_child_name("podcasts");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn replace_widget(&mut self, pdw: PodcastWidget) {
|
|
||||||
// let vis = self.stack.get_visible_child_name().unwrap();
|
|
||||||
// let old = self.stack.get_child_by_name("widget").unwrap();
|
|
||||||
// self.stack.remove(&old);
|
|
||||||
|
|
||||||
// self.widget = pdw;
|
|
||||||
// self.stack
|
|
||||||
// .add_titled(&self.widget.container, "widget", "Episodes");
|
|
||||||
// self.stack.set_visible_child_name(&vis);
|
|
||||||
// old.destroy();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ContentState<S> {
|
|
||||||
content: Content,
|
|
||||||
state: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait UpdateView {
|
|
||||||
fn update(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct PodcastsView {}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct WidgetsView {}
|
|
||||||
|
|
||||||
impl UpdateView for ContentState<WidgetsView> {
|
|
||||||
fn update(&mut self) {
|
|
||||||
let old = self.content.stack.get_child_by_name("widget").unwrap();
|
|
||||||
let id = WidgetExt::get_name(&old).unwrap();
|
|
||||||
let pd = dbqueries::get_podcast_from_id(id.parse::<i32>().unwrap()).unwrap();
|
|
||||||
|
|
||||||
let pdw = PodcastWidget::new_initialized(&self.content.stack, &pd);
|
|
||||||
// self.content.replace_widget(pdw);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,13 +113,12 @@ struct ShowsMachine<S> {
|
|||||||
impl<S> ShowsMachine<S> {
|
impl<S> ShowsMachine<S> {
|
||||||
fn update(&mut self) {
|
fn update(&mut self) {
|
||||||
let vis = self.stack.get_visible_child_name().unwrap();
|
let vis = self.stack.get_visible_child_name().unwrap();
|
||||||
let old = self.stack.get_child_by_name("shows").unwrap();
|
let old = self.stack.get_child_by_name("populated").unwrap();
|
||||||
self.stack.remove(&old);
|
self.stack.remove(&old);
|
||||||
|
|
||||||
let pop = ShowsPopulated::new_initialized();
|
let pop = ShowsPopulated::new_initialized();
|
||||||
self.populated = pop;
|
self.populated = pop;
|
||||||
self.stack
|
self.stack.add_named(&self.populated.container, "populated");
|
||||||
.add_titled(&self.populated.container, "shows", "Shows");
|
|
||||||
self.stack.set_visible_child_name(&vis);
|
self.stack.set_visible_child_name(&vis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,6 +131,26 @@ struct EpisodesMachine<S> {
|
|||||||
state: S,
|
state: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> EpisodesMachine<S> {
|
||||||
|
// FIXME:
|
||||||
|
fn update(&mut self) {
|
||||||
|
let vis = self.stack.get_visible_child_name().unwrap();
|
||||||
|
let old = self.stack.get_child_by_name("populated").unwrap();
|
||||||
|
|
||||||
|
let id = WidgetExt::get_name(&old).unwrap();
|
||||||
|
if id == "GtkBox" {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let pd = dbqueries::get_podcast_from_id(id.parse::<i32>().unwrap()).unwrap();
|
||||||
|
let pdw = EpisodesPopulated::new_initialized(&self.stack, &pd);
|
||||||
|
|
||||||
|
self.populated = pdw;
|
||||||
|
self.stack.remove(&old);
|
||||||
|
self.stack.add_named(&self.populated.container, "populated");
|
||||||
|
self.stack.set_visible_child_name(&vis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// impl Into<StackStateMachine<Populated, Shows>> for StackStateMachine<Populated, Episodes> {
|
// impl Into<StackStateMachine<Populated, Shows>> for StackStateMachine<Populated, Episodes> {
|
||||||
// fn into(self) -> StackStateMachine<Populated, Shows> {
|
// fn into(self) -> StackStateMachine<Populated, Shows> {
|
||||||
// self.stack.set_visible_child_name("shows");
|
// self.stack.set_visible_child_name("shows");
|
||||||
@ -353,6 +323,13 @@ impl EpisodeStateWrapper {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update(&mut self) {
|
||||||
|
match *self {
|
||||||
|
EpisodeStateWrapper::Populated(ref mut val) => val.update(),
|
||||||
|
EpisodeStateWrapper::Empty(ref mut val) => val.update(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn switch(self) -> Self {
|
fn switch(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()),
|
EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()),
|
||||||
|
|||||||
@ -4,8 +4,10 @@ use gtk::prelude::*;
|
|||||||
use hammond_data::Source;
|
use hammond_data::Source;
|
||||||
use hammond_data::utils::url_cleaner;
|
use hammond_data::utils::url_cleaner;
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use utils;
|
use utils;
|
||||||
// use content;
|
use content::Content;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Header {
|
pub struct Header {
|
||||||
@ -34,26 +36,31 @@ impl Header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_initialized(stack: >k::Stack) -> Header {
|
pub fn new_initialized(content: Arc<Mutex<Content>>) -> Header {
|
||||||
let header = Header::new();
|
let header = Header::new();
|
||||||
header.init(stack);
|
header.init(content);
|
||||||
header
|
header
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self, stack: >k::Stack) {
|
fn init(&self, content: Arc<Mutex<Content>>) {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui");
|
||||||
|
|
||||||
let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap();
|
let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap();
|
||||||
let new_url: gtk::Entry = builder.get_object("new-url").unwrap();
|
let new_url: gtk::Entry = builder.get_object("new-url").unwrap();
|
||||||
let add_button: gtk::Button = builder.get_object("add-button").unwrap();
|
let add_button: gtk::Button = builder.get_object("add-button").unwrap();
|
||||||
self.switch.set_stack(stack);
|
|
||||||
|
{
|
||||||
|
let cont = content.lock().unwrap();
|
||||||
|
self.switch.set_stack(&cont.stack);
|
||||||
|
}
|
||||||
|
|
||||||
new_url.connect_changed(move |url| {
|
new_url.connect_changed(move |url| {
|
||||||
println!("{:?}", url.get_text());
|
println!("{:?}", url.get_text());
|
||||||
});
|
});
|
||||||
|
|
||||||
add_button.connect_clicked(clone!(stack, add_popover, new_url => move |_| {
|
let cont = content.clone();
|
||||||
on_add_bttn_clicked(&stack, &new_url);
|
add_button.connect_clicked(clone!(cont, add_popover, new_url => move |_| {
|
||||||
|
on_add_bttn_clicked(cont.clone(), &new_url);
|
||||||
|
|
||||||
// TODO: lock the button instead of hiding and add notification of feed added.
|
// TODO: lock the button instead of hiding and add notification of feed added.
|
||||||
// TODO: map the spinner
|
// TODO: map the spinner
|
||||||
@ -62,13 +69,14 @@ impl Header {
|
|||||||
self.add_toggle.set_popover(&add_popover);
|
self.add_toggle.set_popover(&add_popover);
|
||||||
|
|
||||||
// FIXME: There appears to be a memmory leak here.
|
// FIXME: There appears to be a memmory leak here.
|
||||||
self.refresh.connect_clicked(clone!(stack => move |_| {
|
let cont = content.clone();
|
||||||
utils::refresh_feed(&stack, None, None);
|
self.refresh.connect_clicked(clone!(cont => move |_| {
|
||||||
|
utils::refresh_feed(cont.clone(), None, None);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_add_bttn_clicked(stack: >k::Stack, entry: >k::Entry) {
|
fn on_add_bttn_clicked(content: Arc<Mutex<Content>>, entry: >k::Entry) {
|
||||||
let url = entry.get_text().unwrap_or_default();
|
let url = entry.get_text().unwrap_or_default();
|
||||||
let url = url_cleaner(&url);
|
let url = url_cleaner(&url);
|
||||||
let source = Source::from_url(&url);
|
let source = Source::from_url(&url);
|
||||||
@ -76,7 +84,7 @@ fn on_add_bttn_clicked(stack: >k::Stack, entry: >k::Entry) {
|
|||||||
if let Ok(s) = source {
|
if let Ok(s) = source {
|
||||||
info!("{:?} feed added", url);
|
info!("{:?} feed added", url);
|
||||||
// update the db
|
// update the db
|
||||||
utils::refresh_feed(stack, Some(vec![s]), None);
|
utils::refresh_feed(content, Some(vec![s]), None);
|
||||||
} else {
|
} else {
|
||||||
error!("Feed probably already exists.");
|
error!("Feed probably already exists.");
|
||||||
error!("Error: {:?}", source.unwrap_err());
|
error!("Error: {:?}", source.unwrap_err());
|
||||||
|
|||||||
@ -22,6 +22,8 @@ use hammond_data::utils::checkup;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt};
|
use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt};
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
// http://gtk-rs.org/tuto/closures
|
// http://gtk-rs.org/tuto/closures
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! clone {
|
macro_rules! clone {
|
||||||
@ -69,7 +71,8 @@ fn build_ui(app: >k::Application) {
|
|||||||
|
|
||||||
// let ct = content::Content::new_initialized();
|
// let ct = content::Content::new_initialized();
|
||||||
let ct = content::Content::new();
|
let ct = content::Content::new();
|
||||||
let stack = ct.stack;
|
let stack = ct.stack.clone();
|
||||||
|
let ct = Arc::new(Mutex::new(ct));
|
||||||
window.add(&stack);
|
window.add(&stack);
|
||||||
|
|
||||||
window.connect_delete_event(|w, _| {
|
window.connect_delete_event(|w, _| {
|
||||||
@ -93,8 +96,8 @@ fn build_ui(app: >k::Application) {
|
|||||||
app.add_action(&check);
|
app.add_action(&check);
|
||||||
|
|
||||||
// queue a db update 1 minute after the startup.
|
// queue a db update 1 minute after the startup.
|
||||||
gtk::idle_add(clone!(stack => move || {
|
gtk::idle_add(clone!(ct => move || {
|
||||||
utils::refresh_feed(&stack, None, Some(60));
|
utils::refresh_feed(ct.clone(), None, Some(60));
|
||||||
glib::Continue(false)
|
glib::Continue(false)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -104,7 +107,7 @@ fn build_ui(app: >k::Application) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get the headerbar
|
// Get the headerbar
|
||||||
let header = headerbar::Header::new_initialized(&stack);
|
let header = headerbar::Header::new_initialized(ct.clone());
|
||||||
window.set_titlebar(&header.container);
|
window.set_titlebar(&header.container);
|
||||||
|
|
||||||
window.show_all();
|
window.show_all();
|
||||||
|
|||||||
@ -11,10 +11,12 @@ use std::cell::RefCell;
|
|||||||
use std::sync::mpsc::{channel, Receiver};
|
use std::sync::mpsc::{channel, Receiver};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use content;
|
use content::Content;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
type Foo = RefCell<Option<(gtk::Stack, Receiver<bool>)>>;
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
type Foo = RefCell<Option<(Arc<Mutex<Content>>, Receiver<bool>)>>;
|
||||||
|
|
||||||
// Create a thread local storage that will store the arguments to be transfered.
|
// Create a thread local storage that will store the arguments to be transfered.
|
||||||
thread_local!(static GLOBAL: Foo = RefCell::new(None));
|
thread_local!(static GLOBAL: Foo = RefCell::new(None));
|
||||||
@ -23,13 +25,13 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None));
|
|||||||
/// If `source` is None, Fetches all the `Source` entries in the database and updates them.
|
/// If `source` is None, Fetches all the `Source` entries in the database and updates them.
|
||||||
/// `delay` represents the desired time in seconds for the thread to sleep before executing.
|
/// `delay` represents the desired time in seconds for the thread to sleep before executing.
|
||||||
/// When It's done,it queues up a `podcast_view` refresh.
|
/// When It's done,it queues up a `podcast_view` refresh.
|
||||||
pub fn refresh_feed(stack: >k::Stack, source: Option<Vec<Source>>, delay: Option<u64>) {
|
pub fn refresh_feed(content: Arc<Mutex<Content>>, source: Option<Vec<Source>>, delay: Option<u64>) {
|
||||||
// Create a async channel.
|
// Create a async channel.
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
|
|
||||||
// Pass the desired arguments into the Local Thread Storage.
|
// Pass the desired arguments into the Local Thread Storage.
|
||||||
GLOBAL.with(clone!(stack => move |global| {
|
GLOBAL.with(clone!(content => move |global| {
|
||||||
*global.borrow_mut() = Some((stack, receiver));
|
*global.borrow_mut() = Some((content, receiver));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
@ -57,9 +59,10 @@ pub fn refresh_feed(stack: >k::Stack, source: Option<Vec<Source>>, delay: Opti
|
|||||||
|
|
||||||
fn refresh_podcasts_view() -> glib::Continue {
|
fn refresh_podcasts_view() -> glib::Continue {
|
||||||
GLOBAL.with(|global| {
|
GLOBAL.with(|global| {
|
||||||
if let Some((ref stack, ref reciever)) = *global.borrow() {
|
if let Some((ref content, ref reciever)) = *global.borrow() {
|
||||||
if reciever.try_recv().is_ok() {
|
if reciever.try_recv().is_ok() {
|
||||||
content::update_podcasts_preserve_vis(stack);
|
let mut content = content.lock().unwrap();
|
||||||
|
content.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user