1
0
mirror of https://gitlab.com/comunic/comunicapiv2 synced 2025-04-02 02:52:37 +00:00
comunicapiv2/src/helpers/NotificationsHelper.ts

239 lines
5.7 KiB
TypeScript

import { DatabaseHelper } from "./DatabaseHelper";
import { Notif, NotifElemType, NotifEventVisibility } from "../entities/Notification";
import { time } from "../utils/DateUtils";
import { PostsHelper } from "./PostsHelper";
import { PostPageKind, PostVisibilityLevel } from "../entities/Post";
import { FriendsHelper } from "./FriendsHelper";
/**
* Notifications helper
*
* @author Pierre HUBERT
*/
const NOTIFICATIONS_TABLE = "comunic_notifications";
export class NotificationsHelper {
/**
* Push a new notification
*
* @param n Notification to push
*/
public static async Push(n: Notif) {
if(!n.hasTimeCreate)
n.timeCreate = time();
// Determine the visibility level of the notification
if(n.onElemType == NotifElemType.POST) {
const post = await PostsHelper.GetSingle(n.onElemID);
// Determine post container
switch(post.kindPage) {
case PostPageKind.PAGE_KIND_USER:
n.fromContainerType = NotifElemType.USER_PAGE
n.fromContainerID = post.userPageID
break;
case PostPageKind.PAGE_KIND_GROUP:
n.fromContainerType = NotifElemType.GROUP_PAGE
n.fromContainerID = post.groupID
break;
default:
throw new Error("Unsupported page kind: " + post.kindPage)
}
// Check the scope of the notification
// Private post (on user pages)
if(post.visibilityLevel == PostVisibilityLevel.VISIBILITY_USER) {
// Check if the user does not own the post
if(post.userID == post.userPageID)
return;
// If the personn who posted that is not the owner of the page
else if(post.userPageID != n.fromUserID)
n.destUserID = post.userPageID
// If the user is the one who own the page
else
n.destUserID = post.userID
await this.PushPrivate(n)
}
// Posts on users page
else if(n.fromContainerType == NotifElemType.USER_PAGE) {
// Process friends list of the user creating the notification
const friendsList = await FriendsHelper.GetList(n.fromUserID);
const targetUsers = [];
for(const friend of friendsList) {
if(friend.friendID != n.fromContainerID &&
post.userPageID != n.fromUserID && // Skip friendship check if user
// creating the notification
// & target page are the same
!await FriendsHelper.AreFriend(friend.friendID, post.userPageID))
continue;
// Check if the user is following his friend
if(!await FriendsHelper.IsFollowing(friend.friendID, n.fromUserID))
continue;
targetUsers.push(friend.friendID)
}
await this.PushPublic(n, targetUsers);
}
// TODO : continue
}
}
/**
* Push a notification to multiple users
*
* @param n The notification to push
* @param users The list of target users
*/
private static async PushPublic(n: Notif, users: Array<number>) {
n.eventVisibility = NotifEventVisibility.EVENT_PUBLIC
for(const userID of users) {
n.destUserID = userID;
if(await this.SimilarExists(n))
continue
await this.Create(n);
}
}
/**
* Push a private notification
*
* @param n The notification
*/
private static async PushPrivate(n: Notif) {
n.eventVisibility = NotifEventVisibility.EVENT_PRIVATE
if(await this.SimilarExists(n))
return;
await this.Create(n)
}
/**
* Check out whether a similar notification exists
* for a given notification
*
* @param n The notification
*/
private static async SimilarExists(n: Notif) : Promise<boolean> {
return await DatabaseHelper.Count({
table: NOTIFICATIONS_TABLE,
where: this.NotifToDB(n, false)
}) > 0;
}
/**
* Create the notification
*
* @param n The notification
*/
private static async Create(n: Notif) {
await DatabaseHelper.InsertRow(
NOTIFICATIONS_TABLE,
this.NotifToDB(n, true)
)
}
/**
* Count the number of unread notifications of a user
*
* @param userID Target user ID
*/
public static async CountUnread(userID: number) : Promise<number> {
return await DatabaseHelper.Count({
table: NOTIFICATIONS_TABLE,
where: {
dest_user_id: userID,
seen: 0
}
});
}
/**
* Get the list of unread notifications of a user
*
* @param userID Target user ID
*/
public static async GetListUnread(userID: number) : Promise<Array<Notif>> {
const list = await DatabaseHelper.Query({
table: NOTIFICATIONS_TABLE,
where: {
dest_user_id: userID,
seen: 0
},
order: "id DESC"
});
return list.map((e) => this.DBToNotif(e));
}
/**
* Turn a notification into a database entry
*
* @param n The notification
* @param allInfo True to return a full notification entry
*/
private static NotifToDB(n: Notif, allInfo = true) : any {
let data: any = {}
if(n.hasId) data.id = n.id
if(n.hasSeen) data.seen = n.seen ? 1 : 0
if(n.hasFromUserID) data.from_user_id = n.fromUserID
if(n.hasDestUserID) data.dest_user_id = n.destUserID
if(n.hasType) data.type = n.type
if(n.hasOnElemID) data.on_elem_id = n.onElemID
if(n.hasOnElemType) data.on_elem_type = n.onElemType
if(allInfo) {
data.from_container_id = n.fromContainerID
data.from_container_type = n.fromContainerType
data.time_create = n.timeCreate
data.visibility = n.eventVisibility
}
return data;
}
/**
* Database entry to notification
*
* @param row Database entry
*/
private static DBToNotif(row: any) : Notif {
return new Notif({
id: row.id,
seen: row.seen == 1,
timeCreate: row.time_create,
fromUserID: row.from_user_id,
destUserID: row.dest_user_id,
onElemID: row.on_elem_id,
onElemType: row.on_elem_type,
type: row.type,
eventVisibility: row.visibility,
fromContainerID: row.from_container_id,
fromContainerType: row.from_container_type
});
}
}