aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/package.json1
-rw-r--r--client/src/app/app-routing.module.ts2
-rw-r--r--client/src/app/shared/misc/from-now.pipe.ts2
-rw-r--r--client/src/app/shared/search/search.component.ts33
-rw-r--r--client/src/app/shared/shared.module.ts7
-rw-r--r--client/src/app/videos/video-list/shared/abstract-video-list.html14
-rw-r--r--client/src/app/videos/video-list/shared/abstract-video-list.ts63
-rw-r--r--client/src/app/videos/video-list/video-recently-added.component.ts1
-rw-r--r--client/src/app/videos/video-list/video-trending.component.ts1
-rw-r--r--client/src/app/videos/videos.module.ts4
-rw-r--r--client/yarn.lock4
11 files changed, 73 insertions, 59 deletions
diff --git a/client/package.json b/client/package.json
index 310860fec..45f555f29 100644
--- a/client/package.json
+++ b/client/package.json
@@ -71,6 +71,7 @@
71 "ngc-webpack": "3.2.2", 71 "ngc-webpack": "3.2.2",
72 "ngx-bootstrap": "2.0.0-beta.9", 72 "ngx-bootstrap": "2.0.0-beta.9",
73 "ngx-chips": "1.5.3", 73 "ngx-chips": "1.5.3",
74 "ngx-infinite-scroll": "^0.7.0",
74 "ngx-pipes": "^2.0.5", 75 "ngx-pipes": "^2.0.5",
75 "node-sass": "^4.1.1", 76 "node-sass": "^4.1.1",
76 "normalize.css": "^7.0.0", 77 "normalize.css": "^7.0.0",
diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts
index 0f9484344..fe72c9181 100644
--- a/client/src/app/app-routing.module.ts
+++ b/client/src/app/app-routing.module.ts
@@ -6,7 +6,7 @@ import { PreloadSelectedModulesList } from './core'
6const routes: Routes = [ 6const routes: Routes = [
7 { 7 {
8 path: '', 8 path: '',
9 redirectTo: '/videos/list', 9 redirectTo: '/videos/trending',
10 pathMatch: 'full' 10 pathMatch: 'full'
11 }, 11 },
12 { 12 {
diff --git a/client/src/app/shared/misc/from-now.pipe.ts b/client/src/app/shared/misc/from-now.pipe.ts
index 25e5d6a85..80dab02ba 100644
--- a/client/src/app/shared/misc/from-now.pipe.ts
+++ b/client/src/app/shared/misc/from-now.pipe.ts
@@ -1,6 +1,6 @@
1import { Pipe, PipeTransform } from '@angular/core' 1import { Pipe, PipeTransform } from '@angular/core'
2 2
3// Thanks: https://github.com/danrevah/ngx-pipes/blob/master/src/pipes/math/bytes.ts 3// Thanks: https://stackoverflow.com/questions/3177836/how-to-format-time-since-xxx-e-g-4-minutes-ago-similar-to-stack-exchange-site
4 4
5@Pipe({name: 'fromNow'}) 5@Pipe({name: 'fromNow'})
6export class FromNowPipe implements PipeTransform { 6export class FromNowPipe implements PipeTransform {
diff --git a/client/src/app/shared/search/search.component.ts b/client/src/app/shared/search/search.component.ts
index 6ef19c97a..f49ecc8ad 100644
--- a/client/src/app/shared/search/search.component.ts
+++ b/client/src/app/shared/search/search.component.ts
@@ -1,8 +1,6 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3
4import { Search } from './search.model' 3import { Search } from './search.model'
5import { SearchField } from './search-field.type'
6import { SearchService } from './search.service' 4import { SearchService } from './search.service'
7 5
8@Component({ 6@Component({
@@ -12,12 +10,6 @@ import { SearchService } from './search.service'
12}) 10})
13 11
14export class SearchComponent implements OnInit { 12export class SearchComponent implements OnInit {
15 fieldChoices = {
16 name: 'Name',
17 account: 'Account',
18 host: 'Host',
19 tags: 'Tags'
20 }
21 searchCriteria: Search = { 13 searchCriteria: Search = {
22 field: 'name', 14 field: 'name',
23 value: '' 15 value: ''
@@ -40,30 +32,11 @@ export class SearchComponent implements OnInit {
40 ) 32 )
41 } 33 }
42 34
43 get choiceKeys () {
44 return Object.keys(this.fieldChoices)
45 }
46
47 choose ($event: MouseEvent, choice: SearchField) {
48 $event.preventDefault()
49 $event.stopPropagation()
50
51 this.searchCriteria.field = choice
52
53 if (this.searchCriteria.value) {
54 this.doSearch()
55 }
56 }
57
58 doSearch () { 35 doSearch () {
59 if (this.router.url.indexOf('/videos/list') === -1) { 36 // if (this.router.url.indexOf('/videos/list') === -1) {
60 this.router.navigate([ '/videos/list' ]) 37 // this.router.navigate([ '/videos/list' ])
61 } 38 // }
62 39
63 this.searchService.searchUpdated.next(this.searchCriteria) 40 this.searchService.searchUpdated.next(this.searchCriteria)
64 } 41 }
65
66 getStringChoice (choiceKey: SearchField) {
67 return this.fieldChoices[choiceKey]
68 }
69} 42}
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index c7ea6e603..7618748e9 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -6,21 +6,20 @@ import { RouterModule } from '@angular/router'
6 6
7import { BsDropdownModule } from 'ngx-bootstrap/dropdown' 7import { BsDropdownModule } from 'ngx-bootstrap/dropdown'
8import { ModalModule } from 'ngx-bootstrap/modal' 8import { ModalModule } from 'ngx-bootstrap/modal'
9import { PaginationModule } from 'ngx-bootstrap/pagination'
10import { ProgressbarModule } from 'ngx-bootstrap/progressbar' 9import { ProgressbarModule } from 'ngx-bootstrap/progressbar'
11import { BytesPipe, KeysPipe } from 'ngx-pipes' 10import { BytesPipe, KeysPipe } from 'ngx-pipes'
12import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' 11import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared'
13import { DataTableModule } from 'primeng/components/datatable/datatable' 12import { DataTableModule } from 'primeng/components/datatable/datatable'
14 13
15import { AUTH_INTERCEPTOR_PROVIDER } from './auth' 14import { AUTH_INTERCEPTOR_PROVIDER } from './auth'
15import { FromNowPipe } from './misc/from-now.pipe'
16import { LoaderComponent } from './misc/loader.component' 16import { LoaderComponent } from './misc/loader.component'
17import { NumberFormatterPipe } from './misc/number-formatter.pipe'
17import { RestExtractor, RestService } from './rest' 18import { RestExtractor, RestService } from './rest'
18import { SearchComponent, SearchService } from './search' 19import { SearchComponent, SearchService } from './search'
19import { UserService } from './users' 20import { UserService } from './users'
20import { VideoAbuseService } from './video-abuse' 21import { VideoAbuseService } from './video-abuse'
21import { VideoBlacklistService } from './video-blacklist' 22import { VideoBlacklistService } from './video-blacklist'
22import { NumberFormatterPipe } from './misc/number-formatter.pipe'
23import { FromNowPipe } from './misc/from-now.pipe'
24 23
25@NgModule({ 24@NgModule({
26 imports: [ 25 imports: [
@@ -32,7 +31,6 @@ import { FromNowPipe } from './misc/from-now.pipe'
32 31
33 BsDropdownModule.forRoot(), 32 BsDropdownModule.forRoot(),
34 ModalModule.forRoot(), 33 ModalModule.forRoot(),
35 PaginationModule.forRoot(),
36 ProgressbarModule.forRoot(), 34 ProgressbarModule.forRoot(),
37 35
38 DataTableModule, 36 DataTableModule,
@@ -57,7 +55,6 @@ import { FromNowPipe } from './misc/from-now.pipe'
57 55
58 BsDropdownModule, 56 BsDropdownModule,
59 ModalModule, 57 ModalModule,
60 PaginationModule,
61 ProgressbarModule, 58 ProgressbarModule,
62 DataTableModule, 59 DataTableModule,
63 PrimeSharedModule, 60 PrimeSharedModule,
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 ab5530e68..69e16319e 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
@@ -2,15 +2,17 @@
2 {{ titlePage }} 2 {{ titlePage }}
3</div> 3</div>
4 4
5<div class="videos-miniatures"> 5<div
6 class="videos-miniatures"
7 infiniteScroll
8 [infiniteScrollUpDistance]="1.5"
9 [infiniteScrollDistance]="0.5"
10 (scrolled)="onNearOfBottom()"
11 (scrolledUp)="onNearOfTop()"
12>
6 <my-video-miniature 13 <my-video-miniature
7 class="ng-animate" 14 class="ng-animate"
8 *ngFor="let video of videos" [video]="video" [user]="user" [currentSort]="sort" 15 *ngFor="let video of videos" [video]="video" [user]="user" [currentSort]="sort"
9 > 16 >
10 </my-video-miniature> 17 </my-video-miniature>
11</div> 18</div>
12
13<pagination *ngIf="pagination.totalItems !== null && pagination.totalItems !== 0"
14 [totalItems]="pagination.totalItems" [itemsPerPage]="pagination.itemsPerPage" [maxSize]="6" [boundaryLinks]="true" [rotate]="false"
15 [(ngModel)]="pagination.currentPage" (pageChanged)="onPageChanged($event)"
16></pagination>
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 262ea4e21..44cdc1d9f 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
@@ -19,44 +19,77 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
19 protected notificationsService: NotificationsService 19 protected notificationsService: NotificationsService
20 protected router: Router 20 protected router: Router
21 protected route: ActivatedRoute 21 protected route: ActivatedRoute
22
23 protected subActivatedRoute: Subscription 22 protected subActivatedRoute: Subscription
24 23
24 protected abstract currentRoute: string
25
25 abstract titlePage: string 26 abstract titlePage: string
27 private loadedPages: { [ id: number ]: boolean } = {}
28
26 abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}> 29 abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}>
27 30
28 ngOnInit () { 31 ngOnInit () {
29 // Subscribe to route changes 32 // Subscribe to route changes
30 this.subActivatedRoute = this.route.params.subscribe(routeParams => { 33 const routeParams = this.route.snapshot.params
31 this.loadRouteParams(routeParams) 34 this.loadRouteParams(routeParams)
32 35 this.loadMoreVideos('after')
33 this.getVideos()
34 })
35 } 36 }
36 37
37 ngOnDestroy () { 38 ngOnDestroy () {
38 this.subActivatedRoute.unsubscribe() 39 this.subActivatedRoute.unsubscribe()
39 } 40 }
40 41
41 getVideos () { 42 onNearOfTop () {
42 this.videos = [] 43 if (this.pagination.currentPage > 1) {
44 this.previousPage()
45 }
46 }
47
48 onNearOfBottom () {
49 if (this.hasMoreVideos()) {
50 this.nextPage()
51 }
52 }
53
54 loadMoreVideos (where: 'before' | 'after') {
55 if (this.loadedPages[this.pagination.currentPage] === true) return
43 56
44 const observable = this.getVideosObservable() 57 const observable = this.getVideosObservable()
45 58
46 observable.subscribe( 59 observable.subscribe(
47 ({ videos, totalVideos }) => { 60 ({ videos, totalVideos }) => {
48 this.videos = videos 61 this.loadedPages[this.pagination.currentPage] = true
49 this.pagination.totalItems = totalVideos 62 this.pagination.totalItems = totalVideos
63
64 if (where === 'before') {
65 this.videos = videos.concat(this.videos)
66 } else {
67 this.videos = this.videos.concat(videos)
68 }
50 }, 69 },
51 error => this.notificationsService.error('Error', error.text) 70 error => this.notificationsService.error('Error', error.text)
52 ) 71 )
53 } 72 }
54 73
55 onPageChanged (event: { page: number }) { 74 protected hasMoreVideos () {
56 // Be sure the current page is set 75 if (!this.pagination.totalItems) return true
57 this.pagination.currentPage = event.page 76
77 const maxPage = this.pagination.totalItems/this.pagination.itemsPerPage
78 return maxPage > this.pagination.currentPage
79 }
80
81 protected previousPage () {
82 this.pagination.currentPage--
83
84 this.setNewRouteParams()
85 this.loadMoreVideos('before')
86 }
87
88 protected nextPage () {
89 this.pagination.currentPage++
58 90
59 this.navigateToNewParams() 91 this.setNewRouteParams()
92 this.loadMoreVideos('after')
60 } 93 }
61 94
62 protected buildRouteParams () { 95 protected buildRouteParams () {
@@ -79,8 +112,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
79 } 112 }
80 } 113 }
81 114
82 protected navigateToNewParams () { 115 protected setNewRouteParams () {
83 const routeParams = this.buildRouteParams() 116 const routeParams = this.buildRouteParams()
84 this.router.navigate([ '/videos/list', routeParams ]) 117 this.router.navigate([ this.currentRoute, routeParams ])
85 } 118 }
86} 119}
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
index dbba264df..9bf69bd78 100644
--- a/client/src/app/videos/video-list/video-recently-added.component.ts
+++ b/client/src/app/videos/video-list/video-recently-added.component.ts
@@ -11,6 +11,7 @@ import { AbstractVideoList } from './shared'
11}) 11})
12export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy { 12export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy {
13 titlePage = 'Recently added' 13 titlePage = 'Recently added'
14 currentRoute = '/videos/recently-added'
14 15
15 constructor (protected router: Router, 16 constructor (protected router: Router,
16 protected route: ActivatedRoute, 17 protected route: ActivatedRoute,
diff --git a/client/src/app/videos/video-list/video-trending.component.ts b/client/src/app/videos/video-list/video-trending.component.ts
index b97966c12..a1df68711 100644
--- a/client/src/app/videos/video-list/video-trending.component.ts
+++ b/client/src/app/videos/video-list/video-trending.component.ts
@@ -11,6 +11,7 @@ import { AbstractVideoList } from './shared'
11}) 11})
12export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy { 12export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy {
13 titlePage = 'Trending' 13 titlePage = 'Trending'
14 currentRoute = '/videos/trending'
14 15
15 constructor (protected router: Router, 16 constructor (protected router: Router,
16 protected route: ActivatedRoute, 17 protected route: ActivatedRoute,
diff --git a/client/src/app/videos/videos.module.ts b/client/src/app/videos/videos.module.ts
index 93193000c..f3981d275 100644
--- a/client/src/app/videos/videos.module.ts
+++ b/client/src/app/videos/videos.module.ts
@@ -1,4 +1,5 @@
1import { NgModule } from '@angular/core' 1import { NgModule } from '@angular/core'
2import { InfiniteScrollModule } from 'ngx-infinite-scroll'
2import { SharedModule } from '../shared' 3import { SharedModule } from '../shared'
3import { VideoService } from './shared' 4import { VideoService } from './shared'
4import { MyVideosComponent, VideoMiniatureComponent } from './video-list' 5import { MyVideosComponent, VideoMiniatureComponent } from './video-list'
@@ -10,7 +11,8 @@ import { VideosComponent } from './videos.component'
10@NgModule({ 11@NgModule({
11 imports: [ 12 imports: [
12 VideosRoutingModule, 13 VideosRoutingModule,
13 SharedModule 14 SharedModule,
15 InfiniteScrollModule
14 ], 16 ],
15 17
16 declarations: [ 18 declarations: [
diff --git a/client/yarn.lock b/client/yarn.lock
index fa1802a29..bd6870061 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -4714,6 +4714,10 @@ ngx-chips@1.5.3:
4714 dependencies: 4714 dependencies:
4715 ng2-material-dropdown "0.7.10" 4715 ng2-material-dropdown "0.7.10"
4716 4716
4717ngx-infinite-scroll@^0.7.0:
4718 version "0.7.0"
4719 resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-0.7.0.tgz#a390c61c6a05ac14485e1c5bc8b4e6f6bd62fd6a"
4720
4717ngx-pipes@^2.0.5: 4721ngx-pipes@^2.0.5:
4718 version "2.0.5" 4722 version "2.0.5"
4719 resolved "https://registry.yarnpkg.com/ngx-pipes/-/ngx-pipes-2.0.5.tgz#743b827e350b1e66f5bdae49e90a02fa631d4c54" 4723 resolved "https://registry.yarnpkg.com/ngx-pipes/-/ngx-pipes-2.0.5.tgz#743b827e350b1e66f5bdae49e90a02fa631d4c54"