mirror of
https://github.com/youwen5/iamb.git
synced 2025-08-03 19:18:28 -07:00
Clear desktop notification when message is read (#427)
Co-authored-by: Ulyssa <git@ulyssa.dev>
This commit is contained in:
parent
0ff8828a1c
commit
e9cdb3371a
4 changed files with 62 additions and 10 deletions
|
@ -92,6 +92,7 @@ use modalkit::{
|
|||
|
||||
use crate::config::ImagePreviewProtocolValues;
|
||||
use crate::message::ImageStatus;
|
||||
use crate::notifications::NotificationHandle;
|
||||
use crate::preview::{source_from_event, spawn_insert_preview};
|
||||
use crate::{
|
||||
message::{Message, MessageEvent, MessageKey, MessageTimeStamp, Messages},
|
||||
|
@ -1558,6 +1559,9 @@ pub struct ChatStore {
|
|||
|
||||
/// Collator for locale-aware text sorting.
|
||||
pub collator: feruca::Collator,
|
||||
|
||||
/// Notifications that should be dismissed when the user opens the room.
|
||||
pub open_notifications: HashMap<OwnedRoomId, Vec<NotificationHandle>>,
|
||||
}
|
||||
|
||||
impl ChatStore {
|
||||
|
@ -1582,6 +1586,7 @@ impl ChatStore {
|
|||
draw_curr: None,
|
||||
ring_bell: false,
|
||||
focused: true,
|
||||
open_notifications: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -561,6 +561,9 @@ impl Application {
|
|||
IambAction::ClearUnreads => {
|
||||
let user_id = &store.application.settings.profile.user_id;
|
||||
|
||||
// Clear any notifications we displayed:
|
||||
store.application.open_notifications.clear();
|
||||
|
||||
for room_id in store.application.sync_info.chats() {
|
||||
if let Some(room) = store.application.rooms.get_mut(room_id) {
|
||||
room.fully_read(user_id);
|
||||
|
|
|
@ -8,6 +8,7 @@ use matrix_sdk::{
|
|||
events::{room::message::MessageType, AnyMessageLikeEventContent, AnySyncTimelineEvent},
|
||||
serde::Raw,
|
||||
MilliSecondsSinceUnixEpoch,
|
||||
OwnedRoomId,
|
||||
RoomId,
|
||||
},
|
||||
Client,
|
||||
|
@ -24,6 +25,21 @@ const IAMB_XDG_NAME: &str = match option_env!("IAMB_XDG_NAME") {
|
|||
Some(iamb) => iamb,
|
||||
};
|
||||
|
||||
/// Handle for an open notification that should be closed when the user views it.
|
||||
pub struct NotificationHandle(
|
||||
#[cfg(all(feature = "desktop", unix, not(target_os = "macos")))]
|
||||
Option<notify_rust::NotificationHandle>,
|
||||
);
|
||||
|
||||
impl Drop for NotificationHandle {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(all(feature = "desktop", unix, not(target_os = "macos")))]
|
||||
if let Some(handle) = self.0.take() {
|
||||
handle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn register_notifications(
|
||||
client: &Client,
|
||||
settings: &ApplicationSettings,
|
||||
|
@ -54,6 +70,7 @@ pub async fn register_notifications(
|
|||
return;
|
||||
}
|
||||
|
||||
let room_id = room.room_id().to_owned();
|
||||
match notification.event {
|
||||
RawAnySyncOrStrippedTimelineEvent::Sync(e) => {
|
||||
match parse_full_notification(e, room, show_message).await {
|
||||
|
@ -66,8 +83,14 @@ pub async fn register_notifications(
|
|||
return;
|
||||
}
|
||||
|
||||
send_notification(¬ify_via, &store, &summary, body.as_deref())
|
||||
.await;
|
||||
send_notification(
|
||||
¬ify_via,
|
||||
&summary,
|
||||
body.as_deref(),
|
||||
room_id,
|
||||
&store,
|
||||
)
|
||||
.await;
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to extract notification data: {err}")
|
||||
|
@ -86,13 +109,14 @@ pub async fn register_notifications(
|
|||
|
||||
async fn send_notification(
|
||||
via: &NotifyVia,
|
||||
store: &AsyncProgramStore,
|
||||
summary: &str,
|
||||
body: Option<&str>,
|
||||
room_id: OwnedRoomId,
|
||||
store: &AsyncProgramStore,
|
||||
) {
|
||||
#[cfg(feature = "desktop")]
|
||||
if via.desktop {
|
||||
send_notification_desktop(summary, body);
|
||||
send_notification_desktop(summary, body, room_id, store).await;
|
||||
}
|
||||
#[cfg(not(feature = "desktop"))]
|
||||
{
|
||||
|
@ -110,7 +134,12 @@ async fn send_notification_bell(store: &AsyncProgramStore) {
|
|||
}
|
||||
|
||||
#[cfg(feature = "desktop")]
|
||||
fn send_notification_desktop(summary: &str, body: Option<&str>) {
|
||||
async fn send_notification_desktop(
|
||||
summary: &str,
|
||||
body: Option<&str>,
|
||||
room_id: OwnedRoomId,
|
||||
_store: &AsyncProgramStore,
|
||||
) {
|
||||
let mut desktop_notification = notify_rust::Notification::new();
|
||||
desktop_notification
|
||||
.summary(summary)
|
||||
|
@ -125,8 +154,19 @@ fn send_notification_desktop(summary: &str, body: Option<&str>) {
|
|||
desktop_notification.body(body);
|
||||
}
|
||||
|
||||
if let Err(err) = desktop_notification.show() {
|
||||
tracing::error!("Failed to send notification: {err}")
|
||||
match desktop_notification.show() {
|
||||
Err(err) => tracing::error!("Failed to send notification: {err}"),
|
||||
Ok(handle) => {
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
_store
|
||||
.lock()
|
||||
.await
|
||||
.application
|
||||
.open_notifications
|
||||
.entry(room_id)
|
||||
.or_default()
|
||||
.push(NotificationHandle(Some(handle)));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -502,19 +502,23 @@ async fn send_receipts_forever(client: &Client, store: &AsyncProgramStore) {
|
|||
loop {
|
||||
interval.tick().await;
|
||||
|
||||
let locked = store.lock().await;
|
||||
let user_id = &locked.application.settings.profile.user_id;
|
||||
let mut locked = store.lock().await;
|
||||
let ChatStore { settings, open_notifications, rooms, .. } = &mut locked.application;
|
||||
let user_id = &settings.profile.user_id;
|
||||
|
||||
let mut updates = Vec::new();
|
||||
for room in client.joined_rooms() {
|
||||
let room_id = room.room_id();
|
||||
let Some(info) = locked.application.rooms.get(&room_id) else {
|
||||
let Some(info) = rooms.get(room_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let changed = info.receipts(user_id).filter_map(|(thread, new_receipt)| {
|
||||
let old_receipt = sent.get(room_id).and_then(|ts| ts.get(thread));
|
||||
let changed = Some(new_receipt) != old_receipt;
|
||||
if changed {
|
||||
open_notifications.remove(room_id);
|
||||
}
|
||||
changed.then(|| (room_id.to_owned(), thread.to_owned(), new_receipt.to_owned()))
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue