diff options
Diffstat (limited to 'client/src')
3 files changed, 58 insertions, 10 deletions
diff --git a/client/src/app/shared/rxjs/zone.ts b/client/src/app/shared/rxjs/zone.ts new file mode 100644 index 000000000..74eed7032 --- /dev/null +++ b/client/src/app/shared/rxjs/zone.ts | |||
@@ -0,0 +1,40 @@ | |||
1 | import { SchedulerLike, Subscription } from 'rxjs' | ||
2 | import { NgZone } from '@angular/core' | ||
3 | |||
4 | class LeaveZoneScheduler implements SchedulerLike { | ||
5 | constructor (private zone: NgZone, private scheduler: SchedulerLike) { | ||
6 | } | ||
7 | |||
8 | schedule (...args: any[]): Subscription { | ||
9 | return this.zone.runOutsideAngular(() => | ||
10 | this.scheduler.schedule.apply(this.scheduler, args) | ||
11 | ) | ||
12 | } | ||
13 | |||
14 | now (): number { | ||
15 | return this.scheduler.now() | ||
16 | } | ||
17 | } | ||
18 | |||
19 | class EnterZoneScheduler implements SchedulerLike { | ||
20 | constructor (private zone: NgZone, private scheduler: SchedulerLike) { | ||
21 | } | ||
22 | |||
23 | schedule (...args: any[]): Subscription { | ||
24 | return this.zone.run(() => | ||
25 | this.scheduler.schedule.apply(this.scheduler, args) | ||
26 | ) | ||
27 | } | ||
28 | |||
29 | now (): number { | ||
30 | return this.scheduler.now() | ||
31 | } | ||
32 | } | ||
33 | |||
34 | export function leaveZone (zone: NgZone, scheduler: SchedulerLike): SchedulerLike { | ||
35 | return new LeaveZoneScheduler(zone, scheduler) | ||
36 | } | ||
37 | |||
38 | export function enterZone (zone: NgZone, scheduler: SchedulerLike): SchedulerLike { | ||
39 | return new EnterZoneScheduler(zone, scheduler) | ||
40 | } | ||
diff --git a/client/src/app/shared/user-subscription/user-subscription.service.ts b/client/src/app/shared/user-subscription/user-subscription.service.ts index bfb5848bc..9af9ba23e 100644 --- a/client/src/app/shared/user-subscription/user-subscription.service.ts +++ b/client/src/app/shared/user-subscription/user-subscription.service.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { bufferTime, catchError, filter, map, tap, share, switchMap } from 'rxjs/operators' | 1 | import { bufferTime, catchError, filter, map, observeOn, share, switchMap, tap } from 'rxjs/operators' |
2 | import { Observable, ReplaySubject, Subject, of, merge } from 'rxjs' | 2 | import { asyncScheduler, merge, Observable, of, ReplaySubject, Subject } from 'rxjs' |
3 | import { HttpClient, HttpParams } from '@angular/common/http' | 3 | import { HttpClient, HttpParams } from '@angular/common/http' |
4 | import { Injectable } from '@angular/core' | 4 | import { Injectable, NgZone } from '@angular/core' |
5 | import { ResultList } from '../../../../../shared' | 5 | import { ResultList } from '../../../../../shared' |
6 | import { environment } from '../../../environments/environment' | 6 | import { environment } from '../../../environments/environment' |
7 | import { RestExtractor, RestService } from '../rest' | 7 | import { RestExtractor, RestService } from '../rest' |
@@ -11,6 +11,7 @@ import { VideoChannel as VideoChannelServer } from '../../../../../shared/models | |||
11 | import { ComponentPaginationLight } from '@app/shared/rest/component-pagination.model' | 11 | import { ComponentPaginationLight } from '@app/shared/rest/component-pagination.model' |
12 | import { uniq } from 'lodash-es' | 12 | import { uniq } from 'lodash-es' |
13 | import * as debug from 'debug' | 13 | import * as debug from 'debug' |
14 | import { enterZone, leaveZone } from '@app/shared/rxjs/zone' | ||
14 | 15 | ||
15 | const logger = debug('peertube:subscriptions:UserSubscriptionService') | 16 | const logger = debug('peertube:subscriptions:UserSubscriptionService') |
16 | 17 | ||
@@ -32,13 +33,16 @@ export class UserSubscriptionService { | |||
32 | constructor ( | 33 | constructor ( |
33 | private authHttp: HttpClient, | 34 | private authHttp: HttpClient, |
34 | private restExtractor: RestExtractor, | 35 | private restExtractor: RestExtractor, |
35 | private restService: RestService | 36 | private restService: RestService, |
37 | private ngZone: NgZone | ||
36 | ) { | 38 | ) { |
37 | this.existsObservable = merge( | 39 | this.existsObservable = merge( |
38 | this.existsSubject.pipe( | 40 | this.existsSubject.pipe( |
39 | bufferTime(500), | 41 | // We leave Angular zone so Protractor does not get stuck |
42 | bufferTime(500, leaveZone(this.ngZone, asyncScheduler)), | ||
40 | filter(uris => uris.length !== 0), | 43 | filter(uris => uris.length !== 0), |
41 | map(uris => uniq(uris)), | 44 | map(uris => uniq(uris)), |
45 | observeOn(enterZone(this.ngZone, asyncScheduler)), | ||
42 | switchMap(uris => this.doSubscriptionsExist(uris)), | 46 | switchMap(uris => this.doSubscriptionsExist(uris)), |
43 | share() | 47 | share() |
44 | ), | 48 | ), |
diff --git a/client/src/app/shared/video-playlist/video-playlist.service.ts b/client/src/app/shared/video-playlist/video-playlist.service.ts index fc5eb5337..bae6f9e04 100644 --- a/client/src/app/shared/video-playlist/video-playlist.service.ts +++ b/client/src/app/shared/video-playlist/video-playlist.service.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { bufferTime, catchError, filter, map, share, switchMap, tap } from 'rxjs/operators' | 1 | import { bufferTime, catchError, filter, map, observeOn, share, switchMap, tap } from 'rxjs/operators' |
2 | import { Injectable } from '@angular/core' | 2 | import { Injectable, NgZone } from '@angular/core' |
3 | import { merge, Observable, of, ReplaySubject, Subject } from 'rxjs' | 3 | import { asyncScheduler, merge, Observable, of, ReplaySubject, Subject } from 'rxjs' |
4 | import { RestExtractor } from '../rest/rest-extractor.service' | 4 | import { RestExtractor } from '../rest/rest-extractor.service' |
5 | import { HttpClient, HttpParams } from '@angular/common/http' | 5 | import { HttpClient, HttpParams } from '@angular/common/http' |
6 | import { ResultList, VideoPlaylistElementCreate, VideoPlaylistElementUpdate } from '../../../../../shared' | 6 | import { ResultList, VideoPlaylistElementCreate, VideoPlaylistElementUpdate } from '../../../../../shared' |
@@ -23,6 +23,7 @@ import { VideoPlaylistElement as ServerVideoPlaylistElement } from '@shared/mode | |||
23 | import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model' | 23 | import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model' |
24 | import { uniq } from 'lodash-es' | 24 | import { uniq } from 'lodash-es' |
25 | import * as debug from 'debug' | 25 | import * as debug from 'debug' |
26 | import { enterZone, leaveZone } from '@app/shared/rxjs/zone' | ||
26 | 27 | ||
27 | const logger = debug('peertube:playlists:VideoPlaylistService') | 28 | const logger = debug('peertube:playlists:VideoPlaylistService') |
28 | 29 | ||
@@ -49,13 +50,16 @@ export class VideoPlaylistService { | |||
49 | private authHttp: HttpClient, | 50 | private authHttp: HttpClient, |
50 | private serverService: ServerService, | 51 | private serverService: ServerService, |
51 | private restExtractor: RestExtractor, | 52 | private restExtractor: RestExtractor, |
52 | private restService: RestService | 53 | private restService: RestService, |
54 | private ngZone: NgZone | ||
53 | ) { | 55 | ) { |
54 | this.videoExistsInPlaylistObservable = merge( | 56 | this.videoExistsInPlaylistObservable = merge( |
55 | this.videoExistsInPlaylistNotifier.pipe( | 57 | this.videoExistsInPlaylistNotifier.pipe( |
56 | bufferTime(500), | 58 | // We leave Angular zone so Protractor does not get stuck |
59 | bufferTime(500, leaveZone(this.ngZone, asyncScheduler)), | ||
57 | filter(videoIds => videoIds.length !== 0), | 60 | filter(videoIds => videoIds.length !== 0), |
58 | map(videoIds => uniq(videoIds)), | 61 | map(videoIds => uniq(videoIds)), |
62 | observeOn(enterZone(this.ngZone, asyncScheduler)), | ||
59 | switchMap(videoIds => this.doVideosExistInPlaylist(videoIds)), | 63 | switchMap(videoIds => this.doVideosExistInPlaylist(videoIds)), |
60 | share() | 64 | share() |
61 | ), | 65 | ), |