diff options
author | Chocobozzz <me@florianbigard.com> | 2018-02-13 14:11:05 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-02-13 14:20:46 +0100 |
commit | 0cd4344f3cf529b15308fcf3eb7d7eb07726df56 (patch) | |
tree | 276f6e8cfe72d583114d82fd5db981550a395488 /client/src/app/account | |
parent | 29c6b829446a6fb29dffc6b7b638079ce60f3771 (diff) | |
download | PeerTube-0cd4344f3cf529b15308fcf3eb7d7eb07726df56.tar.gz PeerTube-0cd4344f3cf529b15308fcf3eb7d7eb07726df56.tar.zst PeerTube-0cd4344f3cf529b15308fcf3eb7d7eb07726df56.zip |
Rewrite infinite scroll
Diffstat (limited to 'client/src/app/account')
3 files changed, 56 insertions, 42 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 index 0755158b9..3d8c656ee 100644 --- a/client/src/app/account/account-videos/account-videos.component.html +++ b/client/src/app/account/account-videos/account-videos.component.html | |||
@@ -1,44 +1,44 @@ | |||
1 | <div *ngIf="pagination.totalItems === 0">No results.</div> | 1 | <div *ngIf="pagination.totalItems === 0">No results.</div> |
2 | 2 | ||
3 | <div | 3 | <div |
4 | class="videos" | 4 | myInfiniteScroller |
5 | infiniteScroll | 5 | [pageHeight]="pageHeight" |
6 | [infiniteScrollDistance]="0.5" | 6 | (nearOfTop)="onNearOfTop()" (nearOfBottom)="onNearOfBottom()" (pageChanged)="onPageChanged($event)" |
7 | [infiniteScrollUpDistance]="1.5" | 7 | class="videos" #videoElement |
8 | (scrolled)="onNearOfBottom()" | ||
9 | (scrolledUp)="onNearOfTop()" | ||
10 | > | 8 | > |
11 | <div class="video" *ngFor="let video of videos; let i = index"> | 9 | <div *ngFor="let videos of videoPages; let i = index" class="videos-page"> |
12 | <div class="checkbox-container"> | 10 | <div class="video" *ngFor="let video of videos; let j = index"> |
13 | <input [id]="'video-check-' + i" type="checkbox" [(ngModel)]="checkedVideos[video.id]" /> | 11 | <div class="checkbox-container"> |
14 | <label [for]="'video-check-' + i"></label> | 12 | <input [id]="'video-check-' + video.id" type="checkbox" [(ngModel)]="checkedVideos[video.id]" /> |
15 | </div> | 13 | <label [for]="'video-check-' + video.id"></label> |
14 | </div> | ||
16 | 15 | ||
17 | <my-video-thumbnail [video]="video"></my-video-thumbnail> | 16 | <my-video-thumbnail [video]="video"></my-video-thumbnail> |
18 | 17 | ||
19 | <div class="video-info"> | 18 | <div class="video-info"> |
20 | <a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a> | 19 | <a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a> |
21 | <span class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> | 20 | <span class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> |
22 | </div> | 21 | </div> |
23 | 22 | ||
24 | <!-- Display only once --> | 23 | <!-- Display only once --> |
25 | <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0"> | 24 | <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0 && j === 0"> |
26 | <div class="action-selection-mode-child"> | 25 | <div class="action-selection-mode-child"> |
27 | <span class="action-button action-button-cancel-selection" (click)="abortSelectionMode()"> | 26 | <span class="action-button action-button-cancel-selection" (click)="abortSelectionMode()"> |
28 | Cancel | 27 | Cancel |
29 | </span> | 28 | </span> |
30 | 29 | ||
31 | <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()"> | 30 | <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()"> |
32 | <span class="icon icon-delete-white"></span> | 31 | <span class="icon icon-delete-white"></span> |
33 | Delete | 32 | Delete |
34 | </span> | 33 | </span> |
34 | </div> | ||
35 | </div> | 35 | </div> |
36 | </div> | ||
37 | 36 | ||
38 | <div class="video-buttons" *ngIf="isInSelectionMode() === false"> | 37 | <div class="video-buttons" *ngIf="isInSelectionMode() === false"> |
39 | <my-delete-button (click)="deleteVideo(video)"></my-delete-button> | 38 | <my-delete-button (click)="deleteVideo(video)"></my-delete-button> |
40 | 39 | ||
41 | <my-edit-button [routerLink]="[ '/videos', 'edit', video.uuid ]"></my-edit-button> | 40 | <my-edit-button [routerLink]="[ '/videos', 'edit', video.uuid ]"></my-edit-button> |
41 | </div> | ||
42 | </div> | 42 | </div> |
43 | </div> | 43 | </div> |
44 | </div> | 44 | </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 index 707bd66ad..449cc6af4 100644 --- a/client/src/app/account/account-videos/account-videos.component.scss +++ b/client/src/app/account/account-videos/account-videos.component.scss | |||
@@ -45,16 +45,13 @@ | |||
45 | display: flex; | 45 | display: flex; |
46 | min-height: 130px; | 46 | min-height: 130px; |
47 | padding-bottom: 20px; | 47 | padding-bottom: 20px; |
48 | margin-bottom: 20px; | ||
49 | border-bottom: 1px solid #C6C6C6; | ||
48 | 50 | ||
49 | &:first-child { | 51 | &:first-child { |
50 | margin-top: 47px; | 52 | margin-top: 47px; |
51 | } | 53 | } |
52 | 54 | ||
53 | &:not(:last-child) { | ||
54 | margin-bottom: 20px; | ||
55 | border-bottom: 1px solid #C6C6C6; | ||
56 | } | ||
57 | |||
58 | .checkbox-container { | 55 | .checkbox-container { |
59 | display: flex; | 56 | display: flex; |
60 | align-items: center; | 57 | align-items: center; |
diff --git a/client/src/app/account/account-videos/account-videos.component.ts b/client/src/app/account/account-videos/account-videos.component.ts index bce135557..e9d044dbf 100644 --- a/client/src/app/account/account-videos/account-videos.component.ts +++ b/client/src/app/account/account-videos/account-videos.component.ts | |||
@@ -1,5 +1,7 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { ActivatedRoute, Router } from '@angular/router' | 2 | import { ActivatedRoute, Router } from '@angular/router' |
3 | import { immutableAssign } from '@app/shared/misc/utils' | ||
4 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | ||
3 | import { NotificationsService } from 'angular2-notifications' | 5 | import { NotificationsService } from 'angular2-notifications' |
4 | import 'rxjs/add/observable/from' | 6 | import 'rxjs/add/observable/from' |
5 | import 'rxjs/add/operator/concatAll' | 7 | import 'rxjs/add/operator/concatAll' |
@@ -19,7 +21,9 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit | |||
19 | titlePage = 'My videos' | 21 | titlePage = 'My videos' |
20 | currentRoute = '/account/videos' | 22 | currentRoute = '/account/videos' |
21 | checkedVideos: { [ id: number ]: boolean } = {} | 23 | checkedVideos: { [ id: number ]: boolean } = {} |
22 | pagination = { | 24 | videoHeight = 155 |
25 | videoWidth = -1 | ||
26 | pagination: ComponentPagination = { | ||
23 | currentPage: 1, | 27 | currentPage: 1, |
24 | itemsPerPage: 10, | 28 | itemsPerPage: 10, |
25 | totalItems: null | 29 | totalItems: null |
@@ -46,8 +50,10 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit | |||
46 | return Object.keys(this.checkedVideos).some(k => this.checkedVideos[k] === true) | 50 | return Object.keys(this.checkedVideos).some(k => this.checkedVideos[k] === true) |
47 | } | 51 | } |
48 | 52 | ||
49 | getVideosObservable () { | 53 | getVideosObservable (page: number) { |
50 | return this.videoService.getMyVideos(this.pagination, this.sort) | 54 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) |
55 | |||
56 | return this.videoService.getMyVideos(newPagination, this.sort) | ||
51 | } | 57 | } |
52 | 58 | ||
53 | deleteSelectedVideos () { | 59 | deleteSelectedVideos () { |
@@ -71,9 +77,12 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit | |||
71 | Observable.from(observables) | 77 | Observable.from(observables) |
72 | .concatAll() | 78 | .concatAll() |
73 | .subscribe( | 79 | .subscribe( |
74 | res => this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`), | 80 | res => { |
81 | this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`) | ||
82 | this.buildVideoPages() | ||
83 | }, | ||
75 | 84 | ||
76 | err => this.notificationsService.error('Error', err.message) | 85 | err => this.notificationsService.error('Error', err.message) |
77 | ) | 86 | ) |
78 | } | 87 | } |
79 | ) | 88 | ) |
@@ -89,6 +98,7 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit | |||
89 | status => { | 98 | status => { |
90 | this.notificationsService.success('Success', `Video ${video.name} deleted.`) | 99 | this.notificationsService.success('Success', `Video ${video.name} deleted.`) |
91 | this.spliceVideosById(video.id) | 100 | this.spliceVideosById(video.id) |
101 | this.buildVideoPages() | ||
92 | }, | 102 | }, |
93 | 103 | ||
94 | error => this.notificationsService.error('Error', error.message) | 104 | error => this.notificationsService.error('Error', error.message) |
@@ -98,7 +108,14 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit | |||
98 | } | 108 | } |
99 | 109 | ||
100 | private spliceVideosById (id: number) { | 110 | private spliceVideosById (id: number) { |
101 | const index = this.videos.findIndex(v => v.id === id) | 111 | for (const key of Object.keys(this.loadedPages)) { |
102 | this.videos.splice(index, 1) | 112 | const videos = this.loadedPages[key] |
113 | const index = videos.findIndex(v => v.id === id) | ||
114 | |||
115 | if (index !== -1) { | ||
116 | videos.splice(index, 1) | ||
117 | return | ||
118 | } | ||
119 | } | ||
103 | } | 120 | } |
104 | } | 121 | } |