From: Chocobozzz Date: Wed, 25 Apr 2018 14:56:13 +0000 (+0200) Subject: Implement video channel views X-Git-Tag: v1.0.0-beta.4~19 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=170726f523ff48f89da45473fc53ca54784f43dd;p=oweals%2Fpeertube.git Implement video channel views --- diff --git a/client/src/app/+account/account-about/account-about.component.html b/client/src/app/+account/account-about/account-about.component.html deleted file mode 100644 index 003a8045e..000000000 --- a/client/src/app/+account/account-about/account-about.component.html +++ /dev/null @@ -1,12 +0,0 @@ -
-
-
Description
-
{{ getAccountDescription() }}
-
- -
-
Stats
- -
Joined {{ account.createdAt | date }}
-
-
\ No newline at end of file diff --git a/client/src/app/+account/account-about/account-about.component.scss b/client/src/app/+account/account-about/account-about.component.scss deleted file mode 100644 index b1be7d4ed..000000000 --- a/client/src/app/+account/account-about/account-about.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.small-title { - @include in-content-small-title; - - margin-bottom: 20px; -} diff --git a/client/src/app/+account/account-about/account-about.component.ts b/client/src/app/+account/account-about/account-about.component.ts deleted file mode 100644 index 8746875cb..000000000 --- a/client/src/app/+account/account-about/account-about.component.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Component, OnDestroy, OnInit } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { Location } from '@angular/common' -import { getParameterByName, immutableAssign } from '@app/shared/misc/utils' -import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { AuthService } from '../../core/auth' -import { ConfirmService } from '../../core/confirm' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoService } from '../../shared/video/video.service' -import { Account } from '@app/shared/account/account.model' -import { AccountService } from '@app/shared/account/account.service' - -@Component({ - selector: 'my-account-about', - templateUrl: './account-about.component.html', - styleUrls: [ './account-about.component.scss' ] -}) -export class AccountAboutComponent implements OnInit { - account: Account - - constructor ( - protected route: ActivatedRoute, - private accountService: AccountService - ) { } - - ngOnInit () { - // Parent get the account for us - this.accountService.accountLoaded - .subscribe(account => this.account = account) - } - - getAccountDescription () { - if (this.account.description) return this.account.description - - return 'No description' - } -} diff --git a/client/src/app/+account/account-routing.module.ts b/client/src/app/+account/account-routing.module.ts deleted file mode 100644 index f72d8373f..000000000 --- a/client/src/app/+account/account-routing.module.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { NgModule } from '@angular/core' -import { RouterModule, Routes } from '@angular/router' -import { MetaGuard } from '@ngx-meta/core' -import { AccountComponent } from './account.component' -import { AccountVideosComponent } from './account-videos/account-videos.component' -import { AccountAboutComponent } from './account-about/account-about.component' -import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' - -const accountRoutes: Routes = [ - { - path: ':accountId', - component: AccountComponent, - canActivateChild: [ MetaGuard ], - children: [ - { - path: '', - redirectTo: 'videos', - pathMatch: 'full' - }, - { - path: 'videos', - component: AccountVideosComponent, - data: { - meta: { - title: 'Account videos' - } - } - }, - { - path: 'video-channels', - component: AccountVideoChannelsComponent, - data: { - meta: { - title: 'Account video channels' - } - } - }, - { - path: 'about', - component: AccountAboutComponent, - data: { - meta: { - title: 'About account' - } - } - } - ] - } -] - -@NgModule({ - imports: [ RouterModule.forChild(accountRoutes) ], - exports: [ RouterModule ] -}) -export class AccountRoutingModule {} diff --git a/client/src/app/+account/account-video-channels/account-video-channels.component.html b/client/src/app/+account/account-video-channels/account-video-channels.component.html deleted file mode 100644 index d20b40c60..000000000 --- a/client/src/app/+account/account-video-channels/account-video-channels.component.html +++ /dev/null @@ -1,11 +0,0 @@ -
- - Avatar - -
{{ videoChannel.displayName }}
-
{{ videoChannel.followersCount }} subscribers
-
-
\ No newline at end of file diff --git a/client/src/app/+account/account-video-channels/account-video-channels.component.scss b/client/src/app/+account/account-video-channels/account-video-channels.component.scss deleted file mode 100644 index c9c7fa8eb..000000000 --- a/client/src/app/+account/account-video-channels/account-video-channels.component.scss +++ /dev/null @@ -1,30 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.row { - text-align: center; -} - -a.video-channel { - @include disable-default-a-behaviour; - - display: inline-block; - text-align: center; - color: #000; - margin: 10px 30px; - - img { - @include avatar(80px); - - margin-bottom: 10px; - } - - .video-channel-display-name { - font-size: 20px; - font-weight: $font-bold; - } - - .video-channel-followers { - font-size: 15px; - } -} \ No newline at end of file diff --git a/client/src/app/+account/account-video-channels/account-video-channels.component.ts b/client/src/app/+account/account-video-channels/account-video-channels.component.ts deleted file mode 100644 index 8915eb622..000000000 --- a/client/src/app/+account/account-video-channels/account-video-channels.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Component, OnInit } from '@angular/core' -import { ActivatedRoute } from '@angular/router' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { Account } from '@app/shared/account/account.model' -import { AccountService } from '@app/shared/account/account.service' -import { VideoChannel } from '../../../../../shared/models/videos' -import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' - -@Component({ - selector: 'my-account-video-channels', - templateUrl: './account-video-channels.component.html', - styleUrls: [ './account-video-channels.component.scss' ] -}) -export class AccountVideoChannelsComponent implements OnInit { - account: Account - videoChannels: VideoChannel[] = [] - - constructor ( - protected route: ActivatedRoute, - private accountService: AccountService, - private videoChannelService: VideoChannelService - ) { } - - ngOnInit () { - // Parent get the account for us - this.accountService.accountLoaded - .do(account => this.account = account) - .flatMap(account => this.videoChannelService.getVideoChannels(account.id)) - .map(res => res.data) - .subscribe(videoChannels => this.videoChannels = videoChannels) - } -} diff --git a/client/src/app/+account/account-videos/account-videos.component.scss b/client/src/app/+account/account-videos/account-videos.component.scss deleted file mode 100644 index 2ba85c031..000000000 --- a/client/src/app/+account/account-videos/account-videos.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.title-page-single { - margin-top: 0; -} \ No newline at end of file diff --git a/client/src/app/+account/account-videos/account-videos.component.ts b/client/src/app/+account/account-videos/account-videos.component.ts deleted file mode 100644 index 6c0f0bb52..000000000 --- a/client/src/app/+account/account-videos/account-videos.component.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Component, OnDestroy, OnInit } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { Location } from '@angular/common' -import { immutableAssign } from '@app/shared/misc/utils' -import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { AuthService } from '../../core/auth' -import { ConfirmService } from '../../core/confirm' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoService } from '../../shared/video/video.service' -import { Account } from '@app/shared/account/account.model' -import { AccountService } from '@app/shared/account/account.service' - -@Component({ - selector: 'my-account-videos', - templateUrl: '../../shared/video/abstract-video-list.html', - styleUrls: [ - '../../shared/video/abstract-video-list.scss', - './account-videos.component.scss' - ] -}) -export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { - titlePage = 'Published videos' - marginContent = false // Disable margin - currentRoute = '/account/videos' - loadOnInit = false - - private account: Account - - constructor ( - protected router: Router, - protected route: ActivatedRoute, - protected authService: AuthService, - protected notificationsService: NotificationsService, - protected confirmService: ConfirmService, - protected location: Location, - private accountService: AccountService, - private videoService: VideoService - ) { - super() - } - - ngOnInit () { - super.ngOnInit() - - // Parent get the account for us - this.accountService.accountLoaded - .subscribe(account => { - this.account = account - this.currentRoute = '/account/' + this.account.id + '/videos' - - this.loadMoreVideos(this.pagination.currentPage) - this.generateSyndicationList() - }) - } - - ngOnDestroy () { - super.ngOnDestroy() - } - - getVideosObservable (page: number) { - const newPagination = immutableAssign(this.pagination, { currentPage: page }) - - return this.videoService.getAccountVideos(this.account, newPagination, this.sort) - } - - generateSyndicationList () { - this.syndicationItems = this.videoService.getAccountFeedUrls(this.account.id) - } -} diff --git a/client/src/app/+account/account.component.html b/client/src/app/+account/account.component.html deleted file mode 100644 index d0e99edda..000000000 --- a/client/src/app/+account/account.component.html +++ /dev/null @@ -1,25 +0,0 @@ -
- - -
- -
-
diff --git a/client/src/app/+account/account.component.scss b/client/src/app/+account/account.component.scss deleted file mode 100644 index c7b8f038f..000000000 --- a/client/src/app/+account/account.component.scss +++ /dev/null @@ -1,46 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.sub-menu { - height: 160px; - display: flex; - flex-direction: column; - align-items: start; - - .account { - display: flex; - margin-top: 20px; - margin-bottom: 20px; - - img { - @include avatar(80px); - - margin-right: 20px; - } - - .account-info { - display: flex; - flex-direction: column; - justify-content: center; - - .account-display-name { - font-size: 23px; - font-weight: $font-bold; - } - - .account-followers { - font-size: 15px; - } - } - } - - .links { - margin-top: 0; - margin-bottom: 10px; - - a { - margin-top: 0; - margin-bottom: 0; - } - } -} \ No newline at end of file diff --git a/client/src/app/+account/account.component.ts b/client/src/app/+account/account.component.ts deleted file mode 100644 index d936ce2fe..000000000 --- a/client/src/app/+account/account.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Component, OnInit } from '@angular/core' -import { ActivatedRoute } from '@angular/router' -import { AccountService } from '@app/shared/account/account.service' -import { Account } from '@app/shared/account/account.model' - -@Component({ - selector: 'my-account', - templateUrl: './account.component.html', - styleUrls: [ './account.component.scss' ] -}) -export class AccountComponent implements OnInit { - account: Account - - constructor ( - private route: ActivatedRoute, - private accountService: AccountService - ) {} - - ngOnInit () { - const accountId = parseInt(this.route.snapshot.params['accountId'], 10) - - this.accountService.getAccount(accountId) - .subscribe(account => this.account = account) - } -} diff --git a/client/src/app/+account/account.module.ts b/client/src/app/+account/account.module.ts deleted file mode 100644 index 82ef06e76..000000000 --- a/client/src/app/+account/account.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NgModule } from '@angular/core' -import { SharedModule } from '../shared' -import { AccountRoutingModule } from './account-routing.module' -import { AccountComponent } from './account.component' -import { AccountVideosComponent } from './account-videos/account-videos.component' -import { AccountAboutComponent } from './account-about/account-about.component' -import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' - -@NgModule({ - imports: [ - AccountRoutingModule, - SharedModule - ], - - declarations: [ - AccountComponent, - AccountVideosComponent, - AccountVideoChannelsComponent, - AccountAboutComponent - ], - - exports: [ - AccountComponent - ], - - providers: [] -}) -export class AccountModule { } diff --git a/client/src/app/+account/index.ts b/client/src/app/+account/index.ts deleted file mode 100644 index dc56ffdbd..000000000 --- a/client/src/app/+account/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './account-routing.module' -export * from './account.component' -export * from './account.module' diff --git a/client/src/app/+accounts/account-about/account-about.component.html b/client/src/app/+accounts/account-about/account-about.component.html new file mode 100644 index 000000000..003a8045e --- /dev/null +++ b/client/src/app/+accounts/account-about/account-about.component.html @@ -0,0 +1,12 @@ +
+
+
Description
+
{{ getAccountDescription() }}
+
+ +
+
Stats
+ +
Joined {{ account.createdAt | date }}
+
+
\ No newline at end of file diff --git a/client/src/app/+accounts/account-about/account-about.component.scss b/client/src/app/+accounts/account-about/account-about.component.scss new file mode 100644 index 000000000..b1be7d4ed --- /dev/null +++ b/client/src/app/+accounts/account-about/account-about.component.scss @@ -0,0 +1,8 @@ +@import '_variables'; +@import '_mixins'; + +.small-title { + @include in-content-small-title; + + margin-bottom: 20px; +} diff --git a/client/src/app/+accounts/account-about/account-about.component.ts b/client/src/app/+accounts/account-about/account-about.component.ts new file mode 100644 index 000000000..8746875cb --- /dev/null +++ b/client/src/app/+accounts/account-about/account-about.component.ts @@ -0,0 +1,39 @@ +import { Component, OnDestroy, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { Location } from '@angular/common' +import { getParameterByName, immutableAssign } from '@app/shared/misc/utils' +import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { AuthService } from '../../core/auth' +import { ConfirmService } from '../../core/confirm' +import { AbstractVideoList } from '../../shared/video/abstract-video-list' +import { VideoService } from '../../shared/video/video.service' +import { Account } from '@app/shared/account/account.model' +import { AccountService } from '@app/shared/account/account.service' + +@Component({ + selector: 'my-account-about', + templateUrl: './account-about.component.html', + styleUrls: [ './account-about.component.scss' ] +}) +export class AccountAboutComponent implements OnInit { + account: Account + + constructor ( + protected route: ActivatedRoute, + private accountService: AccountService + ) { } + + ngOnInit () { + // Parent get the account for us + this.accountService.accountLoaded + .subscribe(account => this.account = account) + } + + getAccountDescription () { + if (this.account.description) return this.account.description + + return 'No description' + } +} 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 new file mode 100644 index 000000000..d20b40c60 --- /dev/null +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html @@ -0,0 +1,11 @@ +
+ + Avatar + +
{{ videoChannel.displayName }}
+
{{ videoChannel.followersCount }} subscribers
+
+
\ No newline at end of file diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.scss b/client/src/app/+accounts/account-video-channels/account-video-channels.component.scss new file mode 100644 index 000000000..c9c7fa8eb --- /dev/null +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.scss @@ -0,0 +1,30 @@ +@import '_variables'; +@import '_mixins'; + +.row { + text-align: center; +} + +a.video-channel { + @include disable-default-a-behaviour; + + display: inline-block; + text-align: center; + color: #000; + margin: 10px 30px; + + img { + @include avatar(80px); + + margin-bottom: 10px; + } + + .video-channel-display-name { + font-size: 20px; + font-weight: $font-bold; + } + + .video-channel-followers { + font-size: 15px; + } +} \ No newline at end of file diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts new file mode 100644 index 000000000..4c5782f9d --- /dev/null +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts @@ -0,0 +1,33 @@ +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute } from '@angular/router' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { Account } from '@app/shared/account/account.model' +import { AccountService } from '@app/shared/account/account.service' +import { VideoChannel } from '../../../../../shared/models/videos' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' + +@Component({ + selector: 'my-account-video-channels', + templateUrl: './account-video-channels.component.html', + styleUrls: [ './account-video-channels.component.scss' ] +}) +export class AccountVideoChannelsComponent implements OnInit { + account: Account + videoChannels: VideoChannel[] = [] + + constructor ( + protected route: ActivatedRoute, + private accountService: AccountService, + private videoChannelService: VideoChannelService + ) { } + + ngOnInit () { + // Parent get the account for us + this.accountService.accountLoaded + .do(account => this.account = account) + .flatMap(account => this.videoChannelService.listAccountVideoChannels(account.id)) + .map(res => res.data) + .subscribe(videoChannels => this.videoChannels = videoChannels) + } +} diff --git a/client/src/app/+accounts/account-videos/account-videos.component.scss b/client/src/app/+accounts/account-videos/account-videos.component.scss new file mode 100644 index 000000000..2ba85c031 --- /dev/null +++ b/client/src/app/+accounts/account-videos/account-videos.component.scss @@ -0,0 +1,3 @@ +.title-page-single { + margin-top: 0; +} \ No newline at end of file diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts new file mode 100644 index 000000000..6c0f0bb52 --- /dev/null +++ b/client/src/app/+accounts/account-videos/account-videos.component.ts @@ -0,0 +1,71 @@ +import { Component, OnDestroy, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { Location } from '@angular/common' +import { immutableAssign } from '@app/shared/misc/utils' +import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { AuthService } from '../../core/auth' +import { ConfirmService } from '../../core/confirm' +import { AbstractVideoList } from '../../shared/video/abstract-video-list' +import { VideoService } from '../../shared/video/video.service' +import { Account } from '@app/shared/account/account.model' +import { AccountService } from '@app/shared/account/account.service' + +@Component({ + selector: 'my-account-videos', + templateUrl: '../../shared/video/abstract-video-list.html', + styleUrls: [ + '../../shared/video/abstract-video-list.scss', + './account-videos.component.scss' + ] +}) +export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { + titlePage = 'Published videos' + marginContent = false // Disable margin + currentRoute = '/account/videos' + loadOnInit = false + + private account: Account + + constructor ( + protected router: Router, + protected route: ActivatedRoute, + protected authService: AuthService, + protected notificationsService: NotificationsService, + protected confirmService: ConfirmService, + protected location: Location, + private accountService: AccountService, + private videoService: VideoService + ) { + super() + } + + ngOnInit () { + super.ngOnInit() + + // Parent get the account for us + this.accountService.accountLoaded + .subscribe(account => { + this.account = account + this.currentRoute = '/account/' + this.account.id + '/videos' + + this.loadMoreVideos(this.pagination.currentPage) + this.generateSyndicationList() + }) + } + + ngOnDestroy () { + super.ngOnDestroy() + } + + getVideosObservable (page: number) { + const newPagination = immutableAssign(this.pagination, { currentPage: page }) + + return this.videoService.getAccountVideos(this.account, newPagination, this.sort) + } + + generateSyndicationList () { + this.syndicationItems = this.videoService.getAccountFeedUrls(this.account.id) + } +} diff --git a/client/src/app/+accounts/accounts-routing.module.ts b/client/src/app/+accounts/accounts-routing.module.ts new file mode 100644 index 000000000..ffe606b43 --- /dev/null +++ b/client/src/app/+accounts/accounts-routing.module.ts @@ -0,0 +1,55 @@ +import { NgModule } from '@angular/core' +import { RouterModule, Routes } from '@angular/router' +import { MetaGuard } from '@ngx-meta/core' +import { AccountsComponent } from './accounts.component' +import { AccountVideosComponent } from './account-videos/account-videos.component' +import { AccountAboutComponent } from './account-about/account-about.component' +import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' + +const accountsRoutes: Routes = [ + { + path: ':accountId', + component: AccountsComponent, + canActivateChild: [ MetaGuard ], + children: [ + { + path: '', + redirectTo: 'videos', + pathMatch: 'full' + }, + { + path: 'videos', + component: AccountVideosComponent, + data: { + meta: { + title: 'Account videos' + } + } + }, + { + path: 'video-channels', + component: AccountVideoChannelsComponent, + data: { + meta: { + title: 'Account video channels' + } + } + }, + { + path: 'about', + component: AccountAboutComponent, + data: { + meta: { + title: 'About account' + } + } + } + ] + } +] + +@NgModule({ + imports: [ RouterModule.forChild(accountsRoutes) ], + exports: [ RouterModule ] +}) +export class AccountsRoutingModule {} diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html new file mode 100644 index 000000000..549676e5a --- /dev/null +++ b/client/src/app/+accounts/accounts.component.html @@ -0,0 +1,25 @@ +
+ + +
+ +
+
diff --git a/client/src/app/+accounts/accounts.component.scss b/client/src/app/+accounts/accounts.component.scss new file mode 100644 index 000000000..909b65bc7 --- /dev/null +++ b/client/src/app/+accounts/accounts.component.scss @@ -0,0 +1,6 @@ +@import '_variables'; +@import '_mixins'; + +.sub-menu { + @include sub-menu-with-actor; +} \ No newline at end of file diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts new file mode 100644 index 000000000..1298803c3 --- /dev/null +++ b/client/src/app/+accounts/accounts.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute } from '@angular/router' +import { AccountService } from '@app/shared/account/account.service' +import { Account } from '@app/shared/account/account.model' + +@Component({ + templateUrl: './accounts.component.html', + styleUrls: [ './accounts.component.scss' ] +}) +export class AccountsComponent implements OnInit { + account: Account + + constructor ( + private route: ActivatedRoute, + private accountService: AccountService + ) {} + + ngOnInit () { + const accountId = parseInt(this.route.snapshot.params['accountId'], 10) + + this.accountService.getAccount(accountId) + .subscribe(account => this.account = account) + } +} diff --git a/client/src/app/+accounts/accounts.module.ts b/client/src/app/+accounts/accounts.module.ts new file mode 100644 index 000000000..8e679822a --- /dev/null +++ b/client/src/app/+accounts/accounts.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core' +import { SharedModule } from '../shared' +import { AccountsRoutingModule } from './accounts-routing.module' +import { AccountsComponent } from './accounts.component' +import { AccountVideosComponent } from './account-videos/account-videos.component' +import { AccountAboutComponent } from './account-about/account-about.component' +import { AccountVideoChannelsComponent } from './account-video-channels/account-video-channels.component' + +@NgModule({ + imports: [ + AccountsRoutingModule, + SharedModule + ], + + declarations: [ + AccountsComponent, + AccountVideosComponent, + AccountVideoChannelsComponent, + AccountAboutComponent + ], + + exports: [ + AccountsComponent + ], + + providers: [] +}) +export class AccountsModule { } diff --git a/client/src/app/+accounts/index.ts b/client/src/app/+accounts/index.ts new file mode 100644 index 000000000..4dfb6f586 --- /dev/null +++ b/client/src/app/+accounts/index.ts @@ -0,0 +1,3 @@ +export * from './accounts-routing.module' +export * from './accounts.component' +export * from './accounts.module' diff --git a/client/src/app/+video-channels/index.ts b/client/src/app/+video-channels/index.ts new file mode 100644 index 000000000..6683d1b12 --- /dev/null +++ b/client/src/app/+video-channels/index.ts @@ -0,0 +1,3 @@ +export * from './video-channels-routing.module' +export * from './video-channels.component' +export * from './video-channels.module' diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.html b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.html new file mode 100644 index 000000000..65ad6f541 --- /dev/null +++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.html @@ -0,0 +1,12 @@ +
+
+
Description
+
{{ getVideoChannelDescription() }}
+
+ +
+
Stats
+ +
Created {{ videoChannel.createdAt | date }}
+
+
\ No newline at end of file diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.scss b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.scss new file mode 100644 index 000000000..b1be7d4ed --- /dev/null +++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.scss @@ -0,0 +1,8 @@ +@import '_variables'; +@import '_mixins'; + +.small-title { + @include in-content-small-title; + + margin-bottom: 20px; +} diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts new file mode 100644 index 000000000..5d435708e --- /dev/null +++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts @@ -0,0 +1,32 @@ +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute } from '@angular/router' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' +import { VideoChannel } from '@app/shared/video-channel/video-channel.model' + +@Component({ + selector: 'my-video-channel-about', + templateUrl: './video-channel-about.component.html', + styleUrls: [ './video-channel-about.component.scss' ] +}) +export class VideoChannelAboutComponent implements OnInit { + videoChannel: VideoChannel + + constructor ( + protected route: ActivatedRoute, + private videoChannelService: VideoChannelService + ) { } + + ngOnInit () { + // Parent get the video channel for us + this.videoChannelService.videoChannelLoaded + .subscribe(videoChannel => this.videoChannel = videoChannel) + } + + getVideoChannelDescription () { + if (this.videoChannel.description) return this.videoChannel.description + + return 'No description' + } +} diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.scss b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.scss new file mode 100644 index 000000000..2ba85c031 --- /dev/null +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.scss @@ -0,0 +1,3 @@ +.title-page-single { + margin-top: 0; +} \ No newline at end of file diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts new file mode 100644 index 000000000..3cda630d3 --- /dev/null +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts @@ -0,0 +1,71 @@ +import { Component, OnDestroy, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { Location } from '@angular/common' +import { immutableAssign } from '@app/shared/misc/utils' +import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { AuthService } from '../../core/auth' +import { ConfirmService } from '../../core/confirm' +import { AbstractVideoList } from '../../shared/video/abstract-video-list' +import { VideoService } from '../../shared/video/video.service' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' +import { VideoChannel } from '@app/shared/video-channel/video-channel.model' + +@Component({ + selector: 'my-video-channel-videos', + templateUrl: '../../shared/video/abstract-video-list.html', + styleUrls: [ + '../../shared/video/abstract-video-list.scss', + './video-channel-videos.component.scss' + ] +}) +export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { + titlePage = 'Published videos' + marginContent = false // Disable margin + currentRoute = '/video-channel/videos' + loadOnInit = false + + private videoChannel: VideoChannel + + constructor ( + protected router: Router, + protected route: ActivatedRoute, + protected authService: AuthService, + protected notificationsService: NotificationsService, + protected confirmService: ConfirmService, + protected location: Location, + private videoChannelService: VideoChannelService, + private videoService: VideoService + ) { + super() + } + + ngOnInit () { + super.ngOnInit() + + // Parent get the video channel for us + this.videoChannelService.videoChannelLoaded + .subscribe(videoChannel => { + this.videoChannel = videoChannel + this.currentRoute = '/video-channel/' + this.videoChannel.uuid + '/videos' + + this.loadMoreVideos(this.pagination.currentPage) + this.generateSyndicationList() + }) + } + + ngOnDestroy () { + super.ngOnDestroy() + } + + getVideosObservable (page: number) { + const newPagination = immutableAssign(this.pagination, { currentPage: page }) + + return this.videoService.getVideoChannelVideos(this.videoChannel, newPagination, this.sort) + } + + generateSyndicationList () { + this.syndicationItems = this.videoService.getVideoChannelFeedUrls(this.videoChannel.id) + } +} diff --git a/client/src/app/+video-channels/video-channels-routing.module.ts b/client/src/app/+video-channels/video-channels-routing.module.ts new file mode 100644 index 000000000..935578d2a --- /dev/null +++ b/client/src/app/+video-channels/video-channels-routing.module.ts @@ -0,0 +1,45 @@ +import { NgModule } from '@angular/core' +import { RouterModule, Routes } from '@angular/router' +import { MetaGuard } from '@ngx-meta/core' +import { VideoChannelsComponent } from './video-channels.component' +import { VideoChannelVideosComponent } from './video-channel-videos/video-channel-videos.component' +import { VideoChannelAboutComponent } from './video-channel-about/video-channel-about.component' + +const videoChannelsRoutes: Routes = [ + { + path: ':videoChannelId', + component: VideoChannelsComponent, + canActivateChild: [ MetaGuard ], + children: [ + { + path: '', + redirectTo: 'videos', + pathMatch: 'full' + }, + { + path: 'videos', + component: VideoChannelVideosComponent, + data: { + meta: { + title: 'Video channel videos' + } + } + }, + { + path: 'about', + component: VideoChannelAboutComponent, + data: { + meta: { + title: 'About video channel' + } + } + } + ] + } +] + +@NgModule({ + imports: [ RouterModule.forChild(videoChannelsRoutes) ], + exports: [ RouterModule ] +}) +export class VideoChannelsRoutingModule {} diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html new file mode 100644 index 000000000..098e1eed4 --- /dev/null +++ b/client/src/app/+video-channels/video-channels.component.html @@ -0,0 +1,23 @@ +
+ + +
+ +
+
diff --git a/client/src/app/+video-channels/video-channels.component.scss b/client/src/app/+video-channels/video-channels.component.scss new file mode 100644 index 000000000..909b65bc7 --- /dev/null +++ b/client/src/app/+video-channels/video-channels.component.scss @@ -0,0 +1,6 @@ +@import '_variables'; +@import '_mixins'; + +.sub-menu { + @include sub-menu-with-actor; +} \ No newline at end of file diff --git a/client/src/app/+video-channels/video-channels.component.ts b/client/src/app/+video-channels/video-channels.component.ts new file mode 100644 index 000000000..5eca64fb5 --- /dev/null +++ b/client/src/app/+video-channels/video-channels.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute } from '@angular/router' +import { VideoChannel } from '@app/shared/video-channel/video-channel.model' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' + +@Component({ + templateUrl: './video-channels.component.html', + styleUrls: [ './video-channels.component.scss' ] +}) +export class VideoChannelsComponent implements OnInit { + videoChannel: VideoChannel + + constructor ( + private route: ActivatedRoute, + private videoChannelService: VideoChannelService + ) {} + + ngOnInit () { + const videoChannelId = this.route.snapshot.params['videoChannelId'] + + this.videoChannelService.getVideoChannel(videoChannelId) + .subscribe(videoChannel => this.videoChannel = videoChannel) + } +} diff --git a/client/src/app/+video-channels/video-channels.module.ts b/client/src/app/+video-channels/video-channels.module.ts new file mode 100644 index 000000000..a09ea6f11 --- /dev/null +++ b/client/src/app/+video-channels/video-channels.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core' +import { SharedModule } from '../shared' +import { VideoChannelsRoutingModule } from './video-channels-routing.module' +import { VideoChannelsComponent } from './video-channels.component' +import { VideoChannelVideosComponent } from './video-channel-videos/video-channel-videos.component' +import { VideoChannelAboutComponent } from './video-channel-about/video-channel-about.component' + +@NgModule({ + imports: [ + VideoChannelsRoutingModule, + SharedModule + ], + + declarations: [ + VideoChannelsComponent, + VideoChannelVideosComponent, + VideoChannelAboutComponent + ], + + exports: [ + VideoChannelsComponent + ], + + providers: [] +}) +export class VideoChannelsModule { } diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts index 1d55b4cea..799748cfa 100644 --- a/client/src/app/app-routing.module.ts +++ b/client/src/app/app-routing.module.ts @@ -9,8 +9,12 @@ const routes: Routes = [ loadChildren: './+admin/admin.module#AdminModule' }, { - path: 'account', - loadChildren: './+account/account.module#AccountModule' + path: 'accounts', + loadChildren: './+accounts/accounts.module#AccountsModule' + }, + { + path: 'video-channels', + loadChildren: './+video-channels/video-channels.module#VideoChannelsModule' } ] diff --git a/client/src/app/shared/video-channel/video-channel.service.ts b/client/src/app/shared/video-channel/video-channel.service.ts index 1f9088c38..d8efcc171 100644 --- a/client/src/app/shared/video-channel/video-channel.service.ts +++ b/client/src/app/shared/video-channel/video-channel.service.ts @@ -9,16 +9,29 @@ import { VideoChannel as VideoChannelServer } from '../../../../../shared/models import { AccountService } from '../account/account.service' import { ResultList } from '../../../../../shared' import { VideoChannel } from './video-channel.model' +import { ReplaySubject } from 'rxjs/ReplaySubject' +import { environment } from '../../../environments/environment' @Injectable() export class VideoChannelService { + static BASE_VIDEO_CHANNEL_URL = environment.apiUrl + '/api/v1/video-channels/' + + videoChannelLoaded = new ReplaySubject(1) + constructor ( private authHttp: HttpClient, private restExtractor: RestExtractor, private restService: RestService ) {} - getVideoChannels (accountId: number): Observable> { + getVideoChannel (videoChannelUUID: string) { + return this.authHttp.get(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelUUID) + .map(videoChannelHash => new VideoChannel(videoChannelHash)) + .do(videoChannel => this.videoChannelLoaded.next(videoChannel)) + .catch((res) => this.restExtractor.handleError(res)) + } + + listAccountVideoChannels (accountId: number): Observable> { return this.authHttp.get>(AccountService.BASE_ACCOUNT_URL + accountId + '/video-channels') .map(res => this.extractVideoChannels(res)) .catch((res) => this.restExtractor.handleError(res)) diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html index d0b305509..e26cb058a 100644 --- a/client/src/app/shared/video/video-miniature.component.html +++ b/client/src/app/shared/video/video-miniature.component.html @@ -5,13 +5,13 @@ {{ video.name }} {{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views - + diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index f82aa7389..8870cbee4 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts @@ -23,6 +23,8 @@ import { Video } from './video.model' import { objectToFormData } from '@app/shared/misc/utils' import { Account } from '@app/shared/account/account.model' import { AccountService } from '@app/shared/account/account.service' +import { VideoChannel } from '../../../../../shared/models/videos' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' @Injectable() export class VideoService { @@ -115,6 +117,22 @@ export class VideoService { .catch((res) => this.restExtractor.handleError(res)) } + getVideoChannelVideos ( + videoChannel: VideoChannel, + videoPagination: ComponentPagination, + sort: VideoSortField + ): Observable<{ videos: Video[], totalVideos: number}> { + const pagination = this.restService.componentPaginationToRestPagination(videoPagination) + + let params = new HttpParams() + params = this.restService.addRestGetParams(params, pagination, sort) + + return this.authHttp + .get(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid + '/videos', { params }) + .map(this.extractVideos) + .catch((res) => this.restExtractor.handleError(res)) + } + getVideos ( videoPagination: ComponentPagination, sort: VideoSortField, @@ -175,6 +193,13 @@ export class VideoService { return this.buildBaseFeedUrls(params) } + getVideoChannelFeedUrls (videoChannelId: number) { + let params = this.restService.addRestGetParams(new HttpParams()) + params = params.set('videoChannelId', videoChannelId.toString()) + + return this.buildBaseFeedUrls(params) + } + searchVideos ( search: string, videoPagination: ComponentPagination, diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 5d3361561..f38e90927 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html @@ -22,7 +22,7 @@
- + By {{ video.by }} Account avatar diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss index cbf9b566a..c43bd9803 100644 --- a/client/src/sass/include/_mixins.scss +++ b/client/src/sass/include/_mixins.scss @@ -320,4 +320,48 @@ color: $orange-color; font-weight: $font-bold; font-size: 13px; +} + +@mixin sub-menu-with-actor { + height: 160px; + display: flex; + flex-direction: column; + align-items: start; + + .actor { + display: flex; + margin-top: 20px; + margin-bottom: 20px; + + img { + @include avatar(80px); + + margin-right: 20px; + } + + .actor-info { + display: flex; + flex-direction: column; + justify-content: center; + + .actor-display-name { + font-size: 23px; + font-weight: $font-bold; + } + + .actor-followers { + font-size: 15px; + } + } + } + + .links { + margin-top: 0; + margin-bottom: 10px; + + a { + margin-top: 0; + margin-bottom: 0; + } + } } \ No newline at end of file diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index 850ad12e0..499a4fc94 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts @@ -140,7 +140,7 @@ describe('Test videos API validator', function () { let path: string before(async function () { - path = '/api/v1/accounts/' + accountUUID + '/video-channels/' + channelUUID + '/videos' + path = '/api/v1/video-channels/' + channelUUID + '/videos' }) it('Should fail with a bad start pagination', async function () { diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index 6238cdc08..e462a2d47 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts @@ -47,7 +47,6 @@ describe('Test multiple servers', function () { let servers: ServerInfo[] = [] const toRemove = [] let videoUUID = '' - let accountId: number let videoChannelId: number before(async function () { @@ -58,17 +57,12 @@ describe('Test multiple servers', function () { // Get the access tokens await setAccessTokensToServers(servers) - { - const res = await getAccountsList(servers[0].url) - accountId = res.body.data[0].id - } - { const videoChannel = { name: 'my channel', description: 'super channel' } - await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, accountId, videoChannel) + await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, videoChannel) const channelRes = await getVideoChannelsList(servers[ 0 ].url, 0, 1) videoChannelId = channelRes.body.data[ 0 ].id }