Channel/account page redesign feedbacks
Fix owner default avatar Semi bold orange inverted button Max width account description Increase account's channels padding Use owner avatar/display name links Move "view owner account" link on mobile Try to always display channel in video miniatures Add small border radius for channel's avatar Use main foreground color for the magnifying glass
This commit is contained in:
parent
c8e80d1461
commit
733dbc535d
20 changed files with 63 additions and 41 deletions
|
@ -22,7 +22,7 @@
|
|||
<div class="followers" i18n>{videoChannel.followersCount, plural, =1 {1 subscriber} other {{{ videoChannel.followersCount }} subscribers}}</div>
|
||||
|
||||
<span class="videos-count" *ngIf="getTotalVideosOf(videoChannel) !== undefined" i18n>
|
||||
{getTotalVideosOf(videoChannel), splural, =1 {1 videos} other {{{ getTotalVideosOf(videoChannel) }} videos}}
|
||||
{getTotalVideosOf(videoChannel), plural, =1 {1 videos} other {{{ getTotalVideosOf(videoChannel) }} videos}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
.channel {
|
||||
max-width: $max-channels-width;
|
||||
background-color: pvar(--channelBackgroundColor);
|
||||
padding: 15px;
|
||||
padding: 30px;
|
||||
|
||||
margin: 30px 0;
|
||||
|
||||
|
@ -120,6 +120,10 @@ my-subscribe-button {
|
|||
}
|
||||
|
||||
@media screen and (max-width: $mobile-view) {
|
||||
.channel {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.channel-avatar-row {
|
||||
grid-template-columns: auto auto auto 1fr;
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<div class="created-at" i18n>Account created on {{ account.createdAt | date }}</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!accountDescriptionExpanded" class="show-more" role="button"
|
||||
<div *ngIf="hasShowMoreDescription()" class="show-more" role="button"
|
||||
(click)="accountDescriptionExpanded = !accountDescriptionExpanded"
|
||||
title="Show the complete description" i18n-title i18n
|
||||
>
|
||||
|
|
|
@ -62,6 +62,8 @@ my-user-moderation-dropdown,
|
|||
|
||||
.description {
|
||||
grid-column: 1 / 3;
|
||||
max-width: 1000px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.created-at {
|
||||
|
|
|
@ -147,6 +147,10 @@ export class AccountsComponent implements OnInit, OnDestroy {
|
|||
return this.videoChannels.length !== 0
|
||||
}
|
||||
|
||||
hasShowMoreDescription () {
|
||||
return !this.accountDescriptionExpanded && this.accountDescriptionHTML.length > 100
|
||||
}
|
||||
|
||||
private async onAccount (account: Account) {
|
||||
this.accountFollowerTitle = $localize`${account.followersCount} direct account followers`
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
[miniatureDisplayOptions]="miniatureDisplayOptions"
|
||||
[titlePage]="titlePage"
|
||||
[getVideosObservableFunction]="getVideosObservableFunction"
|
||||
[ownerDisplayType]="ownerDisplayType"
|
||||
[user]="user"
|
||||
#videosSelection
|
||||
>
|
||||
|
|
|
@ -2,12 +2,12 @@ import { concat, Observable, Subject } from 'rxjs'
|
|||
import { debounceTime, tap, toArray } from 'rxjs/operators'
|
||||
import { Component, OnInit, ViewChild } from '@angular/core'
|
||||
import { ActivatedRoute, Router } from '@angular/router'
|
||||
import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, ServerService, User, UserService } from '@app/core'
|
||||
import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, ServerService, User } from '@app/core'
|
||||
import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
|
||||
import { immutableAssign } from '@app/helpers'
|
||||
import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
|
||||
import { LiveStreamInformationComponent } from '@app/shared/shared-video-live'
|
||||
import { MiniatureDisplayOptions, OwnerDisplayType, SelectionType, VideosSelectionComponent } from '@app/shared/shared-video-miniature'
|
||||
import { MiniatureDisplayOptions, SelectionType, VideosSelectionComponent } from '@app/shared/shared-video-miniature'
|
||||
import { VideoSortField } from '@shared/models'
|
||||
import { VideoChangeOwnershipComponent } from './modals/video-change-ownership.component'
|
||||
|
||||
|
@ -36,7 +36,6 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
|
|||
state: true,
|
||||
blacklistInfo: true
|
||||
}
|
||||
ownerDisplayType: OwnerDisplayType = 'videoChannel'
|
||||
|
||||
videoActions: DropdownAction<{ video: Video }>[] = []
|
||||
|
||||
|
|
|
@ -17,10 +17,14 @@
|
|||
<ng-template #ownerTemplate>
|
||||
<div class="owner-block">
|
||||
<div class="avatar-row">
|
||||
<img class="account-avatar" [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" />
|
||||
<a [routerLink]="getAccountUrl()" title="View account" i18n-title>
|
||||
<img class="account-avatar" [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" />
|
||||
</a>
|
||||
|
||||
<div class="actor-info">
|
||||
<h4>{{ videoChannel.ownerAccount.displayName }}</h4>
|
||||
<h4>
|
||||
<a [routerLink]="getAccountUrl()" title="View account" i18n-title>{{ videoChannel.ownerAccount.displayName }}</a>
|
||||
</h4>
|
||||
|
||||
<div class="actor-handle">@{{ videoChannel.ownerBy }}</div>
|
||||
</div>
|
||||
|
@ -30,11 +34,11 @@
|
|||
<div class="description-html" [innerHTML]="ownerDescriptionHTML"></div>
|
||||
</div>
|
||||
|
||||
<a class="view-account short" [routerLink]="[ '/accounts', videoChannel.ownerBy ]" i18n>
|
||||
<a class="view-account short" [routerLink]="getAccountUrl()" i18n>
|
||||
View account
|
||||
</a>
|
||||
|
||||
<a class="view-account complete" [routerLink]="[ '/accounts', videoChannel.ownerBy ]" i18n>
|
||||
<a class="view-account complete" [routerLink]="getAccountUrl()" i18n>
|
||||
View owner account
|
||||
</a>
|
||||
</div>
|
||||
|
@ -83,7 +87,7 @@
|
|||
<div class="created-at" i18n>Channel created on {{ videoChannel.createdAt | date }}</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!channelDescriptionExpanded" class="show-more" role="button"
|
||||
<div *ngIf="hasShowMoreDescription()" class="show-more" role="button"
|
||||
(click)="channelDescriptionExpanded = !channelDescriptionExpanded"
|
||||
title="Show the complete description" i18n-title i18n
|
||||
>
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
.channel-description {
|
||||
grid-column: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.show-more {
|
||||
|
@ -108,6 +109,10 @@
|
|||
h4 {
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
|
||||
a {
|
||||
color: pvar(--mainForegroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
.actor-handle {
|
||||
|
@ -118,6 +123,7 @@
|
|||
|
||||
.owner-description {
|
||||
height: 140px;
|
||||
word-break: break-word;
|
||||
|
||||
@include fade-text(120px, pvar(--mainBackgroundColor));
|
||||
}
|
||||
|
@ -217,7 +223,8 @@
|
|||
}
|
||||
|
||||
.view-account.complete {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
text-align: right;
|
||||
margin-top: 10px;
|
||||
color: pvar(--mainColor);
|
||||
}
|
||||
|
|
|
@ -103,10 +103,18 @@ export class VideoChannelsComponent implements OnInit, OnDestroy {
|
|||
this.notifier.success($localize`Username copied`)
|
||||
}
|
||||
|
||||
hasShowMoreDescription () {
|
||||
return !this.channelDescriptionExpanded && this.channelDescriptionHTML.length > 100
|
||||
}
|
||||
|
||||
showSupportModal () {
|
||||
this.supportModal.show()
|
||||
}
|
||||
|
||||
getAccountUrl () {
|
||||
return [ '/accounts', this.videoChannel.ownerBy ]
|
||||
}
|
||||
|
||||
private loadChannelVideosCount () {
|
||||
this.videoService.getVideoChannelVideos({
|
||||
videoChannel: this.videoChannel,
|
||||
|
|
|
@ -7,7 +7,7 @@ import { HooksService } from '@app/core/plugins/hooks.service'
|
|||
import { immutableAssign } from '@app/helpers'
|
||||
import { VideoService } from '@app/shared/shared-main'
|
||||
import { UserSubscriptionService } from '@app/shared/shared-user-subscription'
|
||||
import { AbstractVideoList, OwnerDisplayType } from '@app/shared/shared-video-miniature'
|
||||
import { AbstractVideoList } from '@app/shared/shared-video-miniature'
|
||||
import { FeedFormat, VideoSortField } from '@shared/models'
|
||||
import { environment } from '../../../environments/environment'
|
||||
import { copyToClipboard } from '../../../root-helpers/utils'
|
||||
|
@ -20,7 +20,6 @@ import { copyToClipboard } from '../../../root-helpers/utils'
|
|||
export class VideoUserSubscriptionsComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
||||
titlePage: string
|
||||
sort = '-publishedAt' as VideoSortField
|
||||
ownerDisplayType: OwnerDisplayType = 'auto'
|
||||
groupByDate = true
|
||||
|
||||
constructor (
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%,-50%);
|
||||
border-radius: 5px;
|
||||
|
||||
&:not(.channel-avatar) {
|
||||
border-radius: 50%;
|
||||
|
|
|
@ -16,7 +16,7 @@ my-global-icon {
|
|||
}
|
||||
|
||||
&[iconName=search] {
|
||||
color: pvar(--mainColor);
|
||||
color: pvar(--mainForegroundColor);
|
||||
}
|
||||
|
||||
&[iconName=cross] {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { VideoChannel as ServerVideoChannel, ViewsPerDate, Account, Avatar } from '@shared/models'
|
||||
import { Account as ServerAccount, Avatar, VideoChannel as ServerVideoChannel, ViewsPerDate } from '@shared/models'
|
||||
import { Account } from '../account/account.model'
|
||||
import { Actor } from '../account/actor.model'
|
||||
|
||||
export class VideoChannel extends Actor implements ServerVideoChannel {
|
||||
|
@ -9,7 +10,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
|
|||
nameWithHost: string
|
||||
nameWithHostForced: string
|
||||
|
||||
ownerAccount?: Account
|
||||
ownerAccount?: ServerAccount
|
||||
ownerBy?: string
|
||||
ownerAvatarUrl?: string
|
||||
|
||||
|
@ -46,7 +47,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
|
|||
if (hash.ownerAccount) {
|
||||
this.ownerAccount = hash.ownerAccount
|
||||
this.ownerBy = Actor.CREATE_BY_STRING(hash.ownerAccount.name, hash.ownerAccount.host)
|
||||
this.ownerAvatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this.ownerAccount)
|
||||
this.ownerAvatarUrl = Account.GET_ACTOR_AVATAR_URL(this.ownerAccount)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,7 @@
|
|||
|
||||
<div class="video-wrapper">
|
||||
<my-video-miniature
|
||||
[fitWidth]="true"
|
||||
[video]="video" [user]="userMiniature" [ownerDisplayType]="ownerDisplayType"
|
||||
[fitWidth]="true" [video]="video" [user]="userMiniature"
|
||||
[displayVideoActions]="displayVideoActions" [displayOptions]="displayOptions"
|
||||
(videoBlocked)="removeVideoFromArray(video)" (videoRemoved)="removeVideoFromArray(video)"
|
||||
>
|
||||
|
|
|
@ -28,8 +28,8 @@ import { isLastMonth, isLastWeek, isThisMonth, isToday, isYesterday } from '@sha
|
|||
import { ServerConfig, UserRight, VideoFilter, VideoSortField } from '@shared/models'
|
||||
import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type'
|
||||
import { Syndication, Video } from '../shared-main'
|
||||
import { MiniatureDisplayOptions, OwnerDisplayType } from './video-miniature.component'
|
||||
import { GenericHeaderComponent, VideoListHeaderComponent } from './video-list-header.component'
|
||||
import { MiniatureDisplayOptions } from './video-miniature.component'
|
||||
|
||||
enum GroupDate {
|
||||
UNKNOWN = 0,
|
||||
|
@ -65,7 +65,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, AfterConte
|
|||
loadOnInit = true
|
||||
loadUserVideoPreferences = false
|
||||
|
||||
ownerDisplayType: OwnerDisplayType = 'auto'
|
||||
displayModerationBlock = false
|
||||
titleTooltip: string
|
||||
displayVideoActions = true
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Video } from '../shared-main'
|
|||
import { VideoPlaylistService } from '../shared-video-playlist'
|
||||
import { VideoActionsDisplayType } from './video-actions-dropdown.component'
|
||||
|
||||
export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto'
|
||||
export type OwnerDisplayType = 'account' | 'videoChannel'
|
||||
export type MiniatureDisplayOptions = {
|
||||
date?: boolean
|
||||
views?: boolean
|
||||
|
@ -40,7 +40,6 @@ export class VideoMiniatureComponent implements OnInit {
|
|||
@Input() user: User
|
||||
@Input() video: Video
|
||||
|
||||
@Input() ownerDisplayType: OwnerDisplayType = 'account'
|
||||
@Input() displayOptions: MiniatureDisplayOptions = {
|
||||
date: true,
|
||||
views: true,
|
||||
|
@ -89,7 +88,7 @@ export class VideoMiniatureComponent implements OnInit {
|
|||
videoHref: string
|
||||
videoTarget: string
|
||||
|
||||
private ownerDisplayTypeChosen: 'account' | 'videoChannel'
|
||||
private ownerDisplayType: 'account' | 'videoChannel'
|
||||
|
||||
constructor (
|
||||
private screenService: ScreenService,
|
||||
|
@ -140,11 +139,11 @@ export class VideoMiniatureComponent implements OnInit {
|
|||
}
|
||||
|
||||
displayOwnerAccount () {
|
||||
return this.ownerDisplayTypeChosen === 'account'
|
||||
return this.ownerDisplayType === 'account'
|
||||
}
|
||||
|
||||
displayOwnerVideoChannel () {
|
||||
return this.ownerDisplayTypeChosen === 'videoChannel'
|
||||
return this.ownerDisplayType === 'videoChannel'
|
||||
}
|
||||
|
||||
isUnlistedVideo () {
|
||||
|
@ -245,21 +244,19 @@ export class VideoMiniatureComponent implements OnInit {
|
|||
}
|
||||
|
||||
private setUpBy () {
|
||||
if (this.ownerDisplayType === 'account' || this.ownerDisplayType === 'videoChannel') {
|
||||
this.ownerDisplayTypeChosen = this.ownerDisplayType
|
||||
return
|
||||
}
|
||||
const accountName = this.video.account.name
|
||||
|
||||
// If the video channel name is an UUID (not really displayable, we changed this behaviour in v1.0.0-beta.12)
|
||||
// Or is just a suffix of the account (default created channel)
|
||||
// Or has not been customized (default created channel display name)
|
||||
// -> Use the account name
|
||||
if (
|
||||
this.video.channel.name === `${this.video.account.name}_channel` ||
|
||||
this.video.channel.displayName === `Default ${accountName} channel` ||
|
||||
this.video.channel.displayName === `Main ${accountName} channel` ||
|
||||
this.video.channel.name.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/)
|
||||
) {
|
||||
this.ownerDisplayTypeChosen = 'account'
|
||||
this.ownerDisplayType = 'account'
|
||||
} else {
|
||||
this.ownerDisplayTypeChosen = 'videoChannel'
|
||||
this.ownerDisplayType = 'videoChannel'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
|
||||
<my-video-miniature
|
||||
[video]="video" [displayAsRow]="true" [displayOptions]="miniatureDisplayOptions"
|
||||
[displayVideoActions]="false" [ownerDisplayType]="ownerDisplayType"
|
||||
[user]="user"
|
||||
[displayVideoActions]="false" [user]="user"
|
||||
></my-video-miniature>
|
||||
|
||||
<!-- Display only once -->
|
||||
|
|
|
@ -17,7 +17,7 @@ import { AuthService, ComponentPagination, LocalStorageService, Notifier, Screen
|
|||
import { ResultList, VideoSortField } from '@shared/models'
|
||||
import { PeerTubeTemplateDirective, Video } from '../shared-main'
|
||||
import { AbstractVideoList } from './abstract-video-list'
|
||||
import { MiniatureDisplayOptions, OwnerDisplayType } from './video-miniature.component'
|
||||
import { MiniatureDisplayOptions } from './video-miniature.component'
|
||||
|
||||
export type SelectionType = { [ id: number ]: boolean }
|
||||
|
||||
|
@ -31,7 +31,6 @@ export class VideosSelectionComponent extends AbstractVideoList implements OnIni
|
|||
@Input() pagination: ComponentPagination
|
||||
@Input() titlePage: string
|
||||
@Input() miniatureDisplayOptions: MiniatureDisplayOptions
|
||||
@Input() ownerDisplayType: OwnerDisplayType
|
||||
|
||||
@Input() getVideosObservableFunction: (page: number, sort?: VideoSortField) => Observable<ResultList<Video>>
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
@include button-focus(pvar(--mainColorLightest));
|
||||
|
||||
border: 2px solid pvar(--mainColor);
|
||||
font-weight: $font-regular;
|
||||
font-weight: $font-semibold;
|
||||
|
||||
&, &:active, &:focus {
|
||||
color: pvar(--mainColor);
|
||||
|
@ -551,6 +551,7 @@
|
|||
height: $size;
|
||||
min-width: $size;
|
||||
min-height: $size;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
@mixin chevron ($size, $border-width) {
|
||||
|
|
Loading…
Reference in a new issue