diff options
Diffstat (limited to 'client/src/app/+accounts')
9 files changed, 74 insertions, 198 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 deleted file mode 100644 index f54ab846a..000000000 --- a/client/src/app/+accounts/account-search/account-search.component.ts +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | import { forkJoin, Subscription } from 'rxjs' | ||
2 | import { first, tap } from 'rxjs/operators' | ||
3 | import { Component, ComponentFactoryResolver, 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: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ] | ||
15 | }) | ||
16 | export class AccountSearchComponent extends AbstractVideoList implements OnInit, OnDestroy { | ||
17 | titlePage: string | ||
18 | loadOnInit = false | ||
19 | loadUserVideoPreferences = true | ||
20 | |||
21 | search = '' | ||
22 | filter: VideoFilter = null | ||
23 | |||
24 | private account: Account | ||
25 | private accountSub: Subscription | ||
26 | |||
27 | constructor ( | ||
28 | protected router: Router, | ||
29 | protected serverService: ServerService, | ||
30 | protected route: ActivatedRoute, | ||
31 | protected authService: AuthService, | ||
32 | protected userService: UserService, | ||
33 | protected notifier: Notifier, | ||
34 | protected confirmService: ConfirmService, | ||
35 | protected screenService: ScreenService, | ||
36 | protected storageService: LocalStorageService, | ||
37 | protected cfr: ComponentFactoryResolver, | ||
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 = forkJoin([ | ||
51 | this.accountService.accountLoaded.pipe(first()), | ||
52 | this.onUserLoadedSubject.pipe(first()) | ||
53 | ]).subscribe(([ account ]) => { | ||
54 | this.account = account | ||
55 | |||
56 | this.reloadVideos() | ||
57 | }) | ||
58 | } | ||
59 | |||
60 | ngOnDestroy () { | ||
61 | if (this.accountSub) this.accountSub.unsubscribe() | ||
62 | |||
63 | super.ngOnDestroy() | ||
64 | } | ||
65 | |||
66 | updateSearch (value: string) { | ||
67 | this.search = value | ||
68 | |||
69 | if (!this.search) { | ||
70 | this.router.navigate([ '../videos' ], { relativeTo: this.route }) | ||
71 | return | ||
72 | } | ||
73 | |||
74 | this.videos = [] | ||
75 | this.reloadVideos() | ||
76 | } | ||
77 | |||
78 | getVideosObservable (page: number) { | ||
79 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) | ||
80 | const options = { | ||
81 | account: this.account, | ||
82 | videoPagination: newPagination, | ||
83 | sort: this.sort, | ||
84 | nsfwPolicy: this.nsfwPolicy, | ||
85 | videoFilter: this.filter, | ||
86 | search: this.search | ||
87 | } | ||
88 | |||
89 | return this.videoService | ||
90 | .getAccountVideos(options) | ||
91 | .pipe( | ||
92 | tap(({ total }) => { | ||
93 | this.titlePage = this.search | ||
94 | ? $localize`Published ${total} videos matching "${this.search}"` | ||
95 | : $localize`Published ${total} videos` | ||
96 | }) | ||
97 | ) | ||
98 | } | ||
99 | |||
100 | toggleModerationDisplay () { | ||
101 | this.filter = this.buildLocalFilter(this.filter, null) | ||
102 | |||
103 | this.reloadVideos() | ||
104 | } | ||
105 | |||
106 | generateSyndicationList () { | ||
107 | /* method disabled */ | ||
108 | throw new Error('Method not implemented.') | ||
109 | } | ||
110 | } | ||
diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html index 922608127..105bc12c3 100644 --- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | <div class="no-results" i18n *ngIf="channelPagination.totalItems === 0">This account does not have channels.</div> | 5 | <div class="no-results" i18n *ngIf="channelPagination.totalItems === 0">This account does not have channels.</div> |
6 | 6 | ||
7 | <div class="channels" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onChannelDataSubject.asObservable()"> | 7 | <div class="channels" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [dataObservable]="onChannelDataSubject.asObservable()"> |
8 | <div class="channel" *ngFor="let videoChannel of videoChannels"> | 8 | <div class="channel" *ngFor="let videoChannel of videoChannels"> |
9 | 9 | ||
10 | <div class="channel-avatar-row"> | 10 | <div class="channel-avatar-row"> |
diff --git a/client/src/app/+accounts/account-videos/account-videos.component.html b/client/src/app/+accounts/account-videos/account-videos.component.html new file mode 100644 index 000000000..5b4b0937f --- /dev/null +++ b/client/src/app/+accounts/account-videos/account-videos.component.html | |||
@@ -0,0 +1,20 @@ | |||
1 | <my-videos-list | ||
2 | *ngIf="account" | ||
3 | |||
4 | [title]="title" | ||
5 | [displayTitle]="false" | ||
6 | |||
7 | [getVideosObservableFunction]="getVideosObservableFunction" | ||
8 | [getSyndicationItemsFunction]="getSyndicationItemsFunction" | ||
9 | |||
10 | [defaultSort]="defaultSort" | ||
11 | |||
12 | [displayFilters]="true" | ||
13 | [displayModerationBlock]="true" | ||
14 | [displayAsRow]="displayAsRow()" | ||
15 | |||
16 | [loadUserVideoPreferences]="true" | ||
17 | |||
18 | [disabled]="disabled" | ||
19 | > | ||
20 | </my-videos-list> | ||
diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts index 4ab6d2147..13d1f857d 100644 --- a/client/src/app/+accounts/account-videos/account-videos.component.ts +++ b/client/src/app/+accounts/account-videos/account-videos.component.ts | |||
@@ -1,96 +1,69 @@ | |||
1 | import { forkJoin, Subscription } from 'rxjs' | 1 | import { Subscription } from 'rxjs' |
2 | import { first } from 'rxjs/operators' | 2 | import { first } from 'rxjs/operators' |
3 | import { Component, ComponentFactoryResolver, OnDestroy, OnInit } from '@angular/core' | 3 | import { Component, OnDestroy, OnInit } from '@angular/core' |
4 | import { ActivatedRoute, Router } from '@angular/router' | 4 | import { ComponentPaginationLight, DisableForReuseHook, ScreenService } from '@app/core' |
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' | 5 | import { Account, AccountService, VideoService } from '@app/shared/shared-main' |
8 | import { AbstractVideoList } from '@app/shared/shared-video-miniature' | 6 | import { VideoFilters } from '@app/shared/shared-video-miniature' |
9 | import { VideoFilter } from '@shared/models' | 7 | import { VideoSortField } from '@shared/models' |
10 | 8 | ||
11 | @Component({ | 9 | @Component({ |
12 | selector: 'my-account-videos', | 10 | selector: 'my-account-videos', |
13 | templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html', | 11 | templateUrl: './account-videos.component.html' |
14 | styleUrls: [ | ||
15 | '../../shared/shared-video-miniature/abstract-video-list.scss' | ||
16 | ] | ||
17 | }) | 12 | }) |
18 | export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { | 13 | export class AccountVideosComponent implements OnInit, OnDestroy, DisableForReuseHook { |
19 | // No value because we don't want a page title | 14 | getVideosObservableFunction = this.getVideosObservable.bind(this) |
20 | titlePage: string | 15 | getSyndicationItemsFunction = this.getSyndicationItems.bind(this) |
21 | loadOnInit = false | ||
22 | loadUserVideoPreferences = true | ||
23 | 16 | ||
24 | filter: VideoFilter = null | 17 | title = $localize`Videos` |
18 | defaultSort = '-publishedAt' as VideoSortField | ||
19 | |||
20 | account: Account | ||
21 | disabled = false | ||
25 | 22 | ||
26 | private account: Account | ||
27 | private accountSub: Subscription | 23 | private accountSub: Subscription |
28 | 24 | ||
29 | constructor ( | 25 | constructor ( |
30 | protected router: Router, | 26 | private screenService: ScreenService, |
31 | protected serverService: ServerService, | ||
32 | protected route: ActivatedRoute, | ||
33 | protected authService: AuthService, | ||
34 | protected userService: UserService, | ||
35 | protected notifier: Notifier, | ||
36 | protected confirmService: ConfirmService, | ||
37 | protected screenService: ScreenService, | ||
38 | protected storageService: LocalStorageService, | ||
39 | private accountService: AccountService, | 27 | private accountService: AccountService, |
40 | private videoService: VideoService, | 28 | private videoService: VideoService |
41 | protected cfr: ComponentFactoryResolver | ||
42 | ) { | 29 | ) { |
43 | super() | ||
44 | } | 30 | } |
45 | 31 | ||
46 | ngOnInit () { | 32 | ngOnInit () { |
47 | super.ngOnInit() | ||
48 | |||
49 | this.enableAllFilterIfPossible() | ||
50 | |||
51 | // Parent get the account for us | 33 | // Parent get the account for us |
52 | this.accountSub = forkJoin([ | 34 | this.accountService.accountLoaded.pipe(first()) |
53 | this.accountService.accountLoaded.pipe(first()), | 35 | .subscribe(account => this.account = account) |
54 | this.onUserLoadedSubject.pipe(first()) | ||
55 | ]).subscribe(([ account ]) => { | ||
56 | this.account = account | ||
57 | |||
58 | this.reloadVideos() | ||
59 | this.generateSyndicationList() | ||
60 | }) | ||
61 | } | 36 | } |
62 | 37 | ||
63 | ngOnDestroy () { | 38 | ngOnDestroy () { |
64 | if (this.accountSub) this.accountSub.unsubscribe() | 39 | if (this.accountSub) this.accountSub.unsubscribe() |
65 | |||
66 | super.ngOnDestroy() | ||
67 | } | 40 | } |
68 | 41 | ||
69 | getVideosObservable (page: number) { | 42 | getVideosObservable (pagination: ComponentPaginationLight, filters: VideoFilters) { |
70 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) | ||
71 | const options = { | 43 | const options = { |
44 | ...filters.toVideosAPIObject(), | ||
45 | |||
46 | videoPagination: pagination, | ||
72 | account: this.account, | 47 | account: this.account, |
73 | videoPagination: newPagination, | 48 | skipCount: true |
74 | sort: this.sort, | ||
75 | nsfwPolicy: this.nsfwPolicy, | ||
76 | videoFilter: this.filter | ||
77 | } | 49 | } |
78 | 50 | ||
79 | return this.videoService | 51 | return this.videoService.getAccountVideos(options) |
80 | .getAccountVideos(options) | ||
81 | } | 52 | } |
82 | 53 | ||
83 | toggleModerationDisplay () { | 54 | getSyndicationItems () { |
84 | this.filter = this.buildLocalFilter(this.filter, null) | 55 | return this.videoService.getAccountFeedUrls(this.account.id) |
56 | } | ||
85 | 57 | ||
86 | this.reloadVideos() | 58 | displayAsRow () { |
59 | return this.screenService.isInMobileView() | ||
87 | } | 60 | } |
88 | 61 | ||
89 | generateSyndicationList () { | 62 | disableForReuse () { |
90 | this.syndicationItems = this.videoService.getAccountFeedUrls(this.account.id) | 63 | this.disabled = true |
91 | } | 64 | } |
92 | 65 | ||
93 | displayAsRow () { | 66 | enabledForReuse () { |
94 | return this.screenService.isInMobileView() | 67 | this.disabled = false |
95 | } | 68 | } |
96 | } | 69 | } |
diff --git a/client/src/app/+accounts/accounts-routing.module.ts b/client/src/app/+accounts/accounts-routing.module.ts index 2f3792a8d..d80df2293 100644 --- a/client/src/app/+accounts/accounts-routing.module.ts +++ b/client/src/app/+accounts/accounts-routing.module.ts | |||
@@ -1,6 +1,5 @@ | |||
1 | import { NgModule } from '@angular/core' | 1 | import { NgModule } from '@angular/core' |
2 | import { RouterModule, Routes } from '@angular/router' | 2 | import { RouterModule, Routes } from '@angular/router' |
3 | import { AccountSearchComponent } from './account-search/account-search.component' | ||
4 | import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' | 3 | import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' |
5 | import { AccountVideosComponent } from './account-videos/account-videos.component' | 4 | import { AccountVideosComponent } from './account-videos/account-videos.component' |
6 | import { AccountsComponent } from './accounts.component' | 5 | import { AccountsComponent } from './accounts.component' |
@@ -41,14 +40,11 @@ const accountsRoutes: Routes = [ | |||
41 | } | 40 | } |
42 | } | 41 | } |
43 | }, | 42 | }, |
43 | |||
44 | // Old URL redirection | ||
44 | { | 45 | { |
45 | path: 'search', | 46 | path: 'search', |
46 | component: AccountSearchComponent, | 47 | redirectTo: 'videos' |
47 | data: { | ||
48 | meta: { | ||
49 | title: $localize`Search videos within account` | ||
50 | } | ||
51 | } | ||
52 | } | 48 | } |
53 | ] | 49 | ] |
54 | } | 50 | } |
diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html index 0906992fe..245edfd58 100644 --- a/client/src/app/+accounts/accounts.component.html +++ b/client/src/app/+accounts/accounts.component.html | |||
@@ -66,7 +66,7 @@ | |||
66 | </div> | 66 | </div> |
67 | </div> | 67 | </div> |
68 | 68 | ||
69 | <div class="links"> | 69 | <div class="links" [ngClass]="{ 'on-channel-page': isOnChannelPage() }"> |
70 | <ng-template #linkTemplate let-item="item"> | 70 | <ng-template #linkTemplate let-item="item"> |
71 | <a [routerLink]="item.routerLink" routerLinkActive="active" class="title-page">{{ item.label }}</a> | 71 | <a [routerLink]="item.routerLink" routerLinkActive="active" class="title-page">{{ item.label }}</a> |
72 | </ng-template> | 72 | </ng-template> |
@@ -81,7 +81,7 @@ | |||
81 | ></my-simple-search-input> | 81 | ></my-simple-search-input> |
82 | </div> | 82 | </div> |
83 | 83 | ||
84 | <router-outlet (activate)="onOutletLoaded($event)"></router-outlet> | 84 | <router-outlet></router-outlet> |
85 | </div> | 85 | </div> |
86 | 86 | ||
87 | <ng-container *ngIf="prependModerationActions"> | 87 | <ng-container *ngIf="prependModerationActions"> |
diff --git a/client/src/app/+accounts/accounts.component.scss b/client/src/app/+accounts/accounts.component.scss index 4c1f94024..c4e2159d1 100644 --- a/client/src/app/+accounts/accounts.component.scss +++ b/client/src/app/+accounts/accounts.component.scss | |||
@@ -20,7 +20,10 @@ | |||
20 | display: flex; | 20 | display: flex; |
21 | justify-content: space-between; | 21 | justify-content: space-between; |
22 | align-items: center; | 22 | align-items: center; |
23 | max-width: $max-channels-width; | 23 | |
24 | &.on-channel-page { | ||
25 | max-width: $max-channels-width; | ||
26 | } | ||
24 | 27 | ||
25 | simple-search-input { | 28 | simple-search-input { |
26 | @include margin-left(auto); | 29 | @include margin-left(auto); |
diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts index 733cff8d5..e90816c5a 100644 --- a/client/src/app/+accounts/accounts.component.ts +++ b/client/src/app/+accounts/accounts.component.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Subscription } from 'rxjs' | 1 | import { Subscription } from 'rxjs' |
2 | import { catchError, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators' | 2 | import { catchError, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators' |
3 | import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core' | 3 | import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core' |
4 | import { ActivatedRoute } from '@angular/router' | 4 | import { ActivatedRoute, Router } from '@angular/router' |
5 | import { AuthService, MarkdownService, Notifier, RedirectService, RestExtractor, ScreenService, UserService } from '@app/core' | 5 | import { AuthService, MarkdownService, Notifier, RedirectService, RestExtractor, ScreenService, UserService } from '@app/core' |
6 | import { | 6 | import { |
7 | Account, | 7 | Account, |
@@ -14,7 +14,6 @@ import { | |||
14 | } from '@app/shared/shared-main' | 14 | } from '@app/shared/shared-main' |
15 | import { AccountReportComponent } from '@app/shared/shared-moderation' | 15 | import { AccountReportComponent } from '@app/shared/shared-moderation' |
16 | import { HttpStatusCode, User, UserRight } from '@shared/models' | 16 | import { HttpStatusCode, User, UserRight } from '@shared/models' |
17 | import { AccountSearchComponent } from './account-search/account-search.component' | ||
18 | 17 | ||
19 | @Component({ | 18 | @Component({ |
20 | templateUrl: './accounts.component.html', | 19 | templateUrl: './accounts.component.html', |
@@ -23,8 +22,6 @@ import { AccountSearchComponent } from './account-search/account-search.componen | |||
23 | export class AccountsComponent implements OnInit, OnDestroy { | 22 | export class AccountsComponent implements OnInit, OnDestroy { |
24 | @ViewChild('accountReportModal') accountReportModal: AccountReportComponent | 23 | @ViewChild('accountReportModal') accountReportModal: AccountReportComponent |
25 | 24 | ||
26 | accountSearch: AccountSearchComponent | ||
27 | |||
28 | account: Account | 25 | account: Account |
29 | accountUser: User | 26 | accountUser: User |
30 | 27 | ||
@@ -45,6 +42,7 @@ export class AccountsComponent implements OnInit, OnDestroy { | |||
45 | 42 | ||
46 | constructor ( | 43 | constructor ( |
47 | private route: ActivatedRoute, | 44 | private route: ActivatedRoute, |
45 | private router: Router, | ||
48 | private userService: UserService, | 46 | private userService: UserService, |
49 | private accountService: AccountService, | 47 | private accountService: AccountService, |
50 | private videoChannelService: VideoChannelService, | 48 | private videoChannelService: VideoChannelService, |
@@ -128,16 +126,10 @@ export class AccountsComponent implements OnInit, OnDestroy { | |||
128 | return $localize`${count} subscribers` | 126 | return $localize`${count} subscribers` |
129 | } | 127 | } |
130 | 128 | ||
131 | onOutletLoaded (component: Component) { | ||
132 | if (component instanceof AccountSearchComponent) { | ||
133 | this.accountSearch = component | ||
134 | } else { | ||
135 | this.accountSearch = undefined | ||
136 | } | ||
137 | } | ||
138 | |||
139 | searchChanged (search: string) { | 129 | searchChanged (search: string) { |
140 | if (this.accountSearch) this.accountSearch.updateSearch(search) | 130 | const queryParams = { search } |
131 | |||
132 | this.router.navigate([ './videos' ], { queryParams, relativeTo: this.route, queryParamsHandling: 'merge' }) | ||
141 | } | 133 | } |
142 | 134 | ||
143 | onSearchInputDisplayChanged (displayed: boolean) { | 135 | onSearchInputDisplayChanged (displayed: boolean) { |
@@ -152,6 +144,10 @@ export class AccountsComponent implements OnInit, OnDestroy { | |||
152 | return !this.accountDescriptionExpanded && this.accountDescriptionHTML.length > 100 | 144 | return !this.accountDescriptionExpanded && this.accountDescriptionHTML.length > 100 |
153 | } | 145 | } |
154 | 146 | ||
147 | isOnChannelPage () { | ||
148 | return this.route.children[0].snapshot.url[0].path === 'video-channels' | ||
149 | } | ||
150 | |||
155 | private async onAccount (account: Account) { | 151 | private async onAccount (account: Account) { |
156 | this.accountFollowerTitle = $localize`${account.followersCount} direct account followers` | 152 | this.accountFollowerTitle = $localize`${account.followersCount} direct account followers` |
157 | 153 | ||
diff --git a/client/src/app/+accounts/accounts.module.ts b/client/src/app/+accounts/accounts.module.ts index 1bafc5141..aedc69b16 100644 --- a/client/src/app/+accounts/accounts.module.ts +++ b/client/src/app/+accounts/accounts.module.ts | |||
@@ -5,12 +5,11 @@ import { SharedMainModule } from '@app/shared/shared-main' | |||
5 | import { SharedModerationModule } from '@app/shared/shared-moderation' | 5 | import { SharedModerationModule } from '@app/shared/shared-moderation' |
6 | import { SharedUserSubscriptionModule } from '@app/shared/shared-user-subscription' | 6 | import { SharedUserSubscriptionModule } from '@app/shared/shared-user-subscription' |
7 | import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature' | 7 | import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature' |
8 | import { AccountSearchComponent } from './account-search/account-search.component' | 8 | import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module' |
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 { AccountsRoutingModule } from './accounts-routing.module' | 11 | import { AccountsRoutingModule } from './accounts-routing.module' |
12 | import { AccountsComponent } from './accounts.component' | 12 | import { AccountsComponent } from './accounts.component' |
13 | import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module' | ||
14 | 13 | ||
15 | @NgModule({ | 14 | @NgModule({ |
16 | imports: [ | 15 | imports: [ |
@@ -28,8 +27,7 @@ import { SharedActorImageModule } from '../shared/shared-actor-image/shared-acto | |||
28 | declarations: [ | 27 | declarations: [ |
29 | AccountsComponent, | 28 | AccountsComponent, |
30 | AccountVideosComponent, | 29 | AccountVideosComponent, |
31 | AccountVideoChannelsComponent, | 30 | AccountVideoChannelsComponent |
32 | AccountSearchComponent | ||
33 | ], | 31 | ], |
34 | 32 | ||
35 | exports: [ | 33 | exports: [ |