From 900f7820814b95b07ef0bcac04036a95abfbe060 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 26 Mar 2021 15:53:18 +0100 Subject: Redesign account's channels page --- .../account-video-channels.component.html | 43 ++++-- .../account-video-channels.component.scss | 166 ++++++++++++++++++--- .../account-video-channels.component.ts | 47 ++++-- client/src/app/+accounts/accounts.component.html | 4 +- client/src/app/+accounts/accounts.component.scss | 22 ++- client/src/app/+accounts/accounts.component.ts | 4 + 6 files changed, 238 insertions(+), 48 deletions(-) (limited to 'client/src/app/+accounts') 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 5dbb341d2..0b22e7526 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,33 +1,50 @@

Video channels

+
This account does not have channels.
-
-
- +
+ +
+ Avatar + -

{{ videoChannel.displayName }}

+

+ + {{ videoChannel.displayName }} + +

+ +
{videoChannel.followersCount, plural, =1 {1 subscriber} other {{{ videoChannel.followersCount }} subscribers}}
- - + + {getTotalVideosOf(videoChannel), splural, =1 {1 videos} other {{{ getTotalVideosOf(videoChannel) }} videos}} + +
+ +
-
-
This channel doesn't have any videos.
+ + + Show this channel + +
+
This channel doesn't have any videos.
-
- - SHOW THIS CHANNEL - + +
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 4957e91d7..ca4c35cb4 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 @@ -3,37 +3,169 @@ @import '_miniature'; .margin-content { - @include fluid-videos-miniature-layout; + @include fluid-videos-miniature-margins; } -.section { - @include miniature-rows; +.channel { + max-width: $max-channels-width; + background-color: pvar(--channelBackgroundColor); + padding: 15px; - padding-top: 0 !important; + margin: 30px 0; - .section-title { + display: grid; + grid-template-columns: 1fr auto; + grid-template-rows: auto auto; + column-gap: 15px; +} + +.channel-avatar-row { + grid-column: 1; + grid-row: 1; + + display: grid; + grid-template-columns: auto auto 1fr; + grid-template-rows: auto 1fr; + + .avatar-link { + grid-column: 1; + grid-row: 1 / 3; + margin-right: 30px; + } + + img { + @include channel-avatar(75px); + } + + a { + color: pvar(--mainForegroundColor); + } + + h2 { + grid-row: 1; + grid-column: 2; + font-size: 20px; + line-height: 1; + font-weight: $font-bold; + margin: 0; + } + + .actor-counters { + grid-row: 1; + grid-column: 3; + color: pvar(--greyForegroundColor); + font-size: 16px; + display: flex; align-items: center; + margin-left: 15px; } - .videos { - overflow: hidden; + .actor-counters > *:not(:last-child)::after { + content: '•'; + margin: 0 10px; + color: pvar(--mainColor); + } - .no-results { - height: 50px; - } + .description-html { + grid-column: 2 / 4; + grid-row: 2; + + max-height: 80px; + font-size: 16px; + + @include fade-text(30px, pvar(--channelBackgroundColor)); + } +} + +my-subscribe-button { + grid-row: 1; + grid-column: 2; +} + +.videos { + display: flex; + grid-column: 1 / 3; + grid-row: 2; + margin-top: 30px; + + position: relative; + overflow: hidden; + + my-video-miniature { + margin-right: 15px; } - my-video-miniature ::ng-deep my-video-actions-dropdown > my-action-dropdown { - // Fix our overflow - position: absolute; + .no-results { + height: auto; } } +.miniature-show-channel { + height: 100%; + position: absolute; + right: 0; + background: linear-gradient(90deg, transparent 0, pvar(--channelBackgroundColor) 45px); + padding: ($video-thumbnail-height / 2 - 10px) 15px 0 60px; + z-index: z(miniature) + 1; + + a { + color: pvar(--mainColor); + font-size: 16px; + font-weight: $font-semibold; + } +} + +.button-show-channel { + display: none; +} + @media screen and (max-width: $mobile-view) { - .section { - .section-title { - flex-direction: column; - align-items: normal; + .channel-avatar-row { + grid-template-columns: auto auto auto 1fr; + + .avatar-link { + grid-row: 1 / 4; + } + + h2 { + font-size: 16px; + } + + .actor-counters { + margin: 0; + font-size: 13px; + grid-row: 2; + grid-column: 2 / 4; + } + + .description-html { + grid-row: 3; + font-size: 14px; } } + + .show-channel a { + @include peertube-button-link; + @include orange-button-inverted; + } + + .videos { + display: none; + } + + my-subscribe-button, + .button-show-channel { + grid-column: 1 / 4; + grid-row: 3; + margin-top: 15px; + } + + my-subscribe-button { + justify-self: start; + } + + .button-show-channel { + display: block; + justify-self: end; + } } 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 f2beb6689..0628c7a96 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 @@ -1,9 +1,10 @@ import { from, Subject, Subscription } from 'rxjs' import { concatMap, map, switchMap, tap } from 'rxjs/operators' import { Component, OnDestroy, OnInit } from '@angular/core' -import { ComponentPagination, hasMoreItems, ScreenService, User, UserService } from '@app/core' +import { ComponentPagination, hasMoreItems, MarkdownService, ScreenService, User, UserService } from '@app/core' import { Account, AccountService, Video, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main' import { NSFWPolicyType, VideoSortField } from '@shared/models' +import { MiniatureDisplayOptions } from '@app/shared/shared-video-miniature' @Component({ selector: 'my-account-video-channels', @@ -13,7 +14,10 @@ import { NSFWPolicyType, VideoSortField } from '@shared/models' export class AccountVideoChannelsComponent implements OnInit, OnDestroy { account: Account videoChannels: VideoChannel[] = [] - videos: { [id: number]: Video[] } = {} + + videos: { [id: number]: { total: number, videos: Video[] } } = {} + + channelsDescriptionHTML: { [ id: number ]: string } = {} channelPagination: ComponentPagination = { currentPage: 1, @@ -23,7 +27,7 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy { videosPagination: ComponentPagination = { currentPage: 1, - itemsPerPage: 12, + itemsPerPage: 5, totalItems: null } videosSort: VideoSortField = '-publishedAt' @@ -32,6 +36,16 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy { userMiniature: User nsfwPolicy: NSFWPolicyType + miniatureDisplayOptions: MiniatureDisplayOptions = { + date: true, + views: true, + by: false, + avatar: false, + privacyLabel: false, + privacyText: false, + state: false, + blacklistInfo: false + } private accountSub: Subscription @@ -39,7 +53,7 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy { private accountService: AccountService, private videoChannelService: VideoChannelService, private videoService: VideoService, - private screenService: ScreenService, + private markdown: MarkdownService, private userService: UserService ) { } @@ -78,23 +92,36 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy { } return this.videoService.getVideoChannelVideos(options) - .pipe(map(data => ({ videoChannel, videos: data.data }))) + .pipe(map(data => ({ videoChannel, videos: data.data, total: data.total }))) }) ) - .subscribe(({ videoChannel, videos }) => { + .subscribe(async ({ videoChannel, videos, total }) => { + this.channelsDescriptionHTML[videoChannel.id] = await this.markdown.textMarkdownToHTML(videoChannel.description) + this.videoChannels.push(videoChannel) - this.videos[videoChannel.id] = videos + this.videos[videoChannel.id] = { videos, total } this.onChannelDataSubject.next([ videoChannel ]) }) } getVideosOf (videoChannel: VideoChannel) { - const numberOfVideos = this.screenService.getNumberOfAvailableMiniatures() + const obj = this.videos[ videoChannel.id ] + if (!obj) return [] + + return obj.videos + } + + getTotalVideosOf (videoChannel: VideoChannel) { + const obj = this.videos[ videoChannel.id ] + if (!obj) return undefined + + return obj.total + } - // 2 rows - return this.videos[ videoChannel.id ].slice(0, numberOfVideos * 2) + getChannelDescription (videoChannel: VideoChannel) { + return this.channelsDescriptionHTML[videoChannel.id] } onNearOfBottom () { diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html index 92d24ce94..e149d0bc6 100644 --- a/client/src/app/+accounts/accounts.component.html +++ b/client/src/app/+accounts/accounts.component.html @@ -60,11 +60,11 @@
diff --git a/client/src/app/+accounts/accounts.component.scss b/client/src/app/+accounts/accounts.component.scss index c1cf53f3a..6a51dd038 100644 --- a/client/src/app/+accounts/accounts.component.scss +++ b/client/src/app/+accounts/accounts.component.scss @@ -4,7 +4,7 @@ @import '_miniature'; .root { - --myGlobalPadding: 60px; + --myGlobalTopPadding: 60px; --myImgMargin: 30px; --myFontSize: 16px; --myGreyFontSize: 16px; @@ -15,12 +15,16 @@ } .links { - @include fluid-videos-miniature-layout; + @include fluid-videos-miniature-margins; display: flex; justify-content: space-between; align-items: center; - max-width: 800px; + max-width: $max-channels-width; + + simple-search-input { + margin-left: auto; + } } my-user-moderation-dropdown, @@ -40,13 +44,15 @@ my-user-moderation-dropdown, } .account-info { + @include fluid-videos-miniature-margins(false, 15px); + display: grid; grid-template-columns: 1fr min-content; grid-template-rows: auto auto; background-color: pvar(--submenuColor); margin-bottom: 45px; - padding: var(--myGlobalPadding) var(--myGlobalPadding) 0 var(--myGlobalPadding); + padding-top: var(--myGlobalTopPadding); font-size: var(--myFontSize); } @@ -83,11 +89,15 @@ my-user-moderation-dropdown, > *:not(:last-child) { margin-bottom: 15px; } + + > a { + white-space: nowrap; + } } @media screen and (max-width: $small-view) { .root { - --myGlobalPadding: 45px; + --myGlobalTopPadding: 45px; --myChannelImgMargin: 15px; } @@ -113,7 +123,7 @@ my-user-moderation-dropdown, @media screen and (max-width: $mobile-view) { .root { - --myGlobalPadding: 15px; + --myGlobalTopPadding: 15px; --myFontSize: 14px; --myGreyFontSize: 13px; } diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts index a00063129..abee0b9bb 100644 --- a/client/src/app/+accounts/accounts.component.ts +++ b/client/src/app/+accounts/accounts.component.ts @@ -143,6 +143,10 @@ export class AccountsComponent implements OnInit, OnDestroy { this.hideMenu = this.isInSmallView() && displayed } + hasVideoChannels () { + return this.videoChannels.length !== 0 + } + private async onAccount (account: Account) { this.accountFollowerTitle = $localize`${account.followersCount} direct account followers` -- cgit v1.2.3