diff options
18 files changed, 199 insertions, 244 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 | }) |
24 | export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { | 24 | export 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 @@ | |||
1 | import { Component, OnInit, OnDestroy } from '@angular/core' | 1 | import { Component, OnDestroy, OnInit } from '@angular/core' |
2 | import { Location } from '@angular/common' | ||
3 | import { I18n } from '@ngx-translate/i18n-polyfill' | 2 | import { I18n } from '@ngx-translate/i18n-polyfill' |
4 | import { Router, ActivatedRoute } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
5 | import { AbstractVideoList } from '@app/shared/video/abstract-video-list' | 4 | import { AbstractVideoList } from '@app/shared/video/abstract-video-list' |
6 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | 5 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' |
7 | import { Notifier, AuthService, ServerService } from '@app/core' | 6 | import { AuthService, Notifier, ServerService } from '@app/core' |
8 | import { Video } from '@shared/models' | 7 | import { Video } from '@shared/models' |
9 | import { VideoBlacklistService } from '@app/shared' | 8 | import { VideoBlacklistService } from '@app/shared' |
10 | import { immutableAssign } from '@app/shared/misc/utils' | 9 | import { immutableAssign } from '@app/shared/misc/utils' |
11 | import { ScreenService } from '@app/shared/misc/screen.service' | 10 | import { ScreenService } from '@app/shared/misc/screen.service' |
11 | import { 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' | |||
14 | import { VideoPrivacy, VideoState } from '../../../../../shared/models/videos' | 14 | import { VideoPrivacy, VideoState } from '../../../../../shared/models/videos' |
15 | import { ScreenService } from '@app/shared/misc/screen.service' | 15 | import { ScreenService } from '@app/shared/misc/screen.service' |
16 | import { VideoChangeOwnershipComponent } from './video-change-ownership/video-change-ownership.component' | 16 | import { VideoChangeOwnershipComponent } from './video-change-ownership/video-change-ownership.component' |
17 | import { 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 | }) |
24 | export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { | 24 | export 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 @@ | |||
1 | import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core' | 1 | import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core' |
2 | import { User } from '../users' | 2 | import { User } from '../users' |
3 | import { Video } from './video.model' | 3 | import { Video } from './video.model' |
4 | import { ServerService } from '@app/core' | 4 | import { ServerService } from '@app/core' |
5 | import { VideoPrivacy } from '../../../../../shared' | 5 | import { VideoPrivacy, VideoState } from '../../../../../shared' |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
6 | 7 | ||
7 | export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto' | 8 | export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto' |
9 | export 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' | |||
15 | export class VideoMiniatureComponent implements OnInit { | 26 | export 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 | } |
diff --git a/client/src/sass/include/_miniature.scss b/client/src/sass/include/_miniature.scss index 4926adb08..13af0b936 100644 --- a/client/src/sass/include/_miniature.scss +++ b/client/src/sass/include/_miniature.scss | |||
@@ -5,7 +5,6 @@ | |||
5 | @include ellipsis-multiline(1.1em, 2); | 5 | @include ellipsis-multiline(1.1em, 2); |
6 | 6 | ||
7 | transition: color 0.2s; | 7 | transition: color 0.2s; |
8 | font-size: 16px; | ||
9 | font-weight: $font-semibold; | 8 | font-weight: $font-semibold; |
10 | color: var(--mainForegroundColor); | 9 | color: var(--mainForegroundColor); |
11 | margin-top: 10px; | 10 | margin-top: 10px; |
diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss index 0dacc7272..9c3f28b28 100644 --- a/client/src/sass/include/_mixins.scss +++ b/client/src/sass/include/_mixins.scss | |||
@@ -515,7 +515,6 @@ | |||
515 | @media screen and (max-width: 800px) { | 515 | @media screen and (max-width: 800px) { |
516 | flex-direction: column; | 516 | flex-direction: column; |
517 | height: auto; | 517 | height: auto; |
518 | text-align: center; | ||
519 | align-items: center; | 518 | align-items: center; |
520 | } | 519 | } |
521 | } | 520 | } |