diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2019-12-28 01:10:26 +0100 |
---|---|---|
committer | Rigel Kent <sendmemail@rigelk.eu> | 2019-12-28 01:10:26 +0100 |
commit | bf64ed4196938ba9002c887cadb01bd2a6e3127a (patch) | |
tree | 889b8f89c59cd513edd973785a76ccf6f8c23f3d /client/src | |
parent | 71810d0bcbed0e46ddaa1d4eadd028154786fffb (diff) | |
download | PeerTube-bf64ed4196938ba9002c887cadb01bd2a6e3127a.tar.gz PeerTube-bf64ed4196938ba9002c887cadb01bd2a6e3127a.tar.zst PeerTube-bf64ed4196938ba9002c887cadb01bd2a6e3127a.zip |
Add search bars for a user's videos and playlist library
Diffstat (limited to 'client/src')
13 files changed, 75 insertions, 13 deletions
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html index 307884c70..878772359 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html | |||
@@ -1,4 +1,6 @@ | |||
1 | <div class="video-playlists-header"> | 1 | <div class="video-playlists-header"> |
2 | <input type="text" placeholder="Search your playlists" i18n-placeholder [(ngModel)]="videoPlaylistsSearch" (ngModelChange)="onVideoPlaylistSearchChanged()" /> | ||
3 | |||
2 | <a class="create-button" routerLink="create"> | 4 | <a class="create-button" routerLink="create"> |
3 | <my-global-icon iconName="add"></my-global-icon> | 5 | <my-global-icon iconName="add"></my-global-icon> |
4 | <ng-container i18n>Create a new playlist</ng-container> | 6 | <ng-container i18n>Create a new playlist</ng-container> |
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss index d5635417d..4fb4ed4be 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss | |||
@@ -29,12 +29,19 @@ | |||
29 | 29 | ||
30 | .video-playlist-buttons { | 30 | .video-playlist-buttons { |
31 | min-width: 190px; | 31 | min-width: 190px; |
32 | height: max-content; | ||
32 | } | 33 | } |
33 | } | 34 | } |
34 | 35 | ||
35 | .video-playlists-header { | 36 | .video-playlists-header { |
37 | display: flex; | ||
38 | justify-content: space-between; | ||
36 | text-align: right; | 39 | text-align: right; |
37 | margin: 20px 0 50px; | 40 | margin: 20px 0 50px; |
41 | |||
42 | input[type=text] { | ||
43 | @include peertube-input-text(300px); | ||
44 | } | ||
38 | } | 45 | } |
39 | 46 | ||
40 | @media screen and (max-width: 800px) { | 47 | @media screen and (max-width: 800px) { |
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts index 76b13fe2b..42e4782eb 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts | |||
@@ -3,7 +3,7 @@ import { Notifier } from '@app/core' | |||
3 | import { AuthService } from '../../core/auth' | 3 | import { AuthService } from '../../core/auth' |
4 | import { ConfirmService } from '../../core/confirm' | 4 | import { ConfirmService } from '../../core/confirm' |
5 | import { User } from '@app/shared' | 5 | import { User } from '@app/shared' |
6 | import { flatMap } from 'rxjs/operators' | 6 | import { flatMap, debounceTime } from 'rxjs/operators' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | 7 | import { I18n } from '@ngx-translate/i18n-polyfill' |
8 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' | 8 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' |
9 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | 9 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' |
@@ -17,7 +17,9 @@ import { Subject } from 'rxjs' | |||
17 | styleUrls: [ './my-account-video-playlists.component.scss' ] | 17 | styleUrls: [ './my-account-video-playlists.component.scss' ] |
18 | }) | 18 | }) |
19 | export class MyAccountVideoPlaylistsComponent implements OnInit { | 19 | export class MyAccountVideoPlaylistsComponent implements OnInit { |
20 | videoPlaylistsSearch: string | ||
20 | videoPlaylists: VideoPlaylist[] = [] | 21 | videoPlaylists: VideoPlaylist[] = [] |
22 | videoPlaylistSearchChanged = new Subject<string>() | ||
21 | 23 | ||
22 | pagination: ComponentPagination = { | 24 | pagination: ComponentPagination = { |
23 | currentPage: 1, | 25 | currentPage: 1, |
@@ -41,6 +43,13 @@ export class MyAccountVideoPlaylistsComponent implements OnInit { | |||
41 | this.user = this.authService.getUser() | 43 | this.user = this.authService.getUser() |
42 | 44 | ||
43 | this.loadVideoPlaylists() | 45 | this.loadVideoPlaylists() |
46 | |||
47 | this.videoPlaylistSearchChanged | ||
48 | .pipe( | ||
49 | debounceTime(500)) | ||
50 | .subscribe(() => { | ||
51 | this.loadVideoPlaylists() | ||
52 | }) | ||
44 | } | 53 | } |
45 | 54 | ||
46 | async deleteVideoPlaylist (videoPlaylist: VideoPlaylist) { | 55 | async deleteVideoPlaylist (videoPlaylist: VideoPlaylist) { |
@@ -80,12 +89,17 @@ export class MyAccountVideoPlaylistsComponent implements OnInit { | |||
80 | this.loadVideoPlaylists() | 89 | this.loadVideoPlaylists() |
81 | } | 90 | } |
82 | 91 | ||
92 | onVideoPlaylistSearchChanged () { | ||
93 | this.videoPlaylistSearchChanged.next() | ||
94 | } | ||
95 | |||
83 | private loadVideoPlaylists () { | 96 | private loadVideoPlaylists () { |
84 | this.authService.userInformationLoaded | 97 | this.authService.userInformationLoaded |
85 | .pipe(flatMap(() => { | 98 | .pipe(flatMap(() => { |
86 | return this.videoPlaylistService.listAccountPlaylists(this.user.account, this.pagination, '-updatedAt') | 99 | return this.videoPlaylistService.listAccountPlaylists(this.user.account, this.pagination, '-updatedAt', this.videoPlaylistsSearch) |
87 | })) | 100 | })) |
88 | .subscribe(res => { | 101 | .subscribe(res => { |
102 | this.videoPlaylists = [] | ||
89 | this.videoPlaylists = this.videoPlaylists.concat(res.data) | 103 | this.videoPlaylists = this.videoPlaylists.concat(res.data) |
90 | this.pagination.totalItems = res.total | 104 | this.pagination.totalItems = res.total |
91 | 105 | ||
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html index 2854093c4..a898cd938 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html | |||
@@ -1,3 +1,7 @@ | |||
1 | <div class="videos-header"> | ||
2 | <input type="text" placeholder="Search your videos" i18n-placeholder [(ngModel)]="videosSearch" (ngModelChange)="onVideosSearchChanged()" /> | ||
3 | </div> | ||
4 | |||
1 | <my-videos-selection | 5 | <my-videos-selection |
2 | [pagination]="pagination" | 6 | [pagination]="pagination" |
3 | [(selection)]="selection" | 7 | [(selection)]="selection" |
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss index 87398e7c8..44545b3e1 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss | |||
@@ -1,6 +1,17 @@ | |||
1 | @import '_variables'; | 1 | @import '_variables'; |
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | 3 | ||
4 | .videos-header { | ||
5 | display: flex; | ||
6 | justify-content: space-between; | ||
7 | text-align: right; | ||
8 | margin: 20px 0 50px; | ||
9 | |||
10 | input[type=text] { | ||
11 | @include peertube-input-text(300px); | ||
12 | } | ||
13 | } | ||
14 | |||
4 | .action-button-delete-selection { | 15 | .action-button-delete-selection { |
5 | display: inline-block; | 16 | display: inline-block; |
6 | 17 | ||
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts index 2c86a3c56..dd4b25d08 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { concat, Observable } from 'rxjs' | 1 | import { concat, Observable, Subject } from 'rxjs' |
2 | import { tap, toArray } from 'rxjs/operators' | 2 | import { tap, toArray, debounceTime } from 'rxjs/operators' |
3 | import { Component, ViewChild } from '@angular/core' | 3 | import { Component, ViewChild, OnInit } from '@angular/core' |
4 | import { ActivatedRoute, Router } from '@angular/router' | 4 | import { ActivatedRoute, Router } from '@angular/router' |
5 | import { immutableAssign } from '@app/shared/misc/utils' | 5 | import { immutableAssign } from '@app/shared/misc/utils' |
6 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | 6 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' |
@@ -22,7 +22,7 @@ import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' | |||
22 | templateUrl: './my-account-videos.component.html', | 22 | templateUrl: './my-account-videos.component.html', |
23 | styleUrls: [ './my-account-videos.component.scss' ] | 23 | styleUrls: [ './my-account-videos.component.scss' ] |
24 | }) | 24 | }) |
25 | export class MyAccountVideosComponent implements DisableForReuseHook { | 25 | export class MyAccountVideosComponent implements OnInit, DisableForReuseHook { |
26 | @ViewChild('videosSelection', { static: true }) videosSelection: VideosSelectionComponent | 26 | @ViewChild('videosSelection', { static: true }) videosSelection: VideosSelectionComponent |
27 | @ViewChild('videoChangeOwnershipModal', { static: true }) videoChangeOwnershipModal: VideoChangeOwnershipComponent | 27 | @ViewChild('videoChangeOwnershipModal', { static: true }) videoChangeOwnershipModal: VideoChangeOwnershipComponent |
28 | 28 | ||
@@ -43,6 +43,8 @@ export class MyAccountVideosComponent implements DisableForReuseHook { | |||
43 | blacklistInfo: true | 43 | blacklistInfo: true |
44 | } | 44 | } |
45 | videos: Video[] = [] | 45 | videos: Video[] = [] |
46 | videosSearch: string | ||
47 | videosSearchChanged = new Subject<string>() | ||
46 | getVideosObservableFunction = this.getVideosObservable.bind(this) | 48 | getVideosObservableFunction = this.getVideosObservable.bind(this) |
47 | 49 | ||
48 | constructor ( | 50 | constructor ( |
@@ -59,6 +61,19 @@ export class MyAccountVideosComponent implements DisableForReuseHook { | |||
59 | this.titlePage = this.i18n('My videos') | 61 | this.titlePage = this.i18n('My videos') |
60 | } | 62 | } |
61 | 63 | ||
64 | ngOnInit () { | ||
65 | this.videosSearchChanged | ||
66 | .pipe( | ||
67 | debounceTime(500)) | ||
68 | .subscribe(() => { | ||
69 | this.videosSelection.reloadVideos() | ||
70 | }) | ||
71 | } | ||
72 | |||
73 | onVideosSearchChanged () { | ||
74 | this.videosSearchChanged.next() | ||
75 | } | ||
76 | |||
62 | disableForReuse () { | 77 | disableForReuse () { |
63 | this.videosSelection.disableForReuse() | 78 | this.videosSelection.disableForReuse() |
64 | } | 79 | } |
@@ -70,7 +85,7 @@ export class MyAccountVideosComponent implements DisableForReuseHook { | |||
70 | getVideosObservable (page: number, sort: VideoSortField) { | 85 | getVideosObservable (page: number, sort: VideoSortField) { |
71 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) | 86 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) |
72 | 87 | ||
73 | return this.videoService.getMyVideos(newPagination, sort) | 88 | return this.videoService.getMyVideos(newPagination, sort, this.videosSearch) |
74 | } | 89 | } |
75 | 90 | ||
76 | async deleteSelectedVideos () { | 91 | async deleteSelectedVideos () { |
diff --git a/client/src/app/shared/users/user.service.ts b/client/src/app/shared/users/user.service.ts index 41ee87197..051e0bfa4 100644 --- a/client/src/app/shared/users/user.service.ts +++ b/client/src/app/shared/users/user.service.ts | |||
@@ -88,7 +88,7 @@ export class UserService { | |||
88 | } | 88 | } |
89 | 89 | ||
90 | getMyVideoQuotaUsed () { | 90 | getMyVideoQuotaUsed () { |
91 | const url = UserService.BASE_USERS_URL + '/me/video-quota-used' | 91 | const url = UserService.BASE_USERS_URL + 'me/video-quota-used' |
92 | 92 | ||
93 | return this.authHttp.get<UserVideoQuota>(url) | 93 | return this.authHttp.get<UserVideoQuota>(url) |
94 | .pipe(catchError(err => this.restExtractor.handleError(err))) | 94 | .pipe(catchError(err => this.restExtractor.handleError(err))) |
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 ba30953b9..6e0989227 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 | |||
@@ -42,7 +42,7 @@ | |||
42 | </div> | 42 | </div> |
43 | 43 | ||
44 | <div class="input-container"> | 44 | <div class="input-container"> |
45 | <input type="text" placeholder="Search playlists" [(ngModel)]="videoPlaylistSearch" (ngModelChange)="onVideoPlaylistSearchChanged()" /> | 45 | <input type="text" placeholder="Search playlists" i18n-placeholder [(ngModel)]="videoPlaylistSearch" (ngModelChange)="onVideoPlaylistSearchChanged()" /> |
46 | </div> | 46 | </div> |
47 | 47 | ||
48 | <div class="playlists"> | 48 | <div class="playlists"> |
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts index a2a12bec7..746359851 100644 --- a/client/src/app/shared/video/abstract-video-list.ts +++ b/client/src/app/shared/video/abstract-video-list.ts | |||
@@ -150,6 +150,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor | |||
150 | this.getVideosObservable(this.pagination.currentPage).subscribe( | 150 | this.getVideosObservable(this.pagination.currentPage).subscribe( |
151 | ({ data, total }) => { | 151 | ({ data, total }) => { |
152 | this.pagination.totalItems = total | 152 | this.pagination.totalItems = total |
153 | this.videos = [] | ||
153 | this.videos = this.videos.concat(data) | 154 | this.videos = this.videos.concat(data) |
154 | 155 | ||
155 | if (this.groupByDate) this.buildGroupedDateLabels() | 156 | if (this.groupByDate) this.buildGroupedDateLabels() |
@@ -170,7 +171,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor | |||
170 | 171 | ||
171 | reloadVideos () { | 172 | reloadVideos () { |
172 | this.pagination.currentPage = 1 | 173 | this.pagination.currentPage = 1 |
173 | this.videos = [] | ||
174 | this.loadMoreVideos() | 174 | this.loadMoreVideos() |
175 | } | 175 | } |
176 | 176 | ||
diff --git a/client/src/app/shared/video/video-miniature.component.scss b/client/src/app/shared/video/video-miniature.component.scss index 3988cc055..ac83c5dfa 100644 --- a/client/src/app/shared/video/video-miniature.component.scss +++ b/client/src/app/shared/video/video-miniature.component.scss | |||
@@ -100,7 +100,8 @@ $more-margin-right: 15px; | |||
100 | flex-direction: row; | 100 | flex-direction: row; |
101 | margin-bottom: 0; | 101 | margin-bottom: 0; |
102 | height: auto; | 102 | height: auto; |
103 | width: 100%; | 103 | display: flex; |
104 | flex-grow: 1; | ||
104 | 105 | ||
105 | my-video-thumbnail { | 106 | my-video-thumbnail { |
106 | margin-right: 10px; | 107 | margin-right: 10px; |
diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index 9adf46495..2dd47d74e 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts | |||
@@ -121,14 +121,15 @@ export class VideoService implements VideosProvider { | |||
121 | .pipe(catchError(err => this.restExtractor.handleError(err))) | 121 | .pipe(catchError(err => this.restExtractor.handleError(err))) |
122 | } | 122 | } |
123 | 123 | ||
124 | getMyVideos (videoPagination: ComponentPagination, sort: VideoSortField): Observable<ResultList<Video>> { | 124 | getMyVideos (videoPagination: ComponentPagination, sort: VideoSortField, search?: string): Observable<ResultList<Video>> { |
125 | const pagination = this.restService.componentPaginationToRestPagination(videoPagination) | 125 | const pagination = this.restService.componentPaginationToRestPagination(videoPagination) |
126 | 126 | ||
127 | let params = new HttpParams() | 127 | let params = new HttpParams() |
128 | params = this.restService.addRestGetParams(params, pagination, sort) | 128 | params = this.restService.addRestGetParams(params, pagination, sort) |
129 | params = this.restService.addObjectParams(params, { search }) | ||
129 | 130 | ||
130 | return this.authHttp | 131 | return this.authHttp |
131 | .get<ResultList<Video>>(UserService.BASE_USERS_URL + '/me/videos', { params }) | 132 | .get<ResultList<Video>>(UserService.BASE_USERS_URL + 'me/videos', { params }) |
132 | .pipe( | 133 | .pipe( |
133 | switchMap(res => this.extractVideos(res)), | 134 | switchMap(res => this.extractVideos(res)), |
134 | catchError(err => this.restExtractor.handleError(err)) | 135 | catchError(err => this.restExtractor.handleError(err)) |
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.scss b/client/src/app/videos/+video-watch/comment/video-comments.component.scss index 9e3682295..c02f6c21b 100644 --- a/client/src/app/videos/+video-watch/comment/video-comments.component.scss +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.scss | |||
@@ -27,6 +27,7 @@ | |||
27 | font-weight: 600; | 27 | font-weight: 600; |
28 | text-transform: uppercase; | 28 | text-transform: uppercase; |
29 | border: none; | 29 | border: none; |
30 | transform: translateY(-7%); | ||
30 | } | 31 | } |
31 | 32 | ||
32 | my-feed { | 33 | my-feed { |
diff --git a/client/src/sass/primeng-custom.scss b/client/src/sass/primeng-custom.scss index 0acffef3c..9398f0adc 100644 --- a/client/src/sass/primeng-custom.scss +++ b/client/src/sass/primeng-custom.scss | |||
@@ -10,6 +10,12 @@ | |||
10 | color: var(--mainForegroundColor) !important; | 10 | color: var(--mainForegroundColor) !important; |
11 | } | 11 | } |
12 | 12 | ||
13 | my-edit-button, | ||
14 | my-delete-button, | ||
15 | my-button { | ||
16 | height: max-content; | ||
17 | } | ||
18 | |||
13 | // data table customizations | 19 | // data table customizations |
14 | p-table { | 20 | p-table { |
15 | .ui-table-caption { | 21 | .ui-table-caption { |