From 900f7820814b95b07ef0bcac04036a95abfbe060 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 26 Mar 2021 15:53:18 +0100 Subject: [PATCH] Redesign account's channels page --- .../account-video-channels.component.html | 43 +++-- .../account-video-channels.component.scss | 166 ++++++++++++++++-- .../account-video-channels.component.ts | 47 +++-- .../src/app/+accounts/accounts.component.html | 4 +- .../src/app/+accounts/accounts.component.scss | 22 ++- .../src/app/+accounts/accounts.component.ts | 4 + .../video-channel-videos.component.ts | 13 +- .../video-channels.component.html | 8 +- .../video-channels.component.scss | 14 +- .../misc/simple-search-input.component.scss | 4 +- client/src/sass/include/_miniature.scss | 41 +++-- client/src/sass/include/_variables.scss | 1 + 12 files changed, 296 insertions(+), 71 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 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` 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 index 803651505..5e2af1b92 100644 --- 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 @@ -5,7 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router' import { AuthService, ConfirmService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { immutableAssign } from '@app/helpers' import { VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main' -import { AbstractVideoList } from '@app/shared/shared-video-miniature' +import { AbstractVideoList, MiniatureDisplayOptions } from '@app/shared/shared-video-miniature' import { VideoFilter } from '@shared/models' @Component({ @@ -22,6 +22,17 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On filter: VideoFilter = null + displayOptions: MiniatureDisplayOptions = { + date: true, + views: true, + by: false, + avatar: false, + privacyLabel: true, + privacyText: false, + state: false, + blacklistInfo: false + } + private videoChannel: VideoChannel private videoChannelSub: Subscription diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html index d1eb15dff..9f9c1f2ca 100644 --- a/client/src/app/+video-channels/video-channels.component.html +++ b/client/src/app/+video-channels/video-channels.component.html @@ -2,17 +2,17 @@
- + Manage channel - +
- Owner account avatar +

{{ videoChannel.ownerAccount.displayName }}

@@ -36,7 +36,7 @@
- Avatar + Avatar
diff --git a/client/src/app/+video-channels/video-channels.component.scss b/client/src/app/+video-channels/video-channels.component.scss index f5547b4e9..fb71844bd 100644 --- a/client/src/app/+video-channels/video-channels.component.scss +++ b/client/src/app/+video-channels/video-channels.component.scss @@ -4,7 +4,7 @@ @import '_miniature'; .root { - --myGlobalPadding: 60px; + --myGlobalTopPadding: 60px; --myChannelImgMargin: 30px; --myFontSize: 16px; --myGreyChannelFontSize: 16px; @@ -16,17 +16,19 @@ } .links { - @include fluid-videos-miniature-layout; + @include fluid-videos-miniature-margins; } .channel-info { + @include fluid-videos-miniature-margins(false, 15px); + display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto; background-color: pvar(--channelBackgroundColor); margin-bottom: 45px; - padding: var(--myGlobalPadding) var(--myGlobalPadding) 0 var(--myGlobalPadding); + padding-top: var(--myGlobalTopPadding); font-size: var(--myFontSize); } @@ -146,7 +148,7 @@ @media screen and (max-width: 1100px) { .root { - --myGlobalPadding: 45px; + --myGlobalTopPadding: 45px; --myChannelImgMargin: 15px; } @@ -184,7 +186,7 @@ display: block; width: 100%; border-bottom: 2px solid $separator-border-color; - padding: var(--myGlobalPadding) 45px; + padding: var(--myGlobalTopPadding) 45px; margin-bottom: 60px; } @@ -223,7 +225,7 @@ @media screen and (max-width: $mobile-view) { .root { - --myGlobalPadding: 15px; + --myGlobalTopPadding: 15px; --myFontSize: 14px; --myGreyChannelFontSize: 13px; --myGreyOwnerFontSize: 13px; diff --git a/client/src/app/shared/shared-main/misc/simple-search-input.component.scss b/client/src/app/shared/shared-main/misc/simple-search-input.component.scss index 037937f80..116ff7ea0 100644 --- a/client/src/app/shared/shared-main/misc/simple-search-input.component.scss +++ b/client/src/app/shared/shared-main/misc/simple-search-input.component.scss @@ -6,8 +6,8 @@ } my-global-icon { - height: 26px; - width: 26px; + height: 28px; + width: 28px; margin-left: 10px; cursor: pointer; diff --git a/client/src/sass/include/_miniature.scss b/client/src/sass/include/_miniature.scss index 134b307b1..326d4677a 100644 --- a/client/src/sass/include/_miniature.scss +++ b/client/src/sass/include/_miniature.scss @@ -176,14 +176,41 @@ $play-overlay-width: 18px; } } -@mixin fluid-videos-miniature-layout { - margin-left: $not-expanded-horizontal-margins !important; - margin-right: $not-expanded-horizontal-margins !important; +// Use margin by default, or padding if $margin is false +@mixin fluid-videos-miniature-margins ($margin: true, $min-margin: 0) { + @if $margin { + margin-left: $not-expanded-horizontal-margins !important; + margin-right: $not-expanded-horizontal-margins !important; + } @else { + padding-left: $not-expanded-horizontal-margins !important; + padding-right: $not-expanded-horizontal-margins !important; + } @media screen and (max-width: $mobile-view) { width: auto; - margin: 0 !important; + @if $margin { + margin: $min-margin !important; + } @else { + padding: $min-margin !important; + } + } + + @media screen and (min-width: #{breakpoint(fhd)}) { + @if $margin { + margin-left: 6vw !important; + margin-right: 6vw !important; + } @else { + padding-left: 6vw !important; + padding-right: 6vw !important; + } + } +} + +@mixin fluid-videos-miniature-layout { + @include fluid-videos-miniature-margins; + + @media screen and (max-width: $mobile-view) { .videos { text-align: center; @@ -209,13 +236,7 @@ $play-overlay-width: 18px; } } - @media screen and (min-width: #{breakpoint(fhd)}) { - margin-left: 6vw !important; - margin-right: 6vw !important; - } - @media screen and (min-width: $mobile-view) { - .videos { --miniature-min-width: #{$video-thumbnail-width - 15px}; --miniature-max-width: #{$video-thumbnail-width}; diff --git a/client/src/sass/include/_variables.scss b/client/src/sass/include/_variables.scss index bcd28215b..724a897fa 100644 --- a/client/src/sass/include/_variables.scss +++ b/client/src/sass/include/_variables.scss @@ -52,6 +52,7 @@ $sub-menu-color: #F7F7F7; $sub-menu-height: 81px; $channel-background-color: #f6ede8; +$max-channels-width: 1200px; $footer-height: 30px; $footer-margin: 30px; -- 2.41.0