aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/videos/video-list
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2016-06-03 22:08:03 +0200
committerChocobozzz <florian.bigard@gmail.com>2016-06-03 22:08:03 +0200
commit4a6995be18b15de1834a39c8921a0e4109671bb6 (patch)
treeb659661cea33687fcc6bd8fc2251cb7a15ab9f9d /client/src/app/videos/video-list
parent468892541175f9662f8b1b977e819dc1a496f282 (diff)
downloadPeerTube-4a6995be18b15de1834a39c8921a0e4109671bb6.tar.gz
PeerTube-4a6995be18b15de1834a39c8921a0e4109671bb6.tar.zst
PeerTube-4a6995be18b15de1834a39c8921a0e4109671bb6.zip
First draft to use webpack instead of systemjs
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/video-list.component.html18
-rw-r--r--client/src/app/videos/video-list/video-list.component.scss37
-rw-r--r--client/src/app/videos/video-list/video-list.component.ts105
-rw-r--r--client/src/app/videos/video-list/video-miniature.component.html22
-rw-r--r--client/src/app/videos/video-list/video-miniature.component.scss55
-rw-r--r--client/src/app/videos/video-list/video-miniature.component.ts46
-rw-r--r--client/src/app/videos/video-list/video-sort.component.html5
-rw-r--r--client/src/app/videos/video-list/video-sort.component.ts35
9 files changed, 326 insertions, 0 deletions
diff --git a/client/src/app/videos/video-list/index.ts b/client/src/app/videos/video-list/index.ts
new file mode 100644
index 000000000..1f6d6a4e7
--- /dev/null
+++ b/client/src/app/videos/video-list/index.ts
@@ -0,0 +1,3 @@
1export * from './video-list.component';
2export * from './video-miniature.component';
3export * from './video-sort.component';
diff --git a/client/src/app/videos/video-list/video-list.component.html b/client/src/app/videos/video-list/video-list.component.html
new file mode 100644
index 000000000..80b1e7b1b
--- /dev/null
+++ b/client/src/app/videos/video-list/video-list.component.html
@@ -0,0 +1,18 @@
1<div class="row videos-info">
2 <div class="col-md-9 videos-total-results"> {{ pagination.total }} videos</div>
3 <my-video-sort class="col-md-3" [currentSort]="sort" (sort)="onSort($event)"></my-video-sort>
4</div>
5
6<div class="videos-miniatures">
7 <my-loader [loading]="loading"></my-loader>
8
9 <div class="col-md-12 no-video" *ngIf="noVideo()">There is no video.</div>
10
11 <my-video-miniature *ngFor="let video of videos" [video]="video" [user]="user" (removed)="onRemoved(video)">
12 </my-video-miniature>
13</div>
14
15<pagination
16 [totalItems]="pagination.total" [itemsPerPage]="pagination.itemsPerPage" [(ngModel)]="pagination.currentPage"
17 (ngModelChange)="getVideos()"
18></pagination>
diff --git a/client/src/app/videos/video-list/video-list.component.scss b/client/src/app/videos/video-list/video-list.component.scss
new file mode 100644
index 000000000..9441d80c3
--- /dev/null
+++ b/client/src/app/videos/video-list/video-list.component.scss
@@ -0,0 +1,37 @@
1.videos-info {
2
3 padding-bottom: 20px;
4 margin-bottom: 20px;
5 border-bottom: 1px solid #f1f1f1;
6 height: 40px;
7 line-height: 40px;
8 width: 765px;
9 margin-left: 15px;
10
11 my-video-sort {
12 padding-right: 0;
13 }
14
15 .videos-total-results {
16 font-size: 13px;
17 padding-left: 0;
18 }
19}
20
21.videos-miniatures {
22 min-height: 600px;
23
24 my-videos-miniature {
25 display: inline-block;
26 }
27
28 .no-video {
29 margin-top: 50px;
30 text-align: center;
31 }
32}
33
34pagination {
35 display: block;
36 text-align: center;
37}
diff --git a/client/src/app/videos/video-list/video-list.component.ts b/client/src/app/videos/video-list/video-list.component.ts
new file mode 100644
index 000000000..b1ce55845
--- /dev/null
+++ b/client/src/app/videos/video-list/video-list.component.ts
@@ -0,0 +1,105 @@
1import { Component, OnInit } from '@angular/core';
2import { Router, ROUTER_DIRECTIVES, RouteParams } from '@angular/router-deprecated';
3
4import { PAGINATION_DIRECTIVES } from 'ng2-bootstrap/components/pagination';
5
6import {
7 LoaderComponent,
8 Pagination,
9 SortField,
10 Video,
11 VideoService
12} from '../shared';
13import { AuthService, Search, SearchField, User } from '../../shared';
14import { VideoMiniatureComponent } from './video-miniature.component';
15import { VideoSortComponent } from './video-sort.component';
16
17@Component({
18 selector: 'my-videos-list',
19 styles: [ require('./video-list.component.scss') ],
20 template: require('./video-list.component.html'),
21 directives: [ LoaderComponent, PAGINATION_DIRECTIVES, ROUTER_DIRECTIVES, VideoMiniatureComponent, VideoSortComponent ]
22})
23
24export class VideoListComponent implements OnInit {
25 loading = false;
26 pagination: Pagination = {
27 currentPage: 1,
28 itemsPerPage: 9,
29 total: 0
30 };
31 sort: SortField;
32 user: User = null;
33 videos: Video[] = [];
34
35 private search: Search;
36
37 constructor(
38 private authService: AuthService,
39 private router: Router,
40 private routeParams: RouteParams,
41 private videoService: VideoService
42 ) {
43 this.search = {
44 value: this.routeParams.get('search'),
45 field: <SearchField>this.routeParams.get('field')
46 };
47
48 this.sort = <SortField>this.routeParams.get('sort') || '-createdDate';
49 }
50
51 ngOnInit() {
52 if (this.authService.isLoggedIn()) {
53 this.user = User.load();
54 }
55
56 this.getVideos();
57 }
58
59 getVideos() {
60 this.loading = true;
61 this.videos = [];
62
63 let observable = null;
64
65 if (this.search.value !== null) {
66 observable = this.videoService.searchVideos(this.search, this.pagination, this.sort);
67 } else {
68 observable = this.videoService.getVideos(this.pagination, this.sort);
69 }
70
71 observable.subscribe(
72 ({ videos, totalVideos }) => {
73 this.videos = videos;
74 this.pagination.total = totalVideos;
75
76 this.loading = false;
77 },
78 error => alert(error)
79 );
80 }
81
82 noVideo() {
83 return !this.loading && this.videos.length === 0;
84 }
85
86 onRemoved(video: Video) {
87 this.videos.splice(this.videos.indexOf(video), 1);
88 }
89
90 onSort(sort: SortField) {
91 this.sort = sort;
92
93 const params: any = {
94 sort: this.sort
95 };
96
97 if (this.search.value) {
98 params.field = this.search.field;
99 params.search = this.search.value;
100 }
101
102 this.router.navigate(['VideosList', params]);
103 this.getVideos();
104 }
105}
diff --git a/client/src/app/videos/video-list/video-miniature.component.html b/client/src/app/videos/video-list/video-miniature.component.html
new file mode 100644
index 000000000..244254b5a
--- /dev/null
+++ b/client/src/app/videos/video-list/video-miniature.component.html
@@ -0,0 +1,22 @@
1<div class="video-miniature col-md-4" (mouseenter)="onHover()" (mouseleave)="onBlur()">
2 <a
3 [routerLink]="['VideosWatch', { id: video.id }]" [attr.title]="video.description"
4 class="video-miniature-thumbnail"
5 >
6 <img [attr.src]="video.thumbnailPath" alt="video thumbnail" />
7 <span class="video-miniature-duration">{{ video.duration }}</span>
8 </a>
9 <span
10 *ngIf="displayRemoveIcon()" (click)="removeVideo(video.id)"
11 class="video-miniature-remove glyphicon glyphicon-remove"
12 ></span>
13
14 <div class="video-miniature-informations">
15 <a [routerLink]="['VideosWatch', { id: video.id }]" class="video-miniature-name">
16 <span>{{ video.name }}</span>
17 </a>
18
19 <span class="video-miniature-author">by {{ video.by }}</span>
20 <span class="video-miniature-created-date">on {{ video.createdDate | date:'short' }}</span>
21 </div>
22</div>
diff --git a/client/src/app/videos/video-list/video-miniature.component.scss b/client/src/app/videos/video-list/video-miniature.component.scss
new file mode 100644
index 000000000..4488abe22
--- /dev/null
+++ b/client/src/app/videos/video-list/video-miniature.component.scss
@@ -0,0 +1,55 @@
1.video-miniature {
2 height: 200px;
3 display: inline-block;
4 position: relative;
5
6 .video-miniature-thumbnail {
7 display: block;
8 position: relative;
9
10 .video-miniature-duration {
11 position: absolute;
12 right: 60px;
13 bottom: 2px;
14 display: inline-block;
15 background-color: rgba(0, 0, 0, 0.8);
16 color: rgba(255, 255, 255, 0.8);
17 padding: 2px;
18 font-size: 11px;
19 }
20 }
21
22 .video-miniature-remove {
23 display: inline-block;
24 position: absolute;
25 left: 16px;
26 background-color: rgba(0, 0, 0, 0.8);
27 color: rgba(255, 255, 255, 0.8);
28 padding: 2px;
29 cursor: pointer;
30
31 &:hover {
32 color: rgba(255, 255, 255, 0.9);
33 }
34 }
35
36 .video-miniature-informations {
37 margin-left: 3px;
38
39 .video-miniature-name {
40 display: block;
41 font-weight: bold;
42
43 &:hover {
44 text-decoration: none;
45 }
46 }
47
48 .video-miniature-author, .video-miniature-created-date {
49 display: block;
50 margin-left: 1px;
51 font-size: 11px;
52 color: rgba(0, 0, 0, 0.5);
53 }
54 }
55}
diff --git a/client/src/app/videos/video-list/video-miniature.component.ts b/client/src/app/videos/video-list/video-miniature.component.ts
new file mode 100644
index 000000000..639339b44
--- /dev/null
+++ b/client/src/app/videos/video-list/video-miniature.component.ts
@@ -0,0 +1,46 @@
1import { DatePipe } from '@angular/common';
2import { Component, Input, Output, EventEmitter } from '@angular/core';
3import { ROUTER_DIRECTIVES } from '@angular/router-deprecated';
4
5import { Video, VideoService } from '../shared';
6import { User } from '../../shared';
7
8@Component({
9 selector: 'my-video-miniature',
10 styles: [ require('./video-miniature.component.scss') ],
11 template: require('./video-miniature.component.html'),
12 directives: [ ROUTER_DIRECTIVES ],
13 pipes: [ DatePipe ]
14})
15
16export class VideoMiniatureComponent {
17 @Output() removed = new EventEmitter<any>();
18
19 @Input() user: User;
20 @Input() video: Video;
21
22 hovering = false;
23
24 constructor(private videoService: VideoService) {}
25
26 displayRemoveIcon() {
27 return this.hovering && this.video.isRemovableBy(this.user);
28 }
29
30 onBlur() {
31 this.hovering = false;
32 }
33
34 onHover() {
35 this.hovering = true;
36 }
37
38 removeVideo(id: string) {
39 if (confirm('Do you really want to remove this video?')) {
40 this.videoService.removeVideo(id).subscribe(
41 status => this.removed.emit(true),
42 error => alert(error)
43 );
44 }
45 }
46}
diff --git a/client/src/app/videos/video-list/video-sort.component.html b/client/src/app/videos/video-list/video-sort.component.html
new file mode 100644
index 000000000..3bece0b22
--- /dev/null
+++ b/client/src/app/videos/video-list/video-sort.component.html
@@ -0,0 +1,5 @@
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/video-sort.component.ts b/client/src/app/videos/video-list/video-sort.component.ts
new file mode 100644
index 000000000..0d76b54b7
--- /dev/null
+++ b/client/src/app/videos/video-list/video-sort.component.ts
@@ -0,0 +1,35 @@
1import { Component, EventEmitter, Input, Output } from '@angular/core';
2
3import { SortField } from '../shared';
4
5@Component({
6 selector: 'my-video-sort',
7 template: require('./video-sort.component.html')
8})
9
10export class VideoSortComponent {
11 @Output() sort = new EventEmitter<any>();
12
13 @Input() currentSort: SortField;
14
15 sortChoices = {
16 'name': 'Name - Asc',
17 '-name': 'Name - Desc',
18 'duration': 'Duration - Asc',
19 '-duration': 'Duration - Desc',
20 'createdDate': 'Created Date - Asc',
21 '-createdDate': 'Created Date - Desc'
22 };
23
24 get choiceKeys() {
25 return Object.keys(this.sortChoices);
26 }
27
28 getStringChoice(choiceKey: SortField) {
29 return this.sortChoices[choiceKey];
30 }
31
32 onSortChange() {
33 this.sort.emit(this.currentSort);
34 }
35}