1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-02-21 16:23:44 +00:00
comunicapiv3/src/helpers/push_notifications_helper.rs

149 lines
4.5 KiB
Rust
Raw Normal View History

//! # Push notifications helper
//!
//! @author Pierre Hubert
2021-04-15 11:08:11 +02:00
use crate::controllers::user_ws_controller;
use crate::data::conversation::ConvID;
use crate::data::conversation_message::ConversationMessage;
use crate::data::error::Res;
2021-04-15 11:08:11 +02:00
use crate::data::push_notification::PushNotification;
use crate::data::user::UserID;
use crate::data::user_token::{PushNotificationToken, UserAccessToken};
use crate::helpers::{account_helper, conversations_helper, independent_push_notifications_service_helper, user_helper};
use crate::helpers::events_helper::Event;
/// Un-register for previous push notifications service
pub fn un_register_from_previous_service(client: &UserAccessToken) -> Res {
// This method must not fail in case of error
if let PushNotificationToken::INDEPENDENT(old_token) = &client.push_notifications_token {
2021-04-12 17:59:00 +02:00
if let Err(e) = independent_push_notifications_service_helper::remove_token(old_token) {
eprintln!("Failed to un-register from independent push notifications service! {}", e);
}
}
2021-04-15 11:08:11 +02:00
Ok(())
}
/// Push a notification to specific tokens
fn push_notification(n: &PushNotification, targets: Vec<PushNotificationToken>) -> Res {
// TODO : implement
println!("* Push notification: {:#?} \n* To {:?}", n, targets);
Ok(())
}
/// Cancel a notification for specific tokens (optional)
fn cancel_notification(id: String, targets: Vec<PushNotificationToken>) -> Res {
// TODO : implement
println!("* Cancel push notification: {:#?} \n* For {:?}", id, targets);
Ok(())
}
/// Push a notification to specific users, only if they are not connected
fn push_notification_to_users(n: &PushNotification, users: Vec<UserID>) -> Res {
let dest_users: Vec<UserID> = users.into_iter()
.filter(|u| !user_ws_controller::is_user_connected(u))
.collect();
let mut dest_tokens = vec![];
for user in dest_users {
for token in account_helper::get_all_login_tokens(&user)? {
dest_tokens.push(token.push_notifications_token);
}
}
push_notification(n, dest_tokens)
}
/// Cancel a notification for one or more users
fn cancel_notification_for_users(id: String, users: Vec<UserID>) -> Res {
let mut dest_tokens = vec![];
for user in users {
for token in account_helper::get_all_login_tokens(&user)? {
dest_tokens.push(token.push_notifications_token);
}
}
cancel_notification(id, dest_tokens)
}
/// Create a conversation notification
pub fn create_conversation_notification(msg: &ConversationMessage) -> Res {
let user_id = match &msg.user_id {
Some(id) => id,
None => {
// Do no create notifications for server messages
return Ok(());
}
};
let user = user_helper::find_user_by_id(user_id)?;
let conv = conversations_helper::get_single(msg.conv_id)?;
let notif_title = match conv.name {
None => user.full_name(),
Some(name) => format!("{} ({})", user.full_name(), name)
};
let notif_message = match &msg.message {
None => "Shared file".to_string(),
Some(msg) => msg.to_string()
};
let notif = PushNotification {
id: format!("conv-{}", msg.conv_id.id()),
title: notif_title,
body: notif_message,
image: None,
timeout: None,
};
let list = conversations_helper::get_list_members(msg.conv_id)?
.into_iter()
.filter(|m| m.following && m.user_id != user_id)
.map(|m| m.user_id)
.collect();
push_notification_to_users(&notif, list)
}
/// Dismiss a conversation notification
pub fn cancel_conversation_notification(conv_id: ConvID, users: Option<Vec<UserID>>) -> Res {
let notif_id = format!("conv-{}", conv_id.id());
let list = match users {
Some(users) => users,
None => conversations_helper::get_list_members(conv_id)?
.into_iter().map(|m| m.user_id).collect()
};
cancel_notification_for_users(notif_id, list)
}
/// Handle event. This method NEVER returns Err
pub fn handle_event(e: &Event) -> Res {
if let Err(e) = handle_event_internal(e) {
eprintln!("Failed to create push notifications associated with event! {}", e);
}
Ok(())
}
fn handle_event_internal(e: &Event) -> Res {
match e {
Event::NewConversationMessage(msg) => {
create_conversation_notification(msg)?;
}
Event::SeenLastConversationMessage(user_id, conv_id) => {
cancel_conversation_notification(*conv_id, Some(vec![user_id.as_owned()]))?;
}
_ => {}
}
Ok(())
}