aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared')
-rw-r--r--client/src/app/shared/video-playlist/video-playlist-element-miniature.component.html2
-rw-r--r--client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss4
-rw-r--r--client/src/app/shared/video-playlist/video-playlist-element-miniature.component.ts16
-rw-r--r--client/src/app/shared/video-playlist/video-playlist-miniature.component.html18
-rw-r--r--client/src/app/shared/video-playlist/video-playlist-miniature.component.scss36
-rw-r--r--client/src/app/shared/video-playlist/video-playlist-miniature.component.ts3
-rw-r--r--client/src/app/shared/video/infinite-scroller.directive.ts23
7 files changed, 85 insertions, 17 deletions
diff --git a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.html b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.html
index 1f178675f..4764fc0e1 100644
--- a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.html
+++ b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.html
@@ -2,7 +2,7 @@
2 <a [routerLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"> 2 <a [routerLink]="buildRouterLink()" [queryParams]="buildRouterQuery()">
3 <div class="position"> 3 <div class="position">
4 <my-global-icon *ngIf="playing" iconName="play"></my-global-icon> 4 <my-global-icon *ngIf="playing" iconName="play"></my-global-icon>
5 <ng-container *ngIf="!playing">{{ video.playlistElement.position }}</ng-container> 5 <ng-container *ngIf="!playing">{{ position }}</ng-container>
6 </div> 6 </div>
7 7
8 <my-video-thumbnail 8 <my-video-thumbnail
diff --git a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss
index eb869f69a..f57fd2e1c 100644
--- a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss
+++ b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss
@@ -34,7 +34,7 @@
34 font-weight: $font-semibold; 34 font-weight: $font-semibold;
35 margin-right: 10px; 35 margin-right: 10px;
36 color: $grey-foreground-color; 36 color: $grey-foreground-color;
37 min-width: 20px; 37 min-width: 25px;
38 38
39 my-global-icon { 39 my-global-icon {
40 @include apply-svg-color($grey-foreground-color); 40 @include apply-svg-color($grey-foreground-color);
@@ -59,7 +59,7 @@
59 59
60 a { 60 a {
61 color: var(--mainForegroundColor); 61 color: var(--mainForegroundColor);
62 width: fit-content; 62 width: auto;
63 63
64 &:hover { 64 &:hover {
65 text-decoration: underline !important; 65 text-decoration: underline !important;
diff --git a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.ts b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.ts
index c0cfd855d..6cc5b87b4 100644
--- a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.ts
+++ b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.ts
@@ -1,4 +1,4 @@
1import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core' 1import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core'
2import { Video } from '@app/shared/video/video.model' 2import { Video } from '@app/shared/video/video.model'
3import { VideoPlaylistElementUpdate } from '@shared/models' 3import { VideoPlaylistElementUpdate } from '@shared/models'
4import { AuthService, ConfirmService, Notifier, ServerService } from '@app/core' 4import { AuthService, ConfirmService, Notifier, ServerService } from '@app/core'
@@ -13,7 +13,8 @@ import { secondsToTime } from '../../../assets/player/utils'
13@Component({ 13@Component({
14 selector: 'my-video-playlist-element-miniature', 14 selector: 'my-video-playlist-element-miniature',
15 styleUrls: [ './video-playlist-element-miniature.component.scss' ], 15 styleUrls: [ './video-playlist-element-miniature.component.scss' ],
16 templateUrl: './video-playlist-element-miniature.component.html' 16 templateUrl: './video-playlist-element-miniature.component.html',
17 changeDetection: ChangeDetectionStrategy.OnPush
17}) 18})
18export class VideoPlaylistElementMiniatureComponent { 19export class VideoPlaylistElementMiniatureComponent {
19 @ViewChild('moreDropdown') moreDropdown: NgbDropdown 20 @ViewChild('moreDropdown') moreDropdown: NgbDropdown
@@ -24,6 +25,7 @@ export class VideoPlaylistElementMiniatureComponent {
24 @Input() playing = false 25 @Input() playing = false
25 @Input() rowLink = false 26 @Input() rowLink = false
26 @Input() accountLink = true 27 @Input() accountLink = true
28 @Input() position: number
27 29
28 @Output() elementRemoved = new EventEmitter<Video>() 30 @Output() elementRemoved = new EventEmitter<Video>()
29 31
@@ -44,7 +46,8 @@ export class VideoPlaylistElementMiniatureComponent {
44 private route: ActivatedRoute, 46 private route: ActivatedRoute,
45 private i18n: I18n, 47 private i18n: I18n,
46 private videoService: VideoService, 48 private videoService: VideoService,
47 private videoPlaylistService: VideoPlaylistService 49 private videoPlaylistService: VideoPlaylistService,
50 private cdr: ChangeDetectorRef
48 ) {} 51 ) {}
49 52
50 buildRouterLink () { 53 buildRouterLink () {
@@ -95,6 +98,8 @@ export class VideoPlaylistElementMiniatureComponent {
95 98
96 video.playlistElement.startTimestamp = body.startTimestamp 99 video.playlistElement.startTimestamp = body.startTimestamp
97 video.playlistElement.stopTimestamp = body.stopTimestamp 100 video.playlistElement.stopTimestamp = body.stopTimestamp
101
102 this.cdr.detectChanges()
98 }, 103 },
99 104
100 err => this.notifier.error(err.message) 105 err => this.notifier.error(err.message)
@@ -145,5 +150,10 @@ export class VideoPlaylistElementMiniatureComponent {
145 this.timestampOptions.stopTimestamp = video.playlistElement.stopTimestamp 150 this.timestampOptions.stopTimestamp = video.playlistElement.stopTimestamp
146 } 151 }
147 } 152 }
153
154 // FIXME: why do we have to use setTimeout here?
155 setTimeout(() => {
156 this.cdr.detectChanges()
157 })
148 } 158 }
149} 159}
diff --git a/client/src/app/shared/video-playlist/video-playlist-miniature.component.html b/client/src/app/shared/video-playlist/video-playlist-miniature.component.html
index a136f9233..c01c73012 100644
--- a/client/src/app/shared/video-playlist/video-playlist-miniature.component.html
+++ b/client/src/app/shared/video-playlist/video-playlist-miniature.component.html
@@ -1,6 +1,6 @@
1<div class="miniature" [ngClass]="{ 'no-videos': playlist.videosLength === 0, 'to-manage': toManage }"> 1<div class="miniature" [ngClass]="{ 'no-videos': playlist.videosLength === 0, 'to-manage': toManage }">
2 <a 2 <a
3 [routerLink]="getPlaylistUrl()" [attr.title]="playlist.displayName" 3 [routerLink]="getPlaylistUrl()" [attr.title]="playlist.description"
4 class="miniature-thumbnail" 4 class="miniature-thumbnail"
5 > 5 >
6 <img alt="" [attr.aria-labelledby]="playlist.displayName" [attr.src]="playlist.thumbnailUrl" /> 6 <img alt="" [attr.aria-labelledby]="playlist.displayName" [attr.src]="playlist.thumbnailUrl" />
@@ -14,9 +14,21 @@
14 </div> 14 </div>
15 </a> 15 </a>
16 16
17 <div class="miniature-bottom"> 17 <div class="miniature-info">
18 <a tabindex="-1" class="miniature-name" [routerLink]="getPlaylistUrl()" [attr.title]="playlist.displayName"> 18 <a tabindex="-1" class="miniature-name" [routerLink]="getPlaylistUrl()" [attr.title]="playlist.description">
19 {{ playlist.displayName }} 19 {{ playlist.displayName }}
20 </a> 20 </a>
21
22 <div class="video-info-privacy" *ngIf="displayPrivacy">{{ playlist.privacy.label }}</div>
23
24 <div class="video-info-by-date">
25 <a i18n [routerLink]="[ '/video-channels', playlist.videoChannelBy ]" class="by" *ngIf="displayChannel && playlist.videoChannelBy">
26 {{ playlist.videoChannelBy }}
27 </a>
28
29 <div i18n class="updated-at">Updated {{ playlist.updatedAt | myFromNow }}</div>
30 </div>
31
32 <div *ngIf="displayDescription" class="video-info-description">{{ playlist.description }}</div>
21 </div> 33 </div>
22</div> 34</div>
diff --git a/client/src/app/shared/video-playlist/video-playlist-miniature.component.scss b/client/src/app/shared/video-playlist/video-playlist-miniature.component.scss
index 72158eb10..94edd1177 100644
--- a/client/src/app/shared/video-playlist/video-playlist-miniature.component.scss
+++ b/client/src/app/shared/video-playlist/video-playlist-miniature.component.scss
@@ -11,9 +11,11 @@
11 } 11 }
12 } 12 }
13 13
14 &.to-manage .play-overlay, 14 &.to-manage,
15 &.no-videos { 15 &.no-videos {
16 display: none; 16 .play-overlay {
17 display: none;
18 }
17 } 19 }
18 20
19 .miniature-thumbnail { 21 .miniature-thumbnail {
@@ -34,7 +36,7 @@
34 } 36 }
35 } 37 }
36 38
37 .miniature-bottom { 39 .miniature-info {
38 width: 200px; 40 width: 200px;
39 margin-top: 2px; 41 margin-top: 2px;
40 line-height: normal; 42 line-height: normal;
@@ -42,5 +44,33 @@
42 .miniature-name { 44 .miniature-name {
43 @include miniature-name; 45 @include miniature-name;
44 } 46 }
47
48 .video-info-by-date {
49 display: flex;
50 font-size: 13px;
51 margin: 5px 0;
52
53 .by {
54 @include disable-default-a-behaviour;
55
56 display: block;
57 color: var(--mainForegroundColor);
58
59 &::after {
60 content: '-';
61 margin: 0 3px;
62 }
63 }
64 }
65
66 .video-info-privacy {
67 font-size: 13px;
68 font-weight: $font-semibold;
69 }
70
71 .video-info-description {
72 margin-top: 10px;
73 color: $grey-foreground-color;
74 }
45 } 75 }
46} 76}
diff --git a/client/src/app/shared/video-playlist/video-playlist-miniature.component.ts b/client/src/app/shared/video-playlist/video-playlist-miniature.component.ts
index cb5803400..523e96f2a 100644
--- a/client/src/app/shared/video-playlist/video-playlist-miniature.component.ts
+++ b/client/src/app/shared/video-playlist/video-playlist-miniature.component.ts
@@ -9,6 +9,9 @@ import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
9export class VideoPlaylistMiniatureComponent { 9export class VideoPlaylistMiniatureComponent {
10 @Input() playlist: VideoPlaylist 10 @Input() playlist: VideoPlaylist
11 @Input() toManage = false 11 @Input() toManage = false
12 @Input() displayChannel = false
13 @Input() displayDescription = false
14 @Input() displayPrivacy = false
12 15
13 getPlaylistUrl () { 16 getPlaylistUrl () {
14 if (this.toManage) return [ '/my-account/video-playlists', this.playlist.uuid ] 17 if (this.toManage) return [ '/my-account/video-playlists', this.playlist.uuid ]
diff --git a/client/src/app/shared/video/infinite-scroller.directive.ts b/client/src/app/shared/video/infinite-scroller.directive.ts
index 186597a3a..a9e75007c 100644
--- a/client/src/app/shared/video/infinite-scroller.directive.ts
+++ b/client/src/app/shared/video/infinite-scroller.directive.ts
@@ -1,5 +1,5 @@
1import { distinct, distinctUntilChanged, filter, map, share, startWith, throttleTime } from 'rxjs/operators' 1import { distinct, distinctUntilChanged, filter, map, share, startWith, throttleTime } from 'rxjs/operators'
2import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core' 2import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'
3import { fromEvent, Subscription } from 'rxjs' 3import { fromEvent, Subscription } from 'rxjs'
4 4
5@Directive({ 5@Directive({
@@ -11,7 +11,7 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
11 @Input() firstLoadedPage = 1 11 @Input() firstLoadedPage = 1
12 @Input() percentLimit = 70 12 @Input() percentLimit = 70
13 @Input() autoInit = false 13 @Input() autoInit = false
14 @Input() container = document.body 14 @Input() onItself = false
15 15
16 @Output() nearOfBottom = new EventEmitter<void>() 16 @Output() nearOfBottom = new EventEmitter<void>()
17 @Output() nearOfTop = new EventEmitter<void>() 17 @Output() nearOfTop = new EventEmitter<void>()
@@ -24,8 +24,9 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
24 private scrollUpSub: Subscription 24 private scrollUpSub: Subscription
25 private pageChangeSub: Subscription 25 private pageChangeSub: Subscription
26 private middleScreen: number 26 private middleScreen: number
27 private container: HTMLElement
27 28
28 constructor () { 29 constructor (private el: ElementRef) {
29 this.decimalLimit = this.percentLimit / 100 30 this.decimalLimit = this.percentLimit / 100
30 } 31 }
31 32
@@ -40,16 +41,20 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
40 } 41 }
41 42
42 initialize () { 43 initialize () {
44 if (this.onItself) {
45 this.container = this.el.nativeElement
46 }
47
43 this.middleScreen = window.innerHeight / 2 48 this.middleScreen = window.innerHeight / 2
44 49
45 // Emit the last value 50 // Emit the last value
46 const throttleOptions = { leading: true, trailing: true } 51 const throttleOptions = { leading: true, trailing: true }
47 52
48 const scrollObservable = fromEvent(window, 'scroll') 53 const scrollObservable = fromEvent(this.container || window, 'scroll')
49 .pipe( 54 .pipe(
50 startWith(null), 55 startWith(null),
51 throttleTime(200, undefined, throttleOptions), 56 throttleTime(200, undefined, throttleOptions),
52 map(() => ({ current: window.scrollY, maximumScroll: this.container.clientHeight - window.innerHeight })), 57 map(() => this.getScrollInfo()),
53 distinctUntilChanged((o1, o2) => o1.current === o2.current), 58 distinctUntilChanged((o1, o2) => o1.current === o2.current),
54 share() 59 share()
55 ) 60 )
@@ -102,4 +107,12 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
102 // Offset page 107 // Offset page
103 return page + (this.firstLoadedPage - 1) 108 return page + (this.firstLoadedPage - 1)
104 } 109 }
110
111 private getScrollInfo () {
112 if (this.container) {
113 return { current: this.container.scrollTop, maximumScroll: this.container.scrollHeight }
114 }
115
116 return { current: window.scrollY, maximumScroll: document.body.clientHeight - window.innerHeight }
117 }
105} 118}