mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-12-27 22:18:51 +00:00
Start to push notifications
This commit is contained in:
parent
0e80564f85
commit
4d6ff8fef3
@ -8,8 +8,9 @@ use crate::constants::PATH_COMMENTS_IMAGES;
|
||||
use crate::controllers::routes::RequestResult;
|
||||
use crate::data::comment::Comment;
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
use crate::data::notification::NotifEventType;
|
||||
use crate::data::post::PostAccessLevel;
|
||||
use crate::helpers::{comments_helper, posts_helper};
|
||||
use crate::helpers::{comments_helper, notifications_helper, posts_helper};
|
||||
use crate::utils::date_utils::time;
|
||||
use crate::utils::string_utils::remove_html_nodes;
|
||||
|
||||
@ -45,7 +46,9 @@ pub fn create(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
|
||||
let comment_id = comments_helper::create(&comment)?;
|
||||
|
||||
// TODO : Create notifications
|
||||
// Create notifications
|
||||
notifications_helper::create_post_notification(&r.user_id()?, post.id, NotifEventType::COMMENT_CREATED)?;
|
||||
|
||||
// TODO : Remove notifications targeting current user about the post
|
||||
|
||||
r.set_response(ResCreateComment::new(comment_id))
|
||||
|
@ -211,6 +211,11 @@ impl PartialNotification {
|
||||
self.id.is_some()
|
||||
}
|
||||
|
||||
pub fn set_time_create(mut self, time: u64) -> PartialNotification {
|
||||
self.time_create = Some(time);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_dest_user_id(mut self, id: &UserID) -> PartialNotification {
|
||||
self.dest_user_id = Some(id.clone());
|
||||
self
|
||||
@ -230,4 +235,9 @@ impl PartialNotification {
|
||||
self.on_elem_type = Some(t);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_type(mut self, t: NotifEventType) -> PartialNotification {
|
||||
self.kind = Some(t);
|
||||
self
|
||||
}
|
||||
}
|
@ -153,6 +153,11 @@ impl Post {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check out whether a post is targeting a group page or not
|
||||
pub fn is_on_group_page(&self) -> bool {
|
||||
matches!(self.target_page, PostPageKind::PAGE_KIND_GROUP(_))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -552,6 +552,13 @@ impl InsertQuery {
|
||||
}
|
||||
}
|
||||
|
||||
/// Add batch values
|
||||
pub fn add_values(mut self, values: HashMap<String, mysql::Value>) -> Self {
|
||||
self.values.extend(values.into_iter());
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
/// Add a string
|
||||
pub fn add_str(mut self, key: &str, value: &str) -> InsertQuery {
|
||||
self.values.insert(key.to_string(), Value::from(value));
|
||||
|
@ -16,8 +16,10 @@ use crate::helpers::database::QueryInfo;
|
||||
pub struct GetFriendsQuery {
|
||||
only_accepted: bool,
|
||||
only_following: bool,
|
||||
only_followers: bool,
|
||||
target_user: UserID,
|
||||
friend_id: Option<UserID>,
|
||||
common_with_user: Option<UserID>,
|
||||
}
|
||||
|
||||
impl GetFriendsQuery {
|
||||
@ -26,8 +28,10 @@ impl GetFriendsQuery {
|
||||
GetFriendsQuery {
|
||||
only_accepted: false,
|
||||
only_following: false,
|
||||
only_followers: false,
|
||||
target_user: target_user.clone(),
|
||||
friend_id: None,
|
||||
common_with_user: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,11 +40,24 @@ impl GetFriendsQuery {
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify whether only the friends followed by friend_id should be selected
|
||||
pub fn set_only_following(mut self, following: bool) -> GetFriendsQuery {
|
||||
self.only_following = following;
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify whether only the friends following friend_id should be selected
|
||||
pub fn set_only_followers(mut self, following: bool) -> GetFriendsQuery {
|
||||
self.only_followers = following;
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify whether all the returned friends should be common with a specified user
|
||||
pub fn set_only_common_with(mut self, user: &UserID) -> GetFriendsQuery {
|
||||
self.common_with_user = Some(user.clone());
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the list of friends
|
||||
pub fn exec(self) -> ResultBoxError<Vec<Friend>> {
|
||||
get_list(&self)
|
||||
@ -80,6 +97,26 @@ fn get_list(friend_query: &GetFriendsQuery) -> ResultBoxError<Vec<Friend>> {
|
||||
query = query.cond_legacy_bool("f.abonnement", true);
|
||||
}
|
||||
|
||||
let mut custom_where = String::new();
|
||||
|
||||
if friend_query.only_followers {
|
||||
custom_where = " EXISTS (SELECT * FROM amis d WHERE d.ID_personne = f.ID_amis AND d.ID_amis = f.ID_personne AND abonnement = 1) ".to_string();
|
||||
}
|
||||
|
||||
if let Some(user_id) = &friend_query.common_with_user {
|
||||
if !custom_where.is_empty() {
|
||||
custom_where.push_str(" AND ");
|
||||
}
|
||||
|
||||
custom_where.push_str(" (f.ID_amis = ? OR EXISTS (SELECT * FROM amis d WHERE d.ID_personne = ? AND d.ID_amis = f.ID_amis AND actif = 1) ) ");
|
||||
query = query.add_custom_where_argument_user_id(user_id);
|
||||
query = query.add_custom_where_argument_user_id(user_id);
|
||||
}
|
||||
|
||||
if !custom_where.is_empty() {
|
||||
query = query.set_custom_where(&custom_where);
|
||||
}
|
||||
|
||||
query.exec(db_to_friend)
|
||||
}
|
||||
|
||||
|
@ -313,6 +313,15 @@ pub fn get_access_level(group_id: &GroupID, user_id: Option<UserID>) -> ResultBo
|
||||
Ok(GroupAccessLevel::NO_ACCESS)
|
||||
}
|
||||
|
||||
/// Get the list of follower of a given group
|
||||
pub fn get_list_followers(group_id: &GroupID) -> ResultBoxError<Vec<UserID>> {
|
||||
database::QueryInfo::new(GROUPS_MEMBERS_TABLE)
|
||||
.cond_group_id("groups_id", group_id)
|
||||
.cond_legacy_bool("following", true)
|
||||
.add_field("user_id")
|
||||
.exec(|r| r.get_user_id("user_id"))
|
||||
}
|
||||
|
||||
/// Count the number of members of a group
|
||||
pub fn count_members(group_id: &GroupID) -> ResultBoxError<usize> {
|
||||
database::QueryInfo::new(GROUPS_MEMBERS_TABLE)
|
||||
|
@ -8,8 +8,147 @@ use crate::constants::database_tables_names::NOTIFICATIONS_TABLE;
|
||||
use crate::data::error::ResultBoxError;
|
||||
use crate::data::group_id::GroupID;
|
||||
use crate::data::notification::{NotifElemType, NotifEventType, NotifEventVisibility, Notification, PartialNotification};
|
||||
use crate::data::post::{PostPageKind, PostVisibilityLevel};
|
||||
use crate::data::user::UserID;
|
||||
use crate::helpers::database;
|
||||
use crate::helpers::{database, groups_helper, posts_helper};
|
||||
use crate::helpers::friends_helper::GetFriendsQuery;
|
||||
use crate::utils::date_utils;
|
||||
|
||||
/// Create post notification
|
||||
pub fn create_post_notification(from_user: &UserID, post_id: u64, action: NotifEventType) -> ResultBoxError {
|
||||
let mut n = PartialNotification::new()
|
||||
.set_time_create(date_utils::time())
|
||||
.set_from_user_id(from_user)
|
||||
.set_on_elem_id(post_id)
|
||||
.set_on_elem_type(NotifElemType::POST)
|
||||
.set_type(action);
|
||||
|
||||
push(&mut n)
|
||||
}
|
||||
|
||||
/// Push a new notification
|
||||
pub fn push(n: &mut PartialNotification) -> ResultBoxError
|
||||
{
|
||||
if n.time_create.is_none()
|
||||
{
|
||||
n.time_create = Some(date_utils::time());
|
||||
}
|
||||
|
||||
// Determine the visibility level of the notification
|
||||
if matches!(n.on_elem_type, Some(NotifElemType::POST)) {
|
||||
let post = posts_helper::get_single(n.on_elem_id.unwrap())?;
|
||||
|
||||
// Determine post container
|
||||
match &post.target_page {
|
||||
PostPageKind::PAGE_KIND_USER(user_id) => {
|
||||
n.container_type = Some(NotifElemType::USER_PAGE);
|
||||
n.container_id = Some(user_id.id());
|
||||
}
|
||||
|
||||
PostPageKind::PAGE_KIND_GROUP(group_id) => {
|
||||
n.container_type = Some(NotifElemType::GROUP_PAGE);
|
||||
n.container_id = Some(group_id.id());
|
||||
}
|
||||
};
|
||||
|
||||
// Check the scope of the notification
|
||||
// Private post (on user page)
|
||||
if matches!(post.visibility, PostVisibilityLevel::VISIBILITY_USER) {
|
||||
// Check if the post belongs to current user => no notification needed
|
||||
if &post.user_id == post.user_page_id().unwrap() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// If the person who posted that is not the owner of the page
|
||||
if post.user_page_id().unwrap() != n.from_user_id.as_ref().unwrap() {
|
||||
n.dest_user_id = Some(post.user_page_id().unwrap().clone());
|
||||
}
|
||||
|
||||
// If the user is the owner of the page, but the post does not belongs to him
|
||||
else {
|
||||
n.dest_user_id = Some(post.user_id);
|
||||
}
|
||||
|
||||
return push_private(n);
|
||||
}
|
||||
|
||||
// Posts on user page
|
||||
else if post.is_on_user_page() {
|
||||
let mut friend_req = GetFriendsQuery::new(n.from_user_id.as_ref().unwrap())
|
||||
.set_only_followers(true);
|
||||
|
||||
// If the person who created the notification is not on his page
|
||||
if n.from_user_id.as_ref().unwrap() != post.user_page_id().unwrap() {
|
||||
friend_req = friend_req.set_only_common_with(post.user_page_id().unwrap())
|
||||
}
|
||||
|
||||
let friends: Vec<UserID> = friend_req
|
||||
.exec()?
|
||||
.into_iter()
|
||||
.map(|f| f.friend_id)
|
||||
.collect();
|
||||
|
||||
return push_public(n, friends);
|
||||
}
|
||||
|
||||
// Posts on group pages
|
||||
else if post.is_on_group_page() {
|
||||
return push_group_members(n, post.group_id().unwrap());
|
||||
}
|
||||
|
||||
// Unsupported scenario
|
||||
else {
|
||||
unimplemented!();
|
||||
}
|
||||
} else {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
/// Push a notification to group members
|
||||
pub fn push_group_members(n: &mut PartialNotification, group_id: &GroupID) -> ResultBoxError {
|
||||
let mut list = groups_helper::get_list_followers(group_id)?;
|
||||
list = list.into_iter().filter(|f| f != n.from_user_id.as_ref().unwrap()).collect();
|
||||
push_public(n, list)
|
||||
}
|
||||
|
||||
/// Push a public notification
|
||||
fn push_public(n: &mut PartialNotification, users: Vec<UserID>) -> ResultBoxError {
|
||||
n.visibility = Some(NotifEventVisibility::EVENT_PUBLIC);
|
||||
|
||||
for user_id in users {
|
||||
n.dest_user_id = Some(user_id);
|
||||
|
||||
if !similar_exists(n)? {
|
||||
create(n)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Push a private notification (to 1 user)
|
||||
fn push_private(n: &mut PartialNotification) -> ResultBoxError {
|
||||
n.visibility = Some(NotifEventVisibility::EVENT_PRIVATE);
|
||||
|
||||
if !similar_exists(n)? {
|
||||
create(n)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a new notification
|
||||
fn create(n: &PartialNotification) -> ResultBoxError {
|
||||
database::InsertQuery::new(NOTIFICATIONS_TABLE)
|
||||
.add_values(notif_to_db(n, true))
|
||||
.insert_drop_result()?;
|
||||
|
||||
// TODO : WebSocket : trigger notify system
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
/// Delete notifications
|
||||
pub fn delete(notification: &PartialNotification) -> ResultBoxError {
|
||||
|
Loading…
Reference in New Issue
Block a user