diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2021-01-19 13:43:33 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-19 13:43:33 +0100 |
commit | 370240824e2fb28b314255f6c23f5ea7d6b08625 (patch) | |
tree | 6d4350fd93ea0b960bd278a948cecbdfbd2b67d7 /client/src/app/+accounts | |
parent | 2264c1ceedcf27998108b8f8b706e51ed910d4fb (diff) | |
download | PeerTube-370240824e2fb28b314255f6c23f5ea7d6b08625.tar.gz PeerTube-370240824e2fb28b314255f6c23f5ea7d6b08625.tar.zst PeerTube-370240824e2fb28b314255f6c23f5ea7d6b08625.zip |
Allow users/visitors to search through an account's videos (#3589)
* WIP: account search
* add search to account view
* add tests for account search
Diffstat (limited to 'client/src/app/+accounts')
5 files changed, 146 insertions, 14 deletions
diff --git a/client/src/app/+accounts/account-search/account-search.component.ts b/client/src/app/+accounts/account-search/account-search.component.ts new file mode 100644 index 000000000..10c7a12d8 --- /dev/null +++ b/client/src/app/+accounts/account-search/account-search.component.ts | |||
@@ -0,0 +1,104 @@ | |||
1 | import { Subscription } from 'rxjs' | ||
2 | import { first, tap } from 'rxjs/operators' | ||
3 | import { Component, OnDestroy, OnInit } from '@angular/core' | ||
4 | import { ActivatedRoute, Router } from '@angular/router' | ||
5 | import { AuthService, ConfirmService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' | ||
6 | import { immutableAssign } from '@app/helpers' | ||
7 | import { Account, AccountService, VideoService } from '@app/shared/shared-main' | ||
8 | import { AbstractVideoList } from '@app/shared/shared-video-miniature' | ||
9 | import { VideoFilter } from '@shared/models' | ||
10 | |||
11 | @Component({ | ||
12 | selector: 'my-account-search', | ||
13 | templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html', | ||
14 | styleUrls: [ | ||
15 | '../../shared/shared-video-miniature/abstract-video-list.scss' | ||
16 | ] | ||
17 | }) | ||
18 | export class AccountSearchComponent extends AbstractVideoList implements OnInit, OnDestroy { | ||
19 | titlePage: string | ||
20 | loadOnInit = false | ||
21 | |||
22 | search = '' | ||
23 | filter: VideoFilter = null | ||
24 | |||
25 | private account: Account | ||
26 | private accountSub: Subscription | ||
27 | |||
28 | constructor ( | ||
29 | protected router: Router, | ||
30 | protected serverService: ServerService, | ||
31 | protected route: ActivatedRoute, | ||
32 | protected authService: AuthService, | ||
33 | protected userService: UserService, | ||
34 | protected notifier: Notifier, | ||
35 | protected confirmService: ConfirmService, | ||
36 | protected screenService: ScreenService, | ||
37 | protected storageService: LocalStorageService, | ||
38 | private accountService: AccountService, | ||
39 | private videoService: VideoService | ||
40 | ) { | ||
41 | super() | ||
42 | } | ||
43 | |||
44 | ngOnInit () { | ||
45 | super.ngOnInit() | ||
46 | |||
47 | this.enableAllFilterIfPossible() | ||
48 | |||
49 | // Parent get the account for us | ||
50 | this.accountSub = this.accountService.accountLoaded | ||
51 | .pipe(first()) | ||
52 | .subscribe(account => { | ||
53 | this.account = account | ||
54 | |||
55 | this.reloadVideos() | ||
56 | this.generateSyndicationList() | ||
57 | }) | ||
58 | } | ||
59 | |||
60 | ngOnDestroy () { | ||
61 | if (this.accountSub) this.accountSub.unsubscribe() | ||
62 | |||
63 | super.ngOnDestroy() | ||
64 | } | ||
65 | |||
66 | updateSearch (value: string) { | ||
67 | if (value === '') this.router.navigate(['../videos'], { relativeTo: this.route }) | ||
68 | this.search = value | ||
69 | |||
70 | this.reloadVideos() | ||
71 | } | ||
72 | |||
73 | getVideosObservable (page: number) { | ||
74 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) | ||
75 | const options = { | ||
76 | account: this.account, | ||
77 | videoPagination: newPagination, | ||
78 | sort: this.sort, | ||
79 | nsfwPolicy: this.nsfwPolicy, | ||
80 | videoFilter: this.filter, | ||
81 | search: this.search | ||
82 | } | ||
83 | |||
84 | return this.videoService | ||
85 | .getAccountVideos(options) | ||
86 | .pipe( | ||
87 | tap(({ total }) => { | ||
88 | this.titlePage = this.search | ||
89 | ? $localize`Published ${total} videos matching "${this.search}"` | ||
90 | : $localize`Published ${total} videos` | ||
91 | }) | ||
92 | ) | ||
93 | } | ||
94 | |||
95 | toggleModerationDisplay () { | ||
96 | this.filter = this.buildLocalFilter(this.filter, null) | ||
97 | |||
98 | this.reloadVideos() | ||
99 | } | ||
100 | |||
101 | generateSyndicationList () { | ||
102 | /* disable syndication */ | ||
103 | } | ||
104 | } | ||
diff --git a/client/src/app/+accounts/accounts-routing.module.ts b/client/src/app/+accounts/accounts-routing.module.ts index d2ca784b0..15937a67b 100644 --- a/client/src/app/+accounts/accounts-routing.module.ts +++ b/client/src/app/+accounts/accounts-routing.module.ts | |||
@@ -5,6 +5,7 @@ import { AccountsComponent } from './accounts.component' | |||
5 | import { AccountVideosComponent } from './account-videos/account-videos.component' | 5 | import { AccountVideosComponent } from './account-videos/account-videos.component' |
6 | import { AccountAboutComponent } from './account-about/account-about.component' | 6 | import { AccountAboutComponent } from './account-about/account-about.component' |
7 | import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' | 7 | import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' |
8 | import { AccountSearchComponent } from './account-search/account-search.component' | ||
8 | 9 | ||
9 | const accountsRoutes: Routes = [ | 10 | const accountsRoutes: Routes = [ |
10 | { | 11 | { |
@@ -22,6 +23,24 @@ const accountsRoutes: Routes = [ | |||
22 | pathMatch: 'full' | 23 | pathMatch: 'full' |
23 | }, | 24 | }, |
24 | { | 25 | { |
26 | path: 'video-channels', | ||
27 | component: AccountVideoChannelsComponent, | ||
28 | data: { | ||
29 | meta: { | ||
30 | title: $localize`Account video channels` | ||
31 | } | ||
32 | } | ||
33 | }, | ||
34 | { | ||
35 | path: 'about', | ||
36 | component: AccountAboutComponent, | ||
37 | data: { | ||
38 | meta: { | ||
39 | title: $localize`About account` | ||
40 | } | ||
41 | } | ||
42 | }, | ||
43 | { | ||
25 | path: 'videos', | 44 | path: 'videos', |
26 | component: AccountVideosComponent, | 45 | component: AccountVideosComponent, |
27 | data: { | 46 | data: { |
@@ -35,20 +54,11 @@ const accountsRoutes: Routes = [ | |||
35 | } | 54 | } |
36 | }, | 55 | }, |
37 | { | 56 | { |
38 | path: 'video-channels', | 57 | path: 'search', |
39 | component: AccountVideoChannelsComponent, | 58 | component: AccountSearchComponent, |
40 | data: { | 59 | data: { |
41 | meta: { | 60 | meta: { |
42 | title: $localize`Account video channels` | 61 | title: $localize`Search videos within account` |
43 | } | ||
44 | } | ||
45 | }, | ||
46 | { | ||
47 | path: 'about', | ||
48 | component: AccountAboutComponent, | ||
49 | data: { | ||
50 | meta: { | ||
51 | title: $localize`About account` | ||
52 | } | 62 | } |
53 | } | 63 | } |
54 | } | 64 | } |
diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html index 31c8e3a8e..5bd7b0824 100644 --- a/client/src/app/+accounts/accounts.component.html +++ b/client/src/app/+accounts/accounts.component.html | |||
@@ -44,11 +44,13 @@ | |||
44 | </ng-template> | 44 | </ng-template> |
45 | 45 | ||
46 | <list-overflow [items]="links" [itemTemplate]="linkTemplate"></list-overflow> | 46 | <list-overflow [items]="links" [itemTemplate]="linkTemplate"></list-overflow> |
47 | |||
48 | <simple-search-input (searchChanged)="searchChanged($event)" name="search-videos" i18n-placeholder placeholder="Search videos"></simple-search-input> | ||
47 | </div> | 49 | </div> |
48 | </div> | 50 | </div> |
49 | 51 | ||
50 | <div class="margin-content"> | 52 | <div class="margin-content"> |
51 | <router-outlet></router-outlet> | 53 | <router-outlet (activate)="onOutletLoaded($event)"></router-outlet> |
52 | </div> | 54 | </div> |
53 | </div> | 55 | </div> |
54 | 56 | ||
diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts index 4820eaf32..1458ea59c 100644 --- a/client/src/app/+accounts/accounts.component.ts +++ b/client/src/app/+accounts/accounts.component.ts | |||
@@ -7,6 +7,7 @@ import { Account, AccountService, DropdownAction, ListOverflowItem, VideoChannel | |||
7 | import { AccountReportComponent } from '@app/shared/shared-moderation' | 7 | import { AccountReportComponent } from '@app/shared/shared-moderation' |
8 | import { User, UserRight } from '@shared/models' | 8 | import { User, UserRight } from '@shared/models' |
9 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | 9 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' |
10 | import { AccountSearchComponent } from './account-search/account-search.component' | ||
10 | 11 | ||
11 | @Component({ | 12 | @Component({ |
12 | templateUrl: './accounts.component.html', | 13 | templateUrl: './accounts.component.html', |
@@ -14,6 +15,7 @@ import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | |||
14 | }) | 15 | }) |
15 | export class AccountsComponent implements OnInit, OnDestroy { | 16 | export class AccountsComponent implements OnInit, OnDestroy { |
16 | @ViewChild('accountReportModal') accountReportModal: AccountReportComponent | 17 | @ViewChild('accountReportModal') accountReportModal: AccountReportComponent |
18 | accountSearch: AccountSearchComponent | ||
17 | 19 | ||
18 | account: Account | 20 | account: Account |
19 | accountUser: User | 21 | accountUser: User |
@@ -99,6 +101,18 @@ export class AccountsComponent implements OnInit, OnDestroy { | |||
99 | return $localize`${count} subscribers` | 101 | return $localize`${count} subscribers` |
100 | } | 102 | } |
101 | 103 | ||
104 | onOutletLoaded (component: Component) { | ||
105 | if (component instanceof AccountSearchComponent) { | ||
106 | this.accountSearch = component | ||
107 | } else { | ||
108 | this.accountSearch = undefined | ||
109 | } | ||
110 | } | ||
111 | |||
112 | searchChanged (search: string) { | ||
113 | if (this.accountSearch) this.accountSearch.updateSearch(search) | ||
114 | } | ||
115 | |||
102 | private onAccount (account: Account) { | 116 | private onAccount (account: Account) { |
103 | this.prependModerationActions = undefined | 117 | this.prependModerationActions = undefined |
104 | 118 | ||
diff --git a/client/src/app/+accounts/accounts.module.ts b/client/src/app/+accounts/accounts.module.ts index 815360341..6da65cbc1 100644 --- a/client/src/app/+accounts/accounts.module.ts +++ b/client/src/app/+accounts/accounts.module.ts | |||
@@ -8,6 +8,7 @@ import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature' | |||
8 | import { AccountAboutComponent } from './account-about/account-about.component' | 8 | import { AccountAboutComponent } from './account-about/account-about.component' |
9 | import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' | 9 | import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' |
10 | import { AccountVideosComponent } from './account-videos/account-videos.component' | 10 | import { AccountVideosComponent } from './account-videos/account-videos.component' |
11 | import { AccountSearchComponent } from './account-search/account-search.component' | ||
11 | import { AccountsRoutingModule } from './accounts-routing.module' | 12 | import { AccountsRoutingModule } from './accounts-routing.module' |
12 | import { AccountsComponent } from './accounts.component' | 13 | import { AccountsComponent } from './accounts.component' |
13 | 14 | ||
@@ -27,7 +28,8 @@ import { AccountsComponent } from './accounts.component' | |||
27 | AccountsComponent, | 28 | AccountsComponent, |
28 | AccountVideosComponent, | 29 | AccountVideosComponent, |
29 | AccountVideoChannelsComponent, | 30 | AccountVideoChannelsComponent, |
30 | AccountAboutComponent | 31 | AccountAboutComponent, |
32 | AccountSearchComponent | ||
31 | ], | 33 | ], |
32 | 34 | ||
33 | exports: [ | 35 | exports: [ |