mirror of
https://github.com/zoriya/flood.git
synced 2026-06-08 04:41:03 +00:00
server: notificationService: replace callbacks with promises
This commit is contained in:
@@ -117,10 +117,7 @@ const FloodActions = {
|
|||||||
fetchNotifications: (options: NotificationFetchOptions) =>
|
fetchNotifications: (options: NotificationFetchOptions) =>
|
||||||
axios
|
axios
|
||||||
.get(`${baseURI}api/notifications`, {
|
.get(`${baseURI}api/notifications`, {
|
||||||
params: {
|
params: options,
|
||||||
limit: options.limit,
|
|
||||||
start: options.start,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
.then((json) => json.data)
|
.then((json) => json.data)
|
||||||
.then(
|
.then(
|
||||||
|
|||||||
@@ -70,12 +70,43 @@ router.get<unknown, unknown, unknown, {snapshot: HistorySnapshot}>('/history', (
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/notifications
|
||||||
|
* @summary Gets notifications
|
||||||
|
* @tags Flood
|
||||||
|
* @security User
|
||||||
|
* @param {NotificationFetchOptions} queries - options
|
||||||
|
* @return {{Notification[][], NotificationCount}} 200 - success response - application/json
|
||||||
|
* @return {Error} 500 - failure response - application/json
|
||||||
|
*/
|
||||||
router.get<unknown, unknown, unknown, NotificationFetchOptions>('/notifications', (req, res) => {
|
router.get<unknown, unknown, unknown, NotificationFetchOptions>('/notifications', (req, res) => {
|
||||||
req.services?.notificationService.getNotifications(req.query, getResponseFn(res));
|
req.services?.notificationService.getNotifications(req.query).then(
|
||||||
|
(notifications) => {
|
||||||
|
res.status(200).json(notifications);
|
||||||
|
},
|
||||||
|
(err: Error) => {
|
||||||
|
res.status(500).json({message: err.message});
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE /api/notifications
|
||||||
|
* @summary Clears notifications
|
||||||
|
* @tags Flood
|
||||||
|
* @security User
|
||||||
|
* @return 200 - success response
|
||||||
|
* @return {Error} 500 - failure response - application/json
|
||||||
|
*/
|
||||||
router.delete('/notifications', (req, res) => {
|
router.delete('/notifications', (req, res) => {
|
||||||
req.services?.notificationService.clearNotifications(getResponseFn(res));
|
req.services?.notificationService.clearNotifications().then(
|
||||||
|
() => {
|
||||||
|
res.status(200).send();
|
||||||
|
},
|
||||||
|
(err: Error) => {
|
||||||
|
res.status(500).json({message: err.message});
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Datastore from 'nedb';
|
import Datastore from 'nedb-promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import type {Notification, NotificationCount, NotificationFetchOptions} from '@shared/types/Notification';
|
import type {Notification, NotificationCount, NotificationFetchOptions} from '@shared/types/Notification';
|
||||||
@@ -14,50 +14,18 @@ const DEFAULT_QUERY_LIMIT = 20;
|
|||||||
|
|
||||||
class NotificationService extends BaseService<NotificationServiceEvents> {
|
class NotificationService extends BaseService<NotificationServiceEvents> {
|
||||||
count: NotificationCount = {read: 0, total: 0, unread: 0};
|
count: NotificationCount = {read: 0, total: 0, unread: 0};
|
||||||
db = this.loadDatabase();
|
db = Datastore.create({
|
||||||
|
autoload: true,
|
||||||
|
filename: path.join(config.dbPath, this.user._id, 'notifications.db'),
|
||||||
|
});
|
||||||
|
|
||||||
constructor(...args: ConstructorParameters<typeof BaseService>) {
|
constructor(...args: ConstructorParameters<typeof BaseService>) {
|
||||||
super(...args);
|
super(...args);
|
||||||
|
|
||||||
this.onServicesUpdated = () => {
|
(async () => {
|
||||||
this.countNotifications();
|
const notifications = await this.db.find<Notification>({}).catch(() => undefined);
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
addNotification(notifications: Array<Pick<Notification, 'id' | 'data'>>) {
|
if (notifications != null) {
|
||||||
this.count.total += notifications.length;
|
|
||||||
this.count.unread += notifications.length;
|
|
||||||
|
|
||||||
const timestamp = Date.now();
|
|
||||||
const notificationsToInsert = notifications.map((notification) => ({
|
|
||||||
ts: timestamp,
|
|
||||||
data: notification.data,
|
|
||||||
id: notification.id,
|
|
||||||
read: false,
|
|
||||||
})) as Notification[];
|
|
||||||
|
|
||||||
this.db.insert(notificationsToInsert, () => this.emitUpdate());
|
|
||||||
}
|
|
||||||
|
|
||||||
clearNotifications(callback: (data?: null, err?: Error) => void) {
|
|
||||||
this.db.remove({}, {multi: true}, (err) => {
|
|
||||||
if (err) {
|
|
||||||
callback(null, err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.count = {read: 0, total: 0, unread: 0};
|
|
||||||
this.emitUpdate();
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
countNotifications() {
|
|
||||||
this.db.find({}, (err: Error, notifications: Array<Notification>) => {
|
|
||||||
if (err) {
|
|
||||||
this.count = {read: 0, total: 0, unread: 0};
|
|
||||||
} else {
|
|
||||||
notifications.forEach((notification) => {
|
notifications.forEach((notification) => {
|
||||||
if (notification.read) {
|
if (notification.read) {
|
||||||
this.count.read += 1;
|
this.count.read += 1;
|
||||||
@@ -70,7 +38,7 @@ class NotificationService extends BaseService<NotificationServiceEvents> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.emitUpdate();
|
this.emitUpdate();
|
||||||
});
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
emitUpdate = () => {
|
emitUpdate = () => {
|
||||||
@@ -84,49 +52,77 @@ class NotificationService extends BaseService<NotificationServiceEvents> {
|
|||||||
return this.count;
|
return this.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
getNotifications(
|
/**
|
||||||
query: NotificationFetchOptions,
|
* Adds notifications
|
||||||
callback: (
|
*
|
||||||
data: {
|
* @param {Array<Notification>} notifications - Notifications to add
|
||||||
notifications: Notification[][];
|
* @return {Promise<void>} - Rejects with error.
|
||||||
count: NotificationCount;
|
*/
|
||||||
} | null,
|
async addNotification(notifications: Array<Pick<Notification, 'id' | 'data'>>): Promise<void> {
|
||||||
err?: Error,
|
this.count.total += notifications.length;
|
||||||
) => void,
|
this.count.unread += notifications.length;
|
||||||
) {
|
|
||||||
const sortedNotifications = this.db.find({}).sort({ts: -1});
|
|
||||||
const queryCallback = (err: Error | null, notifications: Notification[][]) => {
|
|
||||||
if (err) {
|
|
||||||
callback(null, err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
callback({notifications, count: this.count});
|
await this.db
|
||||||
};
|
.insert(
|
||||||
|
notifications.map((notification) => ({
|
||||||
|
ts: Date.now(),
|
||||||
|
data: notification.data,
|
||||||
|
id: notification.id,
|
||||||
|
read: false,
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.catch(() => undefined);
|
||||||
|
|
||||||
if (query.allNotifications) {
|
this.emitUpdate();
|
||||||
sortedNotifications.exec(queryCallback);
|
|
||||||
} else if (query.start != null) {
|
|
||||||
sortedNotifications
|
|
||||||
.skip(Number(query.start))
|
|
||||||
.limit(Number(query.limit) || DEFAULT_QUERY_LIMIT)
|
|
||||||
.exec(queryCallback);
|
|
||||||
} else {
|
|
||||||
sortedNotifications.limit(Number(query.limit) || DEFAULT_QUERY_LIMIT).exec(queryCallback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDatabase(): Datastore<Array<Notification>> {
|
/**
|
||||||
if (this.db != null) {
|
* Clears notifications
|
||||||
return this.db;
|
*
|
||||||
|
* @return {Promise<void>} - Rejects with error.
|
||||||
|
*/
|
||||||
|
async clearNotifications(): Promise<void> {
|
||||||
|
await this.db.remove({}, {multi: true});
|
||||||
|
|
||||||
|
this.count = {read: 0, total: 0, unread: 0};
|
||||||
|
this.emitUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets notifications
|
||||||
|
*
|
||||||
|
* @param {NotificationFetchOptions} - options - An object of options...
|
||||||
|
* @return {Promise<{Notification[][], NotificationCount}>} - Resolves with notifications and counts or rejects with error.
|
||||||
|
*/
|
||||||
|
async getNotifications({
|
||||||
|
allNotifications,
|
||||||
|
start,
|
||||||
|
limit,
|
||||||
|
}: NotificationFetchOptions): Promise<{
|
||||||
|
notifications: Notification[][];
|
||||||
|
count: NotificationCount;
|
||||||
|
}> {
|
||||||
|
const sortedNotifications = this.db.find<Notification>({}).sort({ts: -1});
|
||||||
|
|
||||||
|
if (allNotifications) {
|
||||||
|
return {
|
||||||
|
notifications: await sortedNotifications.exec(),
|
||||||
|
count: this.count,
|
||||||
|
};
|
||||||
|
} else if (start != null) {
|
||||||
|
return {
|
||||||
|
notifications: await sortedNotifications
|
||||||
|
.skip(Number(start))
|
||||||
|
.limit(Number(limit) || DEFAULT_QUERY_LIMIT)
|
||||||
|
.exec(),
|
||||||
|
count: this.count,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
notifications: await sortedNotifications.limit(Number(limit) || DEFAULT_QUERY_LIMIT).exec(),
|
||||||
|
count: this.count,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const db = new Datastore({
|
|
||||||
autoload: true,
|
|
||||||
filename: path.join(config.dbPath, this.user._id, 'notifications.db'),
|
|
||||||
});
|
|
||||||
|
|
||||||
return db;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export interface NotificationState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface NotificationFetchOptions {
|
export interface NotificationFetchOptions {
|
||||||
id: string;
|
id?: string;
|
||||||
limit: number;
|
limit: number;
|
||||||
start: number;
|
start: number;
|
||||||
allNotifications?: boolean;
|
allNotifications?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user