aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/users
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-02-11 14:09:23 +0100
committerChocobozzz <me@florianbigard.com>2019-02-11 14:09:23 +0100
commitb718fd22374d64534bcfe69932cf562894abed6a (patch)
tree311d3c67e2a4d1f33ebdd1dc163527de9d33d0f7 /client/src/app/shared/users
parentadb115f5522bea4d52456a9fc5eb4140bb064476 (diff)
parent501e961199578129629cf0567033d13efced9904 (diff)
downloadPeerTube-b718fd22374d64534bcfe69932cf562894abed6a.tar.gz
PeerTube-b718fd22374d64534bcfe69932cf562894abed6a.tar.zst
PeerTube-b718fd22374d64534bcfe69932cf562894abed6a.zip
Merge branch 'develop' into pr/1285
Diffstat (limited to 'client/src/app/shared/users')
-rw-r--r--client/src/app/shared/users/user-notification.model.ts42
-rw-r--r--client/src/app/shared/users/user-notification.service.ts44
-rw-r--r--client/src/app/shared/users/user-notifications.component.html82
-rw-r--r--client/src/app/shared/users/user-notifications.component.scss53
-rw-r--r--client/src/app/shared/users/user-notifications.component.ts15
5 files changed, 140 insertions, 96 deletions
diff --git a/client/src/app/shared/users/user-notification.model.ts b/client/src/app/shared/users/user-notification.model.ts
index 5ff816fb8..125d2120c 100644
--- a/client/src/app/shared/users/user-notification.model.ts
+++ b/client/src/app/shared/users/user-notification.model.ts
@@ -1,4 +1,5 @@
1import { UserNotification as UserNotificationServer, UserNotificationType, VideoInfo } from '../../../../../shared' 1import { UserNotification as UserNotificationServer, UserNotificationType, VideoInfo, ActorInfo } from '../../../../../shared'
2import { Actor } from '@app/shared/actor/actor.model'
2 3
3export class UserNotification implements UserNotificationServer { 4export class UserNotification implements UserNotificationServer {
4 id: number 5 id: number
@@ -6,10 +7,7 @@ export class UserNotification implements UserNotificationServer {
6 read: boolean 7 read: boolean
7 8
8 video?: VideoInfo & { 9 video?: VideoInfo & {
9 channel: { 10 channel: ActorInfo & { avatarUrl?: string }
10 id: number
11 displayName: string
12 }
13 } 11 }
14 12
15 videoImport?: { 13 videoImport?: {
@@ -23,10 +21,7 @@ export class UserNotification implements UserNotificationServer {
23 comment?: { 21 comment?: {
24 id: number 22 id: number
25 threadId: number 23 threadId: number
26 account: { 24 account: ActorInfo & { avatarUrl?: string }
27 id: number
28 displayName: string
29 }
30 video: VideoInfo 25 video: VideoInfo
31 } 26 }
32 27
@@ -40,18 +35,11 @@ export class UserNotification implements UserNotificationServer {
40 video: VideoInfo 35 video: VideoInfo
41 } 36 }
42 37
43 account?: { 38 account?: ActorInfo & { avatarUrl?: string }
44 id: number
45 displayName: string
46 name: string
47 }
48 39
49 actorFollow?: { 40 actorFollow?: {
50 id: number 41 id: number
51 follower: { 42 follower: ActorInfo & { avatarUrl?: string }
52 name: string
53 displayName: string
54 }
55 following: { 43 following: {
56 type: 'account' | 'channel' 44 type: 'account' | 'channel'
57 name: string 45 name: string
@@ -76,12 +64,22 @@ export class UserNotification implements UserNotificationServer {
76 this.read = hash.read 64 this.read = hash.read
77 65
78 this.video = hash.video 66 this.video = hash.video
67 if (this.video) this.setAvatarUrl(this.video.channel)
68
79 this.videoImport = hash.videoImport 69 this.videoImport = hash.videoImport
70
80 this.comment = hash.comment 71 this.comment = hash.comment
72 if (this.comment) this.setAvatarUrl(this.comment.account)
73
81 this.videoAbuse = hash.videoAbuse 74 this.videoAbuse = hash.videoAbuse
75
82 this.videoBlacklist = hash.videoBlacklist 76 this.videoBlacklist = hash.videoBlacklist
77
83 this.account = hash.account 78 this.account = hash.account
79 if (this.account) this.setAvatarUrl(this.account)
80
84 this.actorFollow = hash.actorFollow 81 this.actorFollow = hash.actorFollow
82 if (this.actorFollow) this.setAvatarUrl(this.actorFollow.follower)
85 83
86 this.createdAt = hash.createdAt 84 this.createdAt = hash.createdAt
87 this.updatedAt = hash.updatedAt 85 this.updatedAt = hash.updatedAt
@@ -97,6 +95,7 @@ export class UserNotification implements UserNotificationServer {
97 95
98 case UserNotificationType.NEW_COMMENT_ON_MY_VIDEO: 96 case UserNotificationType.NEW_COMMENT_ON_MY_VIDEO:
99 case UserNotificationType.COMMENT_MENTION: 97 case UserNotificationType.COMMENT_MENTION:
98 this.accountUrl = this.buildAccountUrl(this.comment.account)
100 this.commentUrl = [ this.buildVideoUrl(this.comment.video), { threadId: this.comment.threadId } ] 99 this.commentUrl = [ this.buildVideoUrl(this.comment.video), { threadId: this.comment.threadId } ]
101 break 100 break
102 101
@@ -138,8 +137,8 @@ export class UserNotification implements UserNotificationServer {
138 return '/videos/watch/' + video.uuid 137 return '/videos/watch/' + video.uuid
139 } 138 }
140 139
141 private buildAccountUrl (account: { name: string }) { 140 private buildAccountUrl (account: { name: string, host: string }) {
142 return '/accounts/' + account.name 141 return '/accounts/' + Actor.CREATE_BY_STRING(account.name, account.host)
143 } 142 }
144 143
145 private buildVideoImportUrl () { 144 private buildVideoImportUrl () {
@@ -150,4 +149,7 @@ export class UserNotification implements UserNotificationServer {
150 return videoImport.targetUrl || videoImport.magnetUri || videoImport.torrentName 149 return videoImport.targetUrl || videoImport.magnetUri || videoImport.torrentName
151 } 150 }
152 151
152 private setAvatarUrl (actor: { avatarUrl?: string, avatar?: { path: string } }) {
153 actor.avatarUrl = Actor.GET_ACTOR_AVATAR_URL(actor)
154 }
153} 155}
diff --git a/client/src/app/shared/users/user-notification.service.ts b/client/src/app/shared/users/user-notification.service.ts
index 2dfee8060..f8a30955d 100644
--- a/client/src/app/shared/users/user-notification.service.ts
+++ b/client/src/app/shared/users/user-notification.service.ts
@@ -1,30 +1,26 @@
1import { Injectable } from '@angular/core' 1import { Injectable } from '@angular/core'
2import { HttpClient, HttpParams } from '@angular/common/http' 2import { HttpClient, HttpParams } from '@angular/common/http'
3import { RestExtractor, RestService } from '@app/shared/rest' 3import { RestExtractor, RestService } from '../rest'
4import { catchError, map, tap } from 'rxjs/operators' 4import { catchError, map, tap } from 'rxjs/operators'
5import { environment } from '../../../environments/environment' 5import { environment } from '../../../environments/environment'
6import { ResultList, UserNotification as UserNotificationServer, UserNotificationSetting } from '../../../../../shared' 6import { ResultList, UserNotification as UserNotificationServer, UserNotificationSetting } from '../../../../../shared'
7import { UserNotification } from '@app/shared/users/user-notification.model' 7import { UserNotification } from './user-notification.model'
8import { Subject } from 'rxjs' 8import { AuthService } from '../../core'
9import * as io from 'socket.io-client' 9import { ComponentPagination } from '../rest/component-pagination.model'
10import { AuthService } from '@app/core' 10import { User } from '..'
11import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 11import { UserNotificationSocket } from '@app/core/notification/user-notification-socket.service'
12import { User } from '@app/shared'
13 12
14@Injectable() 13@Injectable()
15export class UserNotificationService { 14export class UserNotificationService {
16 static BASE_NOTIFICATIONS_URL = environment.apiUrl + '/api/v1/users/me/notifications' 15 static BASE_NOTIFICATIONS_URL = environment.apiUrl + '/api/v1/users/me/notifications'
17 static BASE_NOTIFICATION_SETTINGS = environment.apiUrl + '/api/v1/users/me/notification-settings' 16 static BASE_NOTIFICATION_SETTINGS = environment.apiUrl + '/api/v1/users/me/notification-settings'
18 17
19 private notificationSubject = new Subject<{ type: 'new' | 'read' | 'read-all', notification?: UserNotification }>()
20
21 private socket: SocketIOClient.Socket
22
23 constructor ( 18 constructor (
24 private auth: AuthService, 19 private auth: AuthService,
25 private authHttp: HttpClient, 20 private authHttp: HttpClient,
26 private restExtractor: RestExtractor, 21 private restExtractor: RestExtractor,
27 private restService: RestService 22 private restService: RestService,
23 private userNotificationSocket: UserNotificationSocket
28 ) {} 24 ) {}
29 25
30 listMyNotifications (pagination: ComponentPagination, unread?: boolean, ignoreLoadingBar = false) { 26 listMyNotifications (pagination: ComponentPagination, unread?: boolean, ignoreLoadingBar = false) {
@@ -48,16 +44,6 @@ export class UserNotificationService {
48 .pipe(map(n => n.total)) 44 .pipe(map(n => n.total))
49 } 45 }
50 46
51 getMyNotificationsSocket () {
52 const socket = this.getSocket()
53
54 socket.on('new-notification', (n: UserNotificationServer) => {
55 this.notificationSubject.next({ type: 'new', notification: new UserNotification(n) })
56 })
57
58 return this.notificationSubject.asObservable()
59 }
60
61 markAsRead (notification: UserNotification) { 47 markAsRead (notification: UserNotification) {
62 const url = UserNotificationService.BASE_NOTIFICATIONS_URL + '/read' 48 const url = UserNotificationService.BASE_NOTIFICATIONS_URL + '/read'
63 49
@@ -67,7 +53,7 @@ export class UserNotificationService {
67 return this.authHttp.post(url, body, { headers }) 53 return this.authHttp.post(url, body, { headers })
68 .pipe( 54 .pipe(
69 map(this.restExtractor.extractDataBool), 55 map(this.restExtractor.extractDataBool),
70 tap(() => this.notificationSubject.next({ type: 'read' })), 56 tap(() => this.userNotificationSocket.dispatch('read')),
71 catchError(res => this.restExtractor.handleError(res)) 57 catchError(res => this.restExtractor.handleError(res))
72 ) 58 )
73 } 59 }
@@ -79,7 +65,7 @@ export class UserNotificationService {
79 return this.authHttp.post(url, {}, { headers }) 65 return this.authHttp.post(url, {}, { headers })
80 .pipe( 66 .pipe(
81 map(this.restExtractor.extractDataBool), 67 map(this.restExtractor.extractDataBool),
82 tap(() => this.notificationSubject.next({ type: 'read-all' })), 68 tap(() => this.userNotificationSocket.dispatch('read-all')),
83 catchError(res => this.restExtractor.handleError(res)) 69 catchError(res => this.restExtractor.handleError(res))
84 ) 70 )
85 } 71 }
@@ -94,16 +80,6 @@ export class UserNotificationService {
94 ) 80 )
95 } 81 }
96 82
97 private getSocket () {
98 if (this.socket) return this.socket
99
100 this.socket = io(environment.apiUrl + '/user-notifications', {
101 query: { accessToken: this.auth.getAccessToken() }
102 })
103
104 return this.socket
105 }
106
107 private formatNotification (notification: UserNotificationServer) { 83 private formatNotification (notification: UserNotificationServer) {
108 return new UserNotification(notification) 84 return new UserNotification(notification)
109 } 85 }
diff --git a/client/src/app/shared/users/user-notifications.component.html b/client/src/app/shared/users/user-notifications.component.html
index 86379d941..0d69e0feb 100644
--- a/client/src/app/shared/users/user-notifications.component.html
+++ b/client/src/app/shared/users/user-notifications.component.html
@@ -1,61 +1,101 @@
1<div *ngIf="componentPagination.totalItems === 0" class="no-notification" i18n>You don't have notifications.</div> 1<div *ngIf="componentPagination.totalItems === 0" class="no-notification" i18n>You don't have notifications.</div>
2 2
3<div class="notifications" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()"> 3<div class="notifications" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()">
4 <div *ngFor="let notification of notifications" class="notification" [ngClass]="{ unread: !notification.read }"> 4 <div *ngFor="let notification of notifications" class="notification" [ngClass]="{ unread: !notification.read }" (click)="markAsRead(notification)">
5 5
6 <div [ngSwitch]="notification.type"> 6 <ng-container [ngSwitch]="notification.type">
7 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION"> 7 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION">
8 {{ notification.video.channel.displayName }} published a <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">new video</a> 8 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.video.channel.avatarUrl" />
9
10 <div class="message">
11 {{ notification.video.channel.displayName }} published a <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">new video</a>
12 </div>
9 </ng-container> 13 </ng-container>
10 14
11 <ng-container i18n *ngSwitchCase="UserNotificationType.UNBLACKLIST_ON_MY_VIDEO"> 15 <ng-container i18n *ngSwitchCase="UserNotificationType.UNBLACKLIST_ON_MY_VIDEO">
12 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been unblacklisted 16 <my-global-icon iconName="undo"></my-global-icon>
17
18 <div class="message">
19 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been unblacklisted
20 </div>
13 </ng-container> 21 </ng-container>
14 22
15 <ng-container i18n *ngSwitchCase="UserNotificationType.BLACKLIST_ON_MY_VIDEO"> 23 <ng-container i18n *ngSwitchCase="UserNotificationType.BLACKLIST_ON_MY_VIDEO">
16 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been blacklisted 24 <my-global-icon iconName="no"></my-global-icon>
25
26 <div class="message">
27 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been blacklisted
28 </div>
17 </ng-container> 29 </ng-container>
18 30
19 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS"> 31 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS">
20 <a (click)="markAsRead(notification)" [routerLink]="notification.videoAbuseUrl">A new video abuse</a> has been created on video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoAbuse.video.name }}</a> 32 <my-global-icon iconName="alert"></my-global-icon>
33
34 <div class="message">
35 <a (click)="markAsRead(notification)" [routerLink]="notification.videoAbuseUrl">A new video abuse</a> has been created on video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoAbuse.video.name }}</a>
36 </div>
21 </ng-container> 37 </ng-container>
22 38
23 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_COMMENT_ON_MY_VIDEO"> 39 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_COMMENT_ON_MY_VIDEO">
24 {{ notification.comment.account.displayName }} commented your video <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">{{ notification.comment.video.name }}</a> 40 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.comment.account.avatarUrl" />
41
42 <div class="message">
43 <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.comment.account.displayName }}</a> commented your video <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">{{ notification.comment.video.name }}</a>
44 </div>
25 </ng-container> 45 </ng-container>
26 46
27 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_PUBLISHED"> 47 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_PUBLISHED">
28 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been published 48 <my-global-icon iconName="sparkle"></my-global-icon>
49
50 <div class="message">
51 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been published
52 </div>
29 </ng-container> 53 </ng-container>
30 54
31 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_IMPORT_SUCCESS"> 55 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_IMPORT_SUCCESS">
32 <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">Your video import</a> {{ notification.videoImportIdentifier }} succeeded 56 <my-global-icon iconName="cloud-download"></my-global-icon>
57
58 <div class="message">
59 <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">Your video import</a> {{ notification.videoImportIdentifier }} succeeded
60 </div>
33 </ng-container> 61 </ng-container>
34 62
35 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_IMPORT_ERROR"> 63 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_IMPORT_ERROR">
36 <a (click)="markAsRead(notification)" [routerLink]="notification.videoImportUrl">Your video import</a> {{ notification.videoImportIdentifier }} failed 64 <my-global-icon iconName="cloud-error"></my-global-icon>
65
66 <div class="message">
67 <a (click)="markAsRead(notification)" [routerLink]="notification.videoImportUrl">Your video import</a> {{ notification.videoImportIdentifier }} failed
68 </div>
37 </ng-container> 69 </ng-container>
38 70
39 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_USER_REGISTRATION"> 71 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_USER_REGISTRATION">
40 User <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.account.name }} registered</a> on your instance 72 <my-global-icon iconName="user-add"></my-global-icon>
73
74 <div class="message">
75 User <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.account.name }} registered</a> on your instance
76 </div>
41 </ng-container> 77 </ng-container>
42 78
43 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_FOLLOW"> 79 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_FOLLOW">
44 <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.actorFollow.follower.displayName }}</a> is following 80 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.actorFollow.follower.avatarUrl" />
45 81
46 <ng-container *ngIf="notification.actorFollow.following.type === 'channel'"> 82 <div class="message">
47 your channel {{ notification.actorFollow.following.displayName }} 83 <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.actorFollow.follower.displayName }}</a> is following
48 </ng-container> 84
49 <ng-container *ngIf="notification.actorFollow.following.type === 'account'">your account</ng-container> 85 <ng-container *ngIf="notification.actorFollow.following.type === 'channel'">your channel {{ notification.actorFollow.following.displayName }}</ng-container>
86 <ng-container *ngIf="notification.actorFollow.following.type === 'account'">your account</ng-container>
87 </div>
50 </ng-container> 88 </ng-container>
51 89
52 <ng-container i18n *ngSwitchCase="UserNotificationType.COMMENT_MENTION"> 90 <ng-container i18n *ngSwitchCase="UserNotificationType.COMMENT_MENTION">
53 {{ notification.comment.account.displayName }} mentioned you on <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">video {{ notification.comment.video.name }}</a> 91 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.comment.account.avatarUrl" />
92
93 <div class="message">
94 <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.comment.account.displayName }}</a> mentioned you on <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">video {{ notification.comment.video.name }}</a>
95 </div>
54 </ng-container> 96 </ng-container>
55 </div> 97 </ng-container>
56 98
57 <div i18n title="Mark as read" class="mark-as-read"> 99 <div class="from-date">{{ notification.createdAt | myFromNow }}</div>
58 <div class="glyphicon glyphicon-ok" (click)="markAsRead(notification)"></div>
59 </div>
60 </div> 100 </div>
61</div> 101</div>
diff --git a/client/src/app/shared/users/user-notifications.component.scss b/client/src/app/shared/users/user-notifications.component.scss
index 0493b10d9..315d504c9 100644
--- a/client/src/app/shared/users/user-notifications.component.scss
+++ b/client/src/app/shared/users/user-notifications.component.scss
@@ -1,30 +1,51 @@
1@import '_variables';
2@import '_mixins';
3
4.no-notification {
5 display: flex;
6 justify-content: center;
7 align-items: center;
8 padding: 20px 0;
9}
10
1.notification { 11.notification {
2 display: flex; 12 display: flex;
3 justify-content: space-between;
4 align-items: center; 13 align-items: center;
5 font-size: inherit; 14 font-size: inherit;
6 padding: 15px 10px; 15 padding: 15px 5px 15px 10px;
7 border-bottom: 1px solid rgba(0, 0, 0, 0.10); 16 border-bottom: 1px solid rgba(0, 0, 0, 0.10);
8 17
9 .mark-as-read { 18 &.unread {
10 min-width: 35px; 19 background-color: rgba(0, 0, 0, 0.05);
20 }
21
22 my-global-icon {
23 width: 24px;
24 margin-right: 11px;
25 margin-left: 3px;
11 26
12 .glyphicon { 27 @include apply-svg-color(#333);
13 display: none;
14 cursor: pointer;
15 color: rgba(20, 20, 20, 0.5)
16 }
17 } 28 }
18 29
19 &.unread { 30 .avatar {
20 background-color: rgba(0, 0, 0, 0.05); 31 @include avatar(30px);
21 32
22 &:hover .mark-as-read .glyphicon { 33 margin-right: 10px;
23 display: block; 34 }
35
36 .message {
37 flex-grow: 1;
24 38
25 &:hover { 39 a {
26 color: rgba(20, 20, 20, 0.8); 40 font-weight: $font-semibold;
27 }
28 } 41 }
29 } 42 }
43
44 .from-date {
45 font-size: 0.85em;
46 color: $grey-foreground-color;
47 padding-left: 5px;
48 min-width: 70px;
49 text-align: right;
50 }
30} 51}
diff --git a/client/src/app/shared/users/user-notifications.component.ts b/client/src/app/shared/users/user-notifications.component.ts
index 682116226..b5f9fd399 100644
--- a/client/src/app/shared/users/user-notifications.component.ts
+++ b/client/src/app/shared/users/user-notifications.component.ts
@@ -13,17 +13,14 @@ import { UserNotification } from '@app/shared/users/user-notification.model'
13export class UserNotificationsComponent implements OnInit { 13export class UserNotificationsComponent implements OnInit {
14 @Input() ignoreLoadingBar = false 14 @Input() ignoreLoadingBar = false
15 @Input() infiniteScroll = true 15 @Input() infiniteScroll = true
16 @Input() itemsPerPage = 20
16 17
17 notifications: UserNotification[] = [] 18 notifications: UserNotification[] = []
18 19
19 // So we can access it in the template 20 // So we can access it in the template
20 UserNotificationType = UserNotificationType 21 UserNotificationType = UserNotificationType
21 22
22 componentPagination: ComponentPagination = { 23 componentPagination: ComponentPagination
23 currentPage: 1,
24 itemsPerPage: 10,
25 totalItems: null
26 }
27 24
28 constructor ( 25 constructor (
29 private userNotificationService: UserNotificationService, 26 private userNotificationService: UserNotificationService,
@@ -31,6 +28,12 @@ export class UserNotificationsComponent implements OnInit {
31 ) { } 28 ) { }
32 29
33 ngOnInit () { 30 ngOnInit () {
31 this.componentPagination = {
32 currentPage: 1,
33 itemsPerPage: this.itemsPerPage, // Reset items per page, because of the @Input() variable
34 totalItems: null
35 }
36
34 this.loadMoreNotifications() 37 this.loadMoreNotifications()
35 } 38 }
36 39
@@ -57,6 +60,8 @@ export class UserNotificationsComponent implements OnInit {
57 } 60 }
58 61
59 markAsRead (notification: UserNotification) { 62 markAsRead (notification: UserNotification) {
63 if (notification.read) return
64
60 this.userNotificationService.markAsRead(notification) 65 this.userNotificationService.markAsRead(notification)
61 .subscribe( 66 .subscribe(
62 () => { 67 () => {