aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+accounts/account-videos/account-videos.component.ts1
-rw-r--r--client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html25
-rw-r--r--client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss33
-rw-r--r--client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts19
-rw-r--r--client/src/app/+my-account/my-account-history/my-account-history.component.html8
-rw-r--r--client/src/app/+my-account/my-account-history/my-account-history.component.scss58
-rw-r--r--client/src/app/+my-account/my-account-videos/my-account-videos.component.html12
-rw-r--r--client/src/app/+my-account/my-account-videos/my-account-videos.component.scss49
-rw-r--r--client/src/app/+my-account/my-account-videos/my-account-videos.component.ts10
-rw-r--r--client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts1
-rw-r--r--client/src/app/search/search.component.html8
-rw-r--r--client/src/app/search/search.component.scss47
-rw-r--r--client/src/app/search/search.component.ts11
-rw-r--r--client/src/app/shared/video/video-miniature.component.html34
-rw-r--r--client/src/app/shared/video/video-miniature.component.scss68
-rw-r--r--client/src/app/shared/video/video-miniature.component.ts57
16 files changed, 199 insertions, 242 deletions
diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts
index 7535eef08..1814ef455 100644
--- a/client/src/app/+accounts/account-videos/account-videos.component.ts
+++ b/client/src/app/+accounts/account-videos/account-videos.component.ts
@@ -23,7 +23,6 @@ import { Notifier, ServerService } from '@app/core'
23}) 23})
24export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { 24export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
25 titlePage: string 25 titlePage: string
26 marginContent = false // Disable margin
27 loadOnInit = false 26 loadOnInit = false
28 27
29 private account: Account 28 private account: Account
diff --git a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html
index c4e5be0d6..5ef497fa7 100644
--- a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html
+++ b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html
@@ -6,15 +6,7 @@
6 <my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox> 6 <my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox>
7 </div> 7 </div>
8 8
9 <my-video-thumbnail [video]="video"></my-video-thumbnail> 9 <my-video-miniature [video]="video" [displayAsRow]="true" [displayOptions]="miniatureDisplayOptions"></my-video-miniature>
10
11 <div class="video-info">
12 <a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
13 <div>{{ video.account.displayName }}</div>
14 <div>{{ video.publishedAt | myFromNow }}</div>
15 <div><span i18n>Privacy: </span><span>{{ video.privacy.label }}</span></div>
16 <div><span i18n>Sensitive: </span><span> {{ video.nsfw }}</span></div>
17 </div>
18 10
19 <!-- Display only once --> 11 <!-- Display only once -->
20 <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0"> 12 <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
@@ -30,13 +22,12 @@
30 </div> 22 </div>
31 </div> 23 </div>
32 24
33 <div class="video-buttons" *ngIf="isInSelectionMode() === false"> 25 <my-button
34 <my-button 26 *ngIf="isInSelectionMode() === false"
35 i18n-label 27 i18n-label
36 label="Unblacklist" 28 label="Unblacklist"
37 icon="tick" 29 icon="tick"
38 (click)="removeVideoFromBlacklist(video)" 30 (click)="removeVideoFromBlacklist(video)"
39 ></my-button> 31 ></my-button>
40 </div>
41 </div> 32 </div>
42</div> 33</div>
diff --git a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss
index a73c17eb9..e43a2aa7b 100644
--- a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss
+++ b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss
@@ -46,26 +46,8 @@
46 margin-left: 12px; 46 margin-left: 12px;
47 } 47 }
48 48
49 my-video-thumbnail { 49 my-video-miniature {
50 margin-right: 10px;
51 }
52
53 .video-info {
54 flex-grow: 1; 50 flex-grow: 1;
55
56 .video-info-name {
57 @include disable-default-a-behaviour;
58
59 color: var(--mainForegroundColor);
60 display: block;
61 width: fit-content;
62 font-size: 16px;
63 font-weight: $font-semibold;
64 }
65 }
66
67 .video-buttons {
68 min-width: 190px;
69 } 51 }
70} 52}
71 53
@@ -73,21 +55,12 @@
73 .video { 55 .video {
74 flex-direction: column; 56 flex-direction: column;
75 height: auto; 57 height: auto;
76 text-align: center;
77
78 .video-info-name {
79 margin: auto;
80 }
81 58
82 input[type=checkbox] { 59 .checkbox-container {
83 display: none; 60 display: none;
84 } 61 }
85 62
86 my-video-thumbnail { 63 my-button {
87 margin-right: 0;
88 }
89
90 .video-buttons {
91 margin-top: 10px; 64 margin-top: 10px;
92 } 65 }
93 } 66 }
diff --git a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts
index af68d7e2e..d66a6dcae 100644
--- a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts
+++ b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts
@@ -1,14 +1,14 @@
1import { Component, OnInit, OnDestroy } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { Location } from '@angular/common'
3import { I18n } from '@ngx-translate/i18n-polyfill' 2import { I18n } from '@ngx-translate/i18n-polyfill'
4import { Router, ActivatedRoute } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
5import { AbstractVideoList } from '@app/shared/video/abstract-video-list' 4import { AbstractVideoList } from '@app/shared/video/abstract-video-list'
6import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 5import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
7import { Notifier, AuthService, ServerService } from '@app/core' 6import { AuthService, Notifier, ServerService } from '@app/core'
8import { Video } from '@shared/models' 7import { Video } from '@shared/models'
9import { VideoBlacklistService } from '@app/shared' 8import { VideoBlacklistService } from '@app/shared'
10import { immutableAssign } from '@app/shared/misc/utils' 9import { immutableAssign } from '@app/shared/misc/utils'
11import { ScreenService } from '@app/shared/misc/screen.service' 10import { ScreenService } from '@app/shared/misc/screen.service'
11import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.component'
12 12
13@Component({ 13@Component({
14 selector: 'my-video-auto-blacklist-list', 14 selector: 'my-video-auto-blacklist-list',
@@ -24,6 +24,17 @@ export class VideoAutoBlacklistListComponent extends AbstractVideoList implement
24 totalItems: null 24 totalItems: null
25 } 25 }
26 26
27 miniatureDisplayOptions: MiniatureDisplayOptions = {
28 date: true,
29 views: false,
30 by: true,
31 privacyLabel: false,
32 privacyText: true,
33 state: false,
34 blacklistInfo: false,
35 nsfw: true
36 }
37
27 constructor ( 38 constructor (
28 protected router: Router, 39 protected router: Router,
29 protected route: ActivatedRoute, 40 protected route: ActivatedRoute,
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.html b/client/src/app/+my-account/my-account-history/my-account-history.component.html
index 00ee5fbd1..4b94490a0 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.html
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.html
@@ -15,12 +15,6 @@
15 15
16<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" class="videos"> 16<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" class="videos">
17 <div class="video" *ngFor="let video of videos"> 17 <div class="video" *ngFor="let video of videos">
18 <my-video-thumbnail [video]="video"></my-video-thumbnail> 18 <my-video-miniature [video]="video" [displayAsRow]="true"></my-video-miniature>
19
20 <div class="video-info">
21 <a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
22 <span i18n class="video-info-date-views">{{ video.views | myNumberFormatter }} views</span>
23 <a tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', video.byAccount ]">{{ video.byAccount }}</a>
24 </div>
25 </div> 19 </div>
26</div> 20</div>
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.scss b/client/src/app/+my-account/my-account-history/my-account-history.component.scss
index e03d81055..af6395fb1 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.scss
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.scss
@@ -34,63 +34,7 @@
34.video { 34.video {
35 @include row-blocks; 35 @include row-blocks;
36 36
37 my-video-thumbnail { 37 .my-video-miniature {
38 margin-right: 10px;
39 }
40
41 .video-info {
42 flex-grow: 1; 38 flex-grow: 1;
43
44 .video-info-name {
45 @include disable-default-a-behaviour;
46
47 color: var(--mainForegroundColor);
48 display: block;
49 width: fit-content;
50 font-size: 18px;
51 font-weight: $font-semibold;
52 }
53
54 .video-info-date-views {
55 font-size: 14px;
56 }
57
58 .video-info-account {
59 @include disable-default-a-behaviour;
60 @include ellipsis;
61
62 display: block;
63 width: fit-content;
64 font-size: 14px;
65 color: $grey-foreground-color;
66
67 &:hover {
68 color: $grey-foreground-hover-color;
69 }
70 }
71 }
72}
73
74@media screen and (max-width: $small-view) {
75 .video {
76 flex-direction: column;
77 height: auto;
78 text-align: center;
79
80 .video-info-name {
81 margin: auto;
82 }
83
84 input[type=checkbox] {
85 display: none;
86 }
87
88 my-video-thumbnail {
89 margin-right: 0;
90 }
91
92 .video-buttons {
93 margin-top: 10px;
94 }
95 } 39 }
96} 40}
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
index 1f3ac0005..3a4054de8 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
@@ -6,17 +6,7 @@
6 <my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox> 6 <my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox>
7 </div> 7 </div>
8 8
9 <my-video-thumbnail [video]="video"></my-video-thumbnail> 9 <my-video-miniature [video]="video" [displayOptions]="miniatureDisplayOptions" [displayAsRow]="true"></my-video-miniature>
10
11 <div class="video-info">
12 <a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
13 <span i18n class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
14 <div class="video-info-privacy">{{ video.privacy.label }}{{ getStateLabel(video) }}</div>
15 <div *ngIf="video.blacklisted" class="video-info-blacklisted">
16 <span class="blacklisted-label" i18n>Blacklisted</span>
17 <span class="blacklisted-reason" *ngIf="video.blacklistedReason">{{ video.blacklistedReason }}</span>
18 </div>
19 </div>
20 10
21 <!-- Display only once --> 11 <!-- Display only once -->
22 <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0"> 12 <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
index d2df6f290..405ded3f8 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
@@ -46,44 +46,8 @@
46 margin-left: 12px; 46 margin-left: 12px;
47 } 47 }
48 48
49 my-video-thumbnail { 49 my-video-miniature {
50 margin-right: 10px;
51 }
52
53 .video-info {
54 flex-grow: 1; 50 flex-grow: 1;
55
56 .video-info-name {
57 @include disable-default-a-behaviour;
58
59 color: var(--mainForegroundColor);
60 display: block;
61 width: fit-content;
62 font-size: 16px;
63 font-weight: $font-semibold;
64 }
65
66 .video-info-date-views,
67 .video-info-privacy,
68 .video-info-blacklisted {
69 font-size: 13px;
70
71 &.video-info-privacy,
72 &.video-info-blacklisted .blacklisted-label {
73 font-weight: $font-semibold;
74 }
75
76 &.video-info-blacklisted {
77 color: red;
78
79 .blacklisted-reason {
80 &::before {
81 content: ' - ';
82 }
83 }
84 }
85
86 }
87 } 51 }
88 52
89 .video-buttons { 53 .video-buttons {
@@ -99,20 +63,11 @@
99 .video { 63 .video {
100 flex-direction: column; 64 flex-direction: column;
101 height: auto; 65 height: auto;
102 text-align: center;
103 66
104 .video-info-name { 67 .checkbox-container {
105 margin: auto;
106 }
107
108 input[type=checkbox] {
109 display: none; 68 display: none;
110 } 69 }
111 70
112 my-video-thumbnail {
113 margin-right: 0;
114 }
115
116 .video-buttons { 71 .video-buttons {
117 margin-top: 10px; 72 margin-top: 10px;
118 } 73 }
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
index eb5096a5e..bbe86af73 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
@@ -14,6 +14,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
14import { VideoPrivacy, VideoState } from '../../../../../shared/models/videos' 14import { VideoPrivacy, VideoState } from '../../../../../shared/models/videos'
15import { ScreenService } from '@app/shared/misc/screen.service' 15import { ScreenService } from '@app/shared/misc/screen.service'
16import { VideoChangeOwnershipComponent } from './video-change-ownership/video-change-ownership.component' 16import { VideoChangeOwnershipComponent } from './video-change-ownership/video-change-ownership.component'
17import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.component'
17 18
18@Component({ 19@Component({
19 selector: 'my-account-videos', 20 selector: 'my-account-videos',
@@ -30,6 +31,15 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni
30 itemsPerPage: 5, 31 itemsPerPage: 5,
31 totalItems: null 32 totalItems: null
32 } 33 }
34 miniatureDisplayOptions: MiniatureDisplayOptions = {
35 date: true,
36 views: true,
37 by: false,
38 privacyLabel: false,
39 privacyText: true,
40 state: true,
41 blacklistInfo: true
42 }
33 43
34 constructor ( 44 constructor (
35 protected router: Router, 45 protected router: Router,
diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
index 8af31000e..2045a095d 100644
--- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
+++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
@@ -23,7 +23,6 @@ import { Notifier, ServerService } from '@app/core'
23}) 23})
24export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { 24export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
25 titlePage: string 25 titlePage: string
26 marginContent = false // Disable margin
27 loadOnInit = false 26 loadOnInit = false
28 27
29 private videoChannel: VideoChannel 28 private videoChannel: VideoChannel
diff --git a/client/src/app/search/search.component.html b/client/src/app/search/search.component.html
index 82a5f0f26..da2ace54d 100644
--- a/client/src/app/search/search.component.html
+++ b/client/src/app/search/search.component.html
@@ -48,13 +48,7 @@
48 </div> 48 </div>
49 49
50 <div *ngIf="isVideo(result)" class="entry video"> 50 <div *ngIf="isVideo(result)" class="entry video">
51 <my-video-thumbnail [video]="result" [nsfw]="isVideoBlur(result)"></my-video-thumbnail> 51 <my-video-miniature [video]="result" [user]="user" [displayAsRow]="true"></my-video-miniature>
52
53 <div class="video-info">
54 <a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', result.uuid]" [attr.title]="result.name">{{ result.name }}</a>
55 <span i18n class="video-info-date-views">{{ result.publishedAt | myFromNow }} - {{ result.views | myNumberFormatter }} views</span>
56 <a tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', result.byAccount ]">{{ result.byAccount }}</a>
57 </div>
58 </div> 52 </div>
59 </ng-container> 53 </ng-container>
60 54
diff --git a/client/src/app/search/search.component.scss b/client/src/app/search/search.component.scss
index e0509ee15..4e3ce1c96 100644
--- a/client/src/app/search/search.component.scss
+++ b/client/src/app/search/search.component.scss
@@ -55,51 +55,14 @@
55 padding-bottom: 20px; 55 padding-bottom: 20px;
56 margin-bottom: 20px; 56 margin-bottom: 20px;
57 57
58 &.video {
59
60 my-video-thumbnail {
61 margin-right: 10px;
62 }
63
64 .video-info {
65 flex-grow: 1;
66
67 .video-info-name {
68 @include disable-default-a-behaviour;
69
70 color: var(--mainForegroundColor);
71 display: block;
72 width: fit-content;
73 font-size: 18px;
74 font-weight: $font-semibold;
75 }
76
77 .video-info-date-views {
78 font-size: 14px;
79 }
80
81 .video-info-account {
82 @include disable-default-a-behaviour;
83 @include ellipsis;
84
85 display: block;
86 width: fit-content;
87 font-size: 14px;
88 color: $grey-foreground-color;
89
90 &:hover {
91 color: $grey-foreground-hover-color;
92 }
93 }
94 }
95 }
96
97 &.video-channel { 58 &.video-channel {
98
99 img { 59 img {
100 @include avatar(120px); 60 $image-size: 130px;
61 $margin-size: ($video-thumbnail-width - $image-size) / 2; // So we have the same width than the video miniature
62
63 @include avatar($image-size);
101 64
102 margin: 0 50px 0 40px; 65 margin: 0 ($margin-size + 10) 0 $margin-size;
103 } 66 }
104 67
105 .video-channel-info { 68 .video-channel-info {
diff --git a/client/src/app/search/search.component.ts b/client/src/app/search/search.component.ts
index c4a4b1fde..a3383ed8a 100644
--- a/client/src/app/search/search.component.ts
+++ b/client/src/app/search/search.component.ts
@@ -41,10 +41,13 @@ export class SearchComponent implements OnInit, OnDestroy {
41 private metaService: MetaService, 41 private metaService: MetaService,
42 private notifier: Notifier, 42 private notifier: Notifier,
43 private searchService: SearchService, 43 private searchService: SearchService,
44 private authService: AuthService, 44 private authService: AuthService
45 private serverService: ServerService
46 ) { } 45 ) { }
47 46
47 get user () {
48 return this.authService.getUser()
49 }
50
48 ngOnInit () { 51 ngOnInit () {
49 this.subActivatedRoute = this.route.queryParams.subscribe( 52 this.subActivatedRoute = this.route.queryParams.subscribe(
50 queryParams => { 53 queryParams => {
@@ -76,10 +79,6 @@ export class SearchComponent implements OnInit, OnDestroy {
76 if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe() 79 if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe()
77 } 80 }
78 81
79 isVideoBlur (video: Video) {
80 return video.isVideoNSFWForUser(this.authService.getUser(), this.serverService.getConfig())
81 }
82
83 isVideoChannel (d: VideoChannel | Video): d is VideoChannel { 82 isVideoChannel (d: VideoChannel | Video): d is VideoChannel {
84 return d instanceof VideoChannel 83 return d instanceof VideoChannel
85 } 84 }
diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html
index 2c635fa2f..f4ae0b0dd 100644
--- a/client/src/app/shared/video/video-miniature.component.html
+++ b/client/src/app/shared/video/video-miniature.component.html
@@ -1,4 +1,4 @@
1<div class="video-miniature"> 1<div class="video-miniature" [ngClass]="{ 'display-as-row': displayAsRow }">
2 <my-video-thumbnail [video]="video" [nsfw]="isVideoBlur"></my-video-thumbnail> 2 <my-video-thumbnail [video]="video" [nsfw]="isVideoBlur"></my-video-thumbnail>
3 3
4 <div class="video-miniature-information"> 4 <div class="video-miniature-information">
@@ -7,19 +7,41 @@
7 class="video-miniature-name" 7 class="video-miniature-name"
8 [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }" 8 [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
9 > 9 >
10 <span *ngIf="isUnlistedVideo()" class="badge badge-warning" i18n>Unlisted</span> 10 <ng-container *ngIf="displayOptions.privacyLabel">
11 <span *ngIf="isPrivateVideo()" class="badge badge-danger" i18n>Private</span> 11 <span *ngIf="isUnlistedVideo()" class="badge badge-warning" i18n>Unlisted</span>
12 <span *ngIf="isPrivateVideo()" class="badge badge-danger" i18n>Private</span>
13 </ng-container>
12 14
13 {{ video.name }} 15 {{ video.name }}
14 </a> 16 </a>
15 17
16 <span i18n class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> 18 <span class="video-miniature-created-at-views">
19 <ng-container *ngIf="displayOptions.date">{{ video.publishedAt | myFromNow }}</ng-container>
20 <ng-container *ngIf="displayOptions.date && displayOptions.views"> - </ng-container>
21 <ng-container i18n *ngIf="displayOptions.views">{{ video.views | myNumberFormatter }} views</ng-container>
22 </span>
17 23
18 <a tabindex="-1" *ngIf="displayOwnerAccount()" class="video-miniature-account" [routerLink]="[ '/accounts', video.byAccount ]"> 24 <a tabindex="-1" *ngIf="displayOptions.by && displayOwnerAccount()" class="video-miniature-account" [routerLink]="[ '/accounts', video.byAccount ]">
19 {{ video.byAccount }} 25 {{ video.byAccount }}
20 </a> 26 </a>
21 <a tabindex="-1" *ngIf="displayOwnerVideoChannel()" class="video-miniature-channel" [routerLink]="[ '/video-channels', video.byVideoChannel ]"> 27 <a tabindex="-1" *ngIf="displayOptions.by && displayOwnerVideoChannel()" class="video-miniature-channel" [routerLink]="[ '/video-channels', video.byVideoChannel ]">
22 {{ video.byVideoChannel }} 28 {{ video.byVideoChannel }}
23 </a> 29 </a>
30
31 <div class="video-info-privacy">
32 <ng-container *ngIf="displayOptions.privacyText">{{ video.privacy.label }}</ng-container>
33 <ng-container *ngIf="displayOptions.privacyText && displayOptions.state"> - </ng-container>
34 <ng-container *ngIf="displayOptions.state">{{ getStateLabel(video) }}</ng-container>
35 </div>
36
37 <div *ngIf="displayOptions.blacklistInfo && video.blacklisted" class="video-info-blacklisted">
38 <span class="blacklisted-label" i18n>Blacklisted</span>
39 <span class="blacklisted-reason" *ngIf="video.blacklistedReason">{{ video.blacklistedReason }}</span>
40 </div>
41
42 <div i18n *ngIf="displayOptions.nsfw && video.nsfw" class="video-info-nsfw">
43 Sensitive
44 </div>
45
24 </div> 46 </div>
25</div> 47</div>
diff --git a/client/src/app/shared/video/video-miniature.component.scss b/client/src/app/shared/video/video-miniature.component.scss
index 4799e00c2..fdc3dc033 100644
--- a/client/src/app/shared/video/video-miniature.component.scss
+++ b/client/src/app/shared/video/video-miniature.component.scss
@@ -4,15 +4,14 @@
4 4
5.video-miniature { 5.video-miniature {
6 width: $video-miniature-width; 6 width: $video-miniature-width;
7 7 display: inline-flex;
8 display: inline-block; 8 flex-direction: column;
9 margin-bottom: 30px; 9 margin-bottom: 30px;
10 height: 195px; 10 height: 195px;
11 vertical-align: top; 11 vertical-align: top;
12 12
13 .video-miniature-information { 13 .video-miniature-information {
14 width: 200px; 14 width: 200px;
15 margin-top: 2px;
16 line-height: normal; 15 line-height: normal;
17 16
18 .video-miniature-name { 17 .video-miniature-name {
@@ -37,5 +36,68 @@
37 color: $grey-foreground-hover-color; 36 color: $grey-foreground-hover-color;
38 } 37 }
39 } 38 }
39
40 .video-info-privacy,
41 .video-info-blacklisted .blacklisted-label,
42 .video-info-nsfw {
43 font-weight: $font-semibold;
44 }
45
46 .video-info-blacklisted {
47 color: red;
48
49 .blacklisted-reason::before {
50 content: ' - ';
51 }
52 }
53
54 .video-info-nsfw {
55 color: red;
56 }
57 }
58
59 &.display-as-row {
60 flex-direction: row;
61 margin-bottom: 0;
62 height: auto;
63 width: 100%;
64
65 my-video-thumbnail {
66 margin-right: 10px;
67 }
68
69 .video-miniature-information {
70 width: auto;
71
72 .video-miniature-name {
73 @include ellipsis-multiline(1.3em, 2);
74
75 margin-top: 2px;
76 margin-bottom: 5px;
77 }
78
79 .video-miniature-created-at-views,
80 .video-miniature-account,
81 .video-miniature-channel {
82 font-size: 14px;
83 }
84
85 .video-info-privacy {
86 margin-top: 5px;
87 }
88
89 .video-info-blacklisted {
90 margin-top: 3px;
91 }
92 }
93
94 @media screen and (max-width: $small-view) {
95 flex-direction: column;
96 height: auto;
97
98 my-video-thumbnail {
99 margin-right: 0;
100 }
101 }
40 } 102 }
41} 103}
diff --git a/client/src/app/shared/video/video-miniature.component.ts b/client/src/app/shared/video/video-miniature.component.ts
index 2f951a1f1..800417a79 100644
--- a/client/src/app/shared/video/video-miniature.component.ts
+++ b/client/src/app/shared/video/video-miniature.component.ts
@@ -1,10 +1,21 @@
1import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core' 1import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'
2import { User } from '../users' 2import { User } from '../users'
3import { Video } from './video.model' 3import { Video } from './video.model'
4import { ServerService } from '@app/core' 4import { ServerService } from '@app/core'
5import { VideoPrivacy } from '../../../../../shared' 5import { VideoPrivacy, VideoState } from '../../../../../shared'
6import { I18n } from '@ngx-translate/i18n-polyfill'
6 7
7export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto' 8export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto'
9export type MiniatureDisplayOptions = {
10 date?: boolean
11 views?: boolean
12 by?: boolean
13 privacyLabel?: boolean
14 privacyText?: boolean
15 state?: boolean
16 blacklistInfo?: boolean
17 nsfw?: boolean
18}
8 19
9@Component({ 20@Component({
10 selector: 'my-video-miniature', 21 selector: 'my-video-miniature',
@@ -15,11 +26,26 @@ export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto'
15export class VideoMiniatureComponent implements OnInit { 26export class VideoMiniatureComponent implements OnInit {
16 @Input() user: User 27 @Input() user: User
17 @Input() video: Video 28 @Input() video: Video
29
18 @Input() ownerDisplayType: OwnerDisplayType = 'account' 30 @Input() ownerDisplayType: OwnerDisplayType = 'account'
31 @Input() displayOptions: MiniatureDisplayOptions = {
32 date: true,
33 views: true,
34 by: true,
35 privacyLabel: false,
36 privacyText: false,
37 state: false,
38 blacklistInfo: false
39 }
40 @Input() displayAsRow = false
19 41
20 private ownerDisplayTypeChosen: 'account' | 'videoChannel' 42 private ownerDisplayTypeChosen: 'account' | 'videoChannel'
21 43
22 constructor (private serverService: ServerService) { } 44 constructor (
45 private serverService: ServerService,
46 private i18n: I18n,
47 @Inject(LOCALE_ID) private localeId: string
48 ) { }
23 49
24 get isVideoBlur () { 50 get isVideoBlur () {
25 return this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig()) 51 return this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())
@@ -58,4 +84,29 @@ export class VideoMiniatureComponent implements OnInit {
58 isPrivateVideo () { 84 isPrivateVideo () {
59 return this.video.privacy.id === VideoPrivacy.PRIVATE 85 return this.video.privacy.id === VideoPrivacy.PRIVATE
60 } 86 }
87
88 getStateLabel (video: Video) {
89 if (video.privacy.id !== VideoPrivacy.PRIVATE && video.state.id === VideoState.PUBLISHED) {
90 return this.i18n('Published')
91 }
92
93 if (video.scheduledUpdate) {
94 const updateAt = new Date(video.scheduledUpdate.updateAt.toString()).toLocaleString(this.localeId)
95 return this.i18n('Publication scheduled on ') + updateAt
96 }
97
98 if (video.state.id === VideoState.TO_TRANSCODE && video.waitTranscoding === true) {
99 return this.i18n('Waiting transcoding')
100 }
101
102 if (video.state.id === VideoState.TO_TRANSCODE) {
103 return this.i18n('To transcode')
104 }
105
106 if (video.state.id === VideoState.TO_IMPORT) {
107 return this.i18n('To import')
108 }
109
110 return ''
111 }
61} 112}