diff options
Diffstat (limited to 'client/src/app')
8 files changed, 83 insertions, 48 deletions
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html index 8c5285e4b..ab8e0c283 100644 --- a/client/src/app/app.component.html +++ b/client/src/app/app.component.html | |||
@@ -6,7 +6,7 @@ | |||
6 | </div> | 6 | </div> |
7 | 7 | ||
8 | <div class="col-md-9"> | 8 | <div class="col-md-9"> |
9 | <my-search (search)="onSearch($event)"></my-search> | 9 | <my-search></my-search> |
10 | </div> | 10 | </div> |
11 | </header> | 11 | </header> |
12 | 12 | ||
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index 88b181f9c..354d00a7a 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts | |||
@@ -1,12 +1,11 @@ | |||
1 | import { Component } from '@angular/core'; | 1 | import { Component } from '@angular/core'; |
2 | import { HTTP_PROVIDERS } from '@angular/http'; | 2 | import { HTTP_PROVIDERS } from '@angular/http'; |
3 | import { Router, ROUTER_DIRECTIVES } from '@angular/router'; | 3 | import { ActivatedRoute, Router, ROUTER_DIRECTIVES } from '@angular/router'; |
4 | 4 | ||
5 | import { FriendService } from './friends'; | 5 | import { FriendService } from './friends'; |
6 | import { | 6 | import { |
7 | AuthService, | 7 | AuthService, |
8 | AuthStatus, | 8 | AuthStatus, |
9 | Search, | ||
10 | SearchComponent, | 9 | SearchComponent, |
11 | SearchService | 10 | SearchService |
12 | } from './shared'; | 11 | } from './shared'; |
@@ -27,6 +26,7 @@ export class AppComponent { | |||
27 | constructor( | 26 | constructor( |
28 | private authService: AuthService, | 27 | private authService: AuthService, |
29 | private friendService: FriendService, | 28 | private friendService: FriendService, |
29 | private route: ActivatedRoute, | ||
30 | private router: Router | 30 | private router: Router |
31 | ) { | 31 | ) { |
32 | this.isLoggedIn = this.authService.isLoggedIn(); | 32 | this.isLoggedIn = this.authService.isLoggedIn(); |
@@ -40,19 +40,6 @@ export class AppComponent { | |||
40 | ); | 40 | ); |
41 | } | 41 | } |
42 | 42 | ||
43 | onSearch(search: Search) { | ||
44 | if (search.value !== '') { | ||
45 | const params = { | ||
46 | field: search.field, | ||
47 | search: search.value | ||
48 | }; | ||
49 | |||
50 | this.router.navigate(['/videos/list', params]); | ||
51 | } else { | ||
52 | this.router.navigate(['/videos/list']); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | // FIXME | 43 | // FIXME |
57 | logout() { | 44 | logout() { |
58 | // this._authService.logout(); | 45 | // this._authService.logout(); |
diff --git a/client/src/app/shared/search/search.component.ts b/client/src/app/shared/search/search.component.ts index d33701bc8..e864fbc17 100644 --- a/client/src/app/shared/search/search.component.ts +++ b/client/src/app/shared/search/search.component.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Component, EventEmitter, Output, OnInit } from '@angular/core'; | 1 | import { Component, OnInit } from '@angular/core'; |
2 | 2 | ||
3 | import { DROPDOWN_DIRECTIVES} from 'ng2-bootstrap/components/dropdown'; | 3 | import { DROPDOWN_DIRECTIVES} from 'ng2-bootstrap/components/dropdown'; |
4 | 4 | ||
@@ -13,8 +13,6 @@ import { SearchService } from './search.service'; | |||
13 | }) | 13 | }) |
14 | 14 | ||
15 | export class SearchComponent implements OnInit { | 15 | export class SearchComponent implements OnInit { |
16 | @Output() search = new EventEmitter<Search>(); | ||
17 | |||
18 | fieldChoices = { | 16 | fieldChoices = { |
19 | name: 'Name', | 17 | name: 'Name', |
20 | author: 'Author', | 18 | author: 'Author', |
@@ -30,7 +28,9 @@ export class SearchComponent implements OnInit { | |||
30 | constructor(private searchService: SearchService) {} | 28 | constructor(private searchService: SearchService) {} |
31 | 29 | ||
32 | ngOnInit() { | 30 | ngOnInit() { |
33 | this.searchService.searchChanged.subscribe( | 31 | // Subscribe is the search changed |
32 | // Usually changed by videos list component | ||
33 | this.searchService.updateSearch.subscribe( | ||
34 | newSearchCriterias => { | 34 | newSearchCriterias => { |
35 | // Put a field by default | 35 | // Put a field by default |
36 | if (!newSearchCriterias.field) { | 36 | if (!newSearchCriterias.field) { |
@@ -58,7 +58,7 @@ export class SearchComponent implements OnInit { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | doSearch() { | 60 | doSearch() { |
61 | this.search.emit(this.searchCriterias); | 61 | this.searchService.searchUpdated.next(this.searchCriterias); |
62 | } | 62 | } |
63 | 63 | ||
64 | getStringChoice(choiceKey: SearchField) { | 64 | getStringChoice(choiceKey: SearchField) { |
diff --git a/client/src/app/shared/search/search.service.ts b/client/src/app/shared/search/search.service.ts index 0e41cdd34..c7993db3d 100644 --- a/client/src/app/shared/search/search.service.ts +++ b/client/src/app/shared/search/search.service.ts | |||
@@ -7,9 +7,11 @@ import { Search } from './search.model'; | |||
7 | // Remove it when we'll be able to subscribe to router changes | 7 | // Remove it when we'll be able to subscribe to router changes |
8 | @Injectable() | 8 | @Injectable() |
9 | export class SearchService { | 9 | export class SearchService { |
10 | searchChanged: Subject<Search>; | 10 | searchUpdated: Subject<Search>; |
11 | updateSearch: Subject<Search>; | ||
11 | 12 | ||
12 | constructor() { | 13 | constructor() { |
13 | this.searchChanged = new Subject<Search>(); | 14 | this.updateSearch = new Subject<Search>(); |
15 | this.searchUpdated = new Subject<Search>(); | ||
14 | } | 16 | } |
15 | } | 17 | } |
diff --git a/client/src/app/videos/video-list/video-list.component.html b/client/src/app/videos/video-list/video-list.component.html index 0e17ef2c4..e119517a8 100644 --- a/client/src/app/videos/video-list/video-list.component.html +++ b/client/src/app/videos/video-list/video-list.component.html | |||
@@ -8,13 +8,16 @@ | |||
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="videos-miniatures"> | 10 | <div class="videos-miniatures"> |
11 | <div class="col-md-12 no-video" *ngIf="noVideo()">There is no video.</div> | 11 | <div class="col-md-12 no-video" *ngIf="isThereNoVideo()">There is no video.</div> |
12 | 12 | ||
13 | <my-video-miniature class="ng-animate "*ngFor="let video of videos" [video]="video" [user]="user" (removed)="onRemoved(video)"> | 13 | <my-video-miniature |
14 | class="ng-animate" | ||
15 | *ngFor="let video of videos" [video]="video" [user]="user" [currentSort]="sort" (removed)="onRemoved(video)" | ||
16 | > | ||
14 | </my-video-miniature> | 17 | </my-video-miniature> |
15 | </div> | 18 | </div> |
16 | 19 | ||
17 | <pagination *ngIf="pagination.totalItems !== null" | 20 | <pagination *ngIf="pagination.totalItems !== null" |
18 | [totalItems]="pagination.totalItems" [itemsPerPage]="pagination.itemsPerPage" [maxSize]="6" [boundaryLinks]="true" [rotate]="false" | 21 | [totalItems]="pagination.totalItems" [itemsPerPage]="pagination.itemsPerPage" [maxSize]="6" [boundaryLinks]="true" [rotate]="false" |
19 | [(ngModel)]="pagination.currentPage" (pageChanged)="getVideos()" | 22 | [(ngModel)]="pagination.currentPage" (pageChanged)="onPageChanged($event)" |
20 | ></pagination> | 23 | ></pagination> |
diff --git a/client/src/app/videos/video-list/video-list.component.ts b/client/src/app/videos/video-list/video-list.component.ts index 0ebf0ef5c..5691d684e 100644 --- a/client/src/app/videos/video-list/video-list.component.ts +++ b/client/src/app/videos/video-list/video-list.component.ts | |||
@@ -37,7 +37,8 @@ export class VideoListComponent implements OnInit, OnDestroy { | |||
37 | videos: Video[] = []; | 37 | videos: Video[] = []; |
38 | 38 | ||
39 | private search: Search; | 39 | private search: Search; |
40 | private sub: any; | 40 | private subActivatedRoute: any; |
41 | private subSearch: any; | ||
41 | 42 | ||
42 | constructor( | 43 | constructor( |
43 | private authService: AuthService, | 44 | private authService: AuthService, |
@@ -49,33 +50,35 @@ export class VideoListComponent implements OnInit, OnDestroy { | |||
49 | ) {} | 50 | ) {} |
50 | 51 | ||
51 | ngOnInit() { | 52 | ngOnInit() { |
52 | this.sub = this.route.params.subscribe(routeParams => { | 53 | if (this.authService.isLoggedIn()) { |
53 | if (this.authService.isLoggedIn()) { | 54 | this.user = User.load(); |
54 | this.user = User.load(); | 55 | } |
55 | } | ||
56 | 56 | ||
57 | this.search = { | 57 | // Subscribe to route changes |
58 | value: routeParams['search'], | 58 | this.subActivatedRoute = this.route.params.subscribe(routeParams => { |
59 | field: <SearchField>routeParams['field'] | 59 | this.loadRouteParams(routeParams); |
60 | }; | ||
61 | 60 | ||
62 | // Update the search service component | 61 | // Update the search service component |
63 | this.searchService.searchChanged.next(this.search); | 62 | this.searchService.updateSearch.next(this.search); |
63 | this.getVideos(); | ||
64 | }); | ||
64 | 65 | ||
65 | this.sort = <SortField>routeParams['sort'] || '-createdDate'; | 66 | // Subscribe to search changes |
67 | this.subSearch = this.searchService.searchUpdated.subscribe(search => { | ||
68 | this.search = search; | ||
66 | 69 | ||
67 | this.getVideos(); | 70 | this.navigateToNewParams(); |
68 | }); | 71 | }); |
69 | } | 72 | } |
70 | 73 | ||
71 | ngOnDestroy() { | 74 | ngOnDestroy() { |
72 | this.sub.unsubscribe(); | 75 | this.subActivatedRoute.unsubscribe(); |
76 | this.subSearch.unsubscribe(); | ||
73 | } | 77 | } |
74 | 78 | ||
75 | getVideos(detectChanges = true) { | 79 | getVideos(detectChanges = true) { |
76 | this.loading.next(true); | 80 | this.loading.next(true); |
77 | this.videos = []; | 81 | this.videos = []; |
78 | this.pagination.currentPage = 1; | ||
79 | 82 | ||
80 | this.changeDetector.detectChanges(); | 83 | this.changeDetector.detectChanges(); |
81 | 84 | ||
@@ -98,26 +101,65 @@ export class VideoListComponent implements OnInit, OnDestroy { | |||
98 | ); | 101 | ); |
99 | } | 102 | } |
100 | 103 | ||
101 | noVideo() { | 104 | isThereNoVideo() { |
102 | return !this.loading && this.videos.length === 0; | 105 | return !this.loading.getValue() && this.videos.length === 0; |
106 | } | ||
107 | |||
108 | onPageChanged(event: any) { | ||
109 | // Be sure the current page is set | ||
110 | this.pagination.currentPage = event.page; | ||
111 | |||
112 | this.navigateToNewParams(); | ||
103 | } | 113 | } |
104 | 114 | ||
105 | onRemoved(video: Video) { | 115 | onRemoved(video: Video) { |
106 | this.getVideos(false); | 116 | this.getVideos(); |
107 | } | 117 | } |
108 | 118 | ||
109 | onSort(sort: SortField) { | 119 | onSort(sort: SortField) { |
110 | this.sort = sort; | 120 | this.sort = sort; |
111 | 121 | ||
122 | this.navigateToNewParams(); | ||
123 | } | ||
124 | |||
125 | private buildRouteParams() { | ||
126 | // There is always a sort and a current page | ||
112 | const params: any = { | 127 | const params: any = { |
113 | sort: this.sort | 128 | sort: this.sort, |
129 | page: this.pagination.currentPage | ||
114 | }; | 130 | }; |
115 | 131 | ||
132 | // Maybe there is a search | ||
116 | if (this.search.value) { | 133 | if (this.search.value) { |
117 | params.field = this.search.field; | 134 | params.field = this.search.field; |
118 | params.search = this.search.value; | 135 | params.search = this.search.value; |
119 | } | 136 | } |
120 | 137 | ||
121 | this.router.navigate(['/videos/list', params]); | 138 | return params; |
139 | } | ||
140 | |||
141 | private loadRouteParams(routeParams) { | ||
142 | if (routeParams['search'] !== undefined) { | ||
143 | this.search = { | ||
144 | value: routeParams['search'], | ||
145 | field: <SearchField>routeParams['field'] | ||
146 | }; | ||
147 | } else { | ||
148 | this.search = { | ||
149 | value: '', | ||
150 | field: 'name' | ||
151 | }; | ||
152 | } | ||
153 | |||
154 | this.sort = <SortField>routeParams['sort'] || '-createdDate'; | ||
155 | |||
156 | this.pagination.currentPage = parseInt(routeParams['page']) || 1; | ||
157 | |||
158 | this.changeDetector.detectChanges(); | ||
159 | } | ||
160 | |||
161 | private navigateToNewParams() { | ||
162 | const routeParams = this.buildRouteParams(); | ||
163 | this.router.navigate(['/videos/list', routeParams]); | ||
122 | } | 164 | } |
123 | } | 165 | } |
diff --git a/client/src/app/videos/video-list/video-miniature.component.html b/client/src/app/videos/video-list/video-miniature.component.html index 3cf28620e..373ff6bfb 100644 --- a/client/src/app/videos/video-list/video-miniature.component.html +++ b/client/src/app/videos/video-list/video-miniature.component.html | |||
@@ -17,12 +17,12 @@ | |||
17 | 17 | ||
18 | <div class="video-miniature-tags"> | 18 | <div class="video-miniature-tags"> |
19 | <span *ngFor="let tag of video.tags" class="video-miniature-tag"> | 19 | <span *ngFor="let tag of video.tags" class="video-miniature-tag"> |
20 | <a [routerLink]="['/videos/list', { field: 'tags', search: tag }]" class="label label-primary">{{ tag }}</a> | 20 | <a [routerLink]="['/videos/list', { field: 'tags', search: tag, sort: currentSort }]" class="label label-primary">{{ tag }}</a> |
21 | </span> | 21 | </span> |
22 | </div> | 22 | </div> |
23 | </span> | 23 | </span> |
24 | 24 | ||
25 | <a [routerLink]="['/videos/list', { field: 'author', search: video.author }]" class="video-miniature-author">{{ video.by }}</a> | 25 | <a [routerLink]="['/videos/list', { field: 'author', search: video.author, sort: currentSort }]" class="video-miniature-author">{{ video.by }}</a> |
26 | <span class="video-miniature-created-date">{{ video.createdDate | date:'short' }}</span> | 26 | <span class="video-miniature-created-date">{{ video.createdDate | date:'short' }}</span> |
27 | </div> | 27 | </div> |
28 | </div> | 28 | </div> |
diff --git a/client/src/app/videos/video-list/video-miniature.component.ts b/client/src/app/videos/video-list/video-miniature.component.ts index 90645d67f..84bab950e 100644 --- a/client/src/app/videos/video-list/video-miniature.component.ts +++ b/client/src/app/videos/video-list/video-miniature.component.ts | |||
@@ -2,7 +2,7 @@ import { DatePipe } from '@angular/common'; | |||
2 | import { Component, Input, Output, EventEmitter } from '@angular/core'; | 2 | import { Component, Input, Output, EventEmitter } from '@angular/core'; |
3 | import { ROUTER_DIRECTIVES } from '@angular/router'; | 3 | import { ROUTER_DIRECTIVES } from '@angular/router'; |
4 | 4 | ||
5 | import { Video, VideoService } from '../shared'; | 5 | import { SortField, Video, VideoService } from '../shared'; |
6 | import { User } from '../../shared'; | 6 | import { User } from '../../shared'; |
7 | 7 | ||
8 | @Component({ | 8 | @Component({ |
@@ -16,6 +16,7 @@ import { User } from '../../shared'; | |||
16 | export class VideoMiniatureComponent { | 16 | export class VideoMiniatureComponent { |
17 | @Output() removed = new EventEmitter<any>(); | 17 | @Output() removed = new EventEmitter<any>(); |
18 | 18 | ||
19 | @Input() currentSort: SortField; | ||
19 | @Input() user: User; | 20 | @Input() user: User; |
20 | @Input() video: Video; | 21 | @Input() video: Video; |
21 | 22 | ||