From 2f1548fda32c3ba9e53913270394eedfacd55986 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 8 Jan 2019 11:26:41 +0100 Subject: Add notifications in the client --- .../app/shared/users/user-notification.service.ts | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 client/src/app/shared/users/user-notification.service.ts (limited to 'client/src/app/shared/users/user-notification.service.ts') diff --git a/client/src/app/shared/users/user-notification.service.ts b/client/src/app/shared/users/user-notification.service.ts new file mode 100644 index 000000000..2dfee8060 --- /dev/null +++ b/client/src/app/shared/users/user-notification.service.ts @@ -0,0 +1,110 @@ +import { Injectable } from '@angular/core' +import { HttpClient, HttpParams } from '@angular/common/http' +import { RestExtractor, RestService } from '@app/shared/rest' +import { catchError, map, tap } from 'rxjs/operators' +import { environment } from '../../../environments/environment' +import { ResultList, UserNotification as UserNotificationServer, UserNotificationSetting } from '../../../../../shared' +import { UserNotification } from '@app/shared/users/user-notification.model' +import { Subject } from 'rxjs' +import * as io from 'socket.io-client' +import { AuthService } from '@app/core' +import { ComponentPagination } from '@app/shared/rest/component-pagination.model' +import { User } from '@app/shared' + +@Injectable() +export class UserNotificationService { + static BASE_NOTIFICATIONS_URL = environment.apiUrl + '/api/v1/users/me/notifications' + static BASE_NOTIFICATION_SETTINGS = environment.apiUrl + '/api/v1/users/me/notification-settings' + + private notificationSubject = new Subject<{ type: 'new' | 'read' | 'read-all', notification?: UserNotification }>() + + private socket: SocketIOClient.Socket + + constructor ( + private auth: AuthService, + private authHttp: HttpClient, + private restExtractor: RestExtractor, + private restService: RestService + ) {} + + listMyNotifications (pagination: ComponentPagination, unread?: boolean, ignoreLoadingBar = false) { + let params = new HttpParams() + params = this.restService.addRestGetParams(params, this.restService.componentPaginationToRestPagination(pagination)) + + if (unread) params = params.append('unread', `${unread}`) + + const headers = ignoreLoadingBar ? { ignoreLoadingBar: '' } : undefined + + return this.authHttp.get>(UserNotificationService.BASE_NOTIFICATIONS_URL, { params, headers }) + .pipe( + map(res => this.restExtractor.convertResultListDateToHuman(res)), + map(res => this.restExtractor.applyToResultListData(res, this.formatNotification.bind(this))), + catchError(err => this.restExtractor.handleError(err)) + ) + } + + countUnreadNotifications () { + return this.listMyNotifications({ currentPage: 1, itemsPerPage: 0 }, true) + .pipe(map(n => n.total)) + } + + getMyNotificationsSocket () { + const socket = this.getSocket() + + socket.on('new-notification', (n: UserNotificationServer) => { + this.notificationSubject.next({ type: 'new', notification: new UserNotification(n) }) + }) + + return this.notificationSubject.asObservable() + } + + markAsRead (notification: UserNotification) { + const url = UserNotificationService.BASE_NOTIFICATIONS_URL + '/read' + + const body = { ids: [ notification.id ] } + const headers = { ignoreLoadingBar: '' } + + return this.authHttp.post(url, body, { headers }) + .pipe( + map(this.restExtractor.extractDataBool), + tap(() => this.notificationSubject.next({ type: 'read' })), + catchError(res => this.restExtractor.handleError(res)) + ) + } + + markAllAsRead () { + const url = UserNotificationService.BASE_NOTIFICATIONS_URL + '/read-all' + const headers = { ignoreLoadingBar: '' } + + return this.authHttp.post(url, {}, { headers }) + .pipe( + map(this.restExtractor.extractDataBool), + tap(() => this.notificationSubject.next({ type: 'read-all' })), + catchError(res => this.restExtractor.handleError(res)) + ) + } + + updateNotificationSettings (user: User, settings: UserNotificationSetting) { + const url = UserNotificationService.BASE_NOTIFICATION_SETTINGS + + return this.authHttp.put(url, settings) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) + } + + private getSocket () { + if (this.socket) return this.socket + + this.socket = io(environment.apiUrl + '/user-notifications', { + query: { accessToken: this.auth.getAccessToken() } + }) + + return this.socket + } + + private formatNotification (notification: UserNotificationServer) { + return new UserNotification(notification) + } +} -- cgit v1.2.3 From 9a39392a7e6b3f180104856a4ea893e5baf86a02 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 14 Jan 2019 15:32:09 +0100 Subject: Fix notification socket Should be in core module to share the same subject to all the app --- .../app/shared/users/user-notification.service.ts | 42 ++++++---------------- 1 file changed, 10 insertions(+), 32 deletions(-) (limited to 'client/src/app/shared/users/user-notification.service.ts') diff --git a/client/src/app/shared/users/user-notification.service.ts b/client/src/app/shared/users/user-notification.service.ts index 2dfee8060..67ed8f74e 100644 --- a/client/src/app/shared/users/user-notification.service.ts +++ b/client/src/app/shared/users/user-notification.service.ts @@ -1,30 +1,28 @@ import { Injectable } from '@angular/core' import { HttpClient, HttpParams } from '@angular/common/http' -import { RestExtractor, RestService } from '@app/shared/rest' +import { RestExtractor, RestService } from '../rest' import { catchError, map, tap } from 'rxjs/operators' import { environment } from '../../../environments/environment' import { ResultList, UserNotification as UserNotificationServer, UserNotificationSetting } from '../../../../../shared' -import { UserNotification } from '@app/shared/users/user-notification.model' -import { Subject } from 'rxjs' -import * as io from 'socket.io-client' -import { AuthService } from '@app/core' -import { ComponentPagination } from '@app/shared/rest/component-pagination.model' -import { User } from '@app/shared' +import { UserNotification } from './user-notification.model' +import { AuthService } from '../../core' +import { ComponentPagination } from '../rest/component-pagination.model' +import { User } from '..' +import { UserNotificationSocket } from '@app/core/notification/user-notification-socket.service' @Injectable() export class UserNotificationService { static BASE_NOTIFICATIONS_URL = environment.apiUrl + '/api/v1/users/me/notifications' static BASE_NOTIFICATION_SETTINGS = environment.apiUrl + '/api/v1/users/me/notification-settings' - private notificationSubject = new Subject<{ type: 'new' | 'read' | 'read-all', notification?: UserNotification }>() - private socket: SocketIOClient.Socket constructor ( private auth: AuthService, private authHttp: HttpClient, private restExtractor: RestExtractor, - private restService: RestService + private restService: RestService, + private userNotificationSocket: UserNotificationSocket ) {} listMyNotifications (pagination: ComponentPagination, unread?: boolean, ignoreLoadingBar = false) { @@ -48,16 +46,6 @@ export class UserNotificationService { .pipe(map(n => n.total)) } - getMyNotificationsSocket () { - const socket = this.getSocket() - - socket.on('new-notification', (n: UserNotificationServer) => { - this.notificationSubject.next({ type: 'new', notification: new UserNotification(n) }) - }) - - return this.notificationSubject.asObservable() - } - markAsRead (notification: UserNotification) { const url = UserNotificationService.BASE_NOTIFICATIONS_URL + '/read' @@ -67,7 +55,7 @@ export class UserNotificationService { return this.authHttp.post(url, body, { headers }) .pipe( map(this.restExtractor.extractDataBool), - tap(() => this.notificationSubject.next({ type: 'read' })), + tap(() => this.userNotificationSocket.dispatch('read')), catchError(res => this.restExtractor.handleError(res)) ) } @@ -79,7 +67,7 @@ export class UserNotificationService { return this.authHttp.post(url, {}, { headers }) .pipe( map(this.restExtractor.extractDataBool), - tap(() => this.notificationSubject.next({ type: 'read-all' })), + tap(() => this.userNotificationSocket.dispatch('read-all')), catchError(res => this.restExtractor.handleError(res)) ) } @@ -94,16 +82,6 @@ export class UserNotificationService { ) } - private getSocket () { - if (this.socket) return this.socket - - this.socket = io(environment.apiUrl + '/user-notifications', { - query: { accessToken: this.auth.getAccessToken() } - }) - - return this.socket - } - private formatNotification (notification: UserNotificationServer) { return new UserNotification(notification) } -- cgit v1.2.3 From 457bb213b273a9b206cc5654eb085cede4e916ad Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 16 Jan 2019 16:05:40 +0100 Subject: Refactor how we use icons Inject them in an angular component so we can easily change their color --- client/src/app/shared/users/user-notification.service.ts | 2 -- 1 file changed, 2 deletions(-) (limited to 'client/src/app/shared/users/user-notification.service.ts') diff --git a/client/src/app/shared/users/user-notification.service.ts b/client/src/app/shared/users/user-notification.service.ts index 67ed8f74e..f8a30955d 100644 --- a/client/src/app/shared/users/user-notification.service.ts +++ b/client/src/app/shared/users/user-notification.service.ts @@ -15,8 +15,6 @@ export class UserNotificationService { static BASE_NOTIFICATIONS_URL = environment.apiUrl + '/api/v1/users/me/notifications' static BASE_NOTIFICATION_SETTINGS = environment.apiUrl + '/api/v1/users/me/notification-settings' - private socket: SocketIOClient.Socket - constructor ( private auth: AuthService, private authHttp: HttpClient, -- cgit v1.2.3