From c8487f3f63c90fbfddaa906b3cbd90fb209ab1bb Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 29 May 2019 16:45:59 +0200 Subject: [PATCH] Improve account channel page Set it as the default route for account page. The main goal is to better differentiate the channel page from the account page. With the channel page set as default, I hope people will better understand they are in the account page, and that this account could have multiple channels. --- .../account-video-channels.component.html | 26 +++-- .../account-video-channels.component.scss | 31 ++---- .../account-video-channels.component.ts | 71 ++++++++++++-- .../account-videos.component.ts | 2 - .../app/+accounts/accounts-routing.module.ts | 2 +- .../src/app/+accounts/accounts.component.html | 4 +- .../video-channel-playlists.component.ts | 5 +- .../video-channel/video-channel.service.ts | 17 +++- .../app/shared/video/abstract-video-list.html | 2 +- .../app/shared/video/abstract-video-list.scss | 28 +----- .../video-list/video-overview.component.html | 6 +- .../video-list/video-overview.component.scss | 60 +----------- client/src/sass/include/_miniature.scss | 95 +++++++++++++++++++ 13 files changed, 207 insertions(+), 142 deletions(-) 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 c3ef1d894..63f0514fd 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 @@ -1,11 +1,17 @@ -
- - Avatar + \ 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 index 0c6de2efa..f2604684e 100644 --- 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 @@ -1,30 +1,13 @@ @import '_variables'; @import '_mixins'; +@import '_miniature'; -.row { - justify-content: center; +.margin-content { + @include adapt-margin-content-width; } -a.video-channel { - @include disable-default-a-behaviour; +.section { + @include miniature-rows; - display: inline-block; - text-align: center; - color: var(--mainForegroundColor); - 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 + padding-top: 0 !important; +} 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 index 44f5626bb..ee3b5f8e4 100644 --- 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 @@ -3,9 +3,14 @@ import { ActivatedRoute } from '@angular/router' import { Account } from '@app/shared/account/account.model' import { AccountService } from '@app/shared/account/account.service' import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' -import { flatMap, map, tap } from 'rxjs/operators' -import { Subscription } from 'rxjs' +import { concatMap, map, switchMap, tap } from 'rxjs/operators' +import { from, Subscription } from 'rxjs' import { VideoChannel } from '@app/shared/video-channel/video-channel.model' +import { Video } from '@app/shared/video/video.model' +import { AuthService } from '@app/core' +import { VideoService } from '@app/shared/video/video.service' +import { VideoSortField } from '@app/shared/video/sort-field.type' +import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' @Component({ selector: 'my-account-video-channels', @@ -15,27 +20,73 @@ import { VideoChannel } from '@app/shared/video-channel/video-channel.model' export class AccountVideoChannelsComponent implements OnInit, OnDestroy { account: Account videoChannels: VideoChannel[] = [] + videos: { [id: number]: Video[] } = {} + + channelPagination: ComponentPagination = { + currentPage: 1, + itemsPerPage: 2 + } + + videosPagination: ComponentPagination = { + currentPage: 1, + itemsPerPage: 12 + } + videosSort: VideoSortField = '-publishedAt' private accountSub: Subscription constructor ( - protected route: ActivatedRoute, + private route: ActivatedRoute, + private authService: AuthService, private accountService: AccountService, - private videoChannelService: VideoChannelService + private videoChannelService: VideoChannelService, + private videoService: VideoService ) { } + get user () { + return this.authService.getUser() + } + ngOnInit () { // Parent get the account for us this.accountSub = this.accountService.accountLoaded - .pipe( - tap(account => this.account = account), - flatMap(account => this.videoChannelService.listAccountVideoChannels(account)), - map(res => res.data) - ) - .subscribe(videoChannels => this.videoChannels = videoChannels) + .subscribe(account => { + this.account = account + + this.loadMoreChannels() + }) } ngOnDestroy () { if (this.accountSub) this.accountSub.unsubscribe() } + + loadMoreChannels () { + this.videoChannelService.listAccountVideoChannels(this.account, this.channelPagination) + .pipe( + tap(res => this.channelPagination.totalItems = res.total), + switchMap(res => from(res.data)), + concatMap(videoChannel => { + return this.videoService.getVideoChannelVideos(videoChannel, this.videosPagination, this.videosSort) + .pipe(map(data => ({ videoChannel, videos: data.videos }))) + }) + ) + .subscribe(({ videoChannel, videos }) => { + this.videoChannels.push(videoChannel) + + this.videos[videoChannel.id] = videos + }) + } + + getVideosOf (videoChannel: VideoChannel) { + return this.videos[ videoChannel.id ] || [] + } + + onNearOfBottom () { + if (!hasMoreItems(this.channelPagination)) return + + this.channelPagination.currentPage += 1 + + this.loadMoreChannels() + } } 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 0d579fa0c..6d26a4322 100644 --- a/client/src/app/+accounts/account-videos/account-videos.component.ts +++ b/client/src/app/+accounts/account-videos/account-videos.component.ts @@ -41,8 +41,6 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit, private videoService: VideoService ) { super() - - this.titlePage = this.i18n('Published videos') } ngOnInit () { diff --git a/client/src/app/+accounts/accounts-routing.module.ts b/client/src/app/+accounts/accounts-routing.module.ts index 531d763c4..55bce351a 100644 --- a/client/src/app/+accounts/accounts-routing.module.ts +++ b/client/src/app/+accounts/accounts-routing.module.ts @@ -14,7 +14,7 @@ const accountsRoutes: Routes = [ children: [ { path: '', - redirectTo: 'videos', + redirectTo: 'video-channels', pathMatch: 'full' }, { diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html index c1377c1ea..038e18c4b 100644 --- a/client/src/app/+accounts/accounts.component.html +++ b/client/src/app/+accounts/accounts.component.html @@ -26,10 +26,10 @@ diff --git a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts index 907aefae1..7990044a2 100644 --- a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts +++ b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts @@ -5,7 +5,7 @@ import { VideoChannel } from '@app/shared/video-channel/video-channel.model' import { Subscription } from 'rxjs' import { Notifier } from '@app/core' import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' -import { ComponentPagination } from '@app/shared/rest/component-pagination.model' +import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' @Component({ @@ -46,8 +46,7 @@ export class VideoChannelPlaylistsComponent implements OnInit, OnDestroy { } onNearOfBottom () { - // Last page - if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return + if (!hasMoreItems(this.pagination)) return this.pagination.currentPage += 1 this.loadVideoPlaylists() 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 d0bec649a..0168d37d9 100644 --- a/client/src/app/shared/video-channel/video-channel.service.ts +++ b/client/src/app/shared/video-channel/video-channel.service.ts @@ -2,7 +2,7 @@ import { catchError, map, tap } from 'rxjs/operators' import { Injectable } from '@angular/core' import { Observable, ReplaySubject } from 'rxjs' import { RestExtractor } from '../rest/rest-extractor.service' -import { HttpClient } from '@angular/common/http' +import { HttpClient, HttpParams } from '@angular/common/http' import { VideoChannel as VideoChannelServer, VideoChannelCreate, VideoChannelUpdate } from '../../../../../shared/models/videos' import { AccountService } from '../account/account.service' import { ResultList } from '../../../../../shared' @@ -10,6 +10,8 @@ import { VideoChannel } from './video-channel.model' import { environment } from '../../../environments/environment' import { Account } from '@app/shared/account/account.model' import { Avatar } from '../../../../../shared/models/avatars/avatar.model' +import { ComponentPagination } from '@app/shared/rest/component-pagination.model' +import { RestService } from '@app/shared/rest' @Injectable() export class VideoChannelService { @@ -29,6 +31,7 @@ export class VideoChannelService { constructor ( private authHttp: HttpClient, + private restService: RestService, private restExtractor: RestExtractor ) { } @@ -41,8 +44,16 @@ export class VideoChannelService { ) } - listAccountVideoChannels (account: Account): Observable> { - return this.authHttp.get>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/video-channels') + listAccountVideoChannels (account: Account, componentPagination?: ComponentPagination): Observable> { + const pagination = componentPagination + ? this.restService.componentPaginationToRestPagination(componentPagination) + : { start: 0, count: 20 } + + let params = new HttpParams() + params = this.restService.addRestGetParams(params, pagination) + + const url = AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/video-channels' + return this.authHttp.get>(url, { params }) .pipe( map(res => VideoChannelService.extractVideoChannels(res)), catchError(err => this.restExtractor.handleError(err)) diff --git a/client/src/app/shared/video/abstract-video-list.html b/client/src/app/shared/video/abstract-video-list.html index 268677977..14f48b54b 100644 --- a/client/src/app/shared/video/abstract-video-list.html +++ b/client/src/app/shared/video/abstract-video-list.html @@ -6,7 +6,7 @@ - +
No results.
-
+ @@ -11,7 +11,7 @@
-
+ @@ -19,7 +19,7 @@
-
+
Avatar diff --git a/client/src/app/videos/video-list/video-overview.component.scss b/client/src/app/videos/video-list/video-overview.component.scss index a24766783..ade6f53b7 100644 --- a/client/src/app/videos/video-list/video-overview.component.scss +++ b/client/src/app/videos/video-list/video-overview.component.scss @@ -2,62 +2,10 @@ @import '_mixins'; @import '_miniature'; -.section { - max-height: 500px; // 2 rows max - overflow: hidden; - padding-top: 10px; - - &:first-child { - padding-top: 30px; - } - - my-video-miniature { - text-align: left; - } -} - -.section-title { - font-size: 24px; - font-weight: $font-semibold; - margin-bottom: 10px; - - a { - &:hover, &:focus:not(.focus-visible), &:active { - text-decoration: none; - outline: none; - } - - color: var(--mainForegroundColor); - } +.margin-content { + @include adapt-margin-content-width; } -.channel { - .section-title a { - display: flex; - width: fit-content; - align-items: center; - - img { - @include avatar(28px); - - margin-right: 8px; - } - } -} - -@media screen and (max-width: 500px) { - .margin-content { - margin: 0 !important; - } - - .section-title { - font-size: 17px; - } - - .section { - max-height: initial; - overflow: initial; - - @include video-miniature-small-screen; - } +.section { + @include miniature-rows; } diff --git a/client/src/sass/include/_miniature.scss b/client/src/sass/include/_miniature.scss index b62187fd2..3afcca310 100644 --- a/client/src/sass/include/_miniature.scss +++ b/client/src/sass/include/_miniature.scss @@ -138,3 +138,98 @@ $play-overlay-width: 18px; } } } + +@mixin miniature-rows { + max-height: 540px; // 2 rows max + overflow: hidden; + padding-top: 10px; + + &:first-child { + padding-top: 30px; + } + + my-video-miniature { + text-align: left; + } + + .section-title { + font-size: 24px; + font-weight: $font-semibold; + margin-bottom: 30px; + + a { + &:hover, &:focus:not(.focus-visible), &:active { + text-decoration: none; + outline: none; + } + + color: var(--mainForegroundColor); + } + } + + &.channel { + .section-title { + a { + display: flex; + width: fit-content; + align-items: center; + + img { + @include avatar(28px); + + margin-right: 8px; + } + } + + .followers { + color: $grey-foreground-color; + font-weight: normal; + font-size: 14px; + margin-left: 10px; + position: relative; + top: 2px; + } + } + } + + @media screen and (max-width: $mobile-view) { + max-height: initial; + overflow: initial; + + @include video-miniature-small-screen; + + .section-title { + font-size: 17px; + } + } +} + +@mixin adapt-margin-content-width { + width: $video-miniature-width * 6; + margin: auto !important; + + @media screen and (max-width: 1800px) { + width: $video-miniature-width * 5; + } + + @media screen and (max-width: 1800px - $video-miniature-width) { + width: $video-miniature-width * 4; + } + + @media screen and (max-width: 1800px - (2* $video-miniature-width)) { + width: $video-miniature-width * 3; + } + + @media screen and (max-width: 1800px - (3* $video-miniature-width)) { + width: $video-miniature-width * 2; + } + + @media screen and (max-width: 500px) { + width: auto; + margin: 0 !important; + + .videos { + @include video-miniature-small-screen; + } + } +} -- 2.25.1