remove deprecated MainContext channel
This commit is contained in:
@ -265,38 +265,40 @@ impl NotifyApplication {
|
|||||||
// `Invalid client serial` and it's broken.
|
// `Invalid client serial` and it's broken.
|
||||||
// Until https://github.com/flatpak/xdg-dbus-proxy/issues/46 is solved, I have to handle these things
|
// Until https://github.com/flatpak/xdg-dbus-proxy/issues/46 is solved, I have to handle these things
|
||||||
// in the main thread. Uff.
|
// in the main thread. Uff.
|
||||||
let (tx, rx) = glib::MainContext::channel(Default::default());
|
|
||||||
|
let (s, r) = async_channel::unbounded::<models::Notification>();
|
||||||
|
|
||||||
let app = self.clone();
|
let app = self.clone();
|
||||||
rx.attach(None, move |n: models::Notification| {
|
glib::MainContext::ref_thread_default().spawn_local(async move {
|
||||||
let gio_notif = gio::Notification::new(&n.title);
|
while let Ok(n) = r.recv().await {
|
||||||
gio_notif.set_body(Some(&n.body));
|
let gio_notif = gio::Notification::new(&n.title);
|
||||||
|
gio_notif.set_body(Some(&n.body));
|
||||||
|
|
||||||
let action_name = |a| {
|
let action_name = |a| {
|
||||||
let json = serde_json::to_string(a).unwrap();
|
let json = serde_json::to_string(a).unwrap();
|
||||||
gio::Action::print_detailed_name("app.message-action", Some(&json.into()))
|
gio::Action::print_detailed_name("app.message-action", Some(&json.into()))
|
||||||
};
|
};
|
||||||
for a in n.actions.iter() {
|
for a in n.actions.iter() {
|
||||||
match a {
|
match a {
|
||||||
models::Action::View { label, .. } => {
|
models::Action::View { label, .. } => {
|
||||||
gio_notif.add_button(&label, &action_name(a))
|
gio_notif.add_button(&label, &action_name(a))
|
||||||
|
}
|
||||||
|
models::Action::Http { label, .. } => {
|
||||||
|
gio_notif.add_button(&label, &action_name(a))
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
models::Action::Http { label, .. } => {
|
|
||||||
gio_notif.add_button(&label, &action_name(a))
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.send_notification(None, &gio_notif);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.send_notification(None, &gio_notif);
|
|
||||||
glib::ControlFlow::Continue
|
|
||||||
});
|
});
|
||||||
|
|
||||||
struct Proxies {
|
struct Proxies {
|
||||||
notification: glib::Sender<models::Notification>,
|
notification: async_channel::Sender<models::Notification>,
|
||||||
}
|
}
|
||||||
impl models::NotificationProxy for Proxies {
|
impl models::NotificationProxy for Proxies {
|
||||||
fn send(&self, n: models::Notification) -> anyhow::Result<()> {
|
fn send(&self, n: models::Notification) -> anyhow::Result<()> {
|
||||||
self.notification.send(n)?;
|
self.notification.send_blocking(n)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,7 +319,7 @@ impl NotifyApplication {
|
|||||||
Box::pin(rx)
|
Box::pin(rx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let proxies = std::sync::Arc::new(Proxies { notification: tx });
|
let proxies = std::sync::Arc::new(Proxies { notification: s });
|
||||||
ntfy_daemon::system_client::start(
|
ntfy_daemon::system_client::start(
|
||||||
socket_path.to_owned(),
|
socket_path.to_owned(),
|
||||||
dbpath.to_str().unwrap(),
|
dbpath.to_str().unwrap(),
|
||||||
|
|||||||
@ -1,28 +1,28 @@
|
|||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use glib::Receiver;
|
|
||||||
use glib::SourceId;
|
use glib::SourceId;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
pub fn debounce_channel<T: 'static>(
|
#[derive(Clone)]
|
||||||
duration: std::time::Duration,
|
pub struct Debouncer {
|
||||||
source: Receiver<T>,
|
scheduled: Rc<Cell<Option<SourceId>>>,
|
||||||
) -> Receiver<T> {
|
}
|
||||||
let (tx, rx) = glib::MainContext::channel(Default::default());
|
impl Debouncer {
|
||||||
let scheduled = Rc::new(Cell::new(None::<SourceId>));
|
pub fn new() -> Self {
|
||||||
source.attach(None, move |data| {
|
Self {
|
||||||
if let Some(scheduled) = scheduled.take() {
|
scheduled: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn call(&self, duration: std::time::Duration, f: impl Fn() -> () + 'static) {
|
||||||
|
if let Some(scheduled) = self.scheduled.take() {
|
||||||
scheduled.remove();
|
scheduled.remove();
|
||||||
}
|
}
|
||||||
let tx = tx.clone();
|
let scheduled_clone = self.scheduled.clone();
|
||||||
let scheduled_clone = scheduled.clone();
|
|
||||||
let source_id = glib::source::timeout_add_local_once(duration, move || {
|
let source_id = glib::source::timeout_add_local_once(duration, move || {
|
||||||
tx.send(data).unwrap();
|
f();
|
||||||
scheduled_clone.take();
|
scheduled_clone.take();
|
||||||
});
|
});
|
||||||
scheduled.set(Some(source_id));
|
self.scheduled.set(Some(source_id));
|
||||||
glib::ControlFlow::Continue
|
}
|
||||||
});
|
|
||||||
rx
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,24 +145,29 @@ impl AddSubscriptionDialog {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
let (tx, rx) = glib::MainContext::channel(Default::default());
|
let debounced_error_check = {
|
||||||
let txc = tx.clone();
|
let db = crate::async_utils::Debouncer::new();
|
||||||
topic_entry.delegate().unwrap().connect_changed(move |_| {
|
let objc = obj.clone();
|
||||||
txc.send(()).unwrap();
|
move || {
|
||||||
});
|
db.call(std::time::Duration::from_millis(500), move || {
|
||||||
let txc = tx.clone();
|
objc.check_errors()
|
||||||
server_entry.delegate().unwrap().connect_changed(move |_| {
|
});
|
||||||
txc.send(()).unwrap();
|
}
|
||||||
});
|
};
|
||||||
server_expander.connect_enable_expansion_notify(move |_| {
|
|
||||||
tx.send(()).unwrap();
|
let f = debounced_error_check.clone();
|
||||||
});
|
topic_entry
|
||||||
let rx = crate::async_utils::debounce_channel(std::time::Duration::from_millis(500), rx);
|
.delegate()
|
||||||
let objc = obj.clone();
|
.unwrap()
|
||||||
rx.attach(None, move |_| {
|
.connect_changed(move |_| f.clone()());
|
||||||
objc.check_errors();
|
let f = debounced_error_check.clone();
|
||||||
glib::ControlFlow::Continue
|
server_entry
|
||||||
});
|
.delegate()
|
||||||
|
.unwrap()
|
||||||
|
.connect_changed(move |_| f.clone()());
|
||||||
|
let f = debounced_error_check.clone();
|
||||||
|
server_expander.connect_enable_expansion_notify(move |_| f.clone()());
|
||||||
|
|
||||||
imp.widgets.replace(Widgets {
|
imp.widgets.replace(Widgets {
|
||||||
topic_entry,
|
topic_entry,
|
||||||
server_expander,
|
server_expander,
|
||||||
|
|||||||
@ -9,6 +9,8 @@ use gtk::{gdk, gio, glib};
|
|||||||
use ntfy_daemon::models;
|
use ntfy_daemon::models;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
|
use crate::widgets::window::SpawnWithToast;
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -161,10 +163,10 @@ impl MessageRow {
|
|||||||
Ok(bytes)
|
Ok(bytes)
|
||||||
}
|
}
|
||||||
fn build_image(&self, url: String) -> gtk::Picture {
|
fn build_image(&self, url: String) -> gtk::Picture {
|
||||||
let (tx, rx) = glib::MainContext::channel(Default::default());
|
let (s, r) = async_channel::unbounded();
|
||||||
gio::spawn_blocking(move || {
|
gio::spawn_blocking(move || {
|
||||||
if let Err(e) =
|
if let Err(e) = Self::fetch_image_bytes(&url)
|
||||||
Self::fetch_image_bytes(&url).map(|bytes| tx.send(glib::Bytes::from_owned(bytes)))
|
.map(|bytes| s.send_blocking(glib::Bytes::from_owned(bytes)))
|
||||||
{
|
{
|
||||||
error!(error = %e)
|
error!(error = %e)
|
||||||
}
|
}
|
||||||
@ -174,18 +176,15 @@ impl MessageRow {
|
|||||||
picture.set_can_shrink(true);
|
picture.set_can_shrink(true);
|
||||||
picture.set_height_request(350);
|
picture.set_height_request(350);
|
||||||
let picturec = picture.clone();
|
let picturec = picture.clone();
|
||||||
rx.attach(Default::default(), move |b| {
|
|
||||||
|
self.spawn_with_near_toast(async move {
|
||||||
|
let b = r.recv().await?;
|
||||||
let stream = gio::MemoryInputStream::from_bytes(&b);
|
let stream = gio::MemoryInputStream::from_bytes(&b);
|
||||||
let pixbuf = match Pixbuf::from_stream(&stream, gio::Cancellable::NONE) {
|
let pixbuf = Pixbuf::from_stream(&stream, gio::Cancellable::NONE)?;
|
||||||
Ok(res) => res,
|
|
||||||
Err(e) => {
|
|
||||||
error!(error = %e, "parsing image contents");
|
|
||||||
return glib::ControlFlow::Break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
picturec.set_paintable(Some(&gdk::Texture::for_pixbuf(&pixbuf)));
|
picturec.set_paintable(Some(&gdk::Texture::for_pixbuf(&pixbuf)));
|
||||||
glib::ControlFlow::Break
|
Ok::<(), anyhow::Error>(())
|
||||||
});
|
});
|
||||||
|
|
||||||
picture
|
picture
|
||||||
}
|
}
|
||||||
fn build_action_btn(&self, action: models::Action) -> gtk::Button {
|
fn build_action_btn(&self, action: models::Action) -> gtk::Button {
|
||||||
|
|||||||
@ -49,23 +49,19 @@ mod imp {
|
|||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
let this = self.obj().clone();
|
let this = self.obj().clone();
|
||||||
|
|
||||||
let (tx, rx) = glib::MainContext::channel(glib::Priority::default());
|
|
||||||
let rx =
|
|
||||||
crate::async_utils::debounce_channel(std::time::Duration::from_millis(500), rx);
|
|
||||||
rx.attach(None, move |entry| {
|
|
||||||
this.update_display_name(&entry);
|
|
||||||
glib::ControlFlow::Continue
|
|
||||||
});
|
|
||||||
|
|
||||||
let this = self.obj().clone();
|
|
||||||
self.display_name_entry
|
self.display_name_entry
|
||||||
.set_text(&this.subscription().unwrap().display_name());
|
.set_text(&this.subscription().unwrap().display_name());
|
||||||
self.muted_switch_row
|
self.muted_switch_row
|
||||||
.set_active(this.subscription().unwrap().muted());
|
.set_active(this.subscription().unwrap().muted());
|
||||||
|
|
||||||
|
let debouncer = crate::async_utils::Debouncer::new();
|
||||||
self.display_name_entry.connect_changed({
|
self.display_name_entry.connect_changed({
|
||||||
move |entry| {
|
move |entry| {
|
||||||
tx.send(entry.clone()).unwrap();
|
let entry = entry.clone();
|
||||||
|
let this = this.clone();
|
||||||
|
debouncer.call(std::time::Duration::from_millis(500), move || {
|
||||||
|
this.update_display_name(&entry);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let this = self.obj().clone();
|
let this = self.obj().clone();
|
||||||
|
|||||||
Reference in New Issue
Block a user