diff options
author | Chocobozzz <me@florianbigard.com> | 2019-01-08 11:26:41 +0100 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-01-09 11:15:15 +0100 |
commit | 2f1548fda32c3ba9e53913270394eedfacd55986 (patch) | |
tree | afee28df36a9e00f921603d9091e5d08d5818159 /client/src/app/+my-account | |
parent | f7cc67b455a12ccae9b0ea16876d166720364357 (diff) | |
download | PeerTube-2f1548fda32c3ba9e53913270394eedfacd55986.tar.gz PeerTube-2f1548fda32c3ba9e53913270394eedfacd55986.tar.zst PeerTube-2f1548fda32c3ba9e53913270394eedfacd55986.zip |
Add notifications in the client
Diffstat (limited to 'client/src/app/+my-account')
11 files changed, 211 insertions, 2 deletions
diff --git a/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html new file mode 100644 index 000000000..d2810c343 --- /dev/null +++ b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html | |||
@@ -0,0 +1,7 @@ | |||
1 | <div class="header"> | ||
2 | <a routerLink="/my-account/settings" i18n>Notification preferences</a> | ||
3 | |||
4 | <button (click)="markAllAsRead()" i18n>Mark all as read</button> | ||
5 | </div> | ||
6 | |||
7 | <my-user-notifications #userNotification></my-user-notifications> | ||
diff --git a/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.scss b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.scss new file mode 100644 index 000000000..86ac094c5 --- /dev/null +++ b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.scss | |||
@@ -0,0 +1,23 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | .header { | ||
5 | display: flex; | ||
6 | justify-content: space-between; | ||
7 | font-size: 15px; | ||
8 | margin-bottom: 10px; | ||
9 | |||
10 | a { | ||
11 | @include peertube-button-link; | ||
12 | @include grey-button; | ||
13 | } | ||
14 | |||
15 | button { | ||
16 | @include peertube-button; | ||
17 | @include grey-button; | ||
18 | } | ||
19 | } | ||
20 | |||
21 | my-user-notifications { | ||
22 | font-size: 15px; | ||
23 | } | ||
diff --git a/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts new file mode 100644 index 000000000..3e197088d --- /dev/null +++ b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts | |||
@@ -0,0 +1,14 @@ | |||
1 | import { Component, ViewChild } from '@angular/core' | ||
2 | import { UserNotificationsComponent } from '@app/shared' | ||
3 | |||
4 | @Component({ | ||
5 | templateUrl: './my-account-notifications.component.html', | ||
6 | styleUrls: [ './my-account-notifications.component.scss' ] | ||
7 | }) | ||
8 | export class MyAccountNotificationsComponent { | ||
9 | @ViewChild('userNotification') userNotification: UserNotificationsComponent | ||
10 | |||
11 | markAllAsRead () { | ||
12 | this.userNotification.markAllAsRead() | ||
13 | } | ||
14 | } | ||
diff --git a/client/src/app/+my-account/my-account-routing.module.ts b/client/src/app/+my-account/my-account-routing.module.ts index a2cbeaffc..9996218ca 100644 --- a/client/src/app/+my-account/my-account-routing.module.ts +++ b/client/src/app/+my-account/my-account-routing.module.ts | |||
@@ -14,6 +14,7 @@ import { MyAccountOwnershipComponent } from '@app/+my-account/my-account-ownersh | |||
14 | import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component' | 14 | import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component' |
15 | import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component' | 15 | import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component' |
16 | import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/my-account-history.component' | 16 | import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/my-account-history.component' |
17 | import { MyAccountNotificationsComponent } from '@app/+my-account/my-account-notifications/my-account-notifications.component' | ||
17 | 18 | ||
18 | const myAccountRoutes: Routes = [ | 19 | const myAccountRoutes: Routes = [ |
19 | { | 20 | { |
@@ -124,6 +125,15 @@ const myAccountRoutes: Routes = [ | |||
124 | title: 'Videos history' | 125 | title: 'Videos history' |
125 | } | 126 | } |
126 | } | 127 | } |
128 | }, | ||
129 | { | ||
130 | path: 'notifications', | ||
131 | component: MyAccountNotificationsComponent, | ||
132 | data: { | ||
133 | meta: { | ||
134 | title: 'Notifications' | ||
135 | } | ||
136 | } | ||
127 | } | 137 | } |
128 | ] | 138 | ] |
129 | } | 139 | } |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts new file mode 100644 index 000000000..5e1d51339 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './my-account-notification-preferences.component' | |||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html new file mode 100644 index 000000000..59422d682 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html | |||
@@ -0,0 +1,19 @@ | |||
1 | <div class="custom-row"> | ||
2 | <div i18n>Activities</div> | ||
3 | <div i18n>Web</div> | ||
4 | <div i18n *ngIf="emailEnabled">Email</div> | ||
5 | </div> | ||
6 | |||
7 | <div class="custom-row" *ngFor="let notificationType of notificationSettingKeys"> | ||
8 | <ng-container *ngIf="hasUserRight(notificationType)"> | ||
9 | <div>{{ labelNotifications[notificationType] }}</div> | ||
10 | |||
11 | <div> | ||
12 | <p-inputSwitch [(ngModel)]="webNotifications[notificationType]" (onChange)="updateWebSetting(notificationType, $event.checked)"></p-inputSwitch> | ||
13 | </div> | ||
14 | |||
15 | <div *ngIf="emailEnabled"> | ||
16 | <p-inputSwitch [(ngModel)]="emailNotifications[notificationType]" (onChange)="updateEmailSetting(notificationType, $event.checked)"></p-inputSwitch> | ||
17 | </div> | ||
18 | </ng-container> | ||
19 | </div> | ||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.scss b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.scss new file mode 100644 index 000000000..6feb16ab1 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.scss | |||
@@ -0,0 +1,25 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | .custom-row { | ||
5 | display: flex; | ||
6 | align-items: center; | ||
7 | border-bottom: 1px solid rgba(0, 0, 0, 0.10); | ||
8 | |||
9 | &:first-child { | ||
10 | font-size: 16px; | ||
11 | |||
12 | & > div { | ||
13 | font-weight: $font-semibold; | ||
14 | } | ||
15 | } | ||
16 | |||
17 | & > div { | ||
18 | width: 350px; | ||
19 | } | ||
20 | |||
21 | & > div { | ||
22 | padding: 10px | ||
23 | } | ||
24 | } | ||
25 | |||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts new file mode 100644 index 000000000..519bdfab4 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts | |||
@@ -0,0 +1,99 @@ | |||
1 | import { Component, Input, OnInit } from '@angular/core' | ||
2 | import { User } from '@app/shared' | ||
3 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
4 | import { Subject } from 'rxjs' | ||
5 | import { UserNotificationSetting, UserNotificationSettingValue, UserRight } from '../../../../../../shared' | ||
6 | import { Notifier, ServerService } from '@app/core' | ||
7 | import { debounce } from 'lodash-es' | ||
8 | import { UserNotificationService } from '@app/shared/users/user-notification.service' | ||
9 | |||
10 | @Component({ | ||
11 | selector: 'my-account-notification-preferences', | ||
12 | templateUrl: './my-account-notification-preferences.component.html', | ||
13 | styleUrls: [ './my-account-notification-preferences.component.scss' ] | ||
14 | }) | ||
15 | export class MyAccountNotificationPreferencesComponent implements OnInit { | ||
16 | @Input() user: User = null | ||
17 | @Input() userInformationLoaded: Subject<any> | ||
18 | |||
19 | notificationSettingKeys: (keyof UserNotificationSetting)[] = [] | ||
20 | emailNotifications: { [ id in keyof UserNotificationSetting ]: boolean } = {} as any | ||
21 | webNotifications: { [ id in keyof UserNotificationSetting ]: boolean } = {} as any | ||
22 | labelNotifications: { [ id in keyof UserNotificationSetting ]: string } = {} as any | ||
23 | rightNotifications: { [ id in keyof Partial<UserNotificationSetting> ]: UserRight } = {} as any | ||
24 | emailEnabled: boolean | ||
25 | |||
26 | private savePreferences = debounce(this.savePreferencesImpl.bind(this), 500) | ||
27 | |||
28 | constructor ( | ||
29 | private i18n: I18n, | ||
30 | private userNotificationService: UserNotificationService, | ||
31 | private serverService: ServerService, | ||
32 | private notifier: Notifier | ||
33 | ) { | ||
34 | this.labelNotifications = { | ||
35 | newVideoFromSubscription: this.i18n('New video from your subscriptions'), | ||
36 | newCommentOnMyVideo: this.i18n('New comment on your video'), | ||
37 | videoAbuseAsModerator: this.i18n('New video abuse on local video'), | ||
38 | blacklistOnMyVideo: this.i18n('One of your video is blacklisted/unblacklisted'), | ||
39 | myVideoPublished: this.i18n('Video published (after transcoding/scheduled update)'), | ||
40 | myVideoImportFinished: this.i18n('Video import finished'), | ||
41 | newUserRegistration: this.i18n('A new user registered on your instance'), | ||
42 | newFollow: this.i18n('You or your channel(s) has a new follower'), | ||
43 | commentMention: this.i18n('Someone mentioned you in video comments') | ||
44 | } | ||
45 | this.notificationSettingKeys = Object.keys(this.labelNotifications) as (keyof UserNotificationSetting)[] | ||
46 | |||
47 | this.rightNotifications = { | ||
48 | videoAbuseAsModerator: UserRight.MANAGE_VIDEO_ABUSES, | ||
49 | newUserRegistration: UserRight.MANAGE_USERS | ||
50 | } | ||
51 | |||
52 | this.emailEnabled = this.serverService.getConfig().email.enabled | ||
53 | } | ||
54 | |||
55 | ngOnInit () { | ||
56 | this.userInformationLoaded.subscribe(() => this.loadNotificationSettings()) | ||
57 | } | ||
58 | |||
59 | hasUserRight (field: keyof UserNotificationSetting) { | ||
60 | const rightToHave = this.rightNotifications[field] | ||
61 | if (!rightToHave) return true // No rights needed | ||
62 | |||
63 | return this.user.hasRight(rightToHave) | ||
64 | } | ||
65 | |||
66 | updateEmailSetting (field: keyof UserNotificationSetting, value: boolean) { | ||
67 | if (value === true) this.user.notificationSettings[field] |= UserNotificationSettingValue.EMAIL | ||
68 | else this.user.notificationSettings[field] &= ~UserNotificationSettingValue.EMAIL | ||
69 | |||
70 | this.savePreferences() | ||
71 | } | ||
72 | |||
73 | updateWebSetting (field: keyof UserNotificationSetting, value: boolean) { | ||
74 | if (value === true) this.user.notificationSettings[field] |= UserNotificationSettingValue.WEB | ||
75 | else this.user.notificationSettings[field] &= ~UserNotificationSettingValue.WEB | ||
76 | |||
77 | this.savePreferences() | ||
78 | } | ||
79 | |||
80 | private savePreferencesImpl () { | ||
81 | this.userNotificationService.updateNotificationSettings(this.user, this.user.notificationSettings) | ||
82 | .subscribe( | ||
83 | () => { | ||
84 | this.notifier.success(this.i18n('Preferences saved'), undefined, 2000) | ||
85 | }, | ||
86 | |||
87 | err => this.notifier.error(err.message) | ||
88 | ) | ||
89 | } | ||
90 | |||
91 | private loadNotificationSettings () { | ||
92 | for (const key of Object.keys(this.user.notificationSettings)) { | ||
93 | const value = this.user.notificationSettings[key] | ||
94 | this.emailNotifications[key] = value & UserNotificationSettingValue.EMAIL | ||
95 | |||
96 | this.webNotifications[key] = value & UserNotificationSettingValue.WEB | ||
97 | } | ||
98 | } | ||
99 | } | ||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html index c7e23cd1f..2eb7dd56e 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html | |||
@@ -9,6 +9,9 @@ | |||
9 | <my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile> | 9 | <my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile> |
10 | </ng-template> | 10 | </ng-template> |
11 | 11 | ||
12 | <div i18n class="account-title" id="notifications">Notifications</div> | ||
13 | <my-account-notification-preferences [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-notification-preferences> | ||
14 | |||
12 | <div i18n class="account-title">Password</div> | 15 | <div i18n class="account-title">Password</div> |
13 | <my-account-change-password></my-account-change-password> | 16 | <my-account-change-password></my-account-change-password> |
14 | 17 | ||
@@ -16,4 +19,4 @@ | |||
16 | <my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings> | 19 | <my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings> |
17 | 20 | ||
18 | <div i18n class="account-title">Danger zone</div> | 21 | <div i18n class="account-title">Danger zone</div> |
19 | <my-account-danger-zone [user]="user"></my-account-danger-zone> \ No newline at end of file | 22 | <my-account-danger-zone [user]="user"></my-account-danger-zone> |
diff --git a/client/src/app/+my-account/my-account.component.ts b/client/src/app/+my-account/my-account.component.ts index 1bac9547d..8a4102d80 100644 --- a/client/src/app/+my-account/my-account.component.ts +++ b/client/src/app/+my-account/my-account.component.ts | |||
@@ -68,6 +68,10 @@ export class MyAccountComponent { | |||
68 | label: this.i18n('My settings'), | 68 | label: this.i18n('My settings'), |
69 | routerLink: '/my-account/settings' | 69 | routerLink: '/my-account/settings' |
70 | }, | 70 | }, |
71 | { | ||
72 | label: this.i18n('My notifications'), | ||
73 | routerLink: '/my-account/notifications' | ||
74 | }, | ||
71 | libraryEntries, | 75 | libraryEntries, |
72 | miscEntries | 76 | miscEntries |
73 | ] | 77 | ] |
diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts index 80d9f0cf7..18f51f171 100644 --- a/client/src/app/+my-account/my-account.module.ts +++ b/client/src/app/+my-account/my-account.module.ts | |||
@@ -23,6 +23,8 @@ import { MyAccountSubscriptionsComponent } from '@app/+my-account/my-account-sub | |||
23 | import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component' | 23 | import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component' |
24 | import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component' | 24 | import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component' |
25 | import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/my-account-history.component' | 25 | import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/my-account-history.component' |
26 | import { MyAccountNotificationsComponent } from '@app/+my-account/my-account-notifications/my-account-notifications.component' | ||
27 | import { MyAccountNotificationPreferencesComponent } from '@app/+my-account/my-account-settings/my-account-notification-preferences' | ||
26 | 28 | ||
27 | @NgModule({ | 29 | @NgModule({ |
28 | imports: [ | 30 | imports: [ |
@@ -53,7 +55,9 @@ import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/m | |||
53 | MyAccountSubscriptionsComponent, | 55 | MyAccountSubscriptionsComponent, |
54 | MyAccountBlocklistComponent, | 56 | MyAccountBlocklistComponent, |
55 | MyAccountServerBlocklistComponent, | 57 | MyAccountServerBlocklistComponent, |
56 | MyAccountHistoryComponent | 58 | MyAccountHistoryComponent, |
59 | MyAccountNotificationsComponent, | ||
60 | MyAccountNotificationPreferencesComponent | ||
57 | ], | 61 | ], |
58 | 62 | ||
59 | exports: [ | 63 | exports: [ |