]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Lazy load charts when listing my channels
authorChocobozzz <me@florianbigard.com>
Mon, 21 Mar 2022 10:40:25 +0000 (11:40 +0100)
committerChocobozzz <me@florianbigard.com>
Mon, 21 Mar 2022 10:40:25 +0000 (11:40 +0100)
client/src/app/+my-library/+my-video-channels/my-video-channels.component.html
client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss
client/src/app/shared/shared-main/angular/defer-loading.directive.ts [new file with mode: 0644]
client/src/app/shared/shared-main/angular/index.ts
client/src/app/shared/shared-main/shared-main.module.ts

index c1ded0f6d3dd16c1a3cbb72152a9be8c5f602b91..89327b065d98ae72271d342152dd2c10d8ec3c7b 100644 (file)
         <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>
index 48435596764b28b75284c83409b451f985c6164b..ab80f3d012204604b9916038859728b30a346015 100644 (file)
@@ -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 (file)
index 0000000..9a10e90
--- /dev/null
@@ -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<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)
+  }
+}
index 069b7f6548086914249955f3ba7e5b75a38c3d0f..4b87c2952121ac99874362b7bfa7c678c4e98a6b 100644 (file)
@@ -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'
index 10fc364b309dce10bf82501ae54ce84eca53ac2c..d83af9a66de07e488c050e0a95eac8ae8e0b931c 100644 (file)
@@ -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,