feat(notification): When clicking on a notification, activate the corresponding channel

Closes #280.
This commit is contained in:
Julian Schmidhuber committed 2026-03-08 11:21:15 +01:00
1 parent ad6935c2f2
commit 730b8bd07c
6 files changed
+70 -3

No files matched your search

+1
View File
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Startup screen when loading messages.
- Clicking on a notification now brings up the channel the notification came from.
### Changed
+22
View File
@@ -591,6 +591,28 @@ impl Channel {
})
.collect()
}
pub fn notification_variant(&self) -> (u8, Vec<u8>) {
let thread = self.thread();
match thread {
Thread::Contact(u) => (0, u.service_id_binary()),
Thread::Group(g) => (1, g.into()),
}
}
pub fn from_notification_variant((kind, data): (u8, Vec<u8>)) -> Thread {
match kind {
0 => Thread::Contact(
ServiceId::parse_from_service_id_binary(&data)
.expect("Notification variant for contact to be a service ID"),
),
1 => Thread::Group(
data.try_into()
.expect("Notification variant for groups to have the correct number of bytes"),
),
_ => unreachable!("Unexpected notification variant type"),
}
}
}
mod imp {
+5
View File
@@ -472,6 +472,11 @@ impl Manager {
channel
}
pub fn channel_from_thread(&self, thread: Thread) -> Option<Channel> {
let known_channels = self.imp().channels.borrow_mut();
known_channels.get(&thread).cloned()
}
#[cfg(not(feature = "screenshot"))]
pub async fn list_contacts(&self) -> Vec<Contact> {
let store = self.store();
+4
View File
@@ -41,6 +41,10 @@ impl DisplayMessage {
notification.set_body(Some(&notification_body));
notification.set_icon(&icon);
notification.set_category(Some("im.received"));
notification.set_default_action_and_target_value(
"app.notification-clicked",
Some(&channel.notification_variant().to_variant()),
);
let manager = self.manager();
let uid = self.uid();
+4
View File
@@ -96,6 +96,10 @@ impl ReactionMessage {
notification.set_body(Some(&notification_body));
notification.set_icon(&icon);
notification.set_category(Some("im.received"));
notification.set_default_action_and_target_value(
"app.notification-clicked",
Some(&channel.notification_variant().to_variant()),
);
let manager = self.manager();
let uid = self.uid();
+34 -3
View File
@@ -1,4 +1,7 @@
use crate::prelude::*;
use gio::SimpleAction;
use presage::store::Thread;
use crate::{backend::Channel, prelude::*};
glib::wrapper! {
/// The main application window.
@@ -24,9 +27,30 @@ impl Window {
);
}
app.set_accels_for_action("channel-list.toggle-search", &["<Control>f"]);
Object::builder::<Self>()
let window = Object::builder::<Self>()
.property("application", app)
.build()
.build();
let action_notification_clicked = SimpleAction::new(
"notification-clicked",
Some(&<(u8, Vec<u8>)>::static_variant_type()),
);
action_notification_clicked.connect_activate(clone!(
#[weak]
window,
move |_, variant| {
let variant: (u8, Vec<u8>) = variant
.expect("Notification-clicked action to have attached data")
.get()
.expect("Variant of notification is of unexpected type");
let thread = Channel::from_notification_variant(variant);
window.activate_channel(thread);
}
));
app.add_action(&action_notification_clicked);
window
}
// Closes the window, even if hide-on-close is set.
@@ -69,6 +93,13 @@ impl Window {
}
}
fn activate_channel(&self, thread: Thread) {
let channel = self
.property::<Manager>("manager")
.channel_from_thread(thread);
self.imp().channel_list.set_active_channel(channel);
}
pub(crate) fn settings(&self) -> gio::Settings {
self.imp().settings.clone()
}