diff options
author | Chocobozzz <me@florianbigard.com> | 2018-09-11 16:27:07 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-09-13 14:05:49 +0200 |
commit | c48e82b5e0478434de30626d14594a97f2402e7c (patch) | |
tree | a78e5272bd0fe4f5b41831e571e02d05f1515b82 /client | |
parent | a651038487faa838bda3ce04695b08bc65baff70 (diff) | |
download | PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.tar.gz PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.tar.zst PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.zip |
Basic video redundancy implementation
Diffstat (limited to 'client')
10 files changed, 112 insertions, 12 deletions
diff --git a/client/src/app/+admin/admin.module.ts b/client/src/app/+admin/admin.module.ts index e94aac1eb..5784609ef 100644 --- a/client/src/app/+admin/admin.module.ts +++ b/client/src/app/+admin/admin.module.ts | |||
@@ -14,6 +14,8 @@ import { UserCreateComponent, UserListComponent, UsersComponent, UserService, Us | |||
14 | import { ModerationCommentModalComponent, VideoAbuseListComponent, VideoBlacklistListComponent } from './moderation' | 14 | import { ModerationCommentModalComponent, VideoAbuseListComponent, VideoBlacklistListComponent } from './moderation' |
15 | import { UserBanModalComponent } from '@app/+admin/users/user-list/user-ban-modal.component' | 15 | import { UserBanModalComponent } from '@app/+admin/users/user-list/user-ban-modal.component' |
16 | import { ModerationComponent } from '@app/+admin/moderation/moderation.component' | 16 | import { ModerationComponent } from '@app/+admin/moderation/moderation.component' |
17 | import { RedundancyCheckboxComponent } from '@app/+admin/follows/shared/redundancy-checkbox.component' | ||
18 | import { RedundancyService } from '@app/+admin/follows/shared/redundancy.service' | ||
17 | 19 | ||
18 | @NgModule({ | 20 | @NgModule({ |
19 | imports: [ | 21 | imports: [ |
@@ -29,6 +31,7 @@ import { ModerationComponent } from '@app/+admin/moderation/moderation.component | |||
29 | FollowingAddComponent, | 31 | FollowingAddComponent, |
30 | FollowersListComponent, | 32 | FollowersListComponent, |
31 | FollowingListComponent, | 33 | FollowingListComponent, |
34 | RedundancyCheckboxComponent, | ||
32 | 35 | ||
33 | UsersComponent, | 36 | UsersComponent, |
34 | UserCreateComponent, | 37 | UserCreateComponent, |
@@ -54,6 +57,7 @@ import { ModerationComponent } from '@app/+admin/moderation/moderation.component | |||
54 | 57 | ||
55 | providers: [ | 58 | providers: [ |
56 | FollowService, | 59 | FollowService, |
60 | RedundancyService, | ||
57 | UserService, | 61 | UserService, |
58 | JobService, | 62 | JobService, |
59 | ConfigService | 63 | ConfigService |
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts index 96fb67588..ca993dcd3 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.ts +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts | |||
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core' | |||
2 | 2 | ||
3 | import { NotificationsService } from 'angular2-notifications' | 3 | import { NotificationsService } from 'angular2-notifications' |
4 | import { SortMeta } from 'primeng/primeng' | 4 | import { SortMeta } from 'primeng/primeng' |
5 | import { AccountFollow } from '../../../../../../shared/models/actors/follow.model' | 5 | import { ActorFollow } from '../../../../../../shared/models/actors/follow.model' |
6 | import { RestPagination, RestTable } from '../../../shared' | 6 | import { RestPagination, RestTable } from '../../../shared' |
7 | import { FollowService } from '../shared' | 7 | import { FollowService } from '../shared' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | 8 | import { I18n } from '@ngx-translate/i18n-polyfill' |
@@ -13,7 +13,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill' | |||
13 | styleUrls: [ './followers-list.component.scss' ] | 13 | styleUrls: [ './followers-list.component.scss' ] |
14 | }) | 14 | }) |
15 | export class FollowersListComponent extends RestTable implements OnInit { | 15 | export class FollowersListComponent extends RestTable implements OnInit { |
16 | followers: AccountFollow[] = [] | 16 | followers: ActorFollow[] = [] |
17 | totalRecords = 0 | 17 | totalRecords = 0 |
18 | rowsPerPage = 10 | 18 | rowsPerPage = 10 |
19 | sort: SortMeta = { field: 'createdAt', order: 1 } | 19 | sort: SortMeta = { field: 'createdAt', order: 1 } |
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html index e4a45e88c..66ab64c50 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.html +++ b/client/src/app/+admin/follows/following-list/following-list.component.html | |||
@@ -8,6 +8,7 @@ | |||
8 | <th i18n>Host</th> | 8 | <th i18n>Host</th> |
9 | <th i18n>State</th> | 9 | <th i18n>State</th> |
10 | <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 10 | <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
11 | <th i18n>Redundancy allowed</th> | ||
11 | <th></th> | 12 | <th></th> |
12 | </tr> | 13 | </tr> |
13 | </ng-template> | 14 | </ng-template> |
@@ -18,6 +19,11 @@ | |||
18 | <td>{{ follow.following.host }}</td> | 19 | <td>{{ follow.following.host }}</td> |
19 | <td>{{ follow.state }}</td> | 20 | <td>{{ follow.state }}</td> |
20 | <td>{{ follow.createdAt }}</td> | 21 | <td>{{ follow.createdAt }}</td> |
22 | <td> | ||
23 | <my-redundancy-checkbox | ||
24 | [host]="follow.following.host" [redundancyAllowed]="follow.following.hostRedundancyAllowed" | ||
25 | ></my-redundancy-checkbox> | ||
26 | </td> | ||
21 | <td class="action-cell"> | 27 | <td class="action-cell"> |
22 | <my-delete-button (click)="removeFollowing(follow)"></my-delete-button> | 28 | <my-delete-button (click)="removeFollowing(follow)"></my-delete-button> |
23 | </td> | 29 | </td> |
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.scss b/client/src/app/+admin/follows/following-list/following-list.component.scss new file mode 100644 index 000000000..bfcdcaa49 --- /dev/null +++ b/client/src/app/+admin/follows/following-list/following-list.component.scss | |||
@@ -0,0 +1,13 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | my-redundancy-checkbox /deep/ my-peertube-checkbox { | ||
5 | .form-group { | ||
6 | margin-bottom: 0; | ||
7 | align-items: center; | ||
8 | } | ||
9 | |||
10 | label { | ||
11 | margin: 0; | ||
12 | } | ||
13 | } \ No newline at end of file | ||
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts index 06e341e68..dd57884c6 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.ts +++ b/client/src/app/+admin/follows/following-list/following-list.component.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { NotificationsService } from 'angular2-notifications' | 2 | import { NotificationsService } from 'angular2-notifications' |
3 | import { SortMeta } from 'primeng/primeng' | 3 | import { SortMeta } from 'primeng/primeng' |
4 | import { AccountFollow } from '../../../../../../shared/models/actors/follow.model' | 4 | import { ActorFollow } from '../../../../../../shared/models/actors/follow.model' |
5 | import { ConfirmService } from '../../../core/confirm/confirm.service' | 5 | import { ConfirmService } from '../../../core/confirm/confirm.service' |
6 | import { RestPagination, RestTable } from '../../../shared' | 6 | import { RestPagination, RestTable } from '../../../shared' |
7 | import { FollowService } from '../shared' | 7 | import { FollowService } from '../shared' |
@@ -9,10 +9,11 @@ import { I18n } from '@ngx-translate/i18n-polyfill' | |||
9 | 9 | ||
10 | @Component({ | 10 | @Component({ |
11 | selector: 'my-followers-list', | 11 | selector: 'my-followers-list', |
12 | templateUrl: './following-list.component.html' | 12 | templateUrl: './following-list.component.html', |
13 | styleUrls: [ './following-list.component.scss' ] | ||
13 | }) | 14 | }) |
14 | export class FollowingListComponent extends RestTable implements OnInit { | 15 | export class FollowingListComponent extends RestTable implements OnInit { |
15 | following: AccountFollow[] = [] | 16 | following: ActorFollow[] = [] |
16 | totalRecords = 0 | 17 | totalRecords = 0 |
17 | rowsPerPage = 10 | 18 | rowsPerPage = 10 |
18 | sort: SortMeta = { field: 'createdAt', order: 1 } | 19 | sort: SortMeta = { field: 'createdAt', order: 1 } |
@@ -31,7 +32,7 @@ export class FollowingListComponent extends RestTable implements OnInit { | |||
31 | this.loadSort() | 32 | this.loadSort() |
32 | } | 33 | } |
33 | 34 | ||
34 | async removeFollowing (follow: AccountFollow) { | 35 | async removeFollowing (follow: ActorFollow) { |
35 | const res = await this.confirmService.confirm( | 36 | const res = await this.confirmService.confirm( |
36 | this.i18n('Do you really want to unfollow {{host}}?', { host: follow.following.host }), | 37 | this.i18n('Do you really want to unfollow {{host}}?', { host: follow.following.host }), |
37 | this.i18n('Unfollow') | 38 | this.i18n('Unfollow') |
diff --git a/client/src/app/+admin/follows/shared/follow.service.ts b/client/src/app/+admin/follows/shared/follow.service.ts index 87ea5fb0c..27169a9cd 100644 --- a/client/src/app/+admin/follows/shared/follow.service.ts +++ b/client/src/app/+admin/follows/shared/follow.service.ts | |||
@@ -3,7 +3,7 @@ import { HttpClient, HttpParams } from '@angular/common/http' | |||
3 | import { Injectable } from '@angular/core' | 3 | import { Injectable } from '@angular/core' |
4 | import { SortMeta } from 'primeng/primeng' | 4 | import { SortMeta } from 'primeng/primeng' |
5 | import { Observable } from 'rxjs' | 5 | import { Observable } from 'rxjs' |
6 | import { AccountFollow, ResultList } from '../../../../../../shared' | 6 | import { ActorFollow, ResultList } from '../../../../../../shared' |
7 | import { environment } from '../../../../environments/environment' | 7 | import { environment } from '../../../../environments/environment' |
8 | import { RestExtractor, RestPagination, RestService } from '../../../shared' | 8 | import { RestExtractor, RestPagination, RestService } from '../../../shared' |
9 | 9 | ||
@@ -18,22 +18,22 @@ export class FollowService { | |||
18 | ) { | 18 | ) { |
19 | } | 19 | } |
20 | 20 | ||
21 | getFollowing (pagination: RestPagination, sort: SortMeta): Observable<ResultList<AccountFollow>> { | 21 | getFollowing (pagination: RestPagination, sort: SortMeta): Observable<ResultList<ActorFollow>> { |
22 | let params = new HttpParams() | 22 | let params = new HttpParams() |
23 | params = this.restService.addRestGetParams(params, pagination, sort) | 23 | params = this.restService.addRestGetParams(params, pagination, sort) |
24 | 24 | ||
25 | return this.authHttp.get<ResultList<AccountFollow>>(FollowService.BASE_APPLICATION_URL + '/following', { params }) | 25 | return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/following', { params }) |
26 | .pipe( | 26 | .pipe( |
27 | map(res => this.restExtractor.convertResultListDateToHuman(res)), | 27 | map(res => this.restExtractor.convertResultListDateToHuman(res)), |
28 | catchError(res => this.restExtractor.handleError(res)) | 28 | catchError(res => this.restExtractor.handleError(res)) |
29 | ) | 29 | ) |
30 | } | 30 | } |
31 | 31 | ||
32 | getFollowers (pagination: RestPagination, sort: SortMeta): Observable<ResultList<AccountFollow>> { | 32 | getFollowers (pagination: RestPagination, sort: SortMeta): Observable<ResultList<ActorFollow>> { |
33 | let params = new HttpParams() | 33 | let params = new HttpParams() |
34 | params = this.restService.addRestGetParams(params, pagination, sort) | 34 | params = this.restService.addRestGetParams(params, pagination, sort) |
35 | 35 | ||
36 | return this.authHttp.get<ResultList<AccountFollow>>(FollowService.BASE_APPLICATION_URL + '/followers', { params }) | 36 | return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/followers', { params }) |
37 | .pipe( | 37 | .pipe( |
38 | map(res => this.restExtractor.convertResultListDateToHuman(res)), | 38 | map(res => this.restExtractor.convertResultListDateToHuman(res)), |
39 | catchError(res => this.restExtractor.handleError(res)) | 39 | catchError(res => this.restExtractor.handleError(res)) |
@@ -52,7 +52,7 @@ export class FollowService { | |||
52 | ) | 52 | ) |
53 | } | 53 | } |
54 | 54 | ||
55 | unfollow (follow: AccountFollow) { | 55 | unfollow (follow: ActorFollow) { |
56 | return this.authHttp.delete(FollowService.BASE_APPLICATION_URL + '/following/' + follow.following.host) | 56 | return this.authHttp.delete(FollowService.BASE_APPLICATION_URL + '/following/' + follow.following.host) |
57 | .pipe( | 57 | .pipe( |
58 | map(this.restExtractor.extractDataBool), | 58 | map(this.restExtractor.extractDataBool), |
diff --git a/client/src/app/+admin/follows/shared/redundancy-checkbox.component.html b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.html new file mode 100644 index 000000000..8a57d65f0 --- /dev/null +++ b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.html | |||
@@ -0,0 +1,3 @@ | |||
1 | <my-peertube-checkbox | ||
2 | [inputName]="host + '-redundancy-allowed'" [(ngModel)]="redundancyAllowed" (ngModelChange)="updateRedundancyState()" | ||
3 | ></my-peertube-checkbox> \ No newline at end of file | ||
diff --git a/client/src/app/+admin/follows/shared/redundancy-checkbox.component.scss b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.scss new file mode 100644 index 000000000..5e6774739 --- /dev/null +++ b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.scss | |||
@@ -0,0 +1,2 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
diff --git a/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts new file mode 100644 index 000000000..ff4725e91 --- /dev/null +++ b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts | |||
@@ -0,0 +1,42 @@ | |||
1 | import { Component, Input } from '@angular/core' | ||
2 | import { AuthService } from '@app/core' | ||
3 | import { RestExtractor } from '@app/shared/rest' | ||
4 | import { RedirectService } from '@app/core/routing/redirect.service' | ||
5 | import { NotificationsService } from 'angular2-notifications' | ||
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
7 | import { RedundancyService } from '@app/+admin/follows/shared/redundancy.service' | ||
8 | |||
9 | @Component({ | ||
10 | selector: 'my-redundancy-checkbox', | ||
11 | templateUrl: './redundancy-checkbox.component.html', | ||
12 | styleUrls: [ './redundancy-checkbox.component.scss' ] | ||
13 | }) | ||
14 | export class RedundancyCheckboxComponent { | ||
15 | @Input() redundancyAllowed: boolean | ||
16 | @Input() host: string | ||
17 | |||
18 | constructor ( | ||
19 | private authService: AuthService, | ||
20 | private restExtractor: RestExtractor, | ||
21 | private redirectService: RedirectService, | ||
22 | private notificationsService: NotificationsService, | ||
23 | private redundancyService: RedundancyService, | ||
24 | private i18n: I18n | ||
25 | ) { } | ||
26 | |||
27 | updateRedundancyState () { | ||
28 | this.redundancyService.updateRedundancy(this.host, this.redundancyAllowed) | ||
29 | .subscribe( | ||
30 | () => { | ||
31 | const stateLabel = this.redundancyAllowed ? this.i18n('enabled') : this.i18n('disabled') | ||
32 | |||
33 | this.notificationsService.success( | ||
34 | this.i18n('Success'), | ||
35 | this.i18n('Redundancy for {{host}} is {{stateLabel}}', { host: this.host, stateLabel }) | ||
36 | ) | ||
37 | }, | ||
38 | |||
39 | err => this.notificationsService.error(this.i18n('Error'), err.message) | ||
40 | ) | ||
41 | } | ||
42 | } | ||
diff --git a/client/src/app/+admin/follows/shared/redundancy.service.ts b/client/src/app/+admin/follows/shared/redundancy.service.ts new file mode 100644 index 000000000..96b29faab --- /dev/null +++ b/client/src/app/+admin/follows/shared/redundancy.service.ts | |||
@@ -0,0 +1,29 @@ | |||
1 | import { catchError, map } from 'rxjs/operators' | ||
2 | import { HttpClient } from '@angular/common/http' | ||
3 | import { Injectable } from '@angular/core' | ||
4 | import { RestExtractor, RestService } from '@app/shared' | ||
5 | import { environment } from '../../../../environments/environment' | ||
6 | |||
7 | @Injectable() | ||
8 | export class RedundancyService { | ||
9 | static BASE_USER_SUBSCRIPTIONS_URL = environment.apiUrl + '/api/v1/server/redundancy' | ||
10 | |||
11 | constructor ( | ||
12 | private authHttp: HttpClient, | ||
13 | private restExtractor: RestExtractor, | ||
14 | private restService: RestService | ||
15 | ) { } | ||
16 | |||
17 | updateRedundancy (host: string, redundancyAllowed: boolean) { | ||
18 | const url = RedundancyService.BASE_USER_SUBSCRIPTIONS_URL + '/' + host | ||
19 | |||
20 | const body = { redundancyAllowed } | ||
21 | |||
22 | return this.authHttp.put(url, body) | ||
23 | .pipe( | ||
24 | map(this.restExtractor.extractDataBool), | ||
25 | catchError(err => this.restExtractor.handleError(err)) | ||
26 | ) | ||
27 | } | ||
28 | |||
29 | } | ||