diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html index c1ded0f6d..89327b065 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html @@ -41,8 +41,16 @@ -
- +
+
+ + + +
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss index 484355967..ab80f3d01 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss @@ -62,9 +62,10 @@ my-edit-button { min-width: 190px; } -::ng-deep .chartjs-render-monitor { - position: relative; - top: 1px; +.chart-container { + // Sync these values with the template + width: 40vw; + height: 100px; } .video-channels-header { diff --git a/client/src/app/shared/shared-main/angular/defer-loading.directive.ts b/client/src/app/shared/shared-main/angular/defer-loading.directive.ts new file mode 100644 index 000000000..9a10e90e3 --- /dev/null +++ b/client/src/app/shared/shared-main/angular/defer-loading.directive.ts @@ -0,0 +1,76 @@ +import * as debug from 'debug' +import { + AfterViewInit, + ChangeDetectorRef, + ContentChild, + Directive, + ElementRef, + EmbeddedViewRef, + EventEmitter, + OnDestroy, + Output, + TemplateRef, + ViewContainerRef +} from '@angular/core' + +const logger = debug('peertube:main:DeferLoadingDirective') + +@Directive({ + selector: '[myDeferLoading]' +}) +export class DeferLoadingDirective implements AfterViewInit, OnDestroy { + @ContentChild(TemplateRef) template: TemplateRef + + @Output() loaded: EventEmitter = new EventEmitter() + + view: EmbeddedViewRef + + private observer: IntersectionObserver + + constructor ( + private el: ElementRef, + private viewContainer: ViewContainerRef, + private cd: ChangeDetectorRef + ) { } + + ngAfterViewInit () { + if (this.hasIncompatibleBrowser()) { + return this.load() + } + + this.observer = new IntersectionObserver(entries => { + const entry = entries[0] + if (!entry.isIntersecting || entry.target !== this.el.nativeElement) return + + this.observer.unobserve(this.el.nativeElement) + this.load() + }, { threshold: 0.1 }) + + this.observer.observe(this.el.nativeElement) + } + + load () { + if (this.isLoaded()) return + + logger('Loading component') + + this.viewContainer.clear() + this.view = this.viewContainer.createEmbeddedView(this.template, {}, 0) + this.loaded.emit() + this.cd.detectChanges() + } + + isLoaded () { + return this.view != null + } + + ngOnDestroy () { + this.view = null + + if (this.observer) this.observer.disconnect() + } + + private hasIncompatibleBrowser () { + return !('IntersectionObserver' in window) + } +} diff --git a/client/src/app/shared/shared-main/angular/index.ts b/client/src/app/shared/shared-main/angular/index.ts index 069b7f654..4b87c2952 100644 --- a/client/src/app/shared/shared-main/angular/index.ts +++ b/client/src/app/shared/shared-main/angular/index.ts @@ -1,5 +1,6 @@ export * from './autofocus.directive' export * from './bytes.pipe' +export * from './defer-loading.directive' export * from './duration-formatter.pipe' export * from './from-now.pipe' export * from './infinite-scroller.directive' diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts index 10fc364b3..d83af9a66 100644 --- a/client/src/app/shared/shared-main/shared-main.module.ts +++ b/client/src/app/shared/shared-main/shared-main.module.ts @@ -21,6 +21,7 @@ import { AccountService } from './account' import { AutofocusDirective, BytesPipe, + DeferLoadingDirective, DurationFormatterPipe, FromNowPipe, InfiniteScrollerDirective, @@ -80,6 +81,7 @@ import { VideoChannelService } from './video-channel' BytesPipe, DurationFormatterPipe, AutofocusDirective, + DeferLoadingDirective, InfiniteScrollerDirective, PeerTubeTemplateDirective, @@ -139,6 +141,7 @@ import { VideoChannelService } from './video-channel' NumberFormatterPipe, DurationFormatterPipe, AutofocusDirective, + DeferLoadingDirective, InfiniteScrollerDirective, PeerTubeTemplateDirective,