diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss
index 88fba5b05..f648c33e4 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss
@@ -20,8 +20,9 @@
/deep/ .miniature {
display: flex;
- .miniature-bottom {
+ .miniature-info {
margin-left: 10px;
+ width: auto;
}
}
}
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
index 69748ef37..b09e845ac 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
@@ -17,7 +17,7 @@
{{ video.name }}
{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views
-
{{ video.privacy.label }}{{ getStateLabel(video) }}
+
{{ video.privacy.label }}{{ getStateLabel(video) }}
Blacklisted
{{ video.blacklistedReason }}
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
index 39d0cf2f7..f6b5faa45 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
@@ -64,11 +64,11 @@
}
.video-info-date-views,
- .video-info-private,
+ .video-info-privacy,
.video-info-blacklisted {
font-size: 13px;
- &.video-info-private,
+ &.video-info-privacy,
&.video-info-blacklisted .blacklisted-label {
font-weight: $font-semibold;
}
diff --git a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html
new file mode 100644
index 000000000..0d9fba375
--- /dev/null
+++ b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html
@@ -0,0 +1,11 @@
+
+ Created {{pagination.totalItems}} playlists
+
+
+
This channel does not have playlists.
+
+
diff --git a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.scss b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.scss
new file mode 100644
index 000000000..fe9104794
--- /dev/null
+++ b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.scss
@@ -0,0 +1,9 @@
+.video-playlist {
+ display: flex;
+ justify-content: center;
+
+ my-video-playlist-miniature {
+ margin-right: 15px;
+ margin-bottom: 30px;
+ }
+}
diff --git a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts
new file mode 100644
index 000000000..f878a5a24
--- /dev/null
+++ b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts
@@ -0,0 +1,67 @@
+import { Component, OnDestroy, OnInit } from '@angular/core'
+import { AuthService } from '../../core/auth'
+import { ConfirmService } from '../../core/confirm'
+import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
+import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
+import { flatMap } from 'rxjs/operators'
+import { Subscription } from 'rxjs'
+import { Notifier } from '@app/core'
+import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
+import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
+import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
+
+@Component({
+ selector: 'my-video-channel-playlists',
+ templateUrl: './video-channel-playlists.component.html',
+ styleUrls: [ './video-channel-playlists.component.scss' ]
+})
+export class VideoChannelPlaylistsComponent implements OnInit, OnDestroy {
+ videoPlaylists: VideoPlaylist[] = []
+
+ pagination: ComponentPagination = {
+ currentPage: 1,
+ itemsPerPage: 20,
+ totalItems: null
+ }
+
+ private videoChannelSub: Subscription
+ private videoChannel: VideoChannel
+
+ constructor (
+ private authService: AuthService,
+ private notifier: Notifier,
+ private confirmService: ConfirmService,
+ private videoPlaylistService: VideoPlaylistService,
+ private videoChannelService: VideoChannelService
+ ) {}
+
+ ngOnInit () {
+ // Parent get the video channel for us
+ this.videoChannelSub = this.videoChannelService.videoChannelLoaded
+ .subscribe(videoChannel => {
+ this.videoChannel = videoChannel
+ this.loadVideoPlaylists()
+ })
+ }
+
+ ngOnDestroy () {
+ if (this.videoChannelSub) this.videoChannelSub.unsubscribe()
+ }
+
+ onNearOfBottom () {
+ // Last page
+ if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return
+
+ this.pagination.currentPage += 1
+ this.loadVideoPlaylists()
+ }
+
+ private loadVideoPlaylists () {
+ this.authService.userInformationLoaded
+ .pipe(flatMap(() => this.videoPlaylistService.listChannelPlaylists(this.videoChannel)))
+ .subscribe(res => {
+ this.videoPlaylists = this.videoPlaylists.concat(res.data)
+ this.pagination.totalItems = res.total
+ })
+ }
+}
diff --git a/client/src/app/+video-channels/video-channels-routing.module.ts b/client/src/app/+video-channels/video-channels-routing.module.ts
index 3ac3533d9..cedd07d39 100644
--- a/client/src/app/+video-channels/video-channels-routing.module.ts
+++ b/client/src/app/+video-channels/video-channels-routing.module.ts
@@ -4,6 +4,7 @@ import { MetaGuard } from '@ngx-meta/core'
import { VideoChannelsComponent } from './video-channels.component'
import { VideoChannelVideosComponent } from './video-channel-videos/video-channel-videos.component'
import { VideoChannelAboutComponent } from './video-channel-about/video-channel-about.component'
+import { VideoChannelPlaylistsComponent } from '@app/+video-channels/video-channel-playlists/video-channel-playlists.component'
const videoChannelsRoutes: Routes = [
{
@@ -25,6 +26,15 @@ const videoChannelsRoutes: Routes = [
}
}
},
+ {
+ path: 'video-playlists',
+ component: VideoChannelPlaylistsComponent,
+ data: {
+ meta: {
+ title: 'Video channel playlists'
+ }
+ }
+ },
{
path: 'about',
component: VideoChannelAboutComponent,
diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html
index c65b5713d..600b7a365 100644
--- a/client/src/app/+video-channels/video-channels.component.html
+++ b/client/src/app/+video-channels/video-channels.component.html
@@ -22,6 +22,7 @@
diff --git a/client/src/app/+video-channels/video-channels.module.ts b/client/src/app/+video-channels/video-channels.module.ts
index a09ea6f11..6975d05b2 100644
--- a/client/src/app/+video-channels/video-channels.module.ts
+++ b/client/src/app/+video-channels/video-channels.module.ts
@@ -4,6 +4,7 @@ import { VideoChannelsRoutingModule } from './video-channels-routing.module'
import { VideoChannelsComponent } from './video-channels.component'
import { VideoChannelVideosComponent } from './video-channel-videos/video-channel-videos.component'
import { VideoChannelAboutComponent } from './video-channel-about/video-channel-about.component'
+import { VideoChannelPlaylistsComponent } from '@app/+video-channels/video-channel-playlists/video-channel-playlists.component'
@NgModule({
imports: [
@@ -14,7 +15,8 @@ import { VideoChannelAboutComponent } from './video-channel-about/video-channel-
declarations: [
VideoChannelsComponent,
VideoChannelVideosComponent,
- VideoChannelAboutComponent
+ VideoChannelAboutComponent,
+ VideoChannelPlaylistsComponent
],
exports: [
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 @@
- {{ video.playlistElement.position }}
+ {{ position }}
()
@@ -44,7 +46,8 @@ export class VideoPlaylistElementMiniatureComponent {
private route: ActivatedRoute,
private i18n: I18n,
private videoService: VideoService,
- private videoPlaylistService: VideoPlaylistService
+ private videoPlaylistService: VideoPlaylistService,
+ private cdr: ChangeDetectorRef
) {}
buildRouterLink () {
@@ -95,6 +98,8 @@ export class VideoPlaylistElementMiniatureComponent {
video.playlistElement.startTimestamp = body.startTimestamp
video.playlistElement.stopTimestamp = body.stopTimestamp
+
+ this.cdr.detectChanges()
},
err => this.notifier.error(err.message)
@@ -145,5 +150,10 @@ export class VideoPlaylistElementMiniatureComponent {
this.timestampOptions.stopTimestamp = video.playlistElement.stopTimestamp
}
}
+
+ // FIXME: why do we have to use setTimeout here?
+ setTimeout(() => {
+ this.cdr.detectChanges()
+ })
}
}
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 @@
-
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 @@
}
}
- &.to-manage .play-overlay,
+ &.to-manage,
&.no-videos {
- display: none;
+ .play-overlay {
+ display: none;
+ }
}
.miniature-thumbnail {
@@ -34,7 +36,7 @@
}
}
- .miniature-bottom {
+ .miniature-info {
width: 200px;
margin-top: 2px;
line-height: normal;
@@ -42,5 +44,33 @@
.miniature-name {
@include miniature-name;
}
+
+ .video-info-by-date {
+ display: flex;
+ font-size: 13px;
+ margin: 5px 0;
+
+ .by {
+ @include disable-default-a-behaviour;
+
+ display: block;
+ color: var(--mainForegroundColor);
+
+ &::after {
+ content: '-';
+ margin: 0 3px;
+ }
+ }
+ }
+
+ .video-info-privacy {
+ font-size: 13px;
+ font-weight: $font-semibold;
+ }
+
+ .video-info-description {
+ margin-top: 10px;
+ color: $grey-foreground-color;
+ }
}
}
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'
export class VideoPlaylistMiniatureComponent {
@Input() playlist: VideoPlaylist
@Input() toManage = false
+ @Input() displayChannel = false
+ @Input() displayDescription = false
+ @Input() displayPrivacy = false
getPlaylistUrl () {
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 @@
import { distinct, distinctUntilChanged, filter, map, share, startWith, throttleTime } from 'rxjs/operators'
-import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'
+import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'
import { fromEvent, Subscription } from 'rxjs'
@Directive({
@@ -11,7 +11,7 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
@Input() firstLoadedPage = 1
@Input() percentLimit = 70
@Input() autoInit = false
- @Input() container = document.body
+ @Input() onItself = false
@Output() nearOfBottom = new EventEmitter
()
@Output() nearOfTop = new EventEmitter()
@@ -24,8 +24,9 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
private scrollUpSub: Subscription
private pageChangeSub: Subscription
private middleScreen: number
+ private container: HTMLElement
- constructor () {
+ constructor (private el: ElementRef) {
this.decimalLimit = this.percentLimit / 100
}
@@ -40,16 +41,20 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
}
initialize () {
+ if (this.onItself) {
+ this.container = this.el.nativeElement
+ }
+
this.middleScreen = window.innerHeight / 2
// Emit the last value
const throttleOptions = { leading: true, trailing: true }
- const scrollObservable = fromEvent(window, 'scroll')
+ const scrollObservable = fromEvent(this.container || window, 'scroll')
.pipe(
startWith(null),
throttleTime(200, undefined, throttleOptions),
- map(() => ({ current: window.scrollY, maximumScroll: this.container.clientHeight - window.innerHeight })),
+ map(() => this.getScrollInfo()),
distinctUntilChanged((o1, o2) => o1.current === o2.current),
share()
)
@@ -102,4 +107,12 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
// Offset page
return page + (this.firstLoadedPage - 1)
}
+
+ private getScrollInfo () {
+ if (this.container) {
+ return { current: this.container.scrollTop, maximumScroll: this.container.scrollHeight }
+ }
+
+ return { current: window.scrollY, maximumScroll: document.body.clientHeight - window.innerHeight }
+ }
}
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html
index 7f3d1cc2e..3df5b7b19 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -9,7 +9,7 @@
-
+
{{ playlist.displayName }}
@@ -27,10 +27,10 @@
-
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss
index e1cb249ef..281b9240b 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/videos/+video-watch/video-watch.component.scss
@@ -43,11 +43,12 @@ $other-videos-width: 260px;
.playlist {
width: 400px;
height: 66vh;
- background-color: #e4e4e4;
+ background-color: var(--mainBackgroundColor);
overflow-y: auto;
.playlist-info {
padding: 5px 30px;
+ background-color: #e4e4e4;
.playlist-display-name {
font-size: 18px;
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index ddd0f1766..adb728aba 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -58,7 +58,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
playlistVideos: Video[] = []
playlistPagination: ComponentPagination = {
currentPage: 1,
- itemsPerPage: 10,
+ itemsPerPage: 30,
totalItems: null
}
noPlaylistVideos = false
@@ -401,7 +401,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
}
private loadPlaylistElements (redirectToFirst = false) {
- this.videoService.getPlaylistVideos(this.playlist.id, this.playlistPagination)
+ this.videoService.getPlaylistVideos(this.playlist.uuid, this.playlistPagination)
.subscribe(({ totalVideos, videos }) => {
this.playlistVideos = this.playlistVideos.concat(videos)
this.playlistPagination.totalItems = totalVideos
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss
index 478737a43..28b466c01 100644
--- a/client/src/sass/application.scss
+++ b/client/src/sass/application.scss
@@ -104,7 +104,7 @@ label {
background-color: var(--submenuColor);
width: 100%;
height: 81px;
- margin-bottom: 30px;
+ margin-bottom: $sub-menu-margin-bottom;
display: flex;
align-items: center;
padding-left: $not-expanded-horizontal-margins;
diff --git a/client/src/sass/include/_variables.scss b/client/src/sass/include/_variables.scss
index deabbf6d4..b8eb06f2c 100644
--- a/client/src/sass/include/_variables.scss
+++ b/client/src/sass/include/_variables.scss
@@ -54,6 +54,8 @@ $theater-bottom-space: 115px;
$input-background-color: $bg-color;
$input-placeholder-color: #898989;
+$sub-menu-margin-bottom: 30px;
+
/*** map theme ***/
// pass variables into a sass map,