aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/account/account-videos
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-12-11 11:06:32 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-12-11 11:06:32 +0100
commitfada8d75550dc7365f7e18ee1569b9406251d660 (patch)
treedb9dc01c18693824f83fce5020f4c1f3ae7c0865 /client/src/app/account/account-videos
parent492fd28167f770d79a430fc57451b5a9e075d8e7 (diff)
parentc2830fa8f84f61462098bf36add824f89436dfa9 (diff)
downloadPeerTube-fada8d75550dc7365f7e18ee1569b9406251d660.tar.gz
PeerTube-fada8d75550dc7365f7e18ee1569b9406251d660.tar.zst
PeerTube-fada8d75550dc7365f7e18ee1569b9406251d660.zip
Merge branch 'feature/design' into develop
Diffstat (limited to 'client/src/app/account/account-videos')
-rw-r--r--client/src/app/account/account-videos/account-videos.component.html39
-rw-r--r--client/src/app/account/account-videos/account-videos.component.scss96
-rw-r--r--client/src/app/account/account-videos/account-videos.component.ts97
3 files changed, 232 insertions, 0 deletions
diff --git a/client/src/app/account/account-videos/account-videos.component.html b/client/src/app/account/account-videos/account-videos.component.html
new file mode 100644
index 000000000..f69c0487d
--- /dev/null
+++ b/client/src/app/account/account-videos/account-videos.component.html
@@ -0,0 +1,39 @@
1<div
2 class="videos"
3 infiniteScroll
4 [infiniteScrollDistance]="0.5"
5 [infiniteScrollUpDistance]="1.5"
6 (scrolled)="onNearOfBottom()"
7 (scrolledUp)="onNearOfTop()"
8>
9 <div class="video" *ngFor="let video of videos; let i = index">
10 <input type="checkbox" [(ngModel)]="checkedVideos[video.id]" />
11
12 <my-video-thumbnail [video]="video"></my-video-thumbnail>
13
14 <div class="video-info">
15 <div class="video-info-name">{{ video.name }}</div>
16 <span class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
17 </div>
18
19 <!-- Display only once -->
20 <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
21 <div class="action-selection-mode-child">
22 <span class="action-button action-button-cancel-selection" (click)="abortSelectionMode()">
23 Cancel
24 </span>
25
26 <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()">
27 <span class="icon icon-delete-white"></span>
28 Delete
29 </span>
30 </div>
31 </div>
32
33 <div class="video-buttons" *ngIf="isInSelectionMode() === false">
34 <my-delete-button (click)="deleteVideo(video)"></my-delete-button>
35
36 <my-edit-button [routerLink]="[ '/videos', 'edit', video.uuid ]"></my-edit-button>
37 </div>
38 </div>
39</div>
diff --git a/client/src/app/account/account-videos/account-videos.component.scss b/client/src/app/account/account-videos/account-videos.component.scss
new file mode 100644
index 000000000..5459014a6
--- /dev/null
+++ b/client/src/app/account/account-videos/account-videos.component.scss
@@ -0,0 +1,96 @@
1.action-selection-mode {
2 width: 174px;
3 display: flex;
4 justify-content: flex-end;
5
6 .action-selection-mode-child {
7 position: fixed;
8
9 .action-button {
10 display: inline-block;
11 }
12
13 .action-button-cancel-selection {
14 @include peertube-button;
15 @include grey-button;
16
17 margin-right: 10px;
18 }
19
20 .action-button-delete-selection {
21 @include peertube-button;
22 @include orange-button;
23 }
24
25 .icon.icon-delete-white {
26 @include icon(21px);
27
28 position: relative;
29 top: -2px;
30 background-image: url('../../../assets/images/global/delete-white.svg');
31 }
32 }
33}
34
35/deep/ .action-button {
36 &.action-button-delete {
37 margin-right: 10px;
38 }
39}
40
41.video {
42 display: flex;
43 height: 130px;
44 padding-bottom: 20px;
45
46 input[type=checkbox] {
47 margin-right: 20px;
48 outline: 0;
49 }
50
51 &:first-child {
52 margin-top: 47px;
53 }
54
55 &:not(:last-child) {
56 margin-bottom: 20px;
57 border-bottom: 1px solid #C6C6C6;
58 }
59
60 my-video-thumbnail {
61 margin-right: 10px;
62 }
63
64 .video-info {
65 flex-grow: 1;
66
67 .video-info-name {
68 font-size: 16px;
69 font-weight: $font-semibold;
70 }
71
72 .video-info-date-views {
73 font-size: 13px;
74 }
75 }
76}
77
78@media screen and (max-width: 800px) {
79 .video {
80 flex-direction: column;
81 height: auto;
82 text-align: center;
83
84 input[type=checkbox] {
85 display: none;
86 }
87
88 my-video-thumbnail {
89 margin-right: 0;
90 }
91
92 .video-buttons {
93 margin-top: 10px;
94 }
95 }
96}
diff --git a/client/src/app/account/account-videos/account-videos.component.ts b/client/src/app/account/account-videos/account-videos.component.ts
new file mode 100644
index 000000000..5f12cfce0
--- /dev/null
+++ b/client/src/app/account/account-videos/account-videos.component.ts
@@ -0,0 +1,97 @@
1import { Component, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications'
4import 'rxjs/add/observable/from'
5import 'rxjs/add/operator/concatAll'
6import { Observable } from 'rxjs/Observable'
7import { ConfirmService } from '../../core/confirm'
8import { AbstractVideoList } from '../../shared/video/abstract-video-list'
9import { Video } from '../../shared/video/video.model'
10import { VideoService } from '../../shared/video/video.service'
11
12@Component({
13 selector: 'my-account-videos',
14 templateUrl: './account-videos.component.html',
15 styleUrls: [ './account-videos.component.scss' ]
16})
17export class AccountVideosComponent extends AbstractVideoList implements OnInit {
18 titlePage = 'My videos'
19 currentRoute = '/account/videos'
20 checkedVideos: { [ id: number ]: boolean } = {}
21
22 constructor (protected router: Router,
23 protected route: ActivatedRoute,
24 protected notificationsService: NotificationsService,
25 protected confirmService: ConfirmService,
26 private videoService: VideoService) {
27 super()
28 }
29
30 ngOnInit () {
31 super.ngOnInit()
32 }
33
34 abortSelectionMode () {
35 this.checkedVideos = {}
36 }
37
38 isInSelectionMode () {
39 return Object.keys(this.checkedVideos).some(k => this.checkedVideos[k] === true)
40 }
41
42 getVideosObservable () {
43 return this.videoService.getMyVideos(this.pagination, this.sort)
44 }
45
46 deleteSelectedVideos () {
47 const toDeleteVideosIds = Object.keys(this.checkedVideos)
48 .filter(k => this.checkedVideos[k] === true)
49 .map(k => parseInt(k, 10))
50
51 this.confirmService.confirm(`Do you really want to delete ${toDeleteVideosIds.length} videos?`, 'Delete').subscribe(
52 res => {
53 if (res === false) return
54
55 const observables: Observable<any>[] = []
56 for (const videoId of toDeleteVideosIds) {
57 const o = this.videoService
58 .removeVideo(videoId)
59 .do(() => this.spliceVideosById(videoId))
60
61 observables.push(o)
62 }
63
64 Observable.from(observables)
65 .concatAll()
66 .subscribe(
67 res => this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`),
68
69 err => this.notificationsService.error('Error', err.text)
70 )
71 }
72 )
73 }
74
75 deleteVideo (video: Video) {
76 this.confirmService.confirm(`Do you really want to delete ${video.name}?`, 'Delete').subscribe(
77 res => {
78 if (res === false) return
79
80 this.videoService.removeVideo(video.id)
81 .subscribe(
82 status => {
83 this.notificationsService.success('Success', `Video ${video.name} deleted.`)
84 this.spliceVideosById(video.id)
85 },
86
87 error => this.notificationsService.error('Error', error.text)
88 )
89 }
90 )
91 }
92
93 private spliceVideosById (id: number) {
94 const index = this.videos.findIndex(v => v.id === id)
95 this.videos.splice(index, 1)
96 }
97}