Refactor video miniatures
This commit is contained in:
parent
8fc02e4768
commit
e2409062de
18 changed files with 199 additions and 244 deletions
|
@ -23,7 +23,6 @@ import { Notifier, ServerService } from '@app/core'
|
||||||
})
|
})
|
||||||
export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
||||||
titlePage: string
|
titlePage: string
|
||||||
marginContent = false // Disable margin
|
|
||||||
loadOnInit = false
|
loadOnInit = false
|
||||||
|
|
||||||
private account: Account
|
private account: Account
|
||||||
|
|
|
@ -6,15 +6,7 @@
|
||||||
<my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox>
|
<my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<my-video-thumbnail [video]="video"></my-video-thumbnail>
|
<my-video-miniature [video]="video" [displayAsRow]="true" [displayOptions]="miniatureDisplayOptions"></my-video-miniature>
|
||||||
|
|
||||||
<div class="video-info">
|
|
||||||
<a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
|
|
||||||
<div>{{ video.account.displayName }}</div>
|
|
||||||
<div>{{ video.publishedAt | myFromNow }}</div>
|
|
||||||
<div><span i18n>Privacy: </span><span>{{ video.privacy.label }}</span></div>
|
|
||||||
<div><span i18n>Sensitive: </span><span> {{ video.nsfw }}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Display only once -->
|
<!-- Display only once -->
|
||||||
<div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
|
<div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
|
||||||
|
@ -30,8 +22,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="video-buttons" *ngIf="isInSelectionMode() === false">
|
|
||||||
<my-button
|
<my-button
|
||||||
|
*ngIf="isInSelectionMode() === false"
|
||||||
i18n-label
|
i18n-label
|
||||||
label="Unblacklist"
|
label="Unblacklist"
|
||||||
icon="tick"
|
icon="tick"
|
||||||
|
@ -39,4 +31,3 @@
|
||||||
></my-button>
|
></my-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
|
@ -46,26 +46,8 @@
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
my-video-thumbnail {
|
my-video-miniature {
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info {
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
||||||
.video-info-name {
|
|
||||||
@include disable-default-a-behaviour;
|
|
||||||
|
|
||||||
color: var(--mainForegroundColor);
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: $font-semibold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-buttons {
|
|
||||||
min-width: 190px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,21 +55,12 @@
|
||||||
.video {
|
.video {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: auto;
|
height: auto;
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.video-info-name {
|
.checkbox-container {
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=checkbox] {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
my-video-thumbnail {
|
my-button {
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-buttons {
|
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { Component, OnInit, OnDestroy } from '@angular/core'
|
import { Component, OnDestroy, OnInit } from '@angular/core'
|
||||||
import { Location } from '@angular/common'
|
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { Router, ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute, Router } from '@angular/router'
|
||||||
import { AbstractVideoList } from '@app/shared/video/abstract-video-list'
|
import { AbstractVideoList } from '@app/shared/video/abstract-video-list'
|
||||||
import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
|
import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
|
||||||
import { Notifier, AuthService, ServerService } from '@app/core'
|
import { AuthService, Notifier, ServerService } from '@app/core'
|
||||||
import { Video } from '@shared/models'
|
import { Video } from '@shared/models'
|
||||||
import { VideoBlacklistService } from '@app/shared'
|
import { VideoBlacklistService } from '@app/shared'
|
||||||
import { immutableAssign } from '@app/shared/misc/utils'
|
import { immutableAssign } from '@app/shared/misc/utils'
|
||||||
import { ScreenService } from '@app/shared/misc/screen.service'
|
import { ScreenService } from '@app/shared/misc/screen.service'
|
||||||
|
import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.component'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-auto-blacklist-list',
|
selector: 'my-video-auto-blacklist-list',
|
||||||
|
@ -24,6 +24,17 @@ export class VideoAutoBlacklistListComponent extends AbstractVideoList implement
|
||||||
totalItems: null
|
totalItems: null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
miniatureDisplayOptions: MiniatureDisplayOptions = {
|
||||||
|
date: true,
|
||||||
|
views: false,
|
||||||
|
by: true,
|
||||||
|
privacyLabel: false,
|
||||||
|
privacyText: true,
|
||||||
|
state: false,
|
||||||
|
blacklistInfo: false,
|
||||||
|
nsfw: true
|
||||||
|
}
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute,
|
||||||
|
|
|
@ -15,12 +15,6 @@
|
||||||
|
|
||||||
<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" class="videos">
|
<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" class="videos">
|
||||||
<div class="video" *ngFor="let video of videos">
|
<div class="video" *ngFor="let video of videos">
|
||||||
<my-video-thumbnail [video]="video"></my-video-thumbnail>
|
<my-video-miniature [video]="video" [displayAsRow]="true"></my-video-miniature>
|
||||||
|
|
||||||
<div class="video-info">
|
|
||||||
<a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
|
|
||||||
<span i18n class="video-info-date-views">{{ video.views | myNumberFormatter }} views</span>
|
|
||||||
<a tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', video.byAccount ]">{{ video.byAccount }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,63 +34,7 @@
|
||||||
.video {
|
.video {
|
||||||
@include row-blocks;
|
@include row-blocks;
|
||||||
|
|
||||||
my-video-thumbnail {
|
.my-video-miniature {
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info {
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
||||||
.video-info-name {
|
|
||||||
@include disable-default-a-behaviour;
|
|
||||||
|
|
||||||
color: var(--mainForegroundColor);
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: $font-semibold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info-date-views {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info-account {
|
|
||||||
@include disable-default-a-behaviour;
|
|
||||||
@include ellipsis;
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
|
||||||
font-size: 14px;
|
|
||||||
color: $grey-foreground-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $grey-foreground-hover-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: $small-view) {
|
|
||||||
.video {
|
|
||||||
flex-direction: column;
|
|
||||||
height: auto;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.video-info-name {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=checkbox] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
my-video-thumbnail {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-buttons {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,7 @@
|
||||||
<my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox>
|
<my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<my-video-thumbnail [video]="video"></my-video-thumbnail>
|
<my-video-miniature [video]="video" [displayOptions]="miniatureDisplayOptions" [displayAsRow]="true"></my-video-miniature>
|
||||||
|
|
||||||
<div class="video-info">
|
|
||||||
<a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
|
|
||||||
<span i18n class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
|
||||||
<div class="video-info-privacy">{{ video.privacy.label }}{{ getStateLabel(video) }}</div>
|
|
||||||
<div *ngIf="video.blacklisted" class="video-info-blacklisted">
|
|
||||||
<span class="blacklisted-label" i18n>Blacklisted</span>
|
|
||||||
<span class="blacklisted-reason" *ngIf="video.blacklistedReason">{{ video.blacklistedReason }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Display only once -->
|
<!-- Display only once -->
|
||||||
<div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
|
<div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
|
||||||
|
|
|
@ -46,44 +46,8 @@
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
my-video-thumbnail {
|
my-video-miniature {
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info {
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
||||||
.video-info-name {
|
|
||||||
@include disable-default-a-behaviour;
|
|
||||||
|
|
||||||
color: var(--mainForegroundColor);
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: $font-semibold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info-date-views,
|
|
||||||
.video-info-privacy,
|
|
||||||
.video-info-blacklisted {
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
&.video-info-privacy,
|
|
||||||
&.video-info-blacklisted .blacklisted-label {
|
|
||||||
font-weight: $font-semibold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.video-info-blacklisted {
|
|
||||||
color: red;
|
|
||||||
|
|
||||||
.blacklisted-reason {
|
|
||||||
&::before {
|
|
||||||
content: ' - ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-buttons {
|
.video-buttons {
|
||||||
|
@ -99,20 +63,11 @@
|
||||||
.video {
|
.video {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: auto;
|
height: auto;
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.video-info-name {
|
.checkbox-container {
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=checkbox] {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
my-video-thumbnail {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-buttons {
|
.video-buttons {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { VideoPrivacy, VideoState } from '../../../../../shared/models/videos'
|
import { VideoPrivacy, VideoState } from '../../../../../shared/models/videos'
|
||||||
import { ScreenService } from '@app/shared/misc/screen.service'
|
import { ScreenService } from '@app/shared/misc/screen.service'
|
||||||
import { VideoChangeOwnershipComponent } from './video-change-ownership/video-change-ownership.component'
|
import { VideoChangeOwnershipComponent } from './video-change-ownership/video-change-ownership.component'
|
||||||
|
import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.component'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-account-videos',
|
selector: 'my-account-videos',
|
||||||
|
@ -30,6 +31,15 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni
|
||||||
itemsPerPage: 5,
|
itemsPerPage: 5,
|
||||||
totalItems: null
|
totalItems: null
|
||||||
}
|
}
|
||||||
|
miniatureDisplayOptions: MiniatureDisplayOptions = {
|
||||||
|
date: true,
|
||||||
|
views: true,
|
||||||
|
by: false,
|
||||||
|
privacyLabel: false,
|
||||||
|
privacyText: true,
|
||||||
|
state: true,
|
||||||
|
blacklistInfo: true
|
||||||
|
}
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
|
|
|
@ -23,7 +23,6 @@ import { Notifier, ServerService } from '@app/core'
|
||||||
})
|
})
|
||||||
export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
||||||
titlePage: string
|
titlePage: string
|
||||||
marginContent = false // Disable margin
|
|
||||||
loadOnInit = false
|
loadOnInit = false
|
||||||
|
|
||||||
private videoChannel: VideoChannel
|
private videoChannel: VideoChannel
|
||||||
|
|
|
@ -48,13 +48,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="isVideo(result)" class="entry video">
|
<div *ngIf="isVideo(result)" class="entry video">
|
||||||
<my-video-thumbnail [video]="result" [nsfw]="isVideoBlur(result)"></my-video-thumbnail>
|
<my-video-miniature [video]="result" [user]="user" [displayAsRow]="true"></my-video-miniature>
|
||||||
|
|
||||||
<div class="video-info">
|
|
||||||
<a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', result.uuid]" [attr.title]="result.name">{{ result.name }}</a>
|
|
||||||
<span i18n class="video-info-date-views">{{ result.publishedAt | myFromNow }} - {{ result.views | myNumberFormatter }} views</span>
|
|
||||||
<a tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', result.byAccount ]">{{ result.byAccount }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|
|
@ -55,51 +55,14 @@
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
&.video {
|
|
||||||
|
|
||||||
my-video-thumbnail {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info {
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
.video-info-name {
|
|
||||||
@include disable-default-a-behaviour;
|
|
||||||
|
|
||||||
color: var(--mainForegroundColor);
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: $font-semibold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info-date-views {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-info-account {
|
|
||||||
@include disable-default-a-behaviour;
|
|
||||||
@include ellipsis;
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
|
||||||
font-size: 14px;
|
|
||||||
color: $grey-foreground-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $grey-foreground-hover-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.video-channel {
|
&.video-channel {
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@include avatar(120px);
|
$image-size: 130px;
|
||||||
|
$margin-size: ($video-thumbnail-width - $image-size) / 2; // So we have the same width than the video miniature
|
||||||
|
|
||||||
margin: 0 50px 0 40px;
|
@include avatar($image-size);
|
||||||
|
|
||||||
|
margin: 0 ($margin-size + 10) 0 $margin-size;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-channel-info {
|
.video-channel-info {
|
||||||
|
|
|
@ -41,10 +41,13 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
private metaService: MetaService,
|
private metaService: MetaService,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private searchService: SearchService,
|
private searchService: SearchService,
|
||||||
private authService: AuthService,
|
private authService: AuthService
|
||||||
private serverService: ServerService
|
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
get user () {
|
||||||
|
return this.authService.getUser()
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.subActivatedRoute = this.route.queryParams.subscribe(
|
this.subActivatedRoute = this.route.queryParams.subscribe(
|
||||||
queryParams => {
|
queryParams => {
|
||||||
|
@ -76,10 +79,6 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe()
|
if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
isVideoBlur (video: Video) {
|
|
||||||
return video.isVideoNSFWForUser(this.authService.getUser(), this.serverService.getConfig())
|
|
||||||
}
|
|
||||||
|
|
||||||
isVideoChannel (d: VideoChannel | Video): d is VideoChannel {
|
isVideoChannel (d: VideoChannel | Video): d is VideoChannel {
|
||||||
return d instanceof VideoChannel
|
return d instanceof VideoChannel
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="video-miniature">
|
<div class="video-miniature" [ngClass]="{ 'display-as-row': displayAsRow }">
|
||||||
<my-video-thumbnail [video]="video" [nsfw]="isVideoBlur"></my-video-thumbnail>
|
<my-video-thumbnail [video]="video" [nsfw]="isVideoBlur"></my-video-thumbnail>
|
||||||
|
|
||||||
<div class="video-miniature-information">
|
<div class="video-miniature-information">
|
||||||
|
@ -7,19 +7,41 @@
|
||||||
class="video-miniature-name"
|
class="video-miniature-name"
|
||||||
[routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
|
[routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
|
||||||
>
|
>
|
||||||
|
<ng-container *ngIf="displayOptions.privacyLabel">
|
||||||
<span *ngIf="isUnlistedVideo()" class="badge badge-warning" i18n>Unlisted</span>
|
<span *ngIf="isUnlistedVideo()" class="badge badge-warning" i18n>Unlisted</span>
|
||||||
<span *ngIf="isPrivateVideo()" class="badge badge-danger" i18n>Private</span>
|
<span *ngIf="isPrivateVideo()" class="badge badge-danger" i18n>Private</span>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
{{ video.name }}
|
{{ video.name }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<span i18n class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
<span class="video-miniature-created-at-views">
|
||||||
|
<ng-container *ngIf="displayOptions.date">{{ video.publishedAt | myFromNow }}</ng-container>
|
||||||
|
<ng-container *ngIf="displayOptions.date && displayOptions.views"> - </ng-container>
|
||||||
|
<ng-container i18n *ngIf="displayOptions.views">{{ video.views | myNumberFormatter }} views</ng-container>
|
||||||
|
</span>
|
||||||
|
|
||||||
<a tabindex="-1" *ngIf="displayOwnerAccount()" class="video-miniature-account" [routerLink]="[ '/accounts', video.byAccount ]">
|
<a tabindex="-1" *ngIf="displayOptions.by && displayOwnerAccount()" class="video-miniature-account" [routerLink]="[ '/accounts', video.byAccount ]">
|
||||||
{{ video.byAccount }}
|
{{ video.byAccount }}
|
||||||
</a>
|
</a>
|
||||||
<a tabindex="-1" *ngIf="displayOwnerVideoChannel()" class="video-miniature-channel" [routerLink]="[ '/video-channels', video.byVideoChannel ]">
|
<a tabindex="-1" *ngIf="displayOptions.by && displayOwnerVideoChannel()" class="video-miniature-channel" [routerLink]="[ '/video-channels', video.byVideoChannel ]">
|
||||||
{{ video.byVideoChannel }}
|
{{ video.byVideoChannel }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div class="video-info-privacy">
|
||||||
|
<ng-container *ngIf="displayOptions.privacyText">{{ video.privacy.label }}</ng-container>
|
||||||
|
<ng-container *ngIf="displayOptions.privacyText && displayOptions.state"> - </ng-container>
|
||||||
|
<ng-container *ngIf="displayOptions.state">{{ getStateLabel(video) }}</ng-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="displayOptions.blacklistInfo && video.blacklisted" class="video-info-blacklisted">
|
||||||
|
<span class="blacklisted-label" i18n>Blacklisted</span>
|
||||||
|
<span class="blacklisted-reason" *ngIf="video.blacklistedReason">{{ video.blacklistedReason }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div i18n *ngIf="displayOptions.nsfw && video.nsfw" class="video-info-nsfw">
|
||||||
|
Sensitive
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,15 +4,14 @@
|
||||||
|
|
||||||
.video-miniature {
|
.video-miniature {
|
||||||
width: $video-miniature-width;
|
width: $video-miniature-width;
|
||||||
|
display: inline-flex;
|
||||||
display: inline-block;
|
flex-direction: column;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
height: 195px;
|
height: 195px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
|
||||||
.video-miniature-information {
|
.video-miniature-information {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
margin-top: 2px;
|
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
|
||||||
.video-miniature-name {
|
.video-miniature-name {
|
||||||
|
@ -37,5 +36,68 @@
|
||||||
color: $grey-foreground-hover-color;
|
color: $grey-foreground-hover-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.video-info-privacy,
|
||||||
|
.video-info-blacklisted .blacklisted-label,
|
||||||
|
.video-info-nsfw {
|
||||||
|
font-weight: $font-semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-info-blacklisted {
|
||||||
|
color: red;
|
||||||
|
|
||||||
|
.blacklisted-reason::before {
|
||||||
|
content: ' - ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-info-nsfw {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.display-as-row {
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 0;
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
my-video-thumbnail {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-miniature-information {
|
||||||
|
width: auto;
|
||||||
|
|
||||||
|
.video-miniature-name {
|
||||||
|
@include ellipsis-multiline(1.3em, 2);
|
||||||
|
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-miniature-created-at-views,
|
||||||
|
.video-miniature-account,
|
||||||
|
.video-miniature-channel {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-info-privacy {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-info-blacklisted {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $small-view) {
|
||||||
|
flex-direction: column;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
my-video-thumbnail {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'
|
import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'
|
||||||
import { User } from '../users'
|
import { User } from '../users'
|
||||||
import { Video } from './video.model'
|
import { Video } from './video.model'
|
||||||
import { ServerService } from '@app/core'
|
import { ServerService } from '@app/core'
|
||||||
import { VideoPrivacy } from '../../../../../shared'
|
import { VideoPrivacy, VideoState } from '../../../../../shared'
|
||||||
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
|
|
||||||
export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto'
|
export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto'
|
||||||
|
export type MiniatureDisplayOptions = {
|
||||||
|
date?: boolean
|
||||||
|
views?: boolean
|
||||||
|
by?: boolean
|
||||||
|
privacyLabel?: boolean
|
||||||
|
privacyText?: boolean
|
||||||
|
state?: boolean
|
||||||
|
blacklistInfo?: boolean
|
||||||
|
nsfw?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-miniature',
|
selector: 'my-video-miniature',
|
||||||
|
@ -15,11 +26,26 @@ export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto'
|
||||||
export class VideoMiniatureComponent implements OnInit {
|
export class VideoMiniatureComponent implements OnInit {
|
||||||
@Input() user: User
|
@Input() user: User
|
||||||
@Input() video: Video
|
@Input() video: Video
|
||||||
|
|
||||||
@Input() ownerDisplayType: OwnerDisplayType = 'account'
|
@Input() ownerDisplayType: OwnerDisplayType = 'account'
|
||||||
|
@Input() displayOptions: MiniatureDisplayOptions = {
|
||||||
|
date: true,
|
||||||
|
views: true,
|
||||||
|
by: true,
|
||||||
|
privacyLabel: false,
|
||||||
|
privacyText: false,
|
||||||
|
state: false,
|
||||||
|
blacklistInfo: false
|
||||||
|
}
|
||||||
|
@Input() displayAsRow = false
|
||||||
|
|
||||||
private ownerDisplayTypeChosen: 'account' | 'videoChannel'
|
private ownerDisplayTypeChosen: 'account' | 'videoChannel'
|
||||||
|
|
||||||
constructor (private serverService: ServerService) { }
|
constructor (
|
||||||
|
private serverService: ServerService,
|
||||||
|
private i18n: I18n,
|
||||||
|
@Inject(LOCALE_ID) private localeId: string
|
||||||
|
) { }
|
||||||
|
|
||||||
get isVideoBlur () {
|
get isVideoBlur () {
|
||||||
return this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())
|
return this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())
|
||||||
|
@ -58,4 +84,29 @@ export class VideoMiniatureComponent implements OnInit {
|
||||||
isPrivateVideo () {
|
isPrivateVideo () {
|
||||||
return this.video.privacy.id === VideoPrivacy.PRIVATE
|
return this.video.privacy.id === VideoPrivacy.PRIVATE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStateLabel (video: Video) {
|
||||||
|
if (video.privacy.id !== VideoPrivacy.PRIVATE && video.state.id === VideoState.PUBLISHED) {
|
||||||
|
return this.i18n('Published')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (video.scheduledUpdate) {
|
||||||
|
const updateAt = new Date(video.scheduledUpdate.updateAt.toString()).toLocaleString(this.localeId)
|
||||||
|
return this.i18n('Publication scheduled on ') + updateAt
|
||||||
|
}
|
||||||
|
|
||||||
|
if (video.state.id === VideoState.TO_TRANSCODE && video.waitTranscoding === true) {
|
||||||
|
return this.i18n('Waiting transcoding')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (video.state.id === VideoState.TO_TRANSCODE) {
|
||||||
|
return this.i18n('To transcode')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (video.state.id === VideoState.TO_IMPORT) {
|
||||||
|
return this.i18n('To import')
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
@include ellipsis-multiline(1.1em, 2);
|
@include ellipsis-multiline(1.1em, 2);
|
||||||
|
|
||||||
transition: color 0.2s;
|
transition: color 0.2s;
|
||||||
font-size: 16px;
|
|
||||||
font-weight: $font-semibold;
|
font-weight: $font-semibold;
|
||||||
color: var(--mainForegroundColor);
|
color: var(--mainForegroundColor);
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
|
@ -515,7 +515,6 @@
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 800px) {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: auto;
|
height: auto;
|
||||||
text-align: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue