From: Chocobozzz Date: Tue, 15 May 2018 09:55:51 +0000 (+0200) Subject: Upgrade to rxjs 6 X-Git-Tag: v1.0.0-beta.5~27 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=db400f447a9f7aae1c56fa25396e93069744483f;p=oweals%2Fpeertube.git Upgrade to rxjs 6 --- diff --git a/.prettierrc.yml b/.prettierrc.yml index aa374328e..d8379671f 100644 --- a/.prettierrc.yml +++ b/.prettierrc.yml @@ -1,8 +1,8 @@ -printWidth: 80 +printWidth: 140 tabWidth: 2 useTabs: false semi: false singleQuote: true -trailingComma: all +trailingComma: false bracketSpacing: true arrowParens: always diff --git a/client/src/app/+accounts/account-about/account-about.component.ts b/client/src/app/+accounts/account-about/account-about.component.ts index 8746875cb..f063df392 100644 --- a/client/src/app/+accounts/account-about/account-about.component.ts +++ b/client/src/app/+accounts/account-about/account-about.component.ts @@ -1,14 +1,5 @@ -import { Component, OnDestroy, OnInit } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { Location } from '@angular/common' -import { getParameterByName, immutableAssign } from '@app/shared/misc/utils' -import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { AuthService } from '../../core/auth' -import { ConfirmService } from '../../core/confirm' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoService } from '../../shared/video/video.service' +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute } from '@angular/router' import { Account } from '@app/shared/account/account.model' import { AccountService } from '@app/shared/account/account.service' diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts index 4c5782f9d..0852c4bb7 100644 --- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts @@ -1,11 +1,10 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' import { Account } from '@app/shared/account/account.model' import { AccountService } from '@app/shared/account/account.service' import { VideoChannel } from '../../../../../shared/models/videos' import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' +import { flatMap, map, tap } from 'rxjs/operators' @Component({ selector: 'my-account-video-channels', @@ -25,9 +24,11 @@ export class AccountVideoChannelsComponent implements OnInit { ngOnInit () { // Parent get the account for us this.accountService.accountLoaded - .do(account => this.account = account) - .flatMap(account => this.videoChannelService.listAccountVideoChannels(account.id)) - .map(res => res.data) + .pipe( + tap(account => this.account = account), + flatMap(account => this.videoChannelService.listAccountVideoChannels(account.id)), + map(res => res.data) + ) .subscribe(videoChannels => this.videoChannels = videoChannels) } } diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts index 6c0f0bb52..1b0590f73 100644 --- a/client/src/app/+accounts/account-videos/account-videos.component.ts +++ b/client/src/app/+accounts/account-videos/account-videos.component.ts @@ -3,8 +3,6 @@ import { ActivatedRoute, Router } from '@angular/router' import { Location } from '@angular/common' import { immutableAssign } from '@app/shared/misc/utils' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' import { AuthService } from '../../core/auth' import { ConfirmService } from '../../core/confirm' import { AbstractVideoList } from '../../shared/video/abstract-video-list' diff --git a/client/src/app/+admin/config/shared/config.service.ts b/client/src/app/+admin/config/shared/config.service.ts index 2a39c7155..1565774b3 100644 --- a/client/src/app/+admin/config/shared/config.service.ts +++ b/client/src/app/+admin/config/shared/config.service.ts @@ -1,3 +1,4 @@ +import { catchError } from 'rxjs/operators' import { HttpClient } from '@angular/common/http' import { Injectable } from '@angular/core' import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' @@ -16,11 +17,11 @@ export class ConfigService { getCustomConfig () { return this.authHttp.get(ConfigService.BASE_APPLICATION_URL + '/custom') - .catch(res => this.restExtractor.handleError(res)) + .pipe(catchError(res => this.restExtractor.handleError(res))) } updateCustomConfig (data: CustomConfig) { return this.authHttp.put(ConfigService.BASE_APPLICATION_URL + '/custom', data) - .catch(res => this.restExtractor.handleError(res)) + .pipe(catchError(res => this.restExtractor.handleError(res))) } } diff --git a/client/src/app/+admin/follows/shared/follow.service.ts b/client/src/app/+admin/follows/shared/follow.service.ts index 089be9d64..5897e64ca 100644 --- a/client/src/app/+admin/follows/shared/follow.service.ts +++ b/client/src/app/+admin/follows/shared/follow.service.ts @@ -1,9 +1,8 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { SortMeta } from 'primeng/primeng' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { AccountFollow, ResultList } from '../../../../../../shared' import { environment } from '../../../../environments/environment' import { RestExtractor, RestPagination, RestService } from '../../../shared' @@ -16,24 +15,29 @@ export class FollowService { private authHttp: HttpClient, private restService: RestService, private restExtractor: RestExtractor - ) {} + ) { + } getFollowing (pagination: RestPagination, sort: SortMeta): Observable> { let params = new HttpParams() params = this.restService.addRestGetParams(params, pagination, sort) return this.authHttp.get>(FollowService.BASE_APPLICATION_URL + '/following', { params }) - .map(res => this.restExtractor.convertResultListDateToHuman(res)) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(res => this.restExtractor.convertResultListDateToHuman(res)), + catchError(res => this.restExtractor.handleError(res)) + ) } getFollowers (pagination: RestPagination, sort: SortMeta): Observable> { let params = new HttpParams() params = this.restService.addRestGetParams(params, pagination, sort) - return this.authHttp.get>(FollowService.BASE_APPLICATION_URL + '/followers', { params }) - .map(res => this.restExtractor.convertResultListDateToHuman(res)) - .catch(res => this.restExtractor.handleError(res)) + return this.authHttp.get>(FollowService.BASE_APPLICATION_URL + '/followers', { params }) + .pipe( + map(res => this.restExtractor.convertResultListDateToHuman(res)), + catchError(res => this.restExtractor.handleError(res)) + ) } follow (notEmptyHosts: string[]) { @@ -42,13 +46,17 @@ export class FollowService { } return this.authHttp.post(FollowService.BASE_APPLICATION_URL + '/following', body) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } unfollow (follow: AccountFollow) { return this.authHttp.delete(FollowService.BASE_APPLICATION_URL + '/following/' + follow.following.host) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } } diff --git a/client/src/app/+admin/jobs/shared/job.service.ts b/client/src/app/+admin/jobs/shared/job.service.ts index 98f29b742..6441eaac1 100644 --- a/client/src/app/+admin/jobs/shared/job.service.ts +++ b/client/src/app/+admin/jobs/shared/job.service.ts @@ -1,9 +1,8 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { SortMeta } from 'primeng/primeng' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { ResultList } from '../../../../../../shared' import { JobState } from '../../../../../../shared/models' import { Job } from '../../../../../../shared/models/server/job.model' @@ -25,9 +24,11 @@ export class JobService { params = this.restService.addRestGetParams(params, pagination, sort) return this.authHttp.get>(JobService.BASE_JOB_URL + '/' + state, { params }) - .map(res => this.restExtractor.convertResultListDateToHuman(res, [ 'createdAt', 'updatedAt' ])) - .map(res => this.restExtractor.applyToResultListData(res, this.prettyPrintData)) - .catch(err => this.restExtractor.handleError(err)) + .pipe( + map(res => this.restExtractor.convertResultListDateToHuman(res, [ 'createdAt', 'updatedAt' ])), + map(res => this.restExtractor.applyToResultListData(res, this.prettyPrintData)), + catchError(err => this.restExtractor.handleError(err)) + ) } private prettyPrintData (obj: Job) { diff --git a/client/src/app/+admin/users/shared/user.service.ts b/client/src/app/+admin/users/shared/user.service.ts index 6536546fb..578cd98c3 100644 --- a/client/src/app/+admin/users/shared/user.service.ts +++ b/client/src/app/+admin/users/shared/user.service.ts @@ -1,10 +1,9 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { BytesPipe } from 'ngx-pipes' import { SortMeta } from 'primeng/components/common/sortmeta' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { ResultList, UserCreate, UserUpdate } from '../../../../../../shared' import { environment } from '../../../../environments/environment' import { RestExtractor, RestPagination, RestService, User } from '../../../shared' @@ -18,23 +17,28 @@ export class UserService { private authHttp: HttpClient, private restService: RestService, private restExtractor: RestExtractor - ) {} + ) { + } addUser (userCreate: UserCreate) { return this.authHttp.post(UserService.BASE_USERS_URL, userCreate) - .map(this.restExtractor.extractDataBool) - .catch(err => this.restExtractor.handleError(err)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(err => this.restExtractor.handleError(err)) + ) } updateUser (userId: number, userUpdate: UserUpdate) { return this.authHttp.put(UserService.BASE_USERS_URL + userId, userUpdate) - .map(this.restExtractor.extractDataBool) - .catch(err => this.restExtractor.handleError(err)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(err => this.restExtractor.handleError(err)) + ) } getUser (userId: number) { return this.authHttp.get(UserService.BASE_USERS_URL + userId) - .catch(err => this.restExtractor.handleError(err)) + .pipe(catchError(err => this.restExtractor.handleError(err))) } getUsers (pagination: RestPagination, sort: SortMeta): Observable> { @@ -42,13 +46,16 @@ export class UserService { params = this.restService.addRestGetParams(params, pagination, sort) return this.authHttp.get>(UserService.BASE_USERS_URL, { params }) - .map(res => this.restExtractor.convertResultListDateToHuman(res)) - .map(res => this.restExtractor.applyToResultListData(res, this.formatUser.bind(this))) - .catch(err => this.restExtractor.handleError(err)) + .pipe( + map(res => this.restExtractor.convertResultListDateToHuman(res)), + map(res => this.restExtractor.applyToResultListData(res, this.formatUser.bind(this))), + catchError(err => this.restExtractor.handleError(err)) + ) } removeUser (user: User) { return this.authHttp.delete(UserService.BASE_USERS_URL + user.id) + .pipe(catchError(err => this.restExtractor.handleError(err))) } private formatUser (user: User) { diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts index 23e44ac1f..3cde07c65 100644 --- a/client/src/app/+admin/users/user-edit/user-update.component.ts +++ b/client/src/app/+admin/users/user-edit/user-update.component.ts @@ -1,20 +1,13 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { FormBuilder, FormGroup } from '@angular/forms' import { ActivatedRoute, Router } from '@angular/router' -import { Subscription } from 'rxjs/Subscription' - +import { Subscription } from 'rxjs' import { NotificationsService } from 'angular2-notifications' - import { UserService } from '../shared' -import { - USER_EMAIL, - USER_VIDEO_QUOTA, - USER_ROLE, - User -} from '../../../shared' +import { User, USER_EMAIL, USER_ROLE, USER_VIDEO_QUOTA } from '../../../shared' import { ServerService } from '../../../core' import { UserEdit } from './user-edit' -import { UserUpdate, UserRole } from '../../../../../../shared' +import { UserUpdate } from '../../../../../../shared' @Component({ selector: 'my-user-update', diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts index fab9cacd8..c82bb39c8 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts @@ -1,8 +1,6 @@ import { Component, OnInit } from '@angular/core' import { Router } from '@angular/router' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' import { FormBuilder, FormGroup } from '@angular/forms' import { VideoChannelCreate } from '../../../../../shared/models/videos' diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts index 9adc38691..b4c8df3cd 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts @@ -1,8 +1,6 @@ -import { Component, OnInit, OnDestroy } from '@angular/core' +import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' import { FormBuilder, FormGroup } from '@angular/forms' import { VideoChannelUpdate } from '../../../../../shared/models/videos' @@ -12,7 +10,7 @@ import { VIDEO_CHANNEL_SUPPORT } from '@app/shared/forms/form-validators/video-channel' import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' -import { Subscription } from 'rxjs/Subscription' +import { Subscription } from 'rxjs' import { VideoChannel } from '@app/shared/video-channel/video-channel.model' import { AuthService } from '@app/core' diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts index eeaca11df..7abf48826 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts @@ -1,12 +1,11 @@ import { Component, OnInit } from '@angular/core' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' import { AuthService } from '../../core/auth' import { ConfirmService } from '../../core/confirm' import { VideoChannel } from '@app/shared/video-channel/video-channel.model' import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' import { User } from '@app/shared' +import { flatMap } from 'rxjs/operators' @Component({ selector: 'my-account-video-channels', @@ -53,7 +52,7 @@ export class MyAccountVideoChannelsComponent implements OnInit { private loadVideoChannels () { this.authService.userInformationLoaded - .flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account.id)) + .pipe(flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account.id))) .subscribe(res => this.videoChannels = res.data) } } diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts index c1b53bcd5..d8c919fee 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts @@ -1,12 +1,11 @@ -import { Component, OnInit, OnDestroy } from '@angular/core' +import { from as observableFrom, Observable } from 'rxjs' +import { concatAll, tap } from 'rxjs/operators' +import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { Location } from '@angular/common' import { immutableAssign } from '@app/shared/misc/utils' import { ComponentPagination } from '@app/shared/rest/component-pagination.model' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { Observable } from 'rxjs/Observable' import { AuthService } from '../../core/auth' import { ConfirmService } from '../../core/confirm' import { AbstractVideoList } from '../../shared/video/abstract-video-list' @@ -78,14 +77,14 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni const observables: Observable[] = [] for (const videoId of toDeleteVideosIds) { const o = this.videoService - .removeVideo(videoId) - .do(() => this.spliceVideosById(videoId)) + .removeVideo(videoId) + .pipe(tap(() => this.spliceVideosById(videoId))) observables.push(o) } - Observable.from(observables) - .concatAll() + observableFrom(observables).pipe( + concatAll()) .subscribe( res => { this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`) diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts index 5d435708e..6f862718f 100644 --- a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts +++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts @@ -1,7 +1,5 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' import { VideoChannel } from '@app/shared/video-channel/video-channel.model' diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts index 3cda630d3..c3eb359f2 100644 --- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts @@ -3,8 +3,6 @@ import { ActivatedRoute, Router } from '@angular/router' import { Location } from '@angular/common' import { immutableAssign } from '@app/shared/misc/utils' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' import { AuthService } from '../../core/auth' import { ConfirmService } from '../../core/confirm' import { AbstractVideoList } from '../../shared/video/abstract-video-list' diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index 6223cde6d..4b388d7be 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts @@ -1,14 +1,9 @@ +import { Observable, ReplaySubject, Subject, throwError as observableThrowError } from 'rxjs' +import { catchError, map, mergeMap, tap } from 'rxjs/operators' import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { Router } from '@angular/router' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/throw' -import 'rxjs/add/operator/do' -import 'rxjs/add/operator/map' -import 'rxjs/add/operator/mergeMap' -import { Observable } from 'rxjs/Observable' -import { ReplaySubject } from 'rxjs/ReplaySubject' -import { Subject } from 'rxjs/Subject' import { OAuthClientLocal, User as UserServerModel, UserRefreshToken } from '../../../../../shared' import { User } from '../../../../../shared/models/users' import { UserLogin } from '../../../../../shared/models/users/user-login.model' @@ -46,7 +41,7 @@ export class AuthService { private notificationsService: NotificationsService, private restExtractor: RestExtractor, private router: Router - ) { + ) { this.loginChanged = new Subject() this.loginChangedSource = this.loginChanged.asObservable() @@ -58,28 +53,28 @@ export class AuthService { // Fetch the client_id/client_secret // FIXME: save in local storage? this.http.get(AuthService.BASE_CLIENT_URL) - .catch(res => this.restExtractor.handleError(res)) - .subscribe( - res => { - this.clientId = res.client_id - this.clientSecret = res.client_secret - console.log('Client credentials loaded.') - }, - - error => { - let errorMessage = error.message - - if (error.status === 403) { - errorMessage = `Cannot retrieve OAuth Client credentials: ${error.text}. \n` - errorMessage += 'Ensure you have correctly configured PeerTube (config/ directory), ' + - 'in particular the "webserver" section.' - } - - // We put a bigger timeout - // This is an important message - this.notificationsService.error('Error', errorMessage, { timeOut: 7000 }) - } - ) + .pipe(catchError(res => this.restExtractor.handleError(res))) + .subscribe( + res => { + this.clientId = res.client_id + this.clientSecret = res.client_secret + console.log('Client credentials loaded.') + }, + + error => { + let errorMessage = error.message + + if (error.status === 403) { + errorMessage = `Cannot retrieve OAuth Client credentials: ${error.text}. \n` + errorMessage += 'Ensure you have correctly configured PeerTube (config/ directory), ' + + 'in particular the "webserver" section.' + } + + // We put a bigger timeout + // This is an important message + this.notificationsService.error('Error', errorMessage, { timeOut: 7000 }) + } + ) } getRefreshToken () { @@ -129,10 +124,12 @@ export class AuthService { const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded') return this.http.post(AuthService.BASE_TOKEN_URL, body.toString(), { headers }) - .map(res => Object.assign(res, { username })) - .flatMap(res => this.mergeUserInformation(res)) - .map(res => this.handleLogin(res)) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(res => Object.assign(res, { username })), + mergeMap(res => this.mergeUserInformation(res)), + map(res => this.handleLogin(res)), + catchError(res => this.restExtractor.handleError(res)) + ) } logout () { @@ -161,20 +158,22 @@ export class AuthService { const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded') this.refreshingTokenObservable = this.http.post(AuthService.BASE_TOKEN_URL, body, { headers }) - .map(res => this.handleRefreshToken(res)) - .do(() => this.refreshingTokenObservable = null) - .catch(err => { - this.refreshingTokenObservable = null - - console.error(err) - console.log('Cannot refresh token -> logout...') - this.logout() - this.router.navigate([ '/login' ]) - - return Observable.throw({ - error: 'You need to reconnect.' - }) - }) + .pipe( + map(res => this.handleRefreshToken(res)), + tap(() => this.refreshingTokenObservable = null), + catchError(err => { + this.refreshingTokenObservable = null + + console.error(err) + console.log('Cannot refresh token -> logout...') + this.logout() + this.router.navigate([ '/login' ]) + + return observableThrowError({ + error: 'You need to reconnect.' + }) + }) + ) return this.refreshingTokenObservable } @@ -188,14 +187,14 @@ export class AuthService { } this.mergeUserInformation(obj) - .subscribe( - res => { - this.user.patch(res) - this.user.save() + .subscribe( + res => { + this.user.patch(res) + this.user.save() - this.userInformationLoaded.next(true) - } - ) + this.userInformationLoaded.next(true) + } + ) } private mergeUserInformation (obj: UserLoginWithUsername): Observable { @@ -203,7 +202,7 @@ export class AuthService { const headers = new HttpHeaders().set('Authorization', `${obj.token_type} ${obj.access_token}`) return this.http.get(AuthService.BASE_USER_INFORMATION_URL, { headers }) - .map(res => Object.assign(obj, res)) + .pipe(map(res => Object.assign(obj, res))) } private handleLogin (obj: UserLoginWithUserInformation) { diff --git a/client/src/app/core/confirm/confirm.service.ts b/client/src/app/core/confirm/confirm.service.ts index d99226f05..8419f622b 100644 --- a/client/src/app/core/confirm/confirm.service.ts +++ b/client/src/app/core/confirm/confirm.service.ts @@ -1,7 +1,6 @@ +import { first } from 'rxjs/operators' import { Injectable } from '@angular/core' -import { Subject } from 'rxjs/Subject' -import 'rxjs/add/operator/first' -import 'rxjs/add/operator/toPromise' +import { Subject } from 'rxjs' type ConfirmOptions = { title: string @@ -19,12 +18,12 @@ export class ConfirmService { confirm (message: string, title = '', confirmButtonText?: string) { this.showConfirm.next({ title, message, confirmButtonText }) - return this.confirmResponse.asObservable().first().toPromise() + return this.confirmResponse.asObservable().pipe(first()).toPromise() } confirmWithInput (message: string, inputLabel: string, expectedInputValue: string, title = '', confirmButtonText?: string) { this.showConfirm.next({ title, message, inputLabel, expectedInputValue, confirmButtonText }) - return this.confirmResponse.asObservable().first().toPromise() + return this.confirmResponse.asObservable().pipe(first()).toPromise() } } diff --git a/client/src/app/core/routing/preload-selected-modules-list.ts b/client/src/app/core/routing/preload-selected-modules-list.ts index 8a458ec3e..3bca60317 100644 --- a/client/src/app/core/routing/preload-selected-modules-list.ts +++ b/client/src/app/core/routing/preload-selected-modules-list.ts @@ -1,14 +1,13 @@ -import { Route, PreloadingStrategy } from '@angular/router' -import { Observable } from 'rxjs/Observable' -import 'rxjs/add/observable/timer' -import 'rxjs/add/operator/switchMap' +import { Observable, timer as observableTimer, of as ofObservable } from 'rxjs' +import { switchMap } from 'rxjs/operators' +import { PreloadingStrategy, Route } from '@angular/router' export class PreloadSelectedModulesList implements PreloadingStrategy { preload (route: Route, load: Function): Observable { - if (!route.data || !route.data.preload) return Observable.of(null) + if (!route.data || !route.data.preload) return ofObservable(null) if (typeof route.data.preload === 'number') { - return Observable.timer(route.data.preload).switchMap(() => load()) + return observableTimer(route.data.preload).pipe(switchMap(() => load())) } return load() diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index a71c6d0bf..c5353023b 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts @@ -1,8 +1,8 @@ +import { tap } from 'rxjs/operators' import { HttpClient } from '@angular/common/http' import { Injectable } from '@angular/core' import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' -import 'rxjs/add/operator/do' -import { ReplaySubject } from 'rxjs/ReplaySubject' +import { ReplaySubject } from 'rxjs' import { ServerConfig } from '../../../../../shared' import { About } from '../../../../../shared/models/server/about.model' import { environment } from '../../../environments/environment' @@ -69,12 +69,12 @@ export class ServerService { loadConfig () { this.http.get(ServerService.BASE_CONFIG_URL) - .do(this.saveConfigLocally) - .subscribe(data => { - this.config = data + .pipe(tap(this.saveConfigLocally)) + .subscribe(data => { + this.config = data - this.configLoaded.next(true) - }) + this.configLoaded.next(true) + }) } loadVideoCategories () { diff --git a/client/src/app/header/header.component.ts b/client/src/app/header/header.component.ts index 42de2dd92..9d2a83773 100644 --- a/client/src/app/header/header.component.ts +++ b/client/src/app/header/header.component.ts @@ -1,5 +1,6 @@ +import { filter, map } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' -import { Router, NavigationEnd } from '@angular/router' +import { NavigationEnd, Router } from '@angular/router' import { getParameterByName } from '../shared/misc/utils' @Component({ @@ -15,9 +16,11 @@ export class HeaderComponent implements OnInit { ngOnInit () { this.router.events - .filter(e => e instanceof NavigationEnd) - .map(() => getParameterByName('search', window.location.href)) - .filter(searchQuery => !!searchQuery) + .pipe( + filter(e => e instanceof NavigationEnd), + map(() => getParameterByName('search', window.location.href)), + filter(searchQuery => !!searchQuery) + ) .subscribe(searchQuery => this.searchValue = searchQuery) } diff --git a/client/src/app/shared/account/account.service.ts b/client/src/app/shared/account/account.service.ts index 8c66ae04a..20e52d946 100644 --- a/client/src/app/shared/account/account.service.ts +++ b/client/src/app/shared/account/account.service.ts @@ -1,14 +1,11 @@ +import { map, tap, catchError } from 'rxjs/operators' import { Injectable } from '@angular/core' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' import { environment } from '../../../environments/environment' -import { Observable } from 'rxjs/Observable' +import { Observable, ReplaySubject } from 'rxjs' import { Account } from '@app/shared/account/account.model' import { RestExtractor } from '@app/shared/rest/rest-extractor.service' -import { RestService } from '@app/shared/rest/rest.service' import { HttpClient } from '@angular/common/http' import { Account as ServerAccount } from '../../../../../shared/models/actors/account.model' -import { ReplaySubject } from 'rxjs/ReplaySubject' @Injectable() export class AccountService { @@ -18,14 +15,15 @@ export class AccountService { constructor ( private authHttp: HttpClient, - private restExtractor: RestExtractor, - private restService: RestService + private restExtractor: RestExtractor ) {} getAccount (id: number): Observable { return this.authHttp.get(AccountService.BASE_ACCOUNT_URL + id) - .map(accountHash => new Account(accountHash)) - .do(account => this.accountLoaded.next(account)) - .catch((res) => this.restExtractor.handleError(res)) + .pipe( + map(accountHash => new Account(accountHash)), + tap(account => this.accountLoaded.next(account)), + catchError(res => this.restExtractor.handleError(res)) + ) } } diff --git a/client/src/app/shared/actor/actor.model.ts b/client/src/app/shared/actor/actor.model.ts index 37d84cb6e..f820dc3c4 100644 --- a/client/src/app/shared/actor/actor.model.ts +++ b/client/src/app/shared/actor/actor.model.ts @@ -10,8 +10,8 @@ export abstract class Actor implements ActorServer { host: string followingCount: number followersCount: number - createdAt: Date - updatedAt: Date + createdAt: Date | string + updatedAt: Date | string avatar: Avatar avatarUrl: string @@ -41,8 +41,8 @@ export abstract class Actor implements ActorServer { this.host = hash.host this.followingCount = hash.followingCount this.followersCount = hash.followersCount - this.createdAt = new Date(hash.createdAt) - this.updatedAt = new Date(hash.updatedAt) + this.createdAt = new Date(hash.createdAt.toString()) + this.updatedAt = new Date(hash.updatedAt.toString()) this.avatar = hash.avatar this.avatarUrl = Actor.GET_ACTOR_AVATAR_URL(this) diff --git a/client/src/app/shared/auth/auth-interceptor.service.ts b/client/src/app/shared/auth/auth-interceptor.service.ts index efcfc452b..bb236bf8c 100644 --- a/client/src/app/shared/auth/auth-interceptor.service.ts +++ b/client/src/app/shared/auth/auth-interceptor.service.ts @@ -1,14 +1,8 @@ +import { Observable, throwError as observableThrowError } from 'rxjs' +import { catchError, switchMap } from 'rxjs/operators' import { Injectable, Injector } from '@angular/core' -import { - HttpInterceptor, - HttpRequest, - HttpEvent, - HttpHandler, HTTP_INTERCEPTORS -} from '@angular/common/http' -import { Observable } from 'rxjs/Observable' - +import { HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http' import { AuthService } from '../../core' -import 'rxjs/add/operator/switchMap' @Injectable() export class AuthInterceptor implements HttpInterceptor { @@ -27,22 +21,26 @@ export class AuthInterceptor implements HttpInterceptor { // Pass on the cloned request instead of the original request // Catch 401 errors (refresh token expired) return next.handle(authReq) - .catch(err => { - if (err.status === 401 && err.error && err.error.code === 'invalid_token') { - return this.handleTokenExpired(req, next) - } - - return Observable.throw(err) - }) + .pipe( + catchError(err => { + if (err.status === 401 && err.error && err.error.code === 'invalid_token') { + return this.handleTokenExpired(req, next) + } + + return observableThrowError(err) + }) + ) } private handleTokenExpired (req: HttpRequest, next: HttpHandler): Observable> { return this.authService.refreshAccessToken() - .switchMap(() => { - const authReq = this.cloneRequestWithAuth(req) + .pipe( + switchMap(() => { + const authReq = this.cloneRequestWithAuth(req) - return next.handle(authReq) - }) + return next.handle(authReq) + }) + ) } private cloneRequestWithAuth (req: HttpRequest) { diff --git a/client/src/app/shared/forms/markdown-textarea.component.ts b/client/src/app/shared/forms/markdown-textarea.component.ts index 928a63b28..dcc85f3cd 100644 --- a/client/src/app/shared/forms/markdown-textarea.component.ts +++ b/client/src/app/shared/forms/markdown-textarea.component.ts @@ -1,10 +1,9 @@ +import { debounceTime, distinctUntilChanged } from 'rxjs/operators' import { Component, forwardRef, Input, OnInit } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' -import 'rxjs/add/operator/debounceTime' -import 'rxjs/add/operator/distinctUntilChanged' import { isInSmallView } from '@app/shared/misc/utils' import { MarkdownService } from '@app/videos/shared' -import { Subject } from 'rxjs/Subject' +import { Subject } from 'rxjs' import truncate from 'lodash-es/truncate' @Component({ @@ -40,9 +39,11 @@ export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit { ngOnInit () { this.contentChanged - .debounceTime(150) - .distinctUntilChanged() - .subscribe(() => this.updatePreviews()) + .pipe( + debounceTime(150), + distinctUntilChanged() + ) + .subscribe(() => this.updatePreviews()) this.contentChanged.next(this.content) diff --git a/client/src/app/shared/guards/can-deactivate-guard.service.ts b/client/src/app/shared/guards/can-deactivate-guard.service.ts index c3b5f37f8..550dd656e 100644 --- a/client/src/app/shared/guards/can-deactivate-guard.service.ts +++ b/client/src/app/shared/guards/can-deactivate-guard.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core' -import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router' -import { Observable } from 'rxjs/Observable' +import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot } from '@angular/router' +import { Observable } from 'rxjs' import { ConfirmService } from '../../core/index' export interface CanComponentDeactivate { diff --git a/client/src/app/shared/rest/rest-extractor.service.ts b/client/src/app/shared/rest/rest-extractor.service.ts index 8ed24c727..4cfe28536 100644 --- a/client/src/app/shared/rest/rest-extractor.service.ts +++ b/client/src/app/shared/rest/rest-extractor.service.ts @@ -1,7 +1,6 @@ -import { HttpErrorResponse } from '@angular/common/http' +import { of, throwError as observableThrowError } from 'rxjs' import { Injectable } from '@angular/core' import { dateToHuman } from '@app/shared/misc/utils' -import { Observable } from 'rxjs/Observable' import { ResultList } from '../../../../../shared' @Injectable() @@ -86,6 +85,8 @@ export class RestExtractor { errorObj.body = err.error } - return Observable.throw(errorObj) + observableThrowError(errorObj) + + return of(undefined) } } diff --git a/client/src/app/shared/users/user.service.ts b/client/src/app/shared/users/user.service.ts index adb840cec..4843be618 100644 --- a/client/src/app/shared/users/user.service.ts +++ b/client/src/app/shared/users/user.service.ts @@ -1,7 +1,6 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient } from '@angular/common/http' import { Injectable } from '@angular/core' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' import { UserCreate, UserUpdateMe } from '../../../../../shared' import { environment } from '../../../environments/environment' import { RestExtractor } from '../rest' @@ -13,7 +12,8 @@ export class UserService { constructor ( private authHttp: HttpClient, private restExtractor: RestExtractor - ) {} + ) { + } changePassword (newPassword: string) { const url = UserService.BASE_USERS_URL + 'me' @@ -22,44 +22,52 @@ export class UserService { } return this.authHttp.put(url, body) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } updateMyProfile (profile: UserUpdateMe) { const url = UserService.BASE_USERS_URL + 'me' return this.authHttp.put(url, profile) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } changeAvatar (avatarForm: FormData) { const url = UserService.BASE_USERS_URL + 'me/avatar/pick' return this.authHttp.post(url, avatarForm) - .catch(this.restExtractor.handleError) + .pipe(catchError(this.restExtractor.handleError)) } signup (userCreate: UserCreate) { return this.authHttp.post(UserService.BASE_USERS_URL + 'register', userCreate) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } getMyVideoQuotaUsed () { const url = UserService.BASE_USERS_URL + '/me/video-quota-used' return this.authHttp.get(url) - .catch(res => this.restExtractor.handleError(res)) + .pipe(catchError(res => this.restExtractor.handleError(res))) } askResetPassword (email: string) { const url = UserService.BASE_USERS_URL + '/ask-reset-password' return this.authHttp.post(url, { email }) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } resetPassword (userId: number, verificationString: string, password: string) { @@ -70,7 +78,9 @@ export class UserService { } return this.authHttp.post(url, body) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } } diff --git a/client/src/app/shared/video-abuse/video-abuse.service.ts b/client/src/app/shared/video-abuse/video-abuse.service.ts index ae00c4c45..6fab3ef43 100644 --- a/client/src/app/shared/video-abuse/video-abuse.service.ts +++ b/client/src/app/shared/video-abuse/video-abuse.service.ts @@ -1,9 +1,8 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { SortMeta } from 'primeng/components/common/sortmeta' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { ResultList, VideoAbuse } from '../../../../../shared' import { environment } from '../../../environments/environment' import { RestExtractor, RestPagination, RestService } from '../rest' @@ -25,8 +24,10 @@ export class VideoAbuseService { params = this.restService.addRestGetParams(params, pagination, sort) return this.authHttp.get>(url, { params }) - .map(res => this.restExtractor.convertResultListDateToHuman(res)) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(res => this.restExtractor.convertResultListDateToHuman(res)), + catchError(res => this.restExtractor.handleError(res)) + ) } reportVideo (id: number, reason: string) { @@ -36,7 +37,9 @@ export class VideoAbuseService { } return this.authHttp.post(url, body) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } } diff --git a/client/src/app/shared/video-blacklist/video-blacklist.service.ts b/client/src/app/shared/video-blacklist/video-blacklist.service.ts index 14c8b5dc0..040d82c9a 100644 --- a/client/src/app/shared/video-blacklist/video-blacklist.service.ts +++ b/client/src/app/shared/video-blacklist/video-blacklist.service.ts @@ -1,9 +1,8 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { SortMeta } from 'primeng/components/common/sortmeta' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { BlacklistedVideo, ResultList } from '../../../../../shared' import { environment } from '../../../environments/environment' import { RestExtractor, RestPagination, RestService } from '../rest' @@ -23,19 +22,25 @@ export class VideoBlacklistService { params = this.restService.addRestGetParams(params, pagination, sort) return this.authHttp.get>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params }) - .map(res => this.restExtractor.convertResultListDateToHuman(res)) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(res => this.restExtractor.convertResultListDateToHuman(res)), + catchError(res => this.restExtractor.handleError(res)) + ) } removeVideoFromBlacklist (videoId: number) { return this.authHttp.delete(VideoBlacklistService.BASE_VIDEOS_URL + videoId + '/blacklist') - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } blacklistVideo (videoId: number) { return this.authHttp.post(VideoBlacklistService.BASE_VIDEOS_URL + videoId + '/blacklist', {}) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } } diff --git a/client/src/app/shared/video-channel/video-channel.service.ts b/client/src/app/shared/video-channel/video-channel.service.ts index 3533a0e9c..e1e3bf697 100644 --- a/client/src/app/shared/video-channel/video-channel.service.ts +++ b/client/src/app/shared/video-channel/video-channel.service.ts @@ -1,18 +1,13 @@ +import { catchError, map, tap } from 'rxjs/operators' import { Injectable } from '@angular/core' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable, ReplaySubject } from 'rxjs' import { RestExtractor } from '../rest/rest-extractor.service' -import { RestService } from '../rest/rest.service' import { HttpClient } from '@angular/common/http' import { VideoChannel as VideoChannelServer, VideoChannelCreate, VideoChannelUpdate } from '../../../../../shared/models/videos' import { AccountService } from '../account/account.service' import { ResultList } from '../../../../../shared' import { VideoChannel } from './video-channel.model' -import { ReplaySubject } from 'rxjs/ReplaySubject' import { environment } from '../../../environments/environment' -import { UserService } from '@app/+admin/users/shared/user.service' -import { User } from '@app/shared' @Injectable() export class VideoChannelService { @@ -22,39 +17,48 @@ export class VideoChannelService { constructor ( private authHttp: HttpClient, - private restExtractor: RestExtractor, - private restService: RestService + private restExtractor: RestExtractor ) {} getVideoChannel (videoChannelUUID: string) { return this.authHttp.get(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelUUID) - .map(videoChannelHash => new VideoChannel(videoChannelHash)) - .do(videoChannel => this.videoChannelLoaded.next(videoChannel)) - .catch((res) => this.restExtractor.handleError(res)) + .pipe( + map(videoChannelHash => new VideoChannel(videoChannelHash)), + tap(videoChannel => this.videoChannelLoaded.next(videoChannel)), + catchError(res => this.restExtractor.handleError(res)) + ) } listAccountVideoChannels (accountId: number): Observable> { return this.authHttp.get>(AccountService.BASE_ACCOUNT_URL + accountId + '/video-channels') - .map(res => this.extractVideoChannels(res)) - .catch((res) => this.restExtractor.handleError(res)) + .pipe( + map(res => this.extractVideoChannels(res)), + catchError((res) => this.restExtractor.handleError(res)) + ) } createVideoChannel (videoChannel: VideoChannelCreate) { return this.authHttp.post(VideoChannelService.BASE_VIDEO_CHANNEL_URL, videoChannel) - .map(this.restExtractor.extractDataBool) - .catch(err => this.restExtractor.handleError(err)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(err => this.restExtractor.handleError(err)) + ) } updateVideoChannel (videoChannelUUID: string, videoChannel: VideoChannelUpdate) { return this.authHttp.put(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelUUID, videoChannel) - .map(this.restExtractor.extractDataBool) - .catch(err => this.restExtractor.handleError(err)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(err => this.restExtractor.handleError(err)) + ) } removeVideoChannel (videoChannel: VideoChannel) { return this.authHttp.delete(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid) - .map(this.restExtractor.extractDataBool) - .catch(err => this.restExtractor.handleError(err)) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(err => this.restExtractor.handleError(err)) + ) } private extractVideoChannels (result: ResultList) { diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts index d8a4b03af..d47df4da4 100644 --- a/client/src/app/shared/video/abstract-video-list.ts +++ b/client/src/app/shared/video/abstract-video-list.ts @@ -1,13 +1,11 @@ +import { debounceTime } from 'rxjs/operators' import { ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { Location } from '@angular/common' import { isInMobileView } from '@app/shared/misc/utils' import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/operator/debounceTime' -import { Observable } from 'rxjs/Observable' -import { fromEvent } from 'rxjs/observable/fromEvent' -import { Subscription } from 'rxjs/Subscription' +import { fromEvent, Observable, Subscription } from 'rxjs' import { AuthService } from '../../core/auth' import { ComponentPagination } from '../rest/component-pagination.model' import { VideoSortField } from './sort-field.type' @@ -64,7 +62,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { this.loadRouteParams(routeParams) this.resizeSubscription = fromEvent(window, 'resize') - .debounceTime(500) + .pipe(debounceTime(500)) .subscribe(() => this.calcPageSizes()) this.calcPageSizes() diff --git a/client/src/app/shared/video/infinite-scroller.directive.ts b/client/src/app/shared/video/infinite-scroller.directive.ts index e2730423f..0448e2c23 100644 --- a/client/src/app/shared/video/infinite-scroller.directive.ts +++ b/client/src/app/shared/video/infinite-scroller.directive.ts @@ -1,14 +1,6 @@ +import { distinct, distinctUntilChanged, filter, map, share, startWith, throttleTime } from 'rxjs/operators' import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core' -import 'rxjs/add/operator/debounceTime' -import 'rxjs/add/operator/distinct' -import 'rxjs/add/operator/distinctUntilChanged' -import 'rxjs/add/operator/filter' -import 'rxjs/add/operator/map' -import 'rxjs/add/operator/share' -import 'rxjs/add/operator/startWith' -import 'rxjs/add/operator/throttleTime' -import { fromEvent } from 'rxjs/observable/fromEvent' -import { Subscription } from 'rxjs/Subscription' +import { fromEvent, Subscription } from 'rxjs' @Directive({ selector: '[myInfiniteScroller]' @@ -51,43 +43,51 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy { const throttleOptions = { leading: true, trailing: true } const scrollObservable = fromEvent(window, 'scroll') - .startWith(true) - .throttleTime(200, undefined, throttleOptions) - .map(() => ({ current: window.scrollY, maximumScroll: document.body.clientHeight - window.innerHeight })) - .distinctUntilChanged((o1, o2) => o1.current === o2.current) - .share() + .pipe( + startWith(null), + throttleTime(200, undefined, throttleOptions), + map(() => ({ current: window.scrollY, maximumScroll: document.body.clientHeight - window.innerHeight })), + distinctUntilChanged((o1, o2) => o1.current === o2.current), + share() + ) // Scroll Down this.scrollDownSub = scrollObservable - // Check we scroll down - .filter(({ current }) => { - const res = this.lastCurrentBottom < current + .pipe( + // Check we scroll down + filter(({ current }) => { + const res = this.lastCurrentBottom < current - this.lastCurrentBottom = current - return res - }) - .filter(({ current, maximumScroll }) => maximumScroll <= 0 || (current / maximumScroll) > this.decimalLimit) + this.lastCurrentBottom = current + return res + }), + filter(({ current, maximumScroll }) => maximumScroll <= 0 || (current / maximumScroll) > this.decimalLimit) + ) .subscribe(() => this.nearOfBottom.emit()) // Scroll up this.scrollUpSub = scrollObservable - // Check we scroll up - .filter(({ current }) => { - const res = this.lastCurrentTop > current + .pipe( + // Check we scroll up + filter(({ current }) => { + const res = this.lastCurrentTop > current - this.lastCurrentTop = current - return res - }) - .filter(({ current, maximumScroll }) => { - return current !== 0 && (1 - (current / maximumScroll)) > this.decimalLimit - }) + this.lastCurrentTop = current + return res + }), + filter(({ current, maximumScroll }) => { + return current !== 0 && (1 - (current / maximumScroll)) > this.decimalLimit + }) + ) .subscribe(() => this.nearOfTop.emit()) // Page change this.pageChangeSub = scrollObservable - .distinct() - .map(({ current }) => this.calculateCurrentPage(current)) - .distinctUntilChanged() + .pipe( + distinct(), + map(({ current }) => this.calculateCurrentPage(current)), + distinctUntilChanged() + ) .subscribe(res => this.pageChanged.emit(res)) } diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index cd8539b41..f57cb6d6d 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts @@ -1,8 +1,7 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http' import { Injectable } from '@angular/core' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { Video as VideoServerModel, VideoDetails as VideoDetailsServerModel } from '../../../../../shared' import { ResultList } from '../../../../../shared/models/result-list.model' import { UserVideoRateUpdate } from '../../../../../shared/models/videos/user-video-rate-update.model' @@ -43,14 +42,18 @@ export class VideoService { getVideo (uuid: string): Observable { return this.authHttp.get(VideoService.BASE_VIDEO_URL + uuid) - .map(videoHash => new VideoDetails(videoHash)) - .catch((res) => this.restExtractor.handleError(res)) + .pipe( + map(videoHash => new VideoDetails(videoHash)), + catchError(res => this.restExtractor.handleError(res)) + ) } viewVideo (uuid: string): Observable { return this.authHttp.post(this.getVideoViewUrl(uuid), {}) - .map(this.restExtractor.extractDataBool) - .catch(this.restExtractor.handleError) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(this.restExtractor.handleError) + ) } updateVideo (video: VideoEdit) { @@ -79,16 +82,18 @@ export class VideoService { const data = objectToFormData(body) return this.authHttp.put(VideoService.BASE_VIDEO_URL + video.id, data) - .map(this.restExtractor.extractDataBool) - .catch(this.restExtractor.handleError) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(this.restExtractor.handleError) + ) } uploadVideo (video: FormData) { const req = new HttpRequest('POST', VideoService.BASE_VIDEO_URL + 'upload', video, { reportProgress: true }) return this.authHttp - .request(req) - .catch(this.restExtractor.handleError) + .request(req) + .pipe(catchError(this.restExtractor.handleError)) } getMyVideos (videoPagination: ComponentPagination, sort: VideoSortField): Observable<{ videos: Video[], totalVideos: number}> { @@ -98,8 +103,10 @@ export class VideoService { params = this.restService.addRestGetParams(params, pagination, sort) return this.authHttp.get(UserService.BASE_USERS_URL + '/me/videos', { params }) - .map(this.extractVideos) - .catch((res) => this.restExtractor.handleError(res)) + .pipe( + map(this.extractVideos), + catchError(res => this.restExtractor.handleError(res)) + ) } getAccountVideos ( @@ -114,8 +121,10 @@ export class VideoService { return this.authHttp .get(AccountService.BASE_ACCOUNT_URL + account.id + '/videos', { params }) - .map(this.extractVideos) - .catch((res) => this.restExtractor.handleError(res)) + .pipe( + map(this.extractVideos), + catchError(res => this.restExtractor.handleError(res)) + ) } getVideoChannelVideos ( @@ -130,8 +139,10 @@ export class VideoService { return this.authHttp .get(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid + '/videos', { params }) - .map(this.extractVideos) - .catch((res) => this.restExtractor.handleError(res)) + .pipe( + map(this.extractVideos), + catchError(res => this.restExtractor.handleError(res)) + ) } getVideos ( @@ -149,9 +160,11 @@ export class VideoService { } return this.authHttp - .get(VideoService.BASE_VIDEO_URL, { params }) - .map(this.extractVideos) - .catch((res) => this.restExtractor.handleError(res)) + .get(VideoService.BASE_VIDEO_URL, { params }) + .pipe( + map(this.extractVideos), + catchError(res => this.restExtractor.handleError(res)) + ) } buildBaseFeedUrls (params: HttpParams) { @@ -215,23 +228,29 @@ export class VideoService { params = params.append('search', search) return this.authHttp - .get>(url, { params }) - .map(this.extractVideos) - .catch((res) => this.restExtractor.handleError(res)) + .get>(url, { params }) + .pipe( + map(this.extractVideos), + catchError(res => this.restExtractor.handleError(res)) + ) } removeVideo (id: number) { return this.authHttp - .delete(VideoService.BASE_VIDEO_URL + id) - .map(this.restExtractor.extractDataBool) - .catch((res) => this.restExtractor.handleError(res)) + .delete(VideoService.BASE_VIDEO_URL + id) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } loadCompleteDescription (descriptionPath: string) { return this.authHttp - .get(environment.apiUrl + descriptionPath) - .map(res => res['description']) - .catch((res) => this.restExtractor.handleError(res)) + .get(environment.apiUrl + descriptionPath) + .pipe( + map(res => res[ 'description' ]), + catchError(res => this.restExtractor.handleError(res)) + ) } setVideoLike (id: number) { @@ -250,8 +269,8 @@ export class VideoService { const url = UserService.BASE_USERS_URL + 'me/videos/' + id + '/rating' return this.authHttp - .get(url) - .catch(res => this.restExtractor.handleError(res)) + .get(url) + .pipe(catchError(res => this.restExtractor.handleError(res))) } private setVideoRate (id: number, rateType: VideoRateType) { @@ -261,9 +280,11 @@ export class VideoService { } return this.authHttp - .put(url, body) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + .put(url, body) + .pipe( + map(this.restExtractor.extractDataBool), + catchError(res => this.restExtractor.handleError(res)) + ) } private extractVideos (result: ResultList) { diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.ts b/client/src/app/videos/+video-edit/shared/video-edit.component.ts index 77e984855..eab0a898e 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.ts +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.ts @@ -3,7 +3,6 @@ import { FormBuilder, FormControl, FormGroup } from '@angular/forms' import { ActivatedRoute, Router } from '@angular/router' import { VIDEO_IMAGE, VIDEO_SUPPORT } from '@app/shared' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/forkJoin' import { ServerService } from '../../../core/server' import { VIDEO_CHANNEL } from '../../../shared/forms/form-validators' import { ValidatorMessage } from '../../../shared/forms/form-validators/validator-message' diff --git a/client/src/app/videos/+video-edit/shared/video-image.component.ts b/client/src/app/videos/+video-edit/shared/video-image.component.ts index 3f5705a92..df6565857 100644 --- a/client/src/app/videos/+video-edit/shared/video-image.component.ts +++ b/client/src/app/videos/+video-edit/shared/video-image.component.ts @@ -2,7 +2,6 @@ import { Component, forwardRef, Input } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' import { ServerService } from '@app/core' -import 'rxjs/add/observable/forkJoin' @Component({ selector: 'my-video-image', @@ -16,7 +15,6 @@ import 'rxjs/add/observable/forkJoin' } ] }) - export class VideoImageComponent implements ControlValueAccessor { @Input() inputLabel: string @Input() inputName: string diff --git a/client/src/app/videos/+video-edit/video-add.component.ts b/client/src/app/videos/+video-edit/video-add.component.ts index fa967018d..41d14573c 100644 --- a/client/src/app/videos/+video-edit/video-add.component.ts +++ b/client/src/app/videos/+video-edit/video-add.component.ts @@ -7,7 +7,7 @@ import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard. import { LoadingBarService } from '@ngx-loading-bar/core' import { NotificationsService } from 'angular2-notifications' import { BytesPipe } from 'ngx-pipes' -import { Subscription } from 'rxjs/Subscription' +import { Subscription } from 'rxjs' import { VideoPrivacy } from '../../../../../shared/models/videos' import { AuthService, ServerService } from '../../core' import { FormReactive } from '../../shared' @@ -24,7 +24,6 @@ import { VideoService } from '../../shared/video/video.service' './video-add.component.scss' ] }) - export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy, CanComponentDeactivate { @ViewChild('videofileInput') videofileInput diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts index 73e2764c6..b1d80bcaa 100644 --- a/client/src/app/videos/+video-edit/video-update.component.ts +++ b/client/src/app/videos/+video-edit/video-update.component.ts @@ -1,9 +1,9 @@ +import { map, switchMap } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' import { FormBuilder, FormGroup } from '@angular/forms' import { ActivatedRoute, Router } from '@angular/router' import { LoadingBarService } from '@ngx-loading-bar/core' import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/forkJoin' import { VideoPrivacy } from '../../../../../shared/models/videos' import { ServerService } from '../../core' import { AuthService } from '../../core/auth' @@ -18,7 +18,6 @@ import { populateAsyncUserVideoChannels } from '@app/shared/misc/utils' styleUrls: [ './shared/video-edit.component.scss' ], templateUrl: './video-update.component.html' }) - export class VideoUpdateComponent extends FormReactive implements OnInit { video: VideoEdit @@ -53,38 +52,40 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { this.serverService.videoPrivaciesLoaded .subscribe(() => this.videoPrivacies = this.serverService.getVideoPrivacies()) - const uuid: string = this.route.snapshot.params['uuid'] + const uuid: string = this.route.snapshot.params[ 'uuid' ] this.videoService.getVideo(uuid) - .switchMap(video => { - return this.videoService - .loadCompleteDescription(video.descriptionPath) - .map(description => Object.assign(video, { description })) - }) - .subscribe( - video => { - this.video = new VideoEdit(video) - - populateAsyncUserVideoChannels(this.authService, this.userVideoChannels) - .catch(err => console.error(err)) - - // We cannot set private a video that was not private - if (video.privacy.id !== VideoPrivacy.PRIVATE) { - const newVideoPrivacies = [] - for (const p of this.videoPrivacies) { - if (p.id !== VideoPrivacy.PRIVATE) newVideoPrivacies.push(p) + .pipe( + switchMap(video => { + return this.videoService + .loadCompleteDescription(video.descriptionPath) + .pipe(map(description => Object.assign(video, { description }))) + }) + ) + .subscribe( + video => { + this.video = new VideoEdit(video) + + populateAsyncUserVideoChannels(this.authService, this.userVideoChannels) + .catch(err => console.error(err)) + + // We cannot set private a video that was not private + if (video.privacy.id !== VideoPrivacy.PRIVATE) { + const newVideoPrivacies = [] + for (const p of this.videoPrivacies) { + if (p.id !== VideoPrivacy.PRIVATE) newVideoPrivacies.push(p) + } + + this.videoPrivacies = newVideoPrivacies } - this.videoPrivacies = newVideoPrivacies - } + this.hydrateFormFromVideo() + }, - this.hydrateFormFromVideo() - }, - - err => { - console.error(err) - this.notificationsService.error('Error', err.message) - } - ) + err => { + console.error(err) + this.notificationsService.error('Error', err.message) + } + ) } checkForm () { diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts index d1ca1968b..b1f446475 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts @@ -1,7 +1,7 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' import { FormBuilder, FormGroup } from '@angular/forms' import { NotificationsService } from 'angular2-notifications' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model' import { FormReactive } from '../../../shared' import { VIDEO_COMMENT_TEXT } from '../../../shared/forms/form-validators/video-comment' diff --git a/client/src/app/videos/+video-watch/comment/video-comment.service.ts b/client/src/app/videos/+video-watch/comment/video-comment.service.ts index 0bf7696fe..5b9a991a0 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.service.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment.service.ts @@ -1,10 +1,8 @@ +import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { lineFeedToHtml } from '@app/shared/misc/utils' -import { MarkdownService } from '@app/videos/shared' -import 'rxjs/add/operator/catch' -import 'rxjs/add/operator/map' -import { Observable } from 'rxjs/Observable' +import { Observable } from 'rxjs' import { ResultList } from '../../../../../../shared/models' import { VideoComment as VideoCommentServerModel, @@ -32,8 +30,10 @@ export class VideoCommentService { const normalizedComment = lineFeedToHtml(comment, 'text') return this.authHttp.post(url, normalizedComment) - .map(data => this.extractVideoComment(data['comment'])) - .catch(this.restExtractor.handleError) + .pipe( + map(data => this.extractVideoComment(data['comment'])), + catchError(this.restExtractor.handleError) + ) } addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) { @@ -41,8 +41,10 @@ export class VideoCommentService { const normalizedComment = lineFeedToHtml(comment, 'text') return this.authHttp.post(url, normalizedComment) - .map(data => this.extractVideoComment(data['comment'])) - .catch(this.restExtractor.handleError) + .pipe( + map(data => this.extractVideoComment(data[ 'comment' ])), + catchError(this.restExtractor.handleError) + ) } getVideoCommentThreads ( @@ -57,27 +59,33 @@ export class VideoCommentService { const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' return this.authHttp - .get(url, { params }) - .map(this.extractVideoComments) - .catch((res) => this.restExtractor.handleError(res)) + .get(url, { params }) + .pipe( + map(this.extractVideoComments), + catchError((res) => this.restExtractor.handleError(res)) + ) } getVideoThreadComments (videoId: number | string, threadId: number): Observable { const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comment-threads/${threadId}` return this.authHttp - .get(url) - .map(tree => this.extractVideoCommentTree(tree as VideoCommentThreadTree)) - .catch((res) => this.restExtractor.handleError(res)) + .get(url) + .pipe( + map(tree => this.extractVideoCommentTree(tree as VideoCommentThreadTree)), + catchError((res) => this.restExtractor.handleError(res)) + ) } deleteVideoComment (videoId: number | string, commentId: number) { const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comments/${commentId}` return this.authHttp - .delete(url) - .map(this.restExtractor.extractDataBool) - .catch((res) => this.restExtractor.handleError(res)) + .delete(url) + .pipe( + map(this.restExtractor.extractDataBool), + catchError((res) => this.restExtractor.handleError(res)) + ) } private extractVideoComment (videoComment: VideoCommentServerModel) { @@ -87,7 +95,7 @@ export class VideoCommentService { private extractVideoComments (result: ResultList) { const videoCommentsJson = result.data const totalComments = result.total - const comments = [] + const comments: VideoComment[] = [] for (const videoCommentJson of videoCommentsJson) { comments.push(new VideoComment(videoCommentJson)) diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.ts b/client/src/app/videos/+video-watch/comment/video-comments.component.ts index a77a6e9f3..34f4a0701 100644 --- a/client/src/app/videos/+video-watch/comment/video-comments.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@ import { ActivatedRoute } from '@angular/router' import { ConfirmService } from '@app/core' import { NotificationsService } from 'angular2-notifications' -import { Subscription } from 'rxjs/Subscription' +import { Subscription } from 'rxjs' import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' import { AuthService } from '../../../core/auth' import { ComponentPagination } from '../../../shared/rest/component-pagination.model' diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index 615b969e5..127ae919d 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts @@ -5,7 +5,7 @@ import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' import { MetaService } from '@ngx-meta/core' import { NotificationsService } from 'angular2-notifications' -import { Subscription } from 'rxjs/Subscription' +import { Subscription } from 'rxjs' import * as videojs from 'video.js' import 'videojs-hotkeys' import * as WebTorrent from 'webtorrent' @@ -13,7 +13,6 @@ import { UserVideoRateType, VideoRateType } from '../../../../../shared' import '../../../assets/player/peertube-videojs-plugin' import { AuthService, ConfirmService } from '../../core' import { VideoBlacklistService } from '../../shared' -import { Account } from '../../shared/account/account.model' import { VideoDetails } from '../../shared/video/video-details.model' import { Video } from '../../shared/video/video.model' import { VideoService } from '../../shared/video/video.service' diff --git a/client/src/app/videos/video-list/video-search.component.ts b/client/src/app/videos/video-list/video-search.component.ts index 774d81ed6..aab896d84 100644 --- a/client/src/app/videos/video-list/video-search.component.ts +++ b/client/src/app/videos/video-list/video-search.component.ts @@ -4,7 +4,7 @@ import { Location } from '@angular/common' import { RedirectService } from '@app/core' import { immutableAssign } from '@app/shared/misc/utils' import { NotificationsService } from 'angular2-notifications' -import { Subscription } from 'rxjs/Subscription' +import { Subscription } from 'rxjs' import { AuthService } from '../../core/auth' import { AbstractVideoList } from '../../shared/video/abstract-video-list' import { VideoService } from '../../shared/video/video.service' diff --git a/package.json b/package.json index 94cda5ef8..8c4409011 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ } }, "lint-staged": { - "*.{js,ts,css,md}": "precise-commits", + "*.{css,md}": "precise-commits", "*.scss": [ "sass-lint-auto-fix -c .sass-lint.yml --verbose", "git add" diff --git a/scripts/watch/client.sh b/scripts/watch/client.sh index 710c87037..7dcce5861 100755 --- a/scripts/watch/client.sh +++ b/scripts/watch/client.sh @@ -4,4 +4,4 @@ set -eu cd client -npm run ng -- server --hmr --host 0.0.0.0 --disable-host-check --port 3000 +npm run ng -- serve --hmr --host 0.0.0.0 --disable-host-check --port 3000