<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>
.channel {
max-width: $max-channels-width;
background-color: pvar(--channelBackgroundColor);
- padding: 15px;
+ padding: 30px;
margin: 30px 0;
}
@media screen and (max-width: $mobile-view) {
+ .channel {
+ padding: 15px;
+ }
+
.channel-avatar-row {
grid-template-columns: auto auto auto 1fr;
<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
>
.description {
grid-column: 1 / 3;
+ max-width: 1000px;
+ word-break: break-word;
}
.created-at {
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`
[miniatureDisplayOptions]="miniatureDisplayOptions"
[titlePage]="titlePage"
[getVideosObservableFunction]="getVideosObservableFunction"
- [ownerDisplayType]="ownerDisplayType"
[user]="user"
#videosSelection
>
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'
state: true,
blacklistInfo: true
}
- ownerDisplayType: OwnerDisplayType = 'videoChannel'
videoActions: DropdownAction<{ video: Video }>[] = []
<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>
<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>
<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
>
.channel-description {
grid-column: 1;
+ word-break: break-word;
}
.show-more {
h4 {
font-size: 18px;
margin: 0;
+
+ a {
+ color: pvar(--mainForegroundColor);
+ }
}
.actor-handle {
.owner-description {
height: 140px;
+ word-break: break-word;
@include fade-text(120px, pvar(--mainBackgroundColor));
}
}
.view-account.complete {
- display: inline-block;
+ display: block;
+ text-align: right;
margin-top: 10px;
color: pvar(--mainColor);
}
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,
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'
export class VideoUserSubscriptionsComponent extends AbstractVideoList implements OnInit, OnDestroy {
titlePage: string
sort = '-publishedAt' as VideoSortField
- ownerDisplayType: OwnerDisplayType = 'auto'
groupByDate = true
constructor (
top:50%;
left:50%;
transform: translate(-50%,-50%);
+ border-radius: 5px;
&:not(.channel-avatar) {
border-radius: 50%;
}
&[iconName=search] {
- color: pvar(--mainColor);
+ color: pvar(--mainForegroundColor);
}
&[iconName=cross] {
-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 {
nameWithHost: string
nameWithHostForced: string
- ownerAccount?: Account
+ ownerAccount?: ServerAccount
ownerBy?: string
ownerAvatarUrl?: string
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)
}
}
<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)"
>
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,
loadOnInit = true
loadUserVideoPreferences = false
- ownerDisplayType: OwnerDisplayType = 'auto'
displayModerationBlock = false
titleTooltip: string
displayVideoActions = true
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
@Input() user: User
@Input() video: Video
- @Input() ownerDisplayType: OwnerDisplayType = 'account'
@Input() displayOptions: MiniatureDisplayOptions = {
date: true,
views: true,
videoHref: string
videoTarget: string
- private ownerDisplayTypeChosen: 'account' | 'videoChannel'
+ private ownerDisplayType: 'account' | 'videoChannel'
constructor (
private screenService: ScreenService,
}
displayOwnerAccount () {
- return this.ownerDisplayTypeChosen === 'account'
+ return this.ownerDisplayType === 'account'
}
displayOwnerVideoChannel () {
- return this.ownerDisplayTypeChosen === 'videoChannel'
+ return this.ownerDisplayType === 'videoChannel'
}
isUnlistedVideo () {
}
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'
}
}
<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 -->
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 }
@Input() pagination: ComponentPagination
@Input() titlePage: string
@Input() miniatureDisplayOptions: MiniatureDisplayOptions
- @Input() ownerDisplayType: OwnerDisplayType
@Input() getVideosObservableFunction: (page: number, sort?: VideoSortField) => Observable<ResultList<Video>>
@include button-focus(pvar(--mainColorLightest));
border: 2px solid pvar(--mainColor);
- font-weight: $font-regular;
+ font-weight: $font-semibold;
&, &:active, &:focus {
color: pvar(--mainColor);
height: $size;
min-width: $size;
min-height: $size;
+ border-radius: 5px;
}
@mixin chevron ($size, $border-width) {