<my-delete-button label (click)="deleteVideoChannel(videoChannel)"></my-delete-button>
</div>
- <div *ngIf="!isInSmallView" class="w-100 d-flex justify-content-end">
- <p-chart *ngIf="chartOptions && videoChannelsChartData && videoChannelsChartData[i]" type="line" [data]="videoChannelsChartData[i]" [options]="chartOptions" width="40vw" height="100px"></p-chart>
+ <div *ngIf="!isInSmallView" class="w-100 d-flex justify-content-end chart-container">
+ <div myDeferLoading>
+ <ng-template>
+ <p-chart
+ *ngIf="chartOptions && videoChannelsChartData && videoChannelsChartData[i]"
+ width="40vw" height="100px"
+ type="line" [data]="videoChannelsChartData[i]" [options]="chartOptions"
+ ></p-chart>
+ </ng-template>
+ </div>
</div>
</div>
</div>
--- /dev/null
+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<any>
+
+ @Output() loaded: EventEmitter<any> = new EventEmitter()
+
+ view: EmbeddedViewRef<any>
+
+ 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)
+ }
+}
import {
AutofocusDirective,
BytesPipe,
+ DeferLoadingDirective,
DurationFormatterPipe,
FromNowPipe,
InfiniteScrollerDirective,
BytesPipe,
DurationFormatterPipe,
AutofocusDirective,
+ DeferLoadingDirective,
InfiniteScrollerDirective,
PeerTubeTemplateDirective,
NumberFormatterPipe,
DurationFormatterPipe,
AutofocusDirective,
+ DeferLoadingDirective,
InfiniteScrollerDirective,
PeerTubeTemplateDirective,