diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2019-12-26 11:52:46 +0100 |
---|---|---|
committer | Rigel Kent <sendmemail@rigelk.eu> | 2019-12-26 11:52:52 +0100 |
commit | c06af5012ecc925ca924e6e20db3a1d909b1148e (patch) | |
tree | 88a3595bfd0a68e8f5314737a22f9516d9790c9b /client/src | |
parent | def2a70b7e5ee807d7b532df8c9d33d17d24ccbb (diff) | |
download | PeerTube-c06af5012ecc925ca924e6e20db3a1d909b1148e.tar.gz PeerTube-c06af5012ecc925ca924e6e20db3a1d909b1148e.tar.zst PeerTube-c06af5012ecc925ca924e6e20db3a1d909b1148e.zip |
Add playlist search option and search input for add-to-video-playlist dropdown
fixes #2138
Diffstat (limited to 'client/src')
5 files changed, 40 insertions, 5 deletions
diff --git a/client/src/app/menu/avatar-notification.component.scss b/client/src/app/menu/avatar-notification.component.scss index 2ca7f24dc..ebb2a5424 100644 --- a/client/src/app/menu/avatar-notification.component.scss +++ b/client/src/app/menu/avatar-notification.component.scss | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | & > my-user-notifications:nth-child(2) { | 35 | & > my-user-notifications:nth-child(2) { |
36 | overflow-y: auto; | 36 | overflow-y: auto; |
37 | flex-grow: 1; | ||
37 | } | 38 | } |
38 | } | 39 | } |
39 | 40 | ||
diff --git a/client/src/app/shared/video-playlist/video-add-to-playlist.component.html b/client/src/app/shared/video-playlist/video-add-to-playlist.component.html index 0cc8af345..ba30953b9 100644 --- a/client/src/app/shared/video-playlist/video-add-to-playlist.component.html +++ b/client/src/app/shared/video-playlist/video-add-to-playlist.component.html | |||
@@ -41,6 +41,10 @@ | |||
41 | </div> | 41 | </div> |
42 | </div> | 42 | </div> |
43 | 43 | ||
44 | <div class="input-container"> | ||
45 | <input type="text" placeholder="Search playlists" [(ngModel)]="videoPlaylistSearch" (ngModelChange)="onVideoPlaylistSearchChanged()" /> | ||
46 | </div> | ||
47 | |||
44 | <div class="playlists"> | 48 | <div class="playlists"> |
45 | <div class="playlist dropdown-item" *ngFor="let playlist of videoPlaylists" (click)="togglePlaylist($event, playlist)"> | 49 | <div class="playlist dropdown-item" *ngFor="let playlist of videoPlaylists" (click)="togglePlaylist($event, playlist)"> |
46 | <my-peertube-checkbox [inputName]="'in-playlist-' + playlist.id" [(ngModel)]="playlist.inPlaylist" [onPushWorkaround]="true"></my-peertube-checkbox> | 50 | <my-peertube-checkbox [inputName]="'in-playlist-' + playlist.id" [(ngModel)]="playlist.inPlaylist" [onPushWorkaround]="true"></my-peertube-checkbox> |
diff --git a/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss b/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss index 090b530cf..5f9bb51a7 100644 --- a/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss +++ b/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss | |||
@@ -53,6 +53,15 @@ | |||
53 | overflow-y: auto; | 53 | overflow-y: auto; |
54 | } | 54 | } |
55 | 55 | ||
56 | .input-container { | ||
57 | display: flex; | ||
58 | |||
59 | input { | ||
60 | flex-grow: 1; | ||
61 | margin: 0 15px 10px 15px; | ||
62 | } | ||
63 | } | ||
64 | |||
56 | .playlist { | 65 | .playlist { |
57 | display: flex; | 66 | display: flex; |
58 | cursor: pointer; | 67 | cursor: pointer; |
@@ -76,7 +85,6 @@ | |||
76 | .new-playlist-button, | 85 | .new-playlist-button, |
77 | .new-playlist-block { | 86 | .new-playlist-block { |
78 | padding-top: 10px; | 87 | padding-top: 10px; |
79 | margin-top: 10px; | ||
80 | border-top: 1px solid $separator-border-color; | 88 | border-top: 1px solid $separator-border-color; |
81 | } | 89 | } |
82 | 90 | ||
diff --git a/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts b/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts index 6380c2e51..25ba8cbca 100644 --- a/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts +++ b/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts | |||
@@ -1,7 +1,8 @@ | |||
1 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core' | 1 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core' |
2 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' | 2 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' |
3 | import { AuthService, Notifier } from '@app/core' | 3 | import { AuthService, Notifier } from '@app/core' |
4 | import { forkJoin } from 'rxjs' | 4 | import { forkJoin, Subject } from 'rxjs' |
5 | import { debounceTime } from 'rxjs/operators' | ||
5 | import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' | 6 | import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' |
6 | import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms' | 7 | import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | 8 | import { I18n } from '@ngx-translate/i18n-polyfill' |
@@ -29,6 +30,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, | |||
29 | @Input() lazyLoad = false | 30 | @Input() lazyLoad = false |
30 | 31 | ||
31 | isNewPlaylistBlockOpened = false | 32 | isNewPlaylistBlockOpened = false |
33 | videoPlaylistSearch: string | ||
34 | videoPlaylistSearchChanged = new Subject<string>() | ||
32 | videoPlaylists: PlaylistSummary[] = [] | 35 | videoPlaylists: PlaylistSummary[] = [] |
33 | timestampOptions: { | 36 | timestampOptions: { |
34 | startTimestampEnabled: boolean | 37 | startTimestampEnabled: boolean |
@@ -58,6 +61,13 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, | |||
58 | this.buildForm({ | 61 | this.buildForm({ |
59 | displayName: this.videoPlaylistValidatorsService.VIDEO_PLAYLIST_DISPLAY_NAME | 62 | displayName: this.videoPlaylistValidatorsService.VIDEO_PLAYLIST_DISPLAY_NAME |
60 | }) | 63 | }) |
64 | |||
65 | this.videoPlaylistSearchChanged | ||
66 | .pipe( | ||
67 | debounceTime(500)) | ||
68 | .subscribe(() => { | ||
69 | this.load() | ||
70 | }) | ||
61 | } | 71 | } |
62 | 72 | ||
63 | ngOnChanges (simpleChanges: SimpleChanges) { | 73 | ngOnChanges (simpleChanges: SimpleChanges) { |
@@ -74,6 +84,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, | |||
74 | 84 | ||
75 | reload () { | 85 | reload () { |
76 | this.videoPlaylists = [] | 86 | this.videoPlaylists = [] |
87 | this.videoPlaylistSearch = undefined | ||
77 | 88 | ||
78 | this.init() | 89 | this.init() |
79 | 90 | ||
@@ -82,11 +93,12 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, | |||
82 | 93 | ||
83 | load () { | 94 | load () { |
84 | forkJoin([ | 95 | forkJoin([ |
85 | this.videoPlaylistService.listAccountPlaylists(this.user.account, undefined,'-updatedAt'), | 96 | this.videoPlaylistService.listAccountPlaylists(this.user.account, undefined, '-updatedAt', this.videoPlaylistSearch), |
86 | this.videoPlaylistService.doesVideoExistInPlaylist(this.video.id) | 97 | this.videoPlaylistService.doesVideoExistInPlaylist(this.video.id) |
87 | ]) | 98 | ]) |
88 | .subscribe( | 99 | .subscribe( |
89 | ([ playlistsResult, existResult ]) => { | 100 | ([ playlistsResult, existResult ]) => { |
101 | this.videoPlaylists = [] | ||
90 | for (const playlist of playlistsResult.data) { | 102 | for (const playlist of playlistsResult.data) { |
91 | const existingPlaylist = existResult[ this.video.id ].find(p => p.playlistId === playlist.id) | 103 | const existingPlaylist = existResult[ this.video.id ].find(p => p.playlistId === playlist.id) |
92 | 104 | ||
@@ -178,6 +190,10 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, | |||
178 | return `(${start}-${stop})` | 190 | return `(${start}-${stop})` |
179 | } | 191 | } |
180 | 192 | ||
193 | onVideoPlaylistSearchChanged () { | ||
194 | this.videoPlaylistSearchChanged.next() | ||
195 | } | ||
196 | |||
181 | private removeVideoFromPlaylist (playlist: PlaylistSummary) { | 197 | private removeVideoFromPlaylist (playlist: PlaylistSummary) { |
182 | if (!playlist.playlistElementId) return | 198 | if (!playlist.playlistElementId) return |
183 | 199 | ||
diff --git a/client/src/app/shared/video-playlist/video-playlist.service.ts b/client/src/app/shared/video-playlist/video-playlist.service.ts index 2945b4959..5f74dcd4c 100644 --- a/client/src/app/shared/video-playlist/video-playlist.service.ts +++ b/client/src/app/shared/video-playlist/video-playlist.service.ts | |||
@@ -59,7 +59,12 @@ export class VideoPlaylistService { | |||
59 | ) | 59 | ) |
60 | } | 60 | } |
61 | 61 | ||
62 | listAccountPlaylists (account: Account, componentPagination: ComponentPagination, sort: string): Observable<ResultList<VideoPlaylist>> { | 62 | listAccountPlaylists ( |
63 | account: Account, | ||
64 | componentPagination: ComponentPagination, | ||
65 | sort: string, | ||
66 | search?: string | ||
67 | ): Observable<ResultList<VideoPlaylist>> { | ||
63 | const url = AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/video-playlists' | 68 | const url = AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/video-playlists' |
64 | const pagination = componentPagination | 69 | const pagination = componentPagination |
65 | ? this.restService.componentPaginationToRestPagination(componentPagination) | 70 | ? this.restService.componentPaginationToRestPagination(componentPagination) |
@@ -67,6 +72,7 @@ export class VideoPlaylistService { | |||
67 | 72 | ||
68 | let params = new HttpParams() | 73 | let params = new HttpParams() |
69 | params = this.restService.addRestGetParams(params, pagination, sort) | 74 | params = this.restService.addRestGetParams(params, pagination, sort) |
75 | if (search) params = this.restService.addObjectParams(params, { search }) | ||
70 | 76 | ||
71 | return this.authHttp.get<ResultList<VideoPlaylist>>(url, { params }) | 77 | return this.authHttp.get<ResultList<VideoPlaylist>>(url, { params }) |
72 | .pipe( | 78 | .pipe( |
@@ -213,8 +219,8 @@ export class VideoPlaylistService { | |||
213 | 219 | ||
214 | private doVideosExistInPlaylist (videoIds: number[]): Observable<VideoExistInPlaylist> { | 220 | private doVideosExistInPlaylist (videoIds: number[]): Observable<VideoExistInPlaylist> { |
215 | const url = VideoPlaylistService.MY_VIDEO_PLAYLIST_URL + 'videos-exist' | 221 | const url = VideoPlaylistService.MY_VIDEO_PLAYLIST_URL + 'videos-exist' |
216 | let params = new HttpParams() | ||
217 | 222 | ||
223 | let params = new HttpParams() | ||
218 | params = this.restService.addObjectParams(params, { videoIds }) | 224 | params = this.restService.addObjectParams(params, { videoIds }) |
219 | 225 | ||
220 | return this.authHttp.get<VideoExistInPlaylist>(url, { params }) | 226 | return this.authHttp.get<VideoExistInPlaylist>(url, { params }) |