aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/shared-main
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared/shared-main')
-rw-r--r--client/src/app/shared/shared-main/angular/defer-loading.directive.ts76
-rw-r--r--client/src/app/shared/shared-main/angular/index.ts1
-rw-r--r--client/src/app/shared/shared-main/shared-main.module.ts3
3 files changed, 80 insertions, 0 deletions
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 @@
1import * as debug from 'debug'
2import {
3 AfterViewInit,
4 ChangeDetectorRef,
5 ContentChild,
6 Directive,
7 ElementRef,
8 EmbeddedViewRef,
9 EventEmitter,
10 OnDestroy,
11 Output,
12 TemplateRef,
13 ViewContainerRef
14} from '@angular/core'
15
16const logger = debug('peertube:main:DeferLoadingDirective')
17
18@Directive({
19 selector: '[myDeferLoading]'
20})
21export class DeferLoadingDirective implements AfterViewInit, OnDestroy {
22 @ContentChild(TemplateRef) template: TemplateRef<any>
23
24 @Output() loaded: EventEmitter<any> = new EventEmitter()
25
26 view: EmbeddedViewRef<any>
27
28 private observer: IntersectionObserver
29
30 constructor (
31 private el: ElementRef,
32 private viewContainer: ViewContainerRef,
33 private cd: ChangeDetectorRef
34 ) { }
35
36 ngAfterViewInit () {
37 if (this.hasIncompatibleBrowser()) {
38 return this.load()
39 }
40
41 this.observer = new IntersectionObserver(entries => {
42 const entry = entries[0]
43 if (!entry.isIntersecting || entry.target !== this.el.nativeElement) return
44
45 this.observer.unobserve(this.el.nativeElement)
46 this.load()
47 }, { threshold: 0.1 })
48
49 this.observer.observe(this.el.nativeElement)
50 }
51
52 load () {
53 if (this.isLoaded()) return
54
55 logger('Loading component')
56
57 this.viewContainer.clear()
58 this.view = this.viewContainer.createEmbeddedView(this.template, {}, 0)
59 this.loaded.emit()
60 this.cd.detectChanges()
61 }
62
63 isLoaded () {
64 return this.view != null
65 }
66
67 ngOnDestroy () {
68 this.view = null
69
70 if (this.observer) this.observer.disconnect()
71 }
72
73 private hasIncompatibleBrowser () {
74 return !('IntersectionObserver' in window)
75 }
76}
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 @@
1export * from './autofocus.directive' 1export * from './autofocus.directive'
2export * from './bytes.pipe' 2export * from './bytes.pipe'
3export * from './defer-loading.directive'
3export * from './duration-formatter.pipe' 4export * from './duration-formatter.pipe'
4export * from './from-now.pipe' 5export * from './from-now.pipe'
5export * from './infinite-scroller.directive' 6export * 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'
21import { 21import {
22 AutofocusDirective, 22 AutofocusDirective,
23 BytesPipe, 23 BytesPipe,
24 DeferLoadingDirective,
24 DurationFormatterPipe, 25 DurationFormatterPipe,
25 FromNowPipe, 26 FromNowPipe,
26 InfiniteScrollerDirective, 27 InfiniteScrollerDirective,
@@ -80,6 +81,7 @@ import { VideoChannelService } from './video-channel'
80 BytesPipe, 81 BytesPipe,
81 DurationFormatterPipe, 82 DurationFormatterPipe,
82 AutofocusDirective, 83 AutofocusDirective,
84 DeferLoadingDirective,
83 85
84 InfiniteScrollerDirective, 86 InfiniteScrollerDirective,
85 PeerTubeTemplateDirective, 87 PeerTubeTemplateDirective,
@@ -139,6 +141,7 @@ import { VideoChannelService } from './video-channel'
139 NumberFormatterPipe, 141 NumberFormatterPipe,
140 DurationFormatterPipe, 142 DurationFormatterPipe,
141 AutofocusDirective, 143 AutofocusDirective,
144 DeferLoadingDirective,
142 145
143 InfiniteScrollerDirective, 146 InfiniteScrollerDirective,
144 PeerTubeTemplateDirective, 147 PeerTubeTemplateDirective,