mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2024-11-10 12:26:35 +03:00
Refactor actor avatar display
This commit is contained in:
parent
ec489ce2f7
commit
746018f6b8
@ -8,9 +8,10 @@
|
||||
<div class="channel" *ngFor="let videoChannel of videoChannels">
|
||||
|
||||
<div class="channel-avatar-row">
|
||||
<a class="avatar-link" [routerLink]="getVideoChannelLink(videoChannel)" i18n-title title="See this video channel">
|
||||
<img [src]="videoChannel.avatarUrl" alt="Avatar" />
|
||||
</a>
|
||||
<my-actor-avatar
|
||||
[channel]="videoChannel" [internalHref]="getVideoChannelLink(videoChannel)"
|
||||
i18n-title title="See this video channel"
|
||||
></my-actor-avatar>
|
||||
|
||||
<h2>
|
||||
<a [routerLink]="getVideoChannelLink(videoChannel)" i18n-title title="See this video channel">
|
||||
|
@ -27,14 +27,12 @@
|
||||
grid-template-columns: auto auto 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
|
||||
.avatar-link {
|
||||
my-actor-avatar {
|
||||
@include actor-avatar-size(75px);
|
||||
|
||||
grid-column: 1;
|
||||
grid-row: 1 / 3;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
img {
|
||||
@include channel-avatar(75px);
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
a {
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="account-info">
|
||||
|
||||
<div class="account-avatar-row">
|
||||
<my-account-avatar [account]="account" size="120"></my-account-avatar>
|
||||
<my-actor-avatar class="main-avatar" [account]="account"></my-actor-avatar>
|
||||
|
||||
<div>
|
||||
<div class="section-label" i18n>PEERTUBE ACCOUNT</div>
|
||||
|
@ -10,7 +10,7 @@ import { AccountVideoChannelsComponent } from './account-video-channels/account-
|
||||
import { AccountVideosComponent } from './account-videos/account-videos.component'
|
||||
import { AccountsRoutingModule } from './accounts-routing.module'
|
||||
import { AccountsComponent } from './accounts.component'
|
||||
import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -22,7 +22,7 @@ import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/share
|
||||
SharedModerationModule,
|
||||
SharedVideoMiniatureModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedAccountAvatarModule
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -9,7 +9,7 @@ import { SharedGlobalIconModule } from '@app/shared/shared-icons'
|
||||
import { SharedMainModule } from '@app/shared/shared-main'
|
||||
import { SharedModerationModule } from '@app/shared/shared-moderation'
|
||||
import { SharedVideoCommentModule } from '@app/shared/shared-video-comment'
|
||||
import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module'
|
||||
import { AdminRoutingModule } from './admin-routing.module'
|
||||
import { AdminComponent } from './admin.component'
|
||||
import {
|
||||
@ -51,7 +51,7 @@ import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersCom
|
||||
SharedGlobalIconModule,
|
||||
SharedAbuseListModule,
|
||||
SharedVideoCommentModule,
|
||||
SharedAccountAvatarModule,
|
||||
SharedActorImageModule,
|
||||
SharedActorImageEditModule,
|
||||
|
||||
TableModule,
|
||||
|
@ -34,7 +34,7 @@
|
||||
<td>
|
||||
<a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
|
||||
<div class="chip two-lines">
|
||||
<my-account-avatar [account]="accountBlock.blockedAccount"></my-account-avatar>
|
||||
<my-actor-avatar [account]="accountBlock.blockedAccount"></my-actor-avatar>
|
||||
<div>
|
||||
{{ accountBlock.blockedAccount.displayName }}
|
||||
<span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span>
|
||||
|
@ -86,7 +86,7 @@
|
||||
<td>
|
||||
<a [href]="videoComment.account.localUrl" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
|
||||
<div class="chip two-lines">
|
||||
<my-account-avatar [account]="videoComment.account"></my-account-avatar>
|
||||
<my-actor-avatar [account]="videoComment.account"></my-actor-avatar>
|
||||
<div>
|
||||
{{ videoComment.account.displayName }}
|
||||
<span>{{ videoComment.by }}</span>
|
||||
|
@ -106,7 +106,7 @@
|
||||
<td *ngIf="isSelected('username')">
|
||||
<a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/accounts/' + user.username ]">
|
||||
<div class="chip two-lines">
|
||||
<my-account-avatar [account]="user?.account" size="32"></my-account-avatar>
|
||||
<my-actor-avatar [account]="user?.account" size="32"></my-actor-avatar>
|
||||
<div>
|
||||
<span class="user-table-primary-text">{{ user.account.displayName }}</span>
|
||||
<span class="text-muted">{{ user.username }}</span>
|
||||
|
@ -10,7 +10,7 @@ import { SharedMainModule } from '@app/shared/shared-main'
|
||||
import { SharedModerationModule } from '@app/shared/shared-moderation'
|
||||
import { SharedShareModal } from '@app/shared/shared-share-modal'
|
||||
import { SharedUserInterfaceSettingsModule } from '@app/shared/shared-user-settings'
|
||||
import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module'
|
||||
import { MyAccountAbusesListComponent } from './my-account-abuses/my-account-abuses-list.component'
|
||||
import { MyAccountApplicationsComponent } from './my-account-applications/my-account-applications.component'
|
||||
import { MyAccountBlocklistComponent } from './my-account-blocklist/my-account-blocklist.component'
|
||||
@ -40,7 +40,7 @@ import { MyAccountComponent } from './my-account.component'
|
||||
SharedGlobalIconModule,
|
||||
SharedAbuseListModule,
|
||||
SharedShareModal,
|
||||
SharedAccountAvatarModule,
|
||||
SharedActorImageModule,
|
||||
SharedActorImageEditModule
|
||||
],
|
||||
|
||||
|
@ -22,9 +22,7 @@
|
||||
|
||||
<div class="video-channels">
|
||||
<div *ngFor="let videoChannel of videoChannels; let i = index" class="video-channel">
|
||||
<a [routerLink]="[ '/video-channels', videoChannel.nameWithHost ]">
|
||||
<img [src]="videoChannel.avatarUrl" alt="Avatar" />
|
||||
</a>
|
||||
<my-actor-avatar [channel]="videoChannel" [internalHref]="[ '/video-channels', videoChannel.nameWithHost ]"></my-actor-avatar>
|
||||
|
||||
<div class="video-channel-info">
|
||||
<a [routerLink]="[ '/video-channels', videoChannel.nameWithHost ]" class="video-channel-names" i18n-title title="Channel page">
|
||||
|
@ -20,8 +20,8 @@ input[type=text] {
|
||||
|
||||
padding-bottom: 0;
|
||||
|
||||
img {
|
||||
@include channel-avatar(80px);
|
||||
my-actor-avatar {
|
||||
@include actor-avatar-size(80px);
|
||||
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import { MyVideoChannelCreateComponent } from './my-video-channel-create.compone
|
||||
import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component'
|
||||
import { MyVideoChannelsRoutingModule } from './my-video-channels-routing.module'
|
||||
import { MyVideoChannelsComponent } from './my-video-channels.component'
|
||||
import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-actor-image.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -18,7 +19,8 @@ import { MyVideoChannelsComponent } from './my-video-channels.component'
|
||||
SharedMainModule,
|
||||
SharedFormModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedActorImageEditModule
|
||||
SharedActorImageEditModule,
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -26,7 +26,7 @@ import { MyVideoPlaylistUpdateComponent } from './my-video-playlists/my-video-pl
|
||||
import { MyVideoPlaylistsComponent } from './my-video-playlists/my-video-playlists.component'
|
||||
import { VideoChangeOwnershipComponent } from './my-videos/modals/video-change-ownership.component'
|
||||
import { MyVideosComponent } from './my-videos/my-videos.component'
|
||||
import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -47,7 +47,7 @@ import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/share
|
||||
SharedAbuseListModule,
|
||||
SharedShareModal,
|
||||
SharedVideoLiveModule,
|
||||
SharedAccountAvatarModule
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -37,7 +37,7 @@
|
||||
<td>
|
||||
<a [href]="videoChangeOwnership.initiatorAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
|
||||
<div class="chip two-lines">
|
||||
<my-account-avatar [account]="videoChangeOwnership.initiatorAccount"></my-account-avatar>
|
||||
<my-actor-avatar [account]="videoChangeOwnership.initiatorAccount"></my-actor-avatar>
|
||||
<div>
|
||||
{{ videoChangeOwnership.initiatorAccount.displayName }}
|
||||
<span class="text-muted">{{ videoChangeOwnership.initiatorAccount.nameWithHost }}</span>
|
||||
|
@ -19,9 +19,7 @@
|
||||
|
||||
<div class="video-channels" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()">
|
||||
<div *ngFor="let videoChannel of videoChannels" class="video-channel">
|
||||
<a [routerLink]="[ '/video-channels', videoChannel.nameWithHost ]">
|
||||
<img [src]="videoChannel.avatarUrl" alt="Avatar" />
|
||||
</a>
|
||||
<my-actor-avatar [channel]="videoChannel" [internalHref]="[ '/video-channels', videoChannel.nameWithHost ]"></my-actor-avatar>
|
||||
|
||||
<div class="video-channel-info">
|
||||
<a [routerLink]="[ '/video-channels', videoChannel.nameWithHost ]" class="video-channel-names" i18n-title title="Channel page">
|
||||
@ -33,7 +31,8 @@
|
||||
|
||||
<a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" i18n-title title="Owner account page" class="actor-owner">
|
||||
<span i18n>Created by {{ videoChannel.ownerBy }}</span>
|
||||
<img [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" />
|
||||
|
||||
<my-actor-avatar [account]="videoChannel.ownerAccount" size="18"></my-actor-avatar>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -8,8 +8,8 @@ input[type=text] {
|
||||
.video-channel {
|
||||
@include row-blocks;
|
||||
|
||||
img {
|
||||
@include channel-avatar(80px);
|
||||
> my-actor-avatar {
|
||||
@include actor-avatar-size(80px);
|
||||
|
||||
margin-right: 10px;
|
||||
}
|
||||
@ -40,9 +40,20 @@ input[type=text] {
|
||||
}
|
||||
|
||||
.actor-owner {
|
||||
@include actor-owner;
|
||||
@include disable-default-a-behaviour;
|
||||
|
||||
margin-top: 0;
|
||||
font-size: 13px;
|
||||
color: pvar(--mainForegroundColor);
|
||||
|
||||
span:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
my-actor-avatar {
|
||||
margin-left: 7px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.video-subscriptions-header {
|
||||
|
@ -33,20 +33,15 @@
|
||||
|
||||
<ng-container *ngFor="let result of results">
|
||||
<div *ngIf="isVideoChannel(result)" class="entry video-channel">
|
||||
<a class="link-avatar" *ngIf="!isExternalChannelUrl()" [routerLink]="getChannelUrl(result)">
|
||||
<img [src]="result.avatarUrl" alt="Avatar" />
|
||||
</a>
|
||||
|
||||
<a class="link-avatar" *ngIf="isExternalChannelUrl()" [href]="getChannelUrl(result)" target="_blank">
|
||||
<img [src]="result.avatarUrl" alt="Avatar" />
|
||||
</a>
|
||||
<my-actor-avatar [channel]="result" [internalHref]="getInternalChannelUrl(result)" [href]="getExternalChannelUrl(result)"></my-actor-avatar>
|
||||
|
||||
<div class="video-channel-info">
|
||||
<a *ngIf="!isExternalChannelUrl()" [routerLink]="getChannelUrl(result)" class="video-channel-names">
|
||||
<a *ngIf="!isExternalChannelUrl()" [routerLink]="getInternalChannelUrl(result)" class="video-channel-names">
|
||||
<ng-container *ngTemplateOutlet="aContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<a *ngIf="isExternalChannelUrl()" [href]="getChannelUrl(result)" target="_blank" class="video-channel-names">
|
||||
<a *ngIf="isExternalChannelUrl()" [href]="getExternalChannelUrl(result)" target="_blank" class="video-channel-names">
|
||||
<ng-container *ngTemplateOutlet="aContent"></ng-container>
|
||||
</a>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
$image-size: min(130px, $video-img-width);
|
||||
$margin-size: ($video-img-width - $image-size) / 2; // So we have the same width than the video miniature
|
||||
|
||||
@include channel-avatar($image-size);
|
||||
@include actor-avatar-size($image-size);
|
||||
|
||||
margin: 0 $margin-size 0 $margin-size;
|
||||
}
|
||||
@ -53,10 +53,8 @@
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.video-channel {
|
||||
img {
|
||||
@include build-channel-img-size($video-thumbnail-width);
|
||||
}
|
||||
.video-channel my-actor-avatar {
|
||||
@include build-channel-img-size($video-thumbnail-width);
|
||||
}
|
||||
|
||||
.video-channel-info {
|
||||
@ -92,14 +90,12 @@
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-rows: auto auto;
|
||||
|
||||
.link-avatar {
|
||||
my-actor-avatar {
|
||||
@include build-channel-img-size($video-thumbnail-medium-width);
|
||||
|
||||
grid-column: 1;
|
||||
grid-row: 1 / -1;
|
||||
}
|
||||
|
||||
img {
|
||||
@include build-channel-img-size($video-thumbnail-medium-width);
|
||||
}
|
||||
}
|
||||
|
||||
.video-channel-info {
|
||||
@ -115,7 +111,7 @@
|
||||
}
|
||||
|
||||
@include on-mobile-main-col {
|
||||
.video-channel img {
|
||||
.video-channel my-actor-avatar {
|
||||
@include build-channel-img-size($video-thumbnail-small-width);
|
||||
}
|
||||
}
|
||||
|
@ -132,10 +132,6 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||
return 'internal'
|
||||
}
|
||||
|
||||
isExternalChannelUrl () {
|
||||
return this.getVideoLinkType() === 'external'
|
||||
}
|
||||
|
||||
search () {
|
||||
forkJoin([
|
||||
this.getVideosObs(),
|
||||
@ -200,17 +196,33 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||
this.results = this.results.filter(r => !this.isVideo(r) || r.id !== video.id)
|
||||
}
|
||||
|
||||
getChannelUrl (channel: VideoChannel) {
|
||||
isExternalChannelUrl () {
|
||||
return this.getVideoLinkType() === 'external'
|
||||
}
|
||||
|
||||
getExternalChannelUrl (channel: VideoChannel) {
|
||||
// Same algorithm than videos
|
||||
if (this.getVideoLinkType() === 'external') {
|
||||
return channel.url
|
||||
}
|
||||
|
||||
if (this.getVideoLinkType() === 'internal') {
|
||||
// lazy-load or internal
|
||||
return undefined
|
||||
}
|
||||
|
||||
getInternalChannelUrl (channel: VideoChannel) {
|
||||
const linkType = this.getVideoLinkType()
|
||||
|
||||
if (linkType === 'internal') {
|
||||
return [ '/video-channels', channel.nameWithHost ]
|
||||
}
|
||||
|
||||
return [ '/search/lazy-load-channel', { url: channel.url } ]
|
||||
if (linkType === 'lazy-load') {
|
||||
return [ '/search/lazy-load-channel', { url: channel.url } ]
|
||||
}
|
||||
|
||||
// external
|
||||
return undefined
|
||||
}
|
||||
|
||||
hideActions () {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-actor-image.module'
|
||||
import { SharedFormModule } from '@app/shared/shared-forms'
|
||||
import { SharedMainModule } from '@app/shared/shared-main'
|
||||
import { SharedSearchModule } from '@app/shared/shared-search'
|
||||
@ -18,6 +19,7 @@ import { VideoLazyLoadResolver } from './video-lazy-load.resolver'
|
||||
SharedMainModule,
|
||||
SharedSearchModule,
|
||||
SharedFormModule,
|
||||
SharedActorImageModule,
|
||||
SharedUserSubscriptionModule,
|
||||
SharedVideoMiniatureModule
|
||||
],
|
||||
|
@ -6,16 +6,16 @@
|
||||
<div class="channel-info">
|
||||
|
||||
<ng-template #buttonsTemplate>
|
||||
<a *ngIf="isManageable()" [routerLink]="[ '/my-library/video-channels/update', videoChannel.nameWithHost ]" class="peertube-button-link orange-button" i18n>
|
||||
Manage channel
|
||||
</a>
|
||||
<a *ngIf="isManageable()" [routerLink]="[ '/my-library/video-channels/update', videoChannel.nameWithHost ]" class="peertube-button-link orange-button" i18n>
|
||||
Manage channel
|
||||
</a>
|
||||
|
||||
<my-subscribe-button *ngIf="!isManageable()" #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button>
|
||||
<my-subscribe-button *ngIf="!isManageable()" #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button>
|
||||
|
||||
<button *ngIf="videoChannel.support" (click)="showSupportModal()" class="support-button peertube-button orange-button-inverted">
|
||||
<my-global-icon iconName="support" aria-hidden="true"></my-global-icon>
|
||||
<span class="icon-text" i18n>Support</span>
|
||||
</button>
|
||||
<button *ngIf="videoChannel.support" (click)="showSupportModal()" class="support-button peertube-button orange-button-inverted">
|
||||
<my-global-icon iconName="support" aria-hidden="true"></my-global-icon>
|
||||
<span class="icon-text" i18n>Support</span>
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #ownerTemplate>
|
||||
@ -23,7 +23,7 @@
|
||||
<div class="section-label" i18n>OWNER ACCOUNT</div>
|
||||
|
||||
<div class="avatar-row">
|
||||
<my-account-avatar [account]="videoChannel.ownerAccount" [internalHref]="getAccountUrl()" size="120"></my-account-avatar>
|
||||
<my-actor-avatar class="account-avatar" [account]="videoChannel.ownerAccount" [internalHref]="getAccountUrl()"></my-actor-avatar>
|
||||
|
||||
<div class="actor-info">
|
||||
<h4>
|
||||
@ -49,7 +49,7 @@
|
||||
</ng-template>
|
||||
|
||||
<div class="channel-avatar-row">
|
||||
<img class="channel-avatar" [src]="videoChannel.avatarUrl" alt="Avatar" />
|
||||
<my-actor-avatar class="main-avatar" [channel]="videoChannel"></my-actor-avatar>
|
||||
|
||||
<div>
|
||||
<div class="section-label" i18n>VIDEO CHANNEL</div>
|
||||
|
@ -107,8 +107,8 @@
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
|
||||
img {
|
||||
@include avatar(48px);
|
||||
.account-avatar {
|
||||
@include actor-avatar-size(48px);
|
||||
}
|
||||
|
||||
.actor-info {
|
||||
@ -289,8 +289,8 @@
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
img {
|
||||
@include channel-avatar(64px);
|
||||
.account-avatar {
|
||||
@include actor-avatar-size(64px);
|
||||
|
||||
margin: -30px 0 0 15px;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import { VideoChannelPlaylistsComponent } from './video-channel-playlists/video-
|
||||
import { VideoChannelVideosComponent } from './video-channel-videos/video-channel-videos.component'
|
||||
import { VideoChannelsRoutingModule } from './video-channels-routing.module'
|
||||
import { VideoChannelsComponent } from './video-channels.component'
|
||||
import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -23,7 +23,7 @@ import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/share
|
||||
SharedUserSubscriptionModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedSupportModal,
|
||||
SharedAccountAvatarModule
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -1,6 +1,6 @@
|
||||
<form novalidate [formGroup]="form" (ngSubmit)="formValidated()">
|
||||
<div class="avatar-and-textarea">
|
||||
<my-account-avatar [account]="user?.account" size="25"></my-account-avatar>
|
||||
<my-actor-avatar [account]="user?.account" size="25"></my-actor-avatar>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea i18n-placeholder placeholder="Add comment..." myAutoResize
|
||||
|
@ -13,8 +13,7 @@ form {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
|
||||
my-account-avatar {
|
||||
vertical-align: top;
|
||||
my-actor-avatar {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
<div *ngIf="isCommentDisplayed()" class="root-comment">
|
||||
<div *ngIf="isCommentDisplayed()" class="root-comment" [ngClass]="{ 'is-child': isChild() }">
|
||||
<div class="left">
|
||||
<my-account-avatar *ngIf="!comment.isDeleted" [href]="comment.account.url" [account]="comment.account"></my-account-avatar>
|
||||
<my-actor-avatar *ngIf="!comment.isDeleted" [href]="comment.account.url" [account]="comment.account"></my-actor-avatar>
|
||||
<div class="vertical-border"></div>
|
||||
</div>
|
||||
|
||||
<div class="right" [ngClass]="{ 'mb-3': firstInThread }">
|
||||
<span *ngIf="comment.isDeleted" class="comment-avatar"></span>
|
||||
|
||||
<div class="comment">
|
||||
<ng-container *ngIf="!comment.isDeleted">
|
||||
<div *ngIf="highlightedComment === true" class="highlighted-comment" i18n>Highlighted comment</div>
|
||||
@ -68,7 +66,7 @@
|
||||
[textValue]="redraftValue"
|
||||
></my-video-comment-add>
|
||||
|
||||
<div *ngIf="commentTree" class="children">
|
||||
<div *ngIf="commentTree">
|
||||
<div *ngFor="let commentChild of commentTree.children">
|
||||
<my-video-comment
|
||||
[comment]="commentChild.comment"
|
||||
|
@ -24,6 +24,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
my-actor-avatar {
|
||||
@include actor-avatar-size(36px);
|
||||
}
|
||||
|
||||
.comment {
|
||||
flex-grow: 1;
|
||||
// Fix word-wrap with flex
|
||||
@ -148,10 +152,10 @@ my-video-comment-add {
|
||||
}
|
||||
}
|
||||
|
||||
.children {
|
||||
.is-child {
|
||||
// Reduce avatars size for replies
|
||||
.comment-avatar {
|
||||
@include avatar(25px);
|
||||
my-actor-avatar {
|
||||
@include actor-avatar-size(25px);
|
||||
}
|
||||
|
||||
.left {
|
||||
|
@ -138,6 +138,10 @@ export class VideoCommentComponent implements OnInit, OnChanges {
|
||||
(this.commentTree?.hasDisplayedChildren) // Or this is a reply that have other replies
|
||||
}
|
||||
|
||||
isChild () {
|
||||
return this.parentComments.length !== 0
|
||||
}
|
||||
|
||||
private getUserIfNeeded (account: Account) {
|
||||
if (!account.userId) return
|
||||
if (!this.authService.isLoggedIn()) return
|
||||
|
@ -4,11 +4,11 @@
|
||||
<img [src]="video.videoChannelAvatarUrl" i18n-alt alt="Channel avatar" class="channel-avatar" />
|
||||
</a>
|
||||
|
||||
<my-account-avatar [account]="video.account" [title]="accountLinkTitle" [internalHref]="[ '/accounts', video.byAccount ]"></my-account-avatar>
|
||||
<my-actor-avatar [account]="video.account" [title]="accountLinkTitle" [internalHref]="[ '/accounts', video.byAccount ]"></my-actor-avatar>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!isChannelAvatarNull() && genericChannel">
|
||||
<my-account-avatar [account]="video.account" [title]="accountLinkTitle" [internalHref]="[ '/accounts', video.byAccount ]"></my-account-avatar>
|
||||
<my-actor-avatar [account]="video.account" [title]="accountLinkTitle" [internalHref]="[ '/accounts', video.byAccount ]"></my-actor-avatar>
|
||||
|
||||
<a [routerLink]="[ '/video-channels', video.byVideoChannel ]" [title]="channelLinkTitle">
|
||||
<img [src]="video.videoChannelAvatarUrl" i18n-alt alt="Channel avatar" class="channel-avatar" />
|
||||
@ -16,6 +16,6 @@
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="isChannelAvatarNull()">
|
||||
<my-account-avatar [account]="video.account" [title]="accountLinkTitle" [internalHref]="[ '/accounts', video.byAccount ]"></my-account-avatar>
|
||||
<my-actor-avatar [account]="video.account" [title]="accountLinkTitle" [internalHref]="[ '/accounts', video.byAccount ]"></my-actor-avatar>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
@ -20,7 +20,7 @@ import { TimestampRouteTransformerDirective } from './timestamp-route-transforme
|
||||
import { VideoWatchPlaylistComponent } from './video-watch-playlist.component'
|
||||
import { VideoWatchRoutingModule } from './video-watch-routing.module'
|
||||
import { VideoWatchComponent } from './video-watch.component'
|
||||
import { SharedAccountAvatarModule } from '../../shared/shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../../shared/shared-actor-image/shared-actor-image.module'
|
||||
import { VideoAvatarChannelComponent } from './video-avatar-channel.component'
|
||||
|
||||
@NgModule({
|
||||
@ -39,7 +39,7 @@ import { VideoAvatarChannelComponent } from './video-avatar-channel.component'
|
||||
SharedShareModal,
|
||||
SharedVideoModule,
|
||||
SharedSupportModal,
|
||||
SharedAccountAvatarModule
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -33,7 +33,7 @@
|
||||
<div class="section channel videos" *ngFor="let object of overview.channels">
|
||||
<div class="section-title">
|
||||
<a [routerLink]="[ '/video-channels', buildVideoChannelBy(object) ]">
|
||||
<img [src]="buildVideoChannelAvatarUrl(object)" alt="Avatar" />
|
||||
<my-actor-avatar [channel]="buildVideoChannel(object)"></my-actor-avatar>
|
||||
|
||||
<h2 class="section-title">{{ object.channel.displayName }}</h2>
|
||||
</a>
|
||||
|
@ -49,9 +49,10 @@
|
||||
width: fit-content;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
@include channel-avatar(28px);
|
||||
my-actor-avatar {
|
||||
@include actor-avatar-size(28px);
|
||||
|
||||
font-size: initial;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ export class VideoOverviewComponent implements OnInit {
|
||||
return object.videos[0].byVideoChannel
|
||||
}
|
||||
|
||||
buildVideoChannelAvatarUrl (object: { videos: Video[] }) {
|
||||
return object.videos[0].videoChannelAvatarUrl
|
||||
buildVideoChannel (object: { videos: Video[] }) {
|
||||
return object.videos[0].channel
|
||||
}
|
||||
|
||||
buildVideos (videos: Video[]) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-actor-image.module'
|
||||
import { SharedFormModule } from '@app/shared/shared-forms'
|
||||
import { SharedGlobalIconModule } from '@app/shared/shared-icons'
|
||||
import { SharedMainModule } from '@app/shared/shared-main'
|
||||
@ -21,7 +22,8 @@ import { VideosComponent } from './videos.component'
|
||||
SharedFormModule,
|
||||
SharedVideoMiniatureModule,
|
||||
SharedUserSubscriptionModule,
|
||||
SharedGlobalIconModule
|
||||
SharedGlobalIconModule,
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -24,7 +24,7 @@ import { SharedGlobalIconModule } from './shared/shared-icons'
|
||||
import { SharedInstanceModule } from './shared/shared-instance'
|
||||
import { SharedMainModule } from './shared/shared-main'
|
||||
import { SharedUserInterfaceSettingsModule } from './shared/shared-user-settings'
|
||||
import { SharedAccountAvatarModule } from './shared/shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from './shared/shared-actor-image/shared-actor-image.module'
|
||||
|
||||
registerLocaleData(localeOc, 'oc')
|
||||
|
||||
@ -60,7 +60,7 @@ registerLocaleData(localeOc, 'oc')
|
||||
SharedUserInterfaceSettingsModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedInstanceModule,
|
||||
SharedAccountAvatarModule,
|
||||
SharedActorImageModule,
|
||||
|
||||
MetaModule.forRoot({
|
||||
provide: MetaLoader,
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div>
|
||||
<div class="logged-in-more" ngbDropdown #dropdown="ngbDropdown" placement="bottom-left" [container]="dropdownContainer" (openChange)="onDropdownOpenChange($event)" autoClose="outside">
|
||||
<div ngbDropdownToggle>
|
||||
<my-account-avatar [account]="user.account" size="34"></my-account-avatar>
|
||||
<my-actor-avatar [account]="user.account" size="34"></my-actor-avatar>
|
||||
<div class="logged-in-info">
|
||||
<div class="logged-in-display-name">{{ user.account?.displayName }}</div>
|
||||
|
||||
|
@ -177,7 +177,7 @@ my-notification {
|
||||
}
|
||||
}
|
||||
|
||||
my-account-avatar {
|
||||
my-actor-avatar {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
<a [routerLink]="[ baseRoute ]" [queryParams]="{ 'search': 'reporter:"' + abuse.reporterAccount.displayName + '"' }"
|
||||
class="chip"
|
||||
>
|
||||
<my-account-avatar [account]="abuse.reporterAccount"></my-account-avatar>
|
||||
<my-actor-avatar [account]="abuse.reporterAccount"></my-actor-avatar>
|
||||
<div>
|
||||
<span class="text-muted">{{ abuse.reporterAccount.nameWithHost }}</span>
|
||||
</div>
|
||||
@ -30,7 +30,7 @@
|
||||
<a [routerLink]="[ baseRoute ]" [queryParams]="{ 'search': 'reportee:"' +abuse.flaggedAccount.displayName + '"' }"
|
||||
class="chip"
|
||||
>
|
||||
<my-account-avatar [account]="abuse.flaggedAccount"></my-account-avatar>
|
||||
<my-actor-avatar [account]="abuse.flaggedAccount"></my-actor-avatar>
|
||||
<div>
|
||||
<span class="text-muted">{{ abuse.flaggedAccount ? abuse.flaggedAccount.nameWithHost : '' }}</span>
|
||||
</div>
|
||||
|
@ -65,7 +65,7 @@
|
||||
<td *ngIf="isAdminView()">
|
||||
<a *ngIf="abuse.reporterAccount" [href]="abuse.reporterAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
|
||||
<div class="chip two-lines">
|
||||
<my-account-avatar [account]="abuse.reporterAccount"></my-account-avatar>
|
||||
<my-actor-avatar [account]="abuse.reporterAccount"></my-actor-avatar>
|
||||
<div>
|
||||
{{ abuse.reporterAccount.displayName }}
|
||||
<span>{{ abuse.reporterAccount.nameWithHost }}</span>
|
||||
|
@ -10,7 +10,7 @@ import { AbuseDetailsComponent } from './abuse-details.component'
|
||||
import { AbuseListTableComponent } from './abuse-list-table.component'
|
||||
import { AbuseMessageModalComponent } from './abuse-message-modal.component'
|
||||
import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
|
||||
import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -21,7 +21,7 @@ import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-accou
|
||||
SharedModerationModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedVideoCommentModule,
|
||||
SharedAccountAvatarModule
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -1,18 +0,0 @@
|
||||
<ng-template #img>
|
||||
<img *ngIf="avatarUrl || !initial" [class]="class" [src]="avatarUrl || defaultAvatarUrl" i18n-alt alt="Account avatar" />
|
||||
<div *ngIf="!avatarUrl && initial" [class]="class">
|
||||
<span>{{ initial }}</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<a *ngIf="account && href" [href]="href" target="_blank" rel="noopener noreferrer" [title]="title">
|
||||
<ng-template *ngTemplateOutlet="img"></ng-template>
|
||||
</a>
|
||||
|
||||
<a *ngIf="account && internalHref" [routerLink]="internalHref" [title]="title">
|
||||
<ng-template *ngTemplateOutlet="img"></ng-template>
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="!account || (!href && !internalHref)">
|
||||
<ng-template *ngTemplateOutlet="img"></ng-template>
|
||||
</ng-container>
|
@ -1,62 +0,0 @@
|
||||
import { Component, Input } from '@angular/core'
|
||||
import { Account } from '../shared-main/account/account.model'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-avatar',
|
||||
styleUrls: [ './account-avatar.component.scss' ],
|
||||
templateUrl: './account-avatar.component.html'
|
||||
})
|
||||
export class AccountAvatarComponent {
|
||||
@Input() account: {
|
||||
name: string
|
||||
avatar?: { url?: string, path: string }
|
||||
url: string
|
||||
}
|
||||
@Input() size: '25' | '32' | '34' | '36' | '40' | '120' = '36'
|
||||
|
||||
// Use an external link
|
||||
@Input() href: string
|
||||
// Use routerLink
|
||||
@Input() internalHref: string | string[]
|
||||
|
||||
@Input() set title (value) {
|
||||
this._title = value
|
||||
}
|
||||
|
||||
defaultAvatarUrl = Account.GET_DEFAULT_AVATAR_URL()
|
||||
|
||||
private _title: string
|
||||
|
||||
get title () {
|
||||
return this._title || $localize`${this.account.name} (account page)`
|
||||
}
|
||||
|
||||
get class () {
|
||||
return `avatar avatar-${this.size}` + (this.avatarUrl ? '' : ` initial ${this.getColorTheme()}`)
|
||||
}
|
||||
|
||||
get avatarUrl () {
|
||||
return Account.GET_ACTOR_AVATAR_URL(this.account)
|
||||
}
|
||||
|
||||
get initial () {
|
||||
return this.account?.name.slice(0, 1)
|
||||
}
|
||||
|
||||
private getColorTheme () {
|
||||
const themes = {
|
||||
abc: 'blue',
|
||||
def: 'green',
|
||||
ghi: 'purple',
|
||||
jkl: 'gray',
|
||||
mno: 'yellow',
|
||||
pqr: 'orange',
|
||||
stv: 'red',
|
||||
wxyz: 'dark-blue'
|
||||
}
|
||||
|
||||
const theme = Object.keys(themes).find(chars => chars.includes(this.initial))
|
||||
|
||||
return themes[theme]
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
export * from './account-avatar.component'
|
||||
export * from './shared-account-avatar.module'
|
@ -1,6 +1,6 @@
|
||||
<div class="actor" *ngIf="actor">
|
||||
<div class="d-flex">
|
||||
<img [ngClass]="{ channel: isChannel() }" [src]="preview || actor.avatarUrl" alt="Avatar" />
|
||||
<my-actor-avatar [channel]="getChannel()" [account]="getAccount()" [previewImage]="preview" size="100"></my-actor-avatar>
|
||||
|
||||
<div class="actor-img-edit-container">
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
<span for="avatarfile" i18n>Upload a new avatar</span>
|
||||
<input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="onAvatarChange(avatarfileInput)"/>
|
||||
</div>
|
||||
|
||||
<div class="dropdown-item c-hand" (click)="deleteAvatar()" (key.enter)="deleteAvatar()">
|
||||
<my-global-icon iconName="delete"></my-global-icon>
|
||||
<span i18n>Remove avatar</span>
|
||||
|
@ -4,16 +4,8 @@
|
||||
.actor {
|
||||
display: flex;
|
||||
|
||||
img {
|
||||
my-actor-avatar {
|
||||
margin-right: 15px;
|
||||
|
||||
&:not(.channel) {
|
||||
@include avatar(100px);
|
||||
}
|
||||
|
||||
&.channel {
|
||||
@include channel-avatar(100px);
|
||||
}
|
||||
}
|
||||
|
||||
.actor-info {
|
||||
|
@ -80,4 +80,16 @@ export class ActorAvatarEditComponent implements OnInit {
|
||||
isChannel () {
|
||||
return !!(this.actor as VideoChannel).ownerAccount
|
||||
}
|
||||
|
||||
getChannel (): VideoChannel {
|
||||
if (this.isChannel()) return this.actor as VideoChannel
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
getAccount (): Account {
|
||||
if (this.isChannel()) return undefined
|
||||
|
||||
return this.actor as Account
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { NgModule } from '@angular/core'
|
||||
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
||||
import { SharedGlobalIconModule } from '../shared-icons'
|
||||
import { SharedMainModule } from '../shared-main'
|
||||
import { ActorAvatarEditComponent } from './actor-avatar-edit.component'
|
||||
@ -11,6 +12,7 @@ import { ActorBannerEditComponent } from './actor-banner-edit.component'
|
||||
CommonModule,
|
||||
|
||||
SharedMainModule,
|
||||
SharedActorImageModule,
|
||||
SharedGlobalIconModule
|
||||
],
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
<ng-template #img>
|
||||
<img *ngIf="previewImage || avatarUrl || !initial" [class]="class" [src]="previewImage || avatarUrl || defaultAvatarUrl" [alt]="alt" />
|
||||
|
||||
<div *ngIf="!avatarUrl && initial" [class]="class">
|
||||
<span>{{ initial }}</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<a *ngIf="hasActor() && href" [href]="href" target="_blank" rel="noopener noreferrer" [title]="title">
|
||||
<ng-template *ngTemplateOutlet="img"></ng-template>
|
||||
</a>
|
||||
|
||||
<a *ngIf="hasActor() && internalHref" [routerLink]="internalHref" [title]="title">
|
||||
<ng-template *ngTemplateOutlet="img"></ng-template>
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="!hasActor() || (!href && !internalHref)">
|
||||
<ng-template *ngTemplateOutlet="img"></ng-template>
|
||||
</ng-container>
|
@ -1,32 +1,58 @@
|
||||
@import '_variables';
|
||||
@import '_mixins';
|
||||
|
||||
.avatar {
|
||||
--avatarSize: 100%;
|
||||
--initialFontSize: 22px;
|
||||
|
||||
width: var(--avatarSize);
|
||||
height: var(--avatarSize);
|
||||
min-width: var(--avatarSize);
|
||||
min-height: var(--avatarSize);
|
||||
|
||||
&.account {
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.channel {
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-18 {
|
||||
--avatarSize: 18px;
|
||||
--initialFontSize: 13px;
|
||||
}
|
||||
|
||||
.avatar-25 {
|
||||
@include avatar(25px);
|
||||
--avatarSize: 25px;
|
||||
}
|
||||
|
||||
.avatar-32 {
|
||||
@include avatar(32px);
|
||||
--avatarSize: 32px;
|
||||
}
|
||||
|
||||
.avatar-34 {
|
||||
@include avatar(34px);
|
||||
--avatarSize: 34px;
|
||||
}
|
||||
|
||||
.avatar-36 {
|
||||
@include avatar(36px);
|
||||
--avatarSize: 36px;
|
||||
}
|
||||
|
||||
.avatar-40 {
|
||||
@include avatar(40px);
|
||||
--avatarSize: 40px;
|
||||
}
|
||||
|
||||
.avatar-120 {
|
||||
@include avatar(120px);
|
||||
.avatar-100 {
|
||||
--avatarSize: 100px;
|
||||
--initialFontSize: 40px;
|
||||
}
|
||||
|
||||
&.initial {
|
||||
font-size: 46px;
|
||||
}
|
||||
.avatar-120 {
|
||||
--avatarSize: 120px;
|
||||
--initialFontSize: 46px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
@ -39,8 +65,7 @@ a:hover {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
border-radius: 50%;
|
||||
font-size: var(--initialFontSize);
|
||||
|
||||
&.blue {
|
||||
background-color: #009FD4;
|
@ -0,0 +1,110 @@
|
||||
import { Component, Input } from '@angular/core'
|
||||
import { SafeResourceUrl } from '@angular/platform-browser'
|
||||
import { VideoChannel } from '../shared-main'
|
||||
import { Account } from '../shared-main/account/account.model'
|
||||
|
||||
type ActorInput = {
|
||||
name: string
|
||||
avatar?: { url?: string, path: string }
|
||||
url: string
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'my-actor-avatar',
|
||||
styleUrls: [ './actor-avatar.component.scss' ],
|
||||
templateUrl: './actor-avatar.component.html'
|
||||
})
|
||||
export class ActorAvatarComponent {
|
||||
@Input() account: ActorInput
|
||||
@Input() channel: ActorInput
|
||||
|
||||
@Input() previewImage: SafeResourceUrl
|
||||
|
||||
@Input() size: '18' | '25' | '32' | '34' | '36' | '40' | '100' | '120'
|
||||
|
||||
// Use an external link
|
||||
@Input() href: string
|
||||
// Use routerLink
|
||||
@Input() internalHref: string | any[]
|
||||
|
||||
@Input() set title (value) {
|
||||
this._title = value
|
||||
}
|
||||
|
||||
private _title: string
|
||||
|
||||
get title () {
|
||||
if (this._title) return this._title
|
||||
if (this.account) return $localize`${this.account.name} (account page)`
|
||||
if (this.channel) return $localize`${this.channel.name} (channel page)`
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
get alt () {
|
||||
if (this.account) return $localize`Account avatar`
|
||||
if (this.channel) return $localize`Channel avatar`
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
get class () {
|
||||
const base = [ 'avatar' ]
|
||||
|
||||
if (this.size) base.push(`avatar-${this.size}`)
|
||||
|
||||
if (this.account) base.push('account')
|
||||
else base.push('channel')
|
||||
|
||||
if (this.initial) {
|
||||
base.push('initial')
|
||||
base.push(this.getColorTheme())
|
||||
}
|
||||
|
||||
return base
|
||||
}
|
||||
|
||||
get defaultAvatarUrl () {
|
||||
if (this.account) Account.GET_DEFAULT_AVATAR_URL()
|
||||
if (this.channel) return VideoChannel.GET_DEFAULT_AVATAR_URL()
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
get avatarUrl () {
|
||||
if (this.account) return Account.GET_ACTOR_AVATAR_URL(this.account)
|
||||
if (this.channel) return VideoChannel.GET_ACTOR_AVATAR_URL(this.account)
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
get initial () {
|
||||
const name = this.account?.name
|
||||
if (!name) return ''
|
||||
|
||||
return name.slice(0, 1)
|
||||
}
|
||||
|
||||
hasActor () {
|
||||
return !!this.account || !!this.channel
|
||||
}
|
||||
|
||||
private getColorTheme () {
|
||||
// Keep consistency with CSS
|
||||
const themes = {
|
||||
abc: 'blue',
|
||||
def: 'green',
|
||||
ghi: 'purple',
|
||||
jkl: 'gray',
|
||||
mno: 'yellow',
|
||||
pqr: 'orange',
|
||||
stv: 'red',
|
||||
wxyz: 'dark-blue'
|
||||
}
|
||||
|
||||
const theme = Object.keys(themes)
|
||||
.find(chars => chars.includes(this.initial))
|
||||
|
||||
return themes[theme]
|
||||
}
|
||||
}
|
1
client/src/app/shared/shared-actor-image/index.ts
Normal file
1
client/src/app/shared/shared-actor-image/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './shared-actor-image.module'
|
@ -2,7 +2,7 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { SharedGlobalIconModule } from '../shared-icons'
|
||||
import { SharedMainModule } from '../shared-main/shared-main.module'
|
||||
import { AccountAvatarComponent } from './account-avatar.component'
|
||||
import { ActorAvatarComponent } from './actor-avatar.component'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -11,13 +11,13 @@ import { AccountAvatarComponent } from './account-avatar.component'
|
||||
],
|
||||
|
||||
declarations: [
|
||||
AccountAvatarComponent
|
||||
ActorAvatarComponent
|
||||
],
|
||||
|
||||
exports: [
|
||||
AccountAvatarComponent
|
||||
ActorAvatarComponent
|
||||
],
|
||||
|
||||
providers: [ ]
|
||||
})
|
||||
export class SharedAccountAvatarModule { }
|
||||
export class SharedActorImageModule { }
|
@ -258,10 +258,10 @@ export class UserNotification implements UserNotificationServer {
|
||||
}
|
||||
|
||||
private setAccountAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) {
|
||||
actor.avatarUrl = Account.GET_ACTOR_AVATAR_URL(actor)
|
||||
actor.avatarUrl = Account.GET_ACTOR_AVATAR_URL(actor) || Account.GET_DEFAULT_AVATAR_URL()
|
||||
}
|
||||
|
||||
private setVideoChannelAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) {
|
||||
actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor)
|
||||
actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor) || VideoChannel.GET_DEFAULT_AVATAR_URL()
|
||||
}
|
||||
}
|
||||
|
@ -29,8 +29,11 @@
|
||||
}
|
||||
|
||||
.avatar {
|
||||
@include avatar(30px);
|
||||
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
min-width: 30px;
|
||||
min-height: 30px;
|
||||
border-radius: 5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
|
||||
viewsPerDay?: ViewsPerDate[]
|
||||
|
||||
static GET_ACTOR_AVATAR_URL (actor: object) {
|
||||
return Actor.GET_ACTOR_AVATAR_URL(actor) || this.GET_DEFAULT_AVATAR_URL()
|
||||
return Actor.GET_ACTOR_AVATAR_URL(actor)
|
||||
}
|
||||
|
||||
static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) {
|
||||
|
@ -38,7 +38,7 @@
|
||||
<td>
|
||||
<a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
|
||||
<div class="chip two-lines">
|
||||
<my-account-avatar [account]="accountBlock.blockedAccount"></my-account-avatar>
|
||||
<my-actor-avatar [account]="accountBlock.blockedAccount"></my-actor-avatar>
|
||||
<div>
|
||||
{{ accountBlock.blockedAccount.displayName }}
|
||||
<span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span>
|
||||
|
@ -13,7 +13,7 @@ import { UserBanModalComponent } from './user-ban-modal.component'
|
||||
import { UserModerationDropdownComponent } from './user-moderation-dropdown.component'
|
||||
import { VideoBlockComponent } from './video-block.component'
|
||||
import { VideoBlockService } from './video-block.service'
|
||||
import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -21,7 +21,7 @@ import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-accou
|
||||
SharedFormModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedVideoCommentModule,
|
||||
SharedAccountAvatarModule
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -13,7 +13,7 @@ import { VideoDownloadComponent } from './video-download.component'
|
||||
import { VideoMiniatureComponent } from './video-miniature.component'
|
||||
import { VideosSelectionComponent } from './videos-selection.component'
|
||||
import { VideoListHeaderComponent } from './video-list-header.component'
|
||||
import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-account-avatar.module'
|
||||
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -25,7 +25,7 @@ import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-accou
|
||||
SharedGlobalIconModule,
|
||||
SharedVideoLiveModule,
|
||||
SharedVideoModule,
|
||||
SharedAccountAvatarModule
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
@ -10,14 +10,15 @@
|
||||
<div class="video-bottom">
|
||||
<div class="video-miniature-information">
|
||||
<div class="d-flex video-miniature-meta">
|
||||
<a *ngIf="displayOptions.avatar && displayOwnerVideoChannel()" class="channel-avatar" [routerLink]="[ '/video-channels', video.byVideoChannel ]" [title]="channelLinkTitle">
|
||||
<img [src]="getAvatarUrl()" alt="" />
|
||||
</a>
|
||||
<my-actor-avatar
|
||||
*ngIf="displayOptions.avatar && displayOwnerVideoChannel()" [title]="channelLinkTitle"
|
||||
[channel]="video.channel" size="40" [internalHref]="[ '/video-channels', video.byVideoChannel ]"
|
||||
></my-actor-avatar>
|
||||
|
||||
<my-account-avatar
|
||||
<my-actor-avatar
|
||||
*ngIf="displayOptions.avatar && displayOwnerAccount()" [title]="channelLinkTitle"
|
||||
[account]="video.account" size="40" [internalHref]="'/video-channels/' + video.byVideoChannel"
|
||||
></my-account-avatar>
|
||||
[account]="video.account" size="40" [internalHref]="[ '/video-channels', video.byVideoChannel ]"
|
||||
></my-actor-avatar>
|
||||
|
||||
<div class="w-100 d-flex flex-column">
|
||||
<a *ngIf="!videoHref" tabindex="-1" class="video-miniature-name"
|
||||
|
@ -12,15 +12,10 @@ $more-button-width: 40px;
|
||||
width: calc(100% - #{$more-button-width});
|
||||
}
|
||||
|
||||
my-account-avatar,
|
||||
.channel-avatar {
|
||||
my-actor-avatar {
|
||||
margin: 10px 10px 0 0;
|
||||
}
|
||||
|
||||
.channel-avatar img{
|
||||
@include channel-avatar(40px);
|
||||
}
|
||||
|
||||
.video-miniature-created-at-views {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
@ -25,8 +25,8 @@
|
||||
grid-column: 1;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.channel-avatar {
|
||||
@include channel-avatar(120px);
|
||||
.main-avatar {
|
||||
@include actor-avatar-size(120px);
|
||||
}
|
||||
|
||||
> div {
|
||||
@ -77,12 +77,8 @@
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.channel-avatar {
|
||||
@include channel-avatar(80px);
|
||||
}
|
||||
|
||||
.account-avatar {
|
||||
@include avatar(120px);
|
||||
.main-avatar {
|
||||
@include actor-avatar-size(80px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -539,23 +539,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin avatar ($size) {
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
@mixin actor-avatar-size ($size) {
|
||||
display: inline-block;
|
||||
width: $size;
|
||||
height: $size;
|
||||
min-width: $size;
|
||||
min-height: $size;
|
||||
}
|
||||
|
||||
@mixin channel-avatar ($size) {
|
||||
width: $size;
|
||||
height: $size;
|
||||
min-width: $size;
|
||||
min-height: $size;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
@mixin chevron ($size, $border-width) {
|
||||
border-style: solid;
|
||||
border-width: $border-width $border-width 0 0;
|
||||
@ -595,26 +586,6 @@
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@mixin actor-owner {
|
||||
@include disable-default-a-behaviour;
|
||||
|
||||
font-size: 13px;
|
||||
margin-top: 4px;
|
||||
color: pvar(--mainForegroundColor);
|
||||
|
||||
span:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
img {
|
||||
@include avatar(18px);
|
||||
|
||||
margin-left: 7px;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin create-button {
|
||||
@include peertube-button-link;
|
||||
@include orange-button;
|
||||
|
Loading…
Reference in New Issue
Block a user