mirror of
				https://gitlab.com/comunic/comunicapiv3
				synced 2025-11-04 09:34:04 +00:00 
			
		
		
		
	Can get the list of unread notifications
This commit is contained in:
		@@ -40,3 +40,4 @@ pub mod posts_targets_api;
 | 
			
		||||
pub mod res_create_comment;
 | 
			
		||||
pub mod res_number_unread_notifications;
 | 
			
		||||
pub mod res_count_all_unreads;
 | 
			
		||||
pub mod notification_api;
 | 
			
		||||
							
								
								
									
										59
									
								
								src/api_data/notification_api.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/api_data/notification_api.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
//! # API Notification object
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
use serde::{Serialize, Serializer};
 | 
			
		||||
use serde::ser::SerializeMap;
 | 
			
		||||
 | 
			
		||||
use crate::data::notification::Notification;
 | 
			
		||||
 | 
			
		||||
struct TypeContainer {
 | 
			
		||||
    t: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Serialize for TypeContainer {
 | 
			
		||||
    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
 | 
			
		||||
        S: Serializer {
 | 
			
		||||
        let mut map = serializer.serialize_map(Some(1))?;
 | 
			
		||||
        map.serialize_entry("type", &self.t)?;
 | 
			
		||||
        map.end()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize)]
 | 
			
		||||
pub struct NotificationAPI {
 | 
			
		||||
    id: u64,
 | 
			
		||||
    time_create: u64,
 | 
			
		||||
    seen: bool,
 | 
			
		||||
    from_user_id: u64,
 | 
			
		||||
    dest_user_id: u64,
 | 
			
		||||
    on_elem_id: u64,
 | 
			
		||||
    on_elem_type: String,
 | 
			
		||||
    #[serde(flatten)]
 | 
			
		||||
    type_container: TypeContainer,
 | 
			
		||||
    event_visibility: String,
 | 
			
		||||
    from_container_id: Option<u64>,
 | 
			
		||||
    from_container_type: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl NotificationAPI {
 | 
			
		||||
    pub fn new(n: &Notification) -> NotificationAPI {
 | 
			
		||||
        NotificationAPI {
 | 
			
		||||
            id: n.id,
 | 
			
		||||
            time_create: n.time_create,
 | 
			
		||||
            seen: n.seen,
 | 
			
		||||
            from_user_id: n.from_user_id.id(),
 | 
			
		||||
            dest_user_id: n.dest_user_id.id(),
 | 
			
		||||
            on_elem_id: n.on_elem_id,
 | 
			
		||||
            on_elem_type: n.on_elem_type.to_api(),
 | 
			
		||||
            type_container: TypeContainer { t: n.kind.to_api() },
 | 
			
		||||
            event_visibility: n.visibility.to_api(),
 | 
			
		||||
            from_container_id: n.container_id,
 | 
			
		||||
            from_container_type: n.container_type.as_ref().map(|f| f.to_api()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn for_list(l: &Vec<Notification>) -> Vec<NotificationAPI> {
 | 
			
		||||
        l.iter().map(Self::new).collect()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
use crate::api_data::notification_api::NotificationAPI;
 | 
			
		||||
use crate::api_data::res_count_all_unreads::ResCountAllUnread;
 | 
			
		||||
use crate::api_data::res_number_unread_notifications::ResNumberUnreadNotifications;
 | 
			
		||||
use crate::controllers::routes::RequestResult;
 | 
			
		||||
@@ -25,3 +26,10 @@ pub fn count_all_news(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
 | 
			
		||||
    r.set_response(ResCountAllUnread::new(notifications, conversations as u64, friends_requests))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the list of unread notifications
 | 
			
		||||
pub fn get_list_unread(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let list = notifications_helper::get_list_unread(r.user_id_ref()?)?;
 | 
			
		||||
 | 
			
		||||
    r.set_response(NotificationAPI::for_list(&list))
 | 
			
		||||
}
 | 
			
		||||
@@ -249,6 +249,9 @@ pub fn get_routes() -> Vec<Route> {
 | 
			
		||||
 | 
			
		||||
        Route::post("/notifications/count_all_news", Box::new(notifications_controller::count_all_news)),
 | 
			
		||||
 | 
			
		||||
        Route::post("/notifications/get_list_unread", Box::new(notifications_controller::get_list_unread)),
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Movies controller
 | 
			
		||||
        Route::post("/movies/get_list", Box::new(movies_controller::get_list)),
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,3 +24,4 @@ pub mod movie;
 | 
			
		||||
pub mod survey;
 | 
			
		||||
pub mod comment;
 | 
			
		||||
pub mod new_survey;
 | 
			
		||||
pub mod notification;
 | 
			
		||||
							
								
								
									
										154
									
								
								src/data/notification.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								src/data/notification.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
			
		||||
//! # Notification
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
use crate::data::user::UserID;
 | 
			
		||||
 | 
			
		||||
#[allow(non_camel_case_types)]
 | 
			
		||||
pub enum NotifElemType {
 | 
			
		||||
    UNKNOWN,
 | 
			
		||||
    USER_PAGE,
 | 
			
		||||
    GROUP_PAGE,
 | 
			
		||||
    CONVERSATION,
 | 
			
		||||
    CONVERSATION_MESSAGE,
 | 
			
		||||
    POST,
 | 
			
		||||
    COMMENT,
 | 
			
		||||
    FRIENDSHIP_REQUEST,
 | 
			
		||||
    GROUP_MEMBERSHIP,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl NotifElemType {
 | 
			
		||||
    pub fn from_db(d: &str) -> NotifElemType {
 | 
			
		||||
        match d {
 | 
			
		||||
            "user_page" => NotifElemType::USER_PAGE,
 | 
			
		||||
            "group_page" => NotifElemType::GROUP_PAGE,
 | 
			
		||||
            "conversation" => NotifElemType::CONVERSATION,
 | 
			
		||||
            "conversation_message" => NotifElemType::CONVERSATION_MESSAGE,
 | 
			
		||||
            "post" => NotifElemType::POST,
 | 
			
		||||
            "comment" => NotifElemType::COMMENT,
 | 
			
		||||
            "friend_request" => NotifElemType::FRIENDSHIP_REQUEST,
 | 
			
		||||
            "group_membership" => NotifElemType::GROUP_MEMBERSHIP,
 | 
			
		||||
            _ => NotifElemType::UNKNOWN,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn to_db(&self) -> String {
 | 
			
		||||
        match self {
 | 
			
		||||
            NotifElemType::USER_PAGE => "user_page",
 | 
			
		||||
            NotifElemType::GROUP_PAGE => "group_page",
 | 
			
		||||
            NotifElemType::CONVERSATION => "conversation",
 | 
			
		||||
            NotifElemType::CONVERSATION_MESSAGE => "conversation_message",
 | 
			
		||||
            NotifElemType::POST => "post",
 | 
			
		||||
            NotifElemType::COMMENT => "comment",
 | 
			
		||||
            NotifElemType::FRIENDSHIP_REQUEST => "friend_request",
 | 
			
		||||
            NotifElemType::GROUP_MEMBERSHIP => "group_membership",
 | 
			
		||||
            NotifElemType::UNKNOWN => "",
 | 
			
		||||
        }.to_string()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn to_api(&self) -> String {
 | 
			
		||||
        self.to_db()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[allow(non_camel_case_types)]
 | 
			
		||||
pub enum NotifEventType {
 | 
			
		||||
    UNKNOWN,
 | 
			
		||||
    COMMENT_CREATED,
 | 
			
		||||
    SENT_FRIEND_REQUEST,
 | 
			
		||||
    ACCEPTED_FRIEND_REQUEST,
 | 
			
		||||
    REJECTED_FRIEND_REQUEST,
 | 
			
		||||
    ELEM_CREATED,
 | 
			
		||||
    ELEM_UPDATED,
 | 
			
		||||
    SENT_GROUP_MEMBERSHIP_INVITATION,
 | 
			
		||||
    ACCEPTED_GROUP_MEMBERSHIP_INVITATION,
 | 
			
		||||
    REJECTED_GROUP_MEMBERSHIP_INVITATION,
 | 
			
		||||
    SENT_GROUP_MEMBERSHIP_REQUEST,
 | 
			
		||||
    ACCEPTED_GROUP_MEMBERSHIP_REQUEST,
 | 
			
		||||
    REJECTED_GROUP_MEMBERSHIP_REQUEST,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl NotifEventType {
 | 
			
		||||
    pub fn from_db(d: &str) -> NotifEventType {
 | 
			
		||||
        match d {
 | 
			
		||||
            "comment_created" => NotifEventType::COMMENT_CREATED,
 | 
			
		||||
            "sent_friend_request" => NotifEventType::SENT_FRIEND_REQUEST,
 | 
			
		||||
            "accepted_friend_request" => NotifEventType::ACCEPTED_FRIEND_REQUEST,
 | 
			
		||||
            "rejected_friend_request" => NotifEventType::REJECTED_FRIEND_REQUEST,
 | 
			
		||||
            "elem_created" => NotifEventType::ELEM_CREATED,
 | 
			
		||||
            "elem_updated" => NotifEventType::ELEM_UPDATED,
 | 
			
		||||
            "sent_group_membership_invitation" => NotifEventType::SENT_GROUP_MEMBERSHIP_INVITATION,
 | 
			
		||||
            "accepted_group_membership_invitation" => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_INVITATION,
 | 
			
		||||
            "rejected_group_membership_invitation" => NotifEventType::REJECTED_GROUP_MEMBERSHIP_INVITATION,
 | 
			
		||||
            "sent_group_membership_request" => NotifEventType::SENT_GROUP_MEMBERSHIP_REQUEST,
 | 
			
		||||
            "accepted_group_membership_request" => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_REQUEST,
 | 
			
		||||
            "rejected_group_membership_request" => NotifEventType::REJECTED_GROUP_MEMBERSHIP_REQUEST,
 | 
			
		||||
            _ => NotifEventType::UNKNOWN,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn to_db(&self) -> String {
 | 
			
		||||
        match self {
 | 
			
		||||
            NotifEventType::COMMENT_CREATED => "comment_created",
 | 
			
		||||
            NotifEventType::SENT_FRIEND_REQUEST => "sent_friend_request",
 | 
			
		||||
            NotifEventType::ACCEPTED_FRIEND_REQUEST => "accepted_friend_request",
 | 
			
		||||
            NotifEventType::REJECTED_FRIEND_REQUEST => "rejected_friend_request",
 | 
			
		||||
            NotifEventType::ELEM_CREATED => "elem_created",
 | 
			
		||||
            NotifEventType::ELEM_UPDATED => "elem_updated",
 | 
			
		||||
            NotifEventType::SENT_GROUP_MEMBERSHIP_INVITATION => "sent_group_membership_invitation",
 | 
			
		||||
            NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_INVITATION => "accepted_group_membership_invitation",
 | 
			
		||||
            NotifEventType::REJECTED_GROUP_MEMBERSHIP_INVITATION => "rejected_group_membership_invitation",
 | 
			
		||||
            NotifEventType::SENT_GROUP_MEMBERSHIP_REQUEST => "sent_group_membership_request",
 | 
			
		||||
            NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_REQUEST => "accepted_group_membership_request",
 | 
			
		||||
            NotifEventType::REJECTED_GROUP_MEMBERSHIP_REQUEST => "rejected_group_membership_request",
 | 
			
		||||
            NotifEventType::UNKNOWN => ""
 | 
			
		||||
        }.to_string()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn to_api(&self) -> String {
 | 
			
		||||
        self.to_db()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[allow(non_camel_case_types)]
 | 
			
		||||
pub enum NotifEventVisibility {
 | 
			
		||||
    EVENT_PRIVATE,
 | 
			
		||||
    EVENT_PUBLIC,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl NotifEventVisibility {
 | 
			
		||||
    pub fn from_db(d: &str) -> NotifEventVisibility {
 | 
			
		||||
        match d {
 | 
			
		||||
            "event_public" => NotifEventVisibility::EVENT_PUBLIC,
 | 
			
		||||
            "event_private" => NotifEventVisibility::EVENT_PRIVATE,
 | 
			
		||||
            _ => NotifEventVisibility::EVENT_PRIVATE,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn to_db(&self) -> String {
 | 
			
		||||
        match self {
 | 
			
		||||
            NotifEventVisibility::EVENT_PUBLIC => "event_public",
 | 
			
		||||
            NotifEventVisibility::EVENT_PRIVATE => "event_private",
 | 
			
		||||
        }.to_string()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn to_api(&self) -> String {
 | 
			
		||||
        self.to_db()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Notification {
 | 
			
		||||
    pub id: u64,
 | 
			
		||||
    pub time_create: u64,
 | 
			
		||||
    pub seen: bool,
 | 
			
		||||
    pub from_user_id: UserID,
 | 
			
		||||
    pub dest_user_id: UserID,
 | 
			
		||||
    pub on_elem_id: u64,
 | 
			
		||||
    pub on_elem_type: NotifElemType,
 | 
			
		||||
    pub kind: NotifEventType,
 | 
			
		||||
    pub visibility: NotifEventVisibility,
 | 
			
		||||
    pub container_id: Option<u64>,
 | 
			
		||||
    pub container_type: Option<NotifElemType>,
 | 
			
		||||
}
 | 
			
		||||
@@ -304,6 +304,14 @@ impl<'a> RowResult<'a> {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Get an optional unsigned number  => Set to None if value is null / empty
 | 
			
		||||
    pub fn get_optional_u64(&self, name: &str) -> ResultBoxError<Option<u64>> {
 | 
			
		||||
        match self.is_null(name)? {
 | 
			
		||||
            true => Ok(None),
 | 
			
		||||
            false => Ok(Some(self.get_u64(name)?))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_u32(&self, name: &str) -> ResultBoxError<u32> {
 | 
			
		||||
        let value = self.row.get_opt(self.find_col(name)?);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
 | 
			
		||||
use crate::constants::database_tables_names::NOTIFICATIONS_TABLE;
 | 
			
		||||
use crate::data::error::ResultBoxError;
 | 
			
		||||
use crate::data::notification::{NotifElemType, NotifEventType, NotifEventVisibility, Notification};
 | 
			
		||||
use crate::data::user::UserID;
 | 
			
		||||
use crate::helpers::database;
 | 
			
		||||
 | 
			
		||||
@@ -15,3 +16,30 @@ pub fn count_unread(user_id: &UserID) -> ResultBoxError<u64> {
 | 
			
		||||
        .exec_count()
 | 
			
		||||
        .map(|c| c as u64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the list of notifications of the user
 | 
			
		||||
pub fn get_list_unread(user_id: &UserID) -> ResultBoxError<Vec<Notification>> {
 | 
			
		||||
    database::QueryInfo::new(NOTIFICATIONS_TABLE)
 | 
			
		||||
        .cond_user_id("dest_user_id", user_id)
 | 
			
		||||
        .cond_legacy_bool("seen", false)
 | 
			
		||||
        .set_order("id DESC")
 | 
			
		||||
        .exec(db_to_notif)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Turn a database row into a notification object
 | 
			
		||||
fn db_to_notif(row: &database::RowResult) -> ResultBoxError<Notification> {
 | 
			
		||||
    Ok(Notification {
 | 
			
		||||
        id: row.get_u64("id")?,
 | 
			
		||||
        time_create: row.get_u64("time_create")?,
 | 
			
		||||
        seen: row.get_legacy_bool("seen")?,
 | 
			
		||||
        from_user_id: row.get_user_id("from_user_id")?,
 | 
			
		||||
        dest_user_id: row.get_user_id("dest_user_id")?,
 | 
			
		||||
        on_elem_id: row.get_u64("on_elem_id")?,
 | 
			
		||||
        on_elem_type: NotifElemType::from_db(&row.get_str("on_elem_type")?),
 | 
			
		||||
        kind: NotifEventType::from_db(&row.get_str("type")?),
 | 
			
		||||
        visibility: NotifEventVisibility::from_db(&row.get_str("visibility")?),
 | 
			
		||||
        container_id: row.get_optional_u64("from_container_id")?,
 | 
			
		||||
        container_type: row.get_optional_str("from_container_type")?
 | 
			
		||||
            .map(|s| NotifElemType::from_db(&s)),
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user