aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/videos/video-list
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/videos/video-list')
-rw-r--r--client/src/app/videos/video-list/index.ts3
-rw-r--r--client/src/app/videos/video-list/my-videos.component.ts2
-rw-r--r--client/src/app/videos/video-list/shared/abstract-video-list.html18
-rw-r--r--client/src/app/videos/video-list/shared/abstract-video-list.scss14
-rw-r--r--client/src/app/videos/video-list/shared/abstract-video-list.ts28
-rw-r--r--client/src/app/videos/video-list/shared/index.ts1
-rw-r--r--client/src/app/videos/video-list/shared/video-miniature.component.html13
-rw-r--r--client/src/app/videos/video-list/shared/video-miniature.component.scss66
-rw-r--r--client/src/app/videos/video-list/shared/video-sort.component.html5
-rw-r--r--client/src/app/videos/video-list/shared/video-sort.component.ts39
-rw-r--r--client/src/app/videos/video-list/video-list.component.ts94
-rw-r--r--client/src/app/videos/video-list/video-recently-added.component.ts33
-rw-r--r--client/src/app/videos/video-list/video-trending.component.ts33
13 files changed, 99 insertions, 250 deletions
diff --git a/client/src/app/videos/video-list/index.ts b/client/src/app/videos/video-list/index.ts
index ed2bb1657..a5a60364a 100644
--- a/client/src/app/videos/video-list/index.ts
+++ b/client/src/app/videos/video-list/index.ts
@@ -1,3 +1,4 @@
1export * from './my-videos.component' 1export * from './my-videos.component'
2export * from './video-list.component' 2export * from './video-recently-added.component'
3export * from './video-trending.component'
3export * from './shared' 4export * from './shared'
diff --git a/client/src/app/videos/video-list/my-videos.component.ts b/client/src/app/videos/video-list/my-videos.component.ts
index 648741a40..146db8262 100644
--- a/client/src/app/videos/video-list/my-videos.component.ts
+++ b/client/src/app/videos/video-list/my-videos.component.ts
@@ -27,7 +27,7 @@ export class MyVideosComponent extends AbstractVideoList implements OnInit, OnDe
27 } 27 }
28 28
29 ngOnDestroy () { 29 ngOnDestroy () {
30 this.subActivatedRoute.unsubscribe() 30 super.ngOnDestroy()
31 } 31 }
32 32
33 getVideosObservable () { 33 getVideosObservable () {
diff --git a/client/src/app/videos/video-list/shared/abstract-video-list.html b/client/src/app/videos/video-list/shared/abstract-video-list.html
index 680fba3f5..ab5530e68 100644
--- a/client/src/app/videos/video-list/shared/abstract-video-list.html
+++ b/client/src/app/videos/video-list/shared/abstract-video-list.html
@@ -1,20 +1,8 @@
1<div class="row"> 1<div class="title-page">
2 <div class="content-padding"> 2 {{ titlePage }}
3 <div class="videos-info">
4 <div class="col-md-9 col-xs-5 videos-total-results">
5 <span *ngIf="pagination.totalItems !== null">{{ pagination.totalItems }} videos</span>
6
7 <my-loader [loading]="loading | async"></my-loader>
8 </div>
9
10 <my-video-sort class="col-md-3 col-xs-7" [currentSort]="sort" (sort)="onSort($event)"></my-video-sort>
11 </div>
12 </div>
13</div> 3</div>
14 4
15<div class="content-padding videos-miniatures"> 5<div class="videos-miniatures">
16 <div class="no-video" *ngIf="isThereNoVideo()">There is no video.</div>
17
18 <my-video-miniature 6 <my-video-miniature
19 class="ng-animate" 7 class="ng-animate"
20 *ngFor="let video of videos" [video]="video" [user]="user" [currentSort]="sort" 8 *ngFor="let video of videos" [video]="video" [user]="user" [currentSort]="sort"
diff --git a/client/src/app/videos/video-list/shared/abstract-video-list.scss b/client/src/app/videos/video-list/shared/abstract-video-list.scss
index 4b4409602..de174802b 100644
--- a/client/src/app/videos/video-list/shared/abstract-video-list.scss
+++ b/client/src/app/videos/video-list/shared/abstract-video-list.scss
@@ -17,20 +17,6 @@
17 } 17 }
18} 18}
19 19
20.videos-miniatures {
21 text-align: center;
22 padding-top: 0;
23
24 my-video-miniature {
25 text-align: left;
26 }
27
28 .no-video {
29 margin-top: 50px;
30 text-align: center;
31 }
32}
33
34pagination { 20pagination {
35 display: block; 21 display: block;
36 text-align: center; 22 text-align: center;
diff --git a/client/src/app/videos/video-list/shared/abstract-video-list.ts b/client/src/app/videos/video-list/shared/abstract-video-list.ts
index 87d5bc48a..262ea4e21 100644
--- a/client/src/app/videos/video-list/shared/abstract-video-list.ts
+++ b/client/src/app/videos/video-list/shared/abstract-video-list.ts
@@ -1,25 +1,19 @@
1import { OnDestroy, OnInit } from '@angular/core' 1import { OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { Subscription } from 'rxjs/Subscription'
4import { BehaviorSubject } from 'rxjs/BehaviorSubject'
5import { Observable } from 'rxjs/Observable'
6 3
7import { NotificationsService } from 'angular2-notifications' 4import { NotificationsService } from 'angular2-notifications'
5import { Observable } from 'rxjs/Observable'
6import { Subscription } from 'rxjs/Subscription'
8 7
9import { 8import { SortField, Video, VideoPagination } from '../../shared'
10 SortField,
11 Video,
12 VideoPagination
13} from '../../shared'
14 9
15export abstract class AbstractVideoList implements OnInit, OnDestroy { 10export abstract class AbstractVideoList implements OnInit, OnDestroy {
16 loading: BehaviorSubject<boolean> = new BehaviorSubject(false)
17 pagination: VideoPagination = { 11 pagination: VideoPagination = {
18 currentPage: 1, 12 currentPage: 1,
19 itemsPerPage: 25, 13 itemsPerPage: 25,
20 totalItems: null 14 totalItems: null
21 } 15 }
22 sort: SortField 16 sort: SortField = '-createdAt'
23 videos: Video[] = [] 17 videos: Video[] = []
24 18
25 protected notificationsService: NotificationsService 19 protected notificationsService: NotificationsService
@@ -28,6 +22,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
28 22
29 protected subActivatedRoute: Subscription 23 protected subActivatedRoute: Subscription
30 24
25 abstract titlePage: string
31 abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}> 26 abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}>
32 27
33 ngOnInit () { 28 ngOnInit () {
@@ -44,7 +39,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
44 } 39 }
45 40
46 getVideos () { 41 getVideos () {
47 this.loading.next(true)
48 this.videos = [] 42 this.videos = []
49 43
50 const observable = this.getVideosObservable() 44 const observable = this.getVideosObservable()
@@ -53,17 +47,11 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
53 ({ videos, totalVideos }) => { 47 ({ videos, totalVideos }) => {
54 this.videos = videos 48 this.videos = videos
55 this.pagination.totalItems = totalVideos 49 this.pagination.totalItems = totalVideos
56
57 this.loading.next(false)
58 }, 50 },
59 error => this.notificationsService.error('Error', error.text) 51 error => this.notificationsService.error('Error', error.text)
60 ) 52 )
61 } 53 }
62 54
63 isThereNoVideo () {
64 return !this.loading.getValue() && this.videos.length === 0
65 }
66
67 onPageChanged (event: { page: number }) { 55 onPageChanged (event: { page: number }) {
68 // Be sure the current page is set 56 // Be sure the current page is set
69 this.pagination.currentPage = event.page 57 this.pagination.currentPage = event.page
@@ -71,12 +59,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
71 this.navigateToNewParams() 59 this.navigateToNewParams()
72 } 60 }
73 61
74 onSort (sort: SortField) {
75 this.sort = sort
76
77 this.navigateToNewParams()
78 }
79
80 protected buildRouteParams () { 62 protected buildRouteParams () {
81 // There is always a sort and a current page 63 // There is always a sort and a current page
82 const params = { 64 const params = {
diff --git a/client/src/app/videos/video-list/shared/index.ts b/client/src/app/videos/video-list/shared/index.ts
index d8f73bcda..170ca4832 100644
--- a/client/src/app/videos/video-list/shared/index.ts
+++ b/client/src/app/videos/video-list/shared/index.ts
@@ -1,3 +1,2 @@
1export * from './abstract-video-list' 1export * from './abstract-video-list'
2export * from './video-miniature.component' 2export * from './video-miniature.component'
3export * from './video-sort.component'
diff --git a/client/src/app/videos/video-list/shared/video-miniature.component.html b/client/src/app/videos/video-list/shared/video-miniature.component.html
index 6bbd29666..aea85b6c6 100644
--- a/client/src/app/videos/video-list/shared/video-miniature.component.html
+++ b/client/src/app/videos/video-list/shared/video-miniature.component.html
@@ -6,8 +6,7 @@
6 <img [attr.src]="video.thumbnailUrl" alt="video thumbnail" [ngClass]="{ 'blur-filter': isVideoNSFWForThisUser() }" /> 6 <img [attr.src]="video.thumbnailUrl" alt="video thumbnail" [ngClass]="{ 'blur-filter': isVideoNSFWForThisUser() }" />
7 7
8 <div class="video-miniature-thumbnail-overlay"> 8 <div class="video-miniature-thumbnail-overlay">
9 <span class="video-miniature-thumbnail-overlay-views">{{ video.views }} views</span> 9 {{ video.durationLabel }}
10 <span class="video-miniature-thumbnail-overlay-duration">{{ video.durationLabel }}</span>
11 </div> 10 </div>
12 </a> 11 </a>
13 12
@@ -21,13 +20,7 @@
21 </a> 20 </a>
22 </span> 21 </span>
23 22
24 <div class="video-miniature-tags"> 23 <span class="video-miniature-created-at-views">{{ video.createdAt | fromNow }} - {{ video.views | numberFormatter }} views</span>
25 <span *ngFor="let tag of video.tags" class="video-miniature-tag"> 24 <span class="video-miniature-account">{{ video.by }}</span>
26 <a [routerLink]="['/videos/list', { field: 'tags', search: tag, sort: currentSort }]" class="label label-primary">{{ tag }}</a>
27 </span>
28 </div>
29
30 <a [routerLink]="['/videos/list', { field: 'account', search: video.account, sort: currentSort }]" class="video-miniature-account">{{ video.by }}</a>
31 <span class="video-miniature-created-at">{{ video.createdAt | date:'short' }}</span>
32 </div> 25 </div>
33</div> 26</div>
diff --git a/client/src/app/videos/video-list/shared/video-miniature.component.scss b/client/src/app/videos/video-list/shared/video-miniature.component.scss
index 507ace098..ed15864d9 100644
--- a/client/src/app/videos/video-list/shared/video-miniature.component.scss
+++ b/client/src/app/videos/video-list/shared/video-miniature.component.scss
@@ -1,14 +1,14 @@
1.video-miniature { 1.video-miniature {
2 margin: 15px 10px;
3 display: inline-block; 2 display: inline-block;
4 position: relative; 3 padding-right: 15px;
5 height: 190px; 4 margin-bottom: 30px;
5 height: 175px;
6 vertical-align: top; 6 vertical-align: top;
7 7
8 .video-miniature-thumbnail { 8 .video-miniature-thumbnail {
9 display: inline-block; 9 display: inline-block;
10 position: relative; 10 position: relative;
11 border-radius: 3px; 11 border-radius: 4px;
12 overflow: hidden; 12 overflow: hidden;
13 13
14 &:hover { 14 &:hover {
@@ -22,38 +22,33 @@
22 22
23 .video-miniature-thumbnail-overlay { 23 .video-miniature-thumbnail-overlay {
24 position: absolute; 24 position: absolute;
25 right: 0px; 25 right: 5px;
26 bottom: 0px; 26 bottom: 5px;
27 display: inline-block; 27 display: inline-block;
28 background-color: rgba(0, 0, 0, 0.7); 28 background-color: rgba(0, 0, 0, 0.7);
29 color: #fff; 29 color: #fff;
30 padding: 3px 5px; 30 font-size: 12px;
31 font-size: 11px; 31 font-weight: $font-bold;
32 font-weight: bold; 32 border-radius: 3px;
33 width: 100%; 33 padding: 0 5px;
34
35 .video-miniature-thumbnail-overlay-views {
36
37 }
38
39 .video-miniature-thumbnail-overlay-duration {
40 float: right;
41 }
42 } 34 }
43 } 35 }
44 36
45 .video-miniature-information { 37 .video-miniature-information {
46 width: 200px; 38 width: 200px;
39 margin-top: 2px;
40 line-height: normal;
47 41
48 .video-miniature-name { 42 .video-miniature-name {
49 height: 23px;
50 display: block; 43 display: block;
51 overflow: hidden; 44 overflow: hidden;
52 text-overflow: ellipsis; 45 text-overflow: ellipsis;
53 white-space: nowrap; 46 white-space: nowrap;
54 font-weight: bold; 47 font-weight: bold;
55 transition: color 0.2s; 48 transition: color 0.2s;
56 font-size: 15px; 49 font-size: 16px;
50 font-weight: $font-semibold;
51 color: #000;
57 52
58 &:hover { 53 &:hover {
59 text-decoration: none; 54 text-decoration: none;
@@ -63,39 +58,16 @@
63 filter: blur(3px); 58 filter: blur(3px);
64 padding-left: 4px; 59 padding-left: 4px;
65 } 60 }
66
67 .video-miniature-tags {
68 // Fix for chrome when tags are long
69 width: 201px;
70
71 .video-miniature-tag {
72 font-size: 13px;
73 cursor: pointer;
74 position: relative;
75 top: -2px;
76
77 .label {
78 transition: background-color 0.2s;
79 }
80 }
81 }
82 } 61 }
83 62
84 .video-miniature-account, .video-miniature-created-at { 63 .video-miniature-created-at-views {
85 display: block; 64 display: block;
86 margin-left: 1px; 65 font-size: 13px;
87 font-size: 11px;
88 color: $video-miniature-other-infos;
89 opacity: 0.9;
90 } 66 }
91 67
92 .video-miniature-account { 68 .video-miniature-account {
93 transition: color 0.2s; 69 font-size: 12px;
94 70 color: #585858;
95 &:hover {
96 color: #23527c;
97 text-decoration: none;
98 }
99 } 71 }
100 } 72 }
101} 73}
diff --git a/client/src/app/videos/video-list/shared/video-sort.component.html b/client/src/app/videos/video-list/shared/video-sort.component.html
deleted file mode 100644
index 3bece0b22..000000000
--- a/client/src/app/videos/video-list/shared/video-sort.component.html
+++ /dev/null
@@ -1,5 +0,0 @@
1<select class="form-control input-sm" [(ngModel)]="currentSort" (ngModelChange)="onSortChange()">
2 <option *ngFor="let choice of choiceKeys" [value]="choice">
3 {{ getStringChoice(choice) }}
4 </option>
5</select>
diff --git a/client/src/app/videos/video-list/shared/video-sort.component.ts b/client/src/app/videos/video-list/shared/video-sort.component.ts
deleted file mode 100644
index 8aa89d32b..000000000
--- a/client/src/app/videos/video-list/shared/video-sort.component.ts
+++ /dev/null
@@ -1,39 +0,0 @@
1import { Component, EventEmitter, Input, Output } from '@angular/core'
2
3import { SortField } from '../../shared'
4
5@Component({
6 selector: 'my-video-sort',
7 templateUrl: './video-sort.component.html'
8})
9
10export class VideoSortComponent {
11 @Output() sort = new EventEmitter<any>()
12
13 @Input() currentSort: SortField
14
15 sortChoices: { [ P in SortField ]: string } = {
16 'name': 'Name - Asc',
17 '-name': 'Name - Desc',
18 'duration': 'Duration - Asc',
19 '-duration': 'Duration - Desc',
20 'createdAt': 'Created Date - Asc',
21 '-createdAt': 'Created Date - Desc',
22 'views': 'Views - Asc',
23 '-views': 'Views - Desc',
24 'likes': 'Likes - Asc',
25 '-likes': 'Likes - Desc'
26 }
27
28 get choiceKeys () {
29 return Object.keys(this.sortChoices)
30 }
31
32 getStringChoice (choiceKey: SortField) {
33 return this.sortChoices[choiceKey]
34 }
35
36 onSortChange () {
37 this.sort.emit(this.currentSort)
38 }
39}
diff --git a/client/src/app/videos/video-list/video-list.component.ts b/client/src/app/videos/video-list/video-list.component.ts
deleted file mode 100644
index 784162679..000000000
--- a/client/src/app/videos/video-list/video-list.component.ts
+++ /dev/null
@@ -1,94 +0,0 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { Subscription } from 'rxjs/Subscription'
4
5import { NotificationsService } from 'angular2-notifications'
6
7import { VideoService } from '../shared'
8import { Search, SearchField, SearchService } from '../../shared'
9import { AbstractVideoList } from './shared'
10
11@Component({
12 selector: 'my-videos-list',
13 styleUrls: [ './shared/abstract-video-list.scss' ],
14 templateUrl: './shared/abstract-video-list.html'
15})
16export class VideoListComponent extends AbstractVideoList implements OnInit, OnDestroy {
17 private search: Search
18 private subSearch: Subscription
19
20 constructor (
21 protected router: Router,
22 protected route: ActivatedRoute,
23 protected notificationsService: NotificationsService,
24 private videoService: VideoService,
25 private searchService: SearchService
26 ) {
27 super()
28 }
29
30 ngOnInit () {
31 // Subscribe to route changes
32 this.subActivatedRoute = this.route.params.subscribe(routeParams => {
33 this.loadRouteParams(routeParams)
34
35 // Update the search service component
36 this.searchService.updateSearch.next(this.search)
37 this.getVideos()
38 })
39
40 // Subscribe to search changes
41 this.subSearch = this.searchService.searchUpdated.subscribe(search => {
42 this.search = search
43 // Reset pagination
44 this.pagination.currentPage = 1
45
46 this.navigateToNewParams()
47 })
48 }
49
50 ngOnDestroy () {
51 super.ngOnDestroy()
52
53 this.subSearch.unsubscribe()
54 }
55
56 getVideosObservable () {
57 let observable = null
58 if (this.search.value) {
59 observable = this.videoService.searchVideos(this.search, this.pagination, this.sort)
60 } else {
61 observable = this.videoService.getVideos(this.pagination, this.sort)
62 }
63
64 return observable
65 }
66
67 protected buildRouteParams () {
68 const params = super.buildRouteParams()
69
70 // Maybe there is a search
71 if (this.search.value) {
72 params['field'] = this.search.field
73 params['search'] = this.search.value
74 }
75
76 return params
77 }
78
79 protected loadRouteParams (routeParams: { [ key: string ]: any }) {
80 super.loadRouteParams(routeParams)
81
82 if (routeParams['search'] !== undefined) {
83 this.search = {
84 value: routeParams['search'],
85 field: routeParams['field'] as SearchField
86 }
87 } else {
88 this.search = {
89 value: '',
90 field: 'name'
91 }
92 }
93 }
94}
diff --git a/client/src/app/videos/video-list/video-recently-added.component.ts b/client/src/app/videos/video-list/video-recently-added.component.ts
new file mode 100644
index 000000000..dbba264df
--- /dev/null
+++ b/client/src/app/videos/video-list/video-recently-added.component.ts
@@ -0,0 +1,33 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications'
4import { VideoService } from '../shared'
5import { AbstractVideoList } from './shared'
6
7@Component({
8 selector: 'my-videos-recently-added',
9 styleUrls: [ './shared/abstract-video-list.scss' ],
10 templateUrl: './shared/abstract-video-list.html'
11})
12export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy {
13 titlePage = 'Recently added'
14
15 constructor (protected router: Router,
16 protected route: ActivatedRoute,
17 protected notificationsService: NotificationsService,
18 private videoService: VideoService) {
19 super()
20 }
21
22 ngOnInit () {
23 super.ngOnInit()
24 }
25
26 ngOnDestroy () {
27 super.ngOnDestroy()
28 }
29
30 getVideosObservable () {
31 return this.videoService.getVideos(this.pagination, this.sort)
32 }
33}
diff --git a/client/src/app/videos/video-list/video-trending.component.ts b/client/src/app/videos/video-list/video-trending.component.ts
new file mode 100644
index 000000000..b97966c12
--- /dev/null
+++ b/client/src/app/videos/video-list/video-trending.component.ts
@@ -0,0 +1,33 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications'
4import { VideoService } from '../shared'
5import { AbstractVideoList } from './shared'
6
7@Component({
8 selector: 'my-videos-trending',
9 styleUrls: [ './shared/abstract-video-list.scss' ],
10 templateUrl: './shared/abstract-video-list.html'
11})
12export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy {
13 titlePage = 'Trending'
14
15 constructor (protected router: Router,
16 protected route: ActivatedRoute,
17 protected notificationsService: NotificationsService,
18 private videoService: VideoService) {
19 super()
20 }
21
22 ngOnInit () {
23 super.ngOnInit()
24 }
25
26 ngOnDestroy () {
27 super.ngOnDestroy()
28 }
29
30 getVideosObservable () {
31 return this.videoService.getVideos(this.pagination, this.sort)
32 }
33}