From 2e46eb97154da909b82d5efe1d336a3412594ff0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 3 May 2021 14:33:34 +0200 Subject: [PATCH] Refactor search filters --- .../followers-list.component.html | 14 ++-- .../followers-list.component.scss | 8 -- .../followers-list.component.ts | 6 +- .../following-list.component.html | 12 +-- .../following-list.component.scss | 8 -- .../following-list.component.ts | 6 +- .../video-redundancies-list.component.ts | 6 +- .../instance-account-blocklist.component.html | 14 ++-- .../video-block-list.component.html | 7 +- .../video-block-list.component.scss | 17 ---- .../video-block-list.component.ts | 17 ++-- .../video-comment-list.component.html | 7 +- .../video-comment-list.component.scss | 17 ---- .../video-comment-list.component.ts | 15 +--- .../app/+admin/system/jobs/jobs.component.ts | 6 +- .../users/user-list/user-list.component.html | 8 +- .../users/user-list/user-list.component.ts | 19 ++--- .../my-video-channels.component.html | 7 +- .../my-video-channels.component.ts | 46 ++++------- .../my-history/my-history.component.html | 32 +++----- .../my-history/my-history.component.ts | 79 ++++++++++--------- .../my-ownership/my-ownership.component.ts | 6 +- .../my-subscriptions.component.html | 7 +- .../my-subscriptions.component.scss | 1 + .../my-subscriptions.component.ts | 35 +++----- .../my-video-imports.component.ts | 2 +- .../my-video-playlists.component.html | 7 +- .../my-video-playlists.component.ts | 45 ++++------- .../my-videos/my-videos.component.html | 4 +- .../my-videos/my-videos.component.ts | 21 +++-- client/src/app/core/rest/rest-table.ts | 19 ++--- client/src/app/core/routing/index.ts | 1 - client/src/app/core/routing/route-filter.ts | 79 ------------------- .../abuse-list-table.component.html | 7 +- .../abuse-list-table.component.ts | 19 ++--- .../advanced-input-filter.component.html | 8 +- .../advanced-input-filter.component.ts | 77 ++++++++++++++++-- .../misc/top-menu-dropdown.component.scss | 4 +- .../account-blocklist.component.html | 9 +-- .../account-blocklist.component.scss | 10 --- .../account-blocklist.component.ts | 4 +- .../shared/shared-moderation/moderation.scss | 17 ---- .../server-blocklist.component.html | 14 ++-- .../server-blocklist.component.scss | 18 ----- .../server-blocklist.component.ts | 6 +- .../videos-selection.component.html | 4 +- .../videos-selection.component.ts | 3 + 47 files changed, 282 insertions(+), 496 deletions(-) delete mode 100644 client/src/app/core/routing/route-filter.ts diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html index 633de9677..c2e9a4df6 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.html +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html @@ -4,20 +4,16 @@
-
- - - Clear filters +
+
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.scss b/client/src/app/+admin/follows/followers-list/followers-list.component.scss index 12c0cd033..35f38aae0 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.scss +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.scss @@ -1,14 +1,6 @@ @import '_variables'; @import '_mixins'; -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - } -} - a { @include disable-default-a-behaviour; display: inline-block; diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts index 904e3c338..4a312f6aa 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.ts +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts @@ -59,7 +59,7 @@ export class FollowersListComponent extends RestTable implements OnInit { const handle = follow.follower.name + '@' + follow.follower.host this.notifier.success($localize`${handle} rejected from instance followers`) - this.loadData() + this.reloadData() }, err => { @@ -80,14 +80,14 @@ export class FollowersListComponent extends RestTable implements OnInit { const handle = follow.follower.name + '@' + follow.follower.host this.notifier.success($localize`${handle} removed from instance followers`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) ) } - protected loadData () { + protected reloadData () { this.followService.getFollowers({ pagination: this.pagination, sort: this.sort, search: this.search }) .subscribe( resultList => { diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html index f4e6a60fe..e7c0c9088 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.html +++ b/client/src/app/+admin/follows/following-list/following-list.component.html @@ -4,8 +4,9 @@ @@ -18,13 +19,8 @@
-
- - - Clear filters +
+
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.scss b/client/src/app/+admin/follows/following-list/following-list.component.scss index 797882d9a..9474b0a23 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.scss +++ b/client/src/app/+admin/follows/following-list/following-list.component.scss @@ -16,14 +16,6 @@ a { } } -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - } -} - .follow-button { @include create-button; } diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts index f34490cc8..b63fe08c0 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.ts +++ b/client/src/app/+admin/follows/following-list/following-list.component.ts @@ -45,7 +45,7 @@ export class FollowingListComponent extends RestTable implements OnInit { this.followService.follow(hosts).subscribe( () => { this.notifier.success($localize`Follow request(s) sent!`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) @@ -62,14 +62,14 @@ export class FollowingListComponent extends RestTable implements OnInit { this.followService.unfollow(follow).subscribe( () => { this.notifier.success($localize`You are not following ${follow.following.host} anymore.`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) ) } - protected loadData () { + protected reloadData () { this.followService.getFollowing({ pagination: this.pagination, sort: this.sort, search: this.search }) .subscribe( resultList => { diff --git a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts index d6fd1a1ab..3cd65dd6e 100644 --- a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts +++ b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts @@ -78,7 +78,7 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit this.pagination.start = 0 this.saveSelectLocalStorage() - this.loadData() + this.reloadData() } getRedundancyStrategy (redundancy: VideoRedundancy) { @@ -145,7 +145,7 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit .subscribe( () => { this.notifier.success($localize`Video redundancies removed!`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) @@ -153,7 +153,7 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit } - protected loadData () { + protected reloadData () { const options = { pagination: this.pagination, sort: this.sort, diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html index 84ce381cc..e3a3a8320 100644 --- a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html +++ b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html @@ -1,18 +1,14 @@
-
- - - Clear filters +
+
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html index cf2466bdb..d89c8f244 100644 --- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html +++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html @@ -4,8 +4,9 @@
- +
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss index b67e33cc1..068aa2aee 100644 --- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss +++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss @@ -5,23 +5,6 @@ my-global-icon { height: 24px; } -.input-group { - @include peertube-input-group(300px); - - .dropdown-toggle::after { - margin-left: 0; - } -} - -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - flex-grow: 1; - } -} - .badge { @include table-badge; } diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts index dfd8dc745..498d8321a 100644 --- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts +++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts @@ -2,9 +2,9 @@ import { SortMeta } from 'primeng/api' import { switchMap } from 'rxjs/operators' import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils' import { environment } from 'src/environments/environment' -import { AfterViewInit, Component, OnInit } from '@angular/core' +import { Component, OnInit } from '@angular/core' import { DomSanitizer } from '@angular/platform-browser' -import { ActivatedRoute, Params, Router } from '@angular/router' +import { ActivatedRoute, Router } from '@angular/router' import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' import { AdvancedInputFilter } from '@app/shared/shared-forms' import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' @@ -16,7 +16,7 @@ import { VideoBlacklist, VideoBlacklistType } from '@shared/models' templateUrl: './video-block-list.component.html', styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-block-list.component.scss' ] }) -export class VideoBlockListComponent extends RestTable implements OnInit, AfterViewInit { +export class VideoBlockListComponent extends RestTable implements OnInit { blocklist: (VideoBlacklist & { reasonHtml?: string, embedHtml?: string })[] = [] totalRecords = 0 sort: SortMeta = { field: 'createdAt', order: -1 } @@ -64,7 +64,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV ).subscribe( () => { this.notifier.success($localize`Video ${videoBlock.video.name} switched to manual block.`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) @@ -116,11 +116,6 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV }) this.initialize() - this.listenToSearchChange() - } - - ngAfterViewInit () { - if (this.search) this.setTableFilter(this.search, false) } getIdentifier () { @@ -144,7 +139,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV this.videoBlocklistService.unblockVideo(entry.video.id).subscribe( () => { this.notifier.success($localize`Video ${entry.video.name} unblocked.`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) @@ -162,7 +157,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV ) } - protected loadData () { + protected reloadData () { this.videoBlocklistService.listBlocks({ pagination: this.pagination, sort: this.sort, diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html index 5cc0ff137..9d9283536 100644 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html +++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html @@ -8,8 +8,9 @@ This view also shows comments from muted accounts.
- +
diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss index 5d97d9bdb..a6f931e3b 100644 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss +++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss @@ -11,23 +11,6 @@ my-global-icon { height: 24px; } -.input-group { - @include peertube-input-group(300px); - - .dropdown-toggle::after { - margin-left: 0; - } -} - -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - flex-grow: 1; - } -} - .video { display: flex; flex-direction: column; diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts index ebbbddb43..e2ae993b0 100644 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts +++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts @@ -13,9 +13,7 @@ import { FeedFormat, UserRight } from '@shared/models' templateUrl: './video-comment-list.component.html', styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ] }) -export class VideoCommentListComponent extends RestTable implements OnInit, AfterViewInit { - baseRoute = '/admin/moderation/video-comments/list' - +export class VideoCommentListComponent extends RestTable implements OnInit { comments: VideoCommentAdmin[] totalRecords = 0 sort: SortMeta = { field: 'createdAt', order: -1 } @@ -91,7 +89,6 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte ngOnInit () { this.initialize() - this.listenToSearchChange() this.bulkCommentActions = [ { @@ -103,10 +100,6 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte ] } - ngAfterViewInit () { - if (this.search) this.setTableFilter(this.search, false) - } - getIdentifier () { return 'VideoCommentListComponent' } @@ -119,7 +112,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte return this.selectedComments.length !== 0 } - protected loadData () { + protected reloadData () { this.videoCommentService.getAdminVideoComments({ pagination: this.pagination, sort: this.sort, @@ -147,7 +140,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte this.videoCommentService.deleteVideoComments(commentArgs).subscribe( () => { this.notifier.success($localize`${commentArgs.length} comments deleted.`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message), @@ -159,7 +152,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte private deleteComment (comment: VideoCommentAdmin) { this.videoCommentService.deleteVideoComment(comment.video.id, comment.id) .subscribe( - () => this.loadData(), + () => this.reloadData(), err => this.notifier.error(err.message) ) diff --git a/client/src/app/+admin/system/jobs/jobs.component.ts b/client/src/app/+admin/system/jobs/jobs.component.ts index 43578eedd..29ba95c5c 100644 --- a/client/src/app/+admin/system/jobs/jobs.component.ts +++ b/client/src/app/+admin/system/jobs/jobs.component.ts @@ -86,7 +86,7 @@ export class JobsComponent extends RestTable implements OnInit { onJobStateOrTypeChanged () { this.pagination.start = 0 - this.loadData() + this.reloadData() this.saveJobStateAndType() } @@ -104,10 +104,10 @@ export class JobsComponent extends RestTable implements OnInit { this.jobs = [] this.totalRecords = 0 - this.loadData() + this.reloadData() } - protected loadData () { + protected reloadData () { let jobState = this.jobState as JobState if (this.jobState === 'all') jobState = null diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html index 7170d7019..44d8a7e87 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.html +++ b/client/src/app/+admin/users/user-list/user-list.component.html @@ -1,7 +1,7 @@
- +
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index 435bc17d7..1c60adf89 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts @@ -1,5 +1,5 @@ import { SortMeta } from 'primeng/api' -import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core' +import { Component, OnInit, ViewChild } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService, UserService } from '@app/core' import { AdvancedInputFilter } from '@app/shared/shared-forms' @@ -19,7 +19,7 @@ type UserForList = User & { templateUrl: './user-list.component.html', styleUrls: [ './user-list.component.scss' ] }) -export class UserListComponent extends RestTable implements OnInit, AfterViewInit { +export class UserListComponent extends RestTable implements OnInit { @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent users: User[] = [] @@ -78,7 +78,6 @@ export class UserListComponent extends RestTable implements OnInit, AfterViewIni .subscribe(config => this.serverConfig = config) this.initialize() - this.listenToSearchChange() this.bulkUserActions = [ [ @@ -127,10 +126,6 @@ export class UserListComponent extends RestTable implements OnInit, AfterViewIni this.columns.push({ id: 'lastLoginDate', label: 'Last login' }) } - ngAfterViewInit () { - if (this.search) this.setTableFilter(this.search, false) - } - getIdentifier () { return 'UserListComponent' } @@ -174,7 +169,7 @@ export class UserListComponent extends RestTable implements OnInit, AfterViewIni } onUserChanged () { - this.loadData() + this.reloadData() } async unbanUsers (users: User[]) { @@ -185,7 +180,7 @@ export class UserListComponent extends RestTable implements OnInit, AfterViewIni .subscribe( () => { this.notifier.success($localize`${users.length} users unbanned.`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) @@ -207,7 +202,7 @@ export class UserListComponent extends RestTable implements OnInit, AfterViewIni this.userService.removeUser(users).subscribe( () => { this.notifier.success($localize`${users.length} users deleted.`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) @@ -218,7 +213,7 @@ export class UserListComponent extends RestTable implements OnInit, AfterViewIni this.userService.updateUsers(users, { emailVerified: true }).subscribe( () => { this.notifier.success($localize`${users.length} users email set as verified.`) - this.loadData() + this.reloadData() }, err => this.notifier.error(err.message) @@ -229,7 +224,7 @@ export class UserListComponent extends RestTable implements OnInit, AfterViewIni return this.selectedUsers.length !== 0 } - protected loadData () { + protected reloadData () { this.selectedUsers = [] this.userService.getUsers({ diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html index 2ed0c93d6..8d5eb04e2 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html @@ -5,12 +5,7 @@
-
- - - Clear filters -
+ diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts index f6ba50a48..9e3bf35b4 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts @@ -1,29 +1,26 @@ import { ChartData } from 'chart.js' import { max, maxBy, min, minBy } from 'lodash-es' -import { Subject } from 'rxjs' -import { debounceTime, mergeMap } from 'rxjs/operators' -import { Component, OnInit } from '@angular/core' -import { AuthService, ConfirmService, Notifier, ScreenService, User } from '@app/core' +import { mergeMap } from 'rxjs/operators' +import { Component } from '@angular/core' +import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core' import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' @Component({ templateUrl: './my-video-channels.component.html', styleUrls: [ './my-video-channels.component.scss' ] }) -export class MyVideoChannelsComponent implements OnInit { +export class MyVideoChannelsComponent { totalItems: number videoChannels: VideoChannel[] = [] + videoChannelsChartData: ChartData[] videoChannelsMinimumDailyViews = 0 videoChannelsMaximumDailyViews: number - channelsSearch: string - channelsSearchChanged = new Subject() - chartOptions: any - private user: User + search: string constructor ( private authService: AuthService, @@ -31,31 +28,15 @@ export class MyVideoChannelsComponent implements OnInit { private confirmService: ConfirmService, private videoChannelService: VideoChannelService, private screenService: ScreenService - ) {} - - ngOnInit () { - this.user = this.authService.getUser() - - this.loadVideoChannels() - - this.channelsSearchChanged - .pipe(debounceTime(500)) - .subscribe(() => { - this.loadVideoChannels() - }) - } + ) {} get isInSmallView () { return this.screenService.isInSmallView() } - resetSearch () { - this.channelsSearch = '' - this.onChannelsSearchChanged() - } - - onChannelsSearchChanged () { - this.channelsSearchChanged.next() + onSearch (search: string) { + this.search = search + this.loadVideoChannels() } async deleteVideoChannel (videoChannel: VideoChannel) { @@ -85,8 +66,11 @@ channel with the same name (${videoChannel.name})!`, private loadVideoChannels () { this.authService.userInformationLoaded - .pipe(mergeMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true, this.channelsSearch))) - .subscribe(res => { + .pipe(mergeMap(() => { + const user = this.authService.getUser() + + return this.videoChannelService.listAccountVideoChannels(user.account, null, true, this.search) + })).subscribe(res => { this.videoChannels = res.data this.totalItems = res.total diff --git a/client/src/app/+my-library/my-history/my-history.component.html b/client/src/app/+my-library/my-history/my-history.component.html index 9dec64645..45ca37e0d 100644 --- a/client/src/app/+my-library/my-history/my-history.component.html +++ b/client/src/app/+my-library/my-history/my-history.component.html @@ -5,14 +5,7 @@
-
- - - Clear filters -
+
@@ -26,14 +19,15 @@
- -
You don't have any video in your watch history yet.
- -
-
- -
-
+ diff --git a/client/src/app/+my-library/my-history/my-history.component.ts b/client/src/app/+my-library/my-history/my-history.component.ts index 1695bd7ad..ad83db7ab 100644 --- a/client/src/app/+my-library/my-history/my-history.component.ts +++ b/client/src/app/+my-library/my-history/my-history.component.ts @@ -1,36 +1,55 @@ -import { Component, ComponentFactoryResolver, OnDestroy, OnInit } from '@angular/core' +import { Subject } from 'rxjs' +import { tap } from 'rxjs/operators' +import { Component, ComponentFactoryResolver, OnInit, ViewChild } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { AuthService, ComponentPagination, ConfirmService, + DisableForReuseHook, LocalStorageService, Notifier, ScreenService, ServerService, + User, UserService } from '@app/core' import { immutableAssign } from '@app/helpers' -import { UserHistoryService } from '@app/shared/shared-main' -import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { Subject } from 'rxjs' -import { debounceTime, tap, distinctUntilChanged } from 'rxjs/operators' +import { UserHistoryService, Video } from '@app/shared/shared-main' +import { MiniatureDisplayOptions, VideosSelectionComponent } from '@app/shared/shared-video-miniature' @Component({ templateUrl: './my-history.component.html', styleUrls: [ './my-history.component.scss' ] }) -export class MyHistoryComponent extends AbstractVideoList implements OnInit, OnDestroy { +export class MyHistoryComponent implements OnInit, DisableForReuseHook { + @ViewChild('videosSelection', { static: true }) videosSelection: VideosSelectionComponent + titlePage: string pagination: ComponentPagination = { currentPage: 1, itemsPerPage: 5, totalItems: null } - videosHistoryEnabled: boolean - search: string - protected searchStream: Subject + videosHistoryEnabled: boolean + + miniatureDisplayOptions: MiniatureDisplayOptions = { + date: true, + views: true, + by: true, + privacyLabel: false, + privacyText: true, + state: true, + blacklistInfo: true + } + + getVideosObservableFunction = this.getVideosObservable.bind(this) + + user: User + + videos: Video[] = [] + search: string constructor ( protected router: Router, @@ -45,45 +64,31 @@ export class MyHistoryComponent extends AbstractVideoList implements OnInit, OnD private userHistoryService: UserHistoryService, protected cfr: ComponentFactoryResolver ) { - super() - this.titlePage = $localize`My watch history` } ngOnInit () { - super.ngOnInit() + this.user = this.authService.getUser() this.authService.userInformationLoaded - .subscribe(() => { - this.videosHistoryEnabled = this.authService.getUser().videosHistoryEnabled - }) - - this.searchStream = new Subject() - - this.searchStream - .pipe( - debounceTime(400), - distinctUntilChanged() - ) - .subscribe(search => { - this.search = search - this.reloadVideos() - }) + .subscribe(() => this.videosHistoryEnabled = this.user.videosHistoryEnabled) } - onSearch (event: Event) { - const target = event.target as HTMLInputElement - this.searchStream.next(target.value) + disableForReuse () { + this.videosSelection.disableForReuse() } - resetSearch () { - const searchInput = document.getElementById('history-search') as HTMLInputElement - searchInput.value = '' - this.searchStream.next('') + enabledForReuse () { + this.videosSelection.enabledForReuse() } - ngOnDestroy () { - super.ngOnDestroy() + reloadData () { + this.videosSelection.reloadVideos() + } + + onSearch (search: string) { + this.search = search + this.reloadData() } getVideosObservable (page: number) { @@ -129,7 +134,7 @@ export class MyHistoryComponent extends AbstractVideoList implements OnInit, OnD () => { this.notifier.success($localize`Videos history deleted`) - this.reloadVideos() + this.reloadData() }, err => this.notifier.error(err.message) diff --git a/client/src/app/+my-library/my-ownership/my-ownership.component.ts b/client/src/app/+my-library/my-ownership/my-ownership.component.ts index a938023b4..aaf028474 100644 --- a/client/src/app/+my-library/my-ownership/my-ownership.component.ts +++ b/client/src/app/+my-library/my-ownership/my-ownership.component.ts @@ -48,18 +48,18 @@ export class MyOwnershipComponent extends RestTable implements OnInit { } accepted () { - this.loadData() + this.reloadData() } refuse (videoChangeOwnership: VideoChangeOwnership) { this.videoOwnershipService.refuseOwnership(videoChangeOwnership.id) .subscribe( - () => this.loadData(), + () => this.reloadData(), err => this.notifier.error(err.message) ) } - protected loadData () { + protected reloadData () { return this.videoOwnershipService.getOwnershipChanges(this.pagination, this.sort) .subscribe( resultList => { diff --git a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html index 853d47fe6..f91cebacf 100644 --- a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html +++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html @@ -7,12 +7,7 @@
-
- - - Clear filters -
+
You don't have any subscription yet.
diff --git a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss index 53ceaa250..6c1ddf716 100644 --- a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss +++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss @@ -58,6 +58,7 @@ input[type=text] { .video-subscriptions-header { margin-bottom: 30px; + display: flex; } @media screen and (max-width: $small-view) { diff --git a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.ts b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.ts index 3b748eccf..1f4a931a0 100644 --- a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.ts +++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.ts @@ -1,6 +1,5 @@ import { Subject } from 'rxjs' -import { debounceTime } from 'rxjs/operators' -import { Component, OnInit } from '@angular/core' +import { Component } from '@angular/core' import { ComponentPagination, Notifier } from '@app/core' import { VideoChannel } from '@app/shared/shared-main' import { UserSubscriptionService } from '@app/shared/shared-user-subscription' @@ -9,7 +8,7 @@ import { UserSubscriptionService } from '@app/shared/shared-user-subscription' templateUrl: './my-subscriptions.component.html', styleUrls: [ './my-subscriptions.component.scss' ] }) -export class MySubscriptionsComponent implements OnInit { +export class MySubscriptionsComponent { videoChannels: VideoChannel[] = [] pagination: ComponentPagination = { @@ -20,34 +19,13 @@ export class MySubscriptionsComponent implements OnInit { onDataSubject = new Subject() - subscriptionsSearch: string - subscriptionsSearchChanged = new Subject() + search: string constructor ( private userSubscriptionService: UserSubscriptionService, private notifier: Notifier ) {} - ngOnInit () { - this.loadSubscriptions() - - this.subscriptionsSearchChanged - .pipe(debounceTime(500)) - .subscribe(() => { - this.pagination.currentPage = 1 - this.loadSubscriptions(false) - }) - } - - resetSearch () { - this.subscriptionsSearch = '' - this.onSubscriptionsSearchChanged() - } - - onSubscriptionsSearchChanged () { - this.subscriptionsSearchChanged.next() - } - onNearOfBottom () { // Last page if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return @@ -56,8 +34,13 @@ export class MySubscriptionsComponent implements OnInit { this.loadSubscriptions() } + onSearch (search: string) { + this.search = search + this.loadSubscriptions(false) + } + private loadSubscriptions (more = true) { - this.userSubscriptionService.listSubscriptions({ pagination: this.pagination, search: this.subscriptionsSearch }) + this.userSubscriptionService.listSubscriptions({ pagination: this.pagination, search: this.search }) .subscribe( res => { this.videoChannels = more diff --git a/client/src/app/+my-library/my-video-imports/my-video-imports.component.ts b/client/src/app/+my-library/my-video-imports/my-video-imports.component.ts index d6d7d7a1b..359535526 100644 --- a/client/src/app/+my-library/my-video-imports/my-video-imports.component.ts +++ b/client/src/app/+my-library/my-video-imports/my-video-imports.component.ts @@ -62,7 +62,7 @@ export class MyVideoImportsComponent extends RestTable implements OnInit { return '/videos/update/' + video.uuid } - protected loadData () { + protected reloadData () { this.videoImportService.getMyVideoImports(this.pagination, this.sort) .subscribe( resultList => { diff --git a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html index b88ea3db7..309afcf13 100644 --- a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html +++ b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html @@ -4,12 +4,7 @@
-
- - - Clear filters -
+ diff --git a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.ts b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.ts index f6d394923..d90102693 100644 --- a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.ts +++ b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.ts @@ -1,7 +1,7 @@ import { Subject } from 'rxjs' -import { debounceTime, mergeMap } from 'rxjs/operators' -import { Component, OnInit } from '@angular/core' -import { AuthService, ComponentPagination, ConfirmService, Notifier, User } from '@app/core' +import { mergeMap } from 'rxjs/operators' +import { Component } from '@angular/core' +import { AuthService, ComponentPagination, ConfirmService, Notifier } from '@app/core' import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist' import { VideoPlaylistType } from '@shared/models' @@ -9,10 +9,8 @@ import { VideoPlaylistType } from '@shared/models' templateUrl: './my-video-playlists.component.html', styleUrls: [ './my-video-playlists.component.scss' ] }) -export class MyVideoPlaylistsComponent implements OnInit { - videoPlaylistsSearch: string +export class MyVideoPlaylistsComponent { videoPlaylists: VideoPlaylist[] = [] - videoPlaylistSearchChanged = new Subject() pagination: ComponentPagination = { currentPage: 1, @@ -22,27 +20,14 @@ export class MyVideoPlaylistsComponent implements OnInit { onDataSubject = new Subject() - private user: User + search: string constructor ( private authService: AuthService, private notifier: Notifier, private confirmService: ConfirmService, private videoPlaylistService: VideoPlaylistService - ) {} - - ngOnInit () { - this.user = this.authService.getUser() - - this.loadVideoPlaylists() - - this.videoPlaylistSearchChanged - .pipe( - debounceTime(500)) - .subscribe(() => { - this.loadVideoPlaylists(true) - }) - } + ) {} async deleteVideoPlaylist (videoPlaylist: VideoPlaylist) { const res = await this.confirmService.confirm( @@ -76,22 +61,20 @@ export class MyVideoPlaylistsComponent implements OnInit { this.loadVideoPlaylists() } - resetSearch () { - this.videoPlaylistsSearch = '' - this.onVideoPlaylistSearchChanged() - } - - onVideoPlaylistSearchChanged () { - this.videoPlaylistSearchChanged.next() + onSearch (search: string) { + this.search = search + this.loadVideoPlaylists(true) } private loadVideoPlaylists (reset = false) { this.authService.userInformationLoaded .pipe(mergeMap(() => { - return this.videoPlaylistService.listAccountPlaylists(this.user.account, this.pagination, '-updatedAt', this.videoPlaylistsSearch) - })) - .subscribe(res => { + const user = this.authService.getUser() + + return this.videoPlaylistService.listAccountPlaylists(user.account, this.pagination, '-updatedAt', this.search) + })).subscribe(res => { if (reset) this.videoPlaylists = [] + this.videoPlaylists = this.videoPlaylists.concat(res.data) this.pagination.totalItems = res.total diff --git a/client/src/app/+my-library/my-videos/my-videos.component.html b/client/src/app/+my-library/my-videos/my-videos.component.html index 7c1cdb511..8d8b482ad 100644 --- a/client/src/app/+my-library/my-videos/my-videos.component.html +++ b/client/src/app/+my-library/my-videos/my-videos.component.html @@ -19,7 +19,7 @@
- +
+ Clear filters
diff --git a/client/src/app/shared/shared-forms/advanced-input-filter.component.ts b/client/src/app/shared/shared-forms/advanced-input-filter.component.ts index 394090751..1b0eed34b 100644 --- a/client/src/app/shared/shared-forms/advanced-input-filter.component.ts +++ b/client/src/app/shared/shared-forms/advanced-input-filter.component.ts @@ -1,27 +1,88 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core' -import { Params } from '@angular/router' +import * as debug from 'debug' +import { Subject } from 'rxjs' +import { debounceTime, distinctUntilChanged } from 'rxjs/operators' +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' +import { ActivatedRoute, Params, Router } from '@angular/router' export type AdvancedInputFilter = { label: string queryParams: Params } +const logger = debug('peertube:AdvancedInputFilterComponent') + @Component({ selector: 'my-advanced-input-filter', templateUrl: './advanced-input-filter.component.html', styleUrls: [ './advanced-input-filter.component.scss' ] }) -export class AdvancedInputFilterComponent { +export class AdvancedInputFilterComponent implements OnInit { @Input() filters: AdvancedInputFilter[] = [] - @Output() resetTableFilter = new EventEmitter() - @Output() search = new EventEmitter() + @Output() search = new EventEmitter() - onSearch (event: Event) { - this.search.emit(event) + searchValue: string + + private searchStream: Subject + + constructor ( + private route: ActivatedRoute, + private router: Router + ) { } + + ngOnInit () { + this.initSearchStream() + this.listenToRouteSearchChange() + } + + onInputSearch (event: Event) { + this.updateSearch((event.target as HTMLInputElement).value) } onResetTableFilter () { - this.resetTableFilter.emit() + this.updateSearch('') + } + + hasFilters () { + return this.filters.length !== 0 + } + + private updateSearch (value: string) { + this.searchValue = value + this.searchStream.next(this.searchValue) + } + + private listenToRouteSearchChange () { + this.route.queryParams + .subscribe(params => { + const search = params.search || '' + + logger('On route search change "%s".', search) + + this.updateSearch(search) + }) + } + + private initSearchStream () { + this.searchStream = new Subject() + + this.searchStream + .pipe( + debounceTime(200), + distinctUntilChanged() + ) + .subscribe(() => { + logger('On search "%s".', this.searchValue) + + this.setQueryParams(this.searchValue) + this.search.emit(this.searchValue) + }) + } + + private setQueryParams (search: string) { + const queryParams: Params = {} + + if (search) Object.assign(queryParams, { search }) + this.router.navigate([ ], { queryParams }) } } diff --git a/client/src/app/shared/shared-main/misc/top-menu-dropdown.component.scss b/client/src/app/shared/shared-main/misc/top-menu-dropdown.component.scss index 84dd7dce3..ffabb3646 100644 --- a/client/src/app/shared/shared-main/misc/top-menu-dropdown.component.scss +++ b/client/src/app/shared/shared-main/misc/top-menu-dropdown.component.scss @@ -11,12 +11,12 @@ } } -::ng-deep .dropdown-toggle::after { +.sub-menu ::ng-deep .dropdown-toggle::after { position: relative; top: 2px; } -::ng-deep .dropdown-menu { +.sub-menu ::ng-deep .dropdown-menu { margin-top: 0 !important; } diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.html b/client/src/app/shared/shared-moderation/account-blocklist.component.html index e914a7c3c..a9fac0810 100644 --- a/client/src/app/shared/shared-moderation/account-blocklist.component.html +++ b/client/src/app/shared/shared-moderation/account-blocklist.component.html @@ -11,13 +11,8 @@ >
-
- - - Clear filters +
+
diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.scss b/client/src/app/shared/shared-moderation/account-blocklist.component.scss index 63a9df823..bc441811e 100644 --- a/client/src/app/shared/shared-moderation/account-blocklist.component.scss +++ b/client/src/app/shared/shared-moderation/account-blocklist.component.scss @@ -1,16 +1,6 @@ @import '_variables'; @import '_mixins'; -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - - flex-grow: 1; - } -} - .chip { @include chip; } diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.ts b/client/src/app/shared/shared-moderation/account-blocklist.component.ts index 1bce65bf0..1146aeec0 100644 --- a/client/src/app/shared/shared-moderation/account-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/account-blocklist.component.ts @@ -44,12 +44,12 @@ export class GenericAccountBlocklistComponent extends RestTable implements OnIni : $localize`Account ${blockedAccount.nameWithHost} unmuted by your instance.` ) - this.loadData() + this.reloadData() } ) } - protected loadData () { + protected reloadData () { const operation = this.mode === BlocklistComponentType.Account ? this.blocklistService.getUserAccountBlocklist({ pagination: this.pagination, diff --git a/client/src/app/shared/shared-moderation/moderation.scss b/client/src/app/shared/shared-moderation/moderation.scss index ab43d8457..b13d06f03 100644 --- a/client/src/app/shared/shared-moderation/moderation.scss +++ b/client/src/app/shared/shared-moderation/moderation.scss @@ -39,27 +39,10 @@ } } -.input-group { - @include peertube-input-group(300px); - - .dropdown-toggle::after { - margin-left: 0; - } -} - .chip { @include chip; } -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - flex-grow: 1; - } -} - my-action-dropdown.show { ::ng-deep .dropdown-root { display: block !important; diff --git a/client/src/app/shared/shared-moderation/server-blocklist.component.html b/client/src/app/shared/shared-moderation/server-blocklist.component.html index 537186f05..c6d29bb21 100644 --- a/client/src/app/shared/shared-moderation/server-blocklist.component.html +++ b/client/src/app/shared/shared-moderation/server-blocklist.component.html @@ -4,8 +4,9 @@ @@ -18,13 +19,8 @@
-
- - - Clear filters +
+
diff --git a/client/src/app/shared/shared-moderation/server-blocklist.component.scss b/client/src/app/shared/shared-moderation/server-blocklist.component.scss index af21c0c20..a22972c5f 100644 --- a/client/src/app/shared/shared-moderation/server-blocklist.component.scss +++ b/client/src/app/shared/shared-moderation/server-blocklist.component.scss @@ -16,15 +16,6 @@ a { } } -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - flex-grow: 1; - } -} - .unblock-button { @include peertube-button; @include grey-button; @@ -34,15 +25,6 @@ a { @include create-button; } -.caption { - justify-content: flex-end; - - input { - @include peertube-input-text(250px); - flex-grow: 1; - } -} - .chip { @include chip; } diff --git a/client/src/app/shared/shared-moderation/server-blocklist.component.ts b/client/src/app/shared/shared-moderation/server-blocklist.component.ts index 546fd53c3..274d8f6e9 100644 --- a/client/src/app/shared/shared-moderation/server-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/server-blocklist.component.ts @@ -46,7 +46,7 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit : $localize`Instance ${host} unmuted by your instance.` ) - this.loadData() + this.reloadData() } ) } @@ -69,13 +69,13 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit : $localize`Instance ${domain} muted by your instance.` ) - this.loadData() + this.reloadData() } ) }) } - protected loadData () { + protected reloadData () { const operation = this.mode === BlocklistComponentType.Account ? this.blocklistService.getUserServerBlocklist({ pagination: this.pagination, diff --git a/client/src/app/shared/shared-video-miniature/videos-selection.component.html b/client/src/app/shared/shared-video-miniature/videos-selection.component.html index dec9e99f3..4ee90ce7f 100644 --- a/client/src/app/shared/shared-video-miniature/videos-selection.component.html +++ b/client/src/app/shared/shared-video-miniature/videos-selection.component.html @@ -1,9 +1,9 @@ -
No results.
+
{{ noResultMessage }}
-
+
diff --git a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts index f8c3800d7..d64ee9b98 100644 --- a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts +++ b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts @@ -31,6 +31,9 @@ export class VideosSelectionComponent extends AbstractVideoList implements OnIni @Input() pagination: ComponentPagination @Input() titlePage: string @Input() miniatureDisplayOptions: MiniatureDisplayOptions + @Input() noResultMessage = $localize`No results.` + @Input() enableSelection = true + @Input() loadOnInit = true @Input() getVideosObservableFunction: (page: number, sort?: VideoSortField) => Observable>