aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+videos
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/+videos')
-rw-r--r--client/src/app/+videos/+video-edit/shared/video-caption-add-modal.component.scss5
-rw-r--r--client/src/app/+videos/+video-edit/shared/video-edit.component.html38
-rw-r--r--client/src/app/+videos/+video-edit/shared/video-edit.component.scss30
-rw-r--r--client/src/app/+videos/+video-edit/shared/video-edit.component.ts2
-rw-r--r--client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html2
-rw-r--r--client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.html2
-rw-r--r--client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.html2
-rw-r--r--client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts2
-rw-r--r--client/src/app/+videos/+video-edit/video-add-components/video-upload.component.html2
-rw-r--r--client/src/app/+videos/+video-edit/video-add.component.html2
-rw-r--r--client/src/app/+videos/+video-edit/video-add.component.scss1
-rw-r--r--client/src/app/+videos/+video-edit/video-update.component.html5
-rw-r--r--client/src/app/+videos/+video-edit/video-update.component.ts5
-rw-r--r--client/src/app/+videos/+video-edit/video-update.resolver.ts7
-rw-r--r--client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html2
-rw-r--r--client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss3
-rw-r--r--client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.ts6
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.html8
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.scss3
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.ts41
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comment.component.html8
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comment.component.scss1
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comments.component.html8
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comments.component.scss12
-rw-r--r--client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts4
-rw-r--r--client/src/app/+videos/+video-watch/shared/information/privacy-concerns.component.html2
-rw-r--r--client/src/app/+videos/+video-watch/shared/information/video-alert.component.html6
-rw-r--r--client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.html6
-rw-r--r--client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.scss6
-rw-r--r--client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.html4
-rw-r--r--client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.scss16
-rw-r--r--client/src/app/+videos/+video-watch/shared/metadata/video-description.component.html6
-rw-r--r--client/src/app/+videos/+video-watch/shared/metadata/video-description.component.scss13
-rw-r--r--client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html6
-rw-r--r--client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss58
-rw-r--r--client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.html5
-rw-r--r--client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.scss8
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.html2
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.scss4
-rw-r--r--client/src/app/+videos/video-list/overview/video-overview.component.html10
-rw-r--r--client/src/app/+videos/video-list/overview/video-overview.component.scss61
-rw-r--r--client/src/app/+videos/video-list/videos-list-common-page.component.ts25
42 files changed, 190 insertions, 249 deletions
diff --git a/client/src/app/+videos/+video-edit/shared/video-caption-add-modal.component.scss b/client/src/app/+videos/+video-edit/shared/video-caption-add-modal.component.scss
index 4ce2c6758..c0b670c65 100644
--- a/client/src/app/+videos/+video-edit/shared/video-caption-add-modal.component.scss
+++ b/client/src/app/+videos/+video-edit/shared/video-caption-add-modal.component.scss
@@ -1,11 +1,6 @@
1@use '_variables' as *; 1@use '_variables' as *;
2@use '_mixins' as *; 2@use '_mixins' as *;
3 3
4label {
5 font-weight: $font-regular;
6 font-size: 100%;
7}
8
9.caption-file { 4.caption-file {
10 margin-top: 20px; 5 margin-top: 20px;
11 width: max-content; 6 width: max-content;
diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.html b/client/src/app/+videos/+video-edit/shared/video-edit.component.html
index 44004eb21..650448a74 100644
--- a/client/src/app/+videos/+video-edit/shared/video-edit.component.html
+++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.html
@@ -51,11 +51,10 @@
51 </ng-template> 51 </ng-template>
52 </my-help> 52 </my-help>
53 53
54 <my-markdown-textarea [truncate]="250" formControlName="description" [markdownVideo]="videoToUpdate"></my-markdown-textarea> 54 <my-markdown-textarea
55 55 formControlName="description" [markdownVideo]="videoToUpdate"
56 <div *ngIf="formErrors.description" class="form-error"> 56 [formError]="formErrors.description" [truncate]="250"
57 {{ formErrors.description }} 57 ></my-markdown-textarea>
58 </div>
59 </div> 58 </div>
60 </div> 59 </div>
61 60
@@ -237,23 +236,23 @@
237 <ng-template ngbNavContent> 236 <ng-template ngbNavContent>
238 <div class="row live-settings"> 237 <div class="row live-settings">
239 <div class="col-md-12"> 238 <div class="col-md-12">
240 <div class="alert alert-info"> 239 <div class="alert pt-alert-primary">
241 <my-live-documentation-link></my-live-documentation-link> 240 <my-live-documentation-link></my-live-documentation-link>
242 </div> 241 </div>
243 242
244 <div *ngIf="liveVideo.rtmpUrl" class="form-group"> 243 <div *ngIf="liveVideo.rtmpUrl" class="form-group">
245 <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label> 244 <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label>
246 <my-input-toggle-hidden inputId="liveVideoRTMPUrl" [value]="liveVideo.rtmpUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> 245 <my-input-text inputId="liveVideoRTMPUrl" [value]="liveVideo.rtmpUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
247 </div> 246 </div>
248 247
249 <div *ngIf="liveVideo.rtmpsUrl" class="form-group"> 248 <div *ngIf="liveVideo.rtmpsUrl" class="form-group">
250 <label for="liveVideoRTMPSUrl" i18n>Live RTMPS Url</label> 249 <label for="liveVideoRTMPSUrl" i18n>Live RTMPS Url</label>
251 <my-input-toggle-hidden inputId="liveVideoRTMPSUrl" [value]="liveVideo.rtmpsUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> 250 <my-input-text inputId="liveVideoRTMPSUrl" [value]="liveVideo.rtmpsUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
252 </div> 251 </div>
253 252
254 <div class="form-group"> 253 <div class="form-group">
255 <label for="liveVideoStreamKey" i18n>Live stream key</label> 254 <label for="liveVideoStreamKey" i18n>Live stream key</label>
256 <my-input-toggle-hidden inputId="liveVideoStreamKey" [value]="liveVideo.streamKey" [withCopy]="true" [readonly]="true"></my-input-toggle-hidden> 255 <my-input-text inputId="liveVideoStreamKey" [value]="liveVideo.streamKey" [withCopy]="true" [readonly]="true"></my-input-text>
257 256
258 <div class="form-group-description" i18n>⚠️ Never share your stream key with anyone.</div> 257 <div class="form-group-description" i18n>⚠️ Never share your stream key with anyone.</div>
259 </div> 258 </div>
@@ -332,17 +331,30 @@
332 </ng-container> 331 </ng-container>
333 </ng-template> 332 </ng-template>
334 </my-help> 333 </my-help>
334
335 <my-markdown-textarea 335 <my-markdown-textarea
336 id="support" formControlName="support" markdownType="enhanced" 336 id="support" formControlName="support" markdownType="enhanced"
337 [classes]="{ 'input-error': formErrors['support'] }" 337 [formError]="formErrors['support']"
338 ></my-markdown-textarea> 338 ></my-markdown-textarea>
339 <div *ngIf="formErrors.support" class="form-error">
340 {{ formErrors.support }}
341 </div>
342 </div> 339 </div>
343 </div> 340 </div>
344 341
345 <div class="col-md-12 col-xl-4"> 342 <div class="col-md-12 col-xl-4">
343
344 <div *ngIf="videoSource" class="form-group">
345 <label i18n for="filename">Filename</label>
346
347 <my-help>
348 <ng-template ptTemplate="preHtml">
349 <ng-container i18n>
350 Name of the uploaded file
351 </ng-container>
352 </ng-template>
353 </my-help>
354
355 <input type="text" [disabled]="true" id="filename" class="form-control" [value]="videoSource.filename" />
356 </div>
357
346 <div class="form-group originally-published-at"> 358 <div class="form-group originally-published-at">
347 <label i18n for="originallyPublishedAt">Original publication date</label> 359 <label i18n for="originallyPublishedAt">Original publication date</label>
348 <my-help> 360 <my-help>
diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.scss b/client/src/app/+videos/+video-edit/shared/video-edit.component.scss
index 5344e5431..e8a6c6e42 100644
--- a/client/src/app/+videos/+video-edit/shared/video-edit.component.scss
+++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.scss
@@ -1,25 +1,10 @@
1@use '_variables' as *; 1@use '_variables' as *;
2@use '_mixins' as *; 2@use '_mixins' as *;
3 3
4label,
5my-dynamic-form-field ::ng-deep label {
6 font-weight: $font-regular;
7 font-size: 100%;
8}
9
10.peertube-select-container { 4.peertube-select-container {
11 @include peertube-select-container(auto); 5 @include peertube-select-container(auto);
12} 6}
13 7
14.title-page a {
15 color: pvar(--mainForegroundColor);
16
17 &:hover {
18 text-decoration: none;
19 opacity: .8;
20 }
21}
22
23my-peertube-checkbox { 8my-peertube-checkbox {
24 display: block; 9 display: block;
25 margin-bottom: 1rem; 10 margin-bottom: 1rem;
@@ -33,22 +18,10 @@ my-peertube-checkbox {
33 height: 100%; 18 height: 100%;
34 min-height: 300px; 19 min-height: 300px;
35 20
36 .form-group {
37 margin-bottom: 25px;
38 }
39
40 input { 21 input {
41 @include peertube-input-text(100%); 22 @include peertube-input-text(100%);
42 display: block; 23 display: block;
43 } 24 }
44
45 .label-tags + span {
46 font-size: 15px;
47 }
48
49 .advanced-settings .form-group {
50 margin-bottom: 20px;
51 }
52} 25}
53 26
54.captions-header { 27.captions-header {
@@ -79,7 +52,6 @@ my-peertube-checkbox {
79 .caption-entry-label { 52 .caption-entry-label {
80 @include margin-right(20px); 53 @include margin-right(20px);
81 54
82 font-size: 15px;
83 font-weight: bold; 55 font-weight: bold;
84 width: 150px; 56 width: 150px;
85 } 57 }
@@ -108,7 +80,6 @@ my-peertube-checkbox {
108 80
109.no-caption { 81.no-caption {
110 text-align: center; 82 text-align: center;
111 font-size: 15px;
112} 83}
113 84
114.submit-container { 85.submit-container {
@@ -119,7 +90,6 @@ my-peertube-checkbox {
119 90
120 display: inline-block; 91 display: inline-block;
121 color: pvar(--greyForegroundColor); 92 color: pvar(--greyForegroundColor);
122 font-size: 15px;
123 } 93 }
124} 94}
125 95
diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts
index 16b964482..c74ef5731 100644
--- a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts
+++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts
@@ -37,6 +37,7 @@ import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service'
37import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component' 37import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component'
38import { VideoCaptionEditModalComponent } from './video-caption-edit-modal/video-caption-edit-modal.component' 38import { VideoCaptionEditModalComponent } from './video-caption-edit-modal/video-caption-edit-modal.component'
39import { VideoEditType } from './video-edit.type' 39import { VideoEditType } from './video-edit.type'
40import { VideoSource } from '@shared/models/videos/video-source'
40 41
41type VideoLanguages = VideoConstant<string> & { group?: string } 42type VideoLanguages = VideoConstant<string> & { group?: string }
42type PluginField = { 43type PluginField = {
@@ -61,6 +62,7 @@ export class VideoEditComponent implements OnInit, OnDestroy {
61 @Input() forbidScheduledPublication = true 62 @Input() forbidScheduledPublication = true
62 63
63 @Input() videoCaptions: VideoCaptionWithPathEdit[] = [] 64 @Input() videoCaptions: VideoCaptionWithPathEdit[] = []
65 @Input() videoSource: VideoSource
64 66
65 @Input() waitTranscodingEnabled = true 67 @Input() waitTranscodingEnabled = true
66 @Input() type: VideoEditType 68 @Input() type: VideoEditType
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html b/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html
index ecec6045b..f537b939f 100644
--- a/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html
+++ b/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html
@@ -44,7 +44,7 @@
44 {{ error }} 44 {{ error }}
45</div> 45</div>
46 46
47<div class="alert alert-info" i18n *ngIf="isInUpdateForm && getMaxLiveDuration() >= 0"> 47<div class="alert pt-alert-primary" i18n *ngIf="isInUpdateForm && getMaxLiveDuration() >= 0">
48 Max live duration is {{ getMaxLiveDuration() | myDurationFormatter }}. 48 Max live duration is {{ getMaxLiveDuration() | myDurationFormatter }}.
49 If your live reaches this limit, it will be automatically terminated. 49 If your live reaches this limit, it will be automatically terminated.
50</div> 50</div>
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.html b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.html
index 14a7a287a..aa34d644a 100644
--- a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.html
+++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.html
@@ -52,7 +52,7 @@
52 {{ error }} 52 {{ error }}
53</div> 53</div>
54 54
55<div *ngIf="hasImportedVideo && !error" class="alert alert-info" i18n> 55<div *ngIf="hasImportedVideo && !error" class="alert pt-alert-primary" i18n>
56 Congratulations, the video will be imported with BitTorrent! You can already add information about this video. 56 Congratulations, the video will be imported with BitTorrent! You can already add information about this video.
57</div> 57</div>
58 58
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.html b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.html
index 60a43c870..67e1cb418 100644
--- a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.html
+++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.html
@@ -45,7 +45,7 @@
45 {{ error }} 45 {{ error }}
46</div> 46</div>
47 47
48<div *ngIf="!error && hasImportedVideo" class="alert alert-info" i18n> 48<div *ngIf="!error && hasImportedVideo" class="alert pt-alert-primary" i18n>
49 Congratulations, the video behind {{ targetUrl }} will be imported! You can already add information about this video. 49 Congratulations, the video behind {{ targetUrl }} will be imported! You can already add information about this video.
50</div> 50</div>
51 51
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts
index 0c78669c1..4c74eda84 100644
--- a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts
+++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts
@@ -78,7 +78,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, AfterV
78 .pipe( 78 .pipe(
79 switchMap(res => { 79 switchMap(res => {
80 return this.videoCaptionService 80 return this.videoCaptionService
81 .listCaptions(res.video.id) 81 .listCaptions(res.video.uuid)
82 .pipe( 82 .pipe(
83 map(result => ({ video: res.video, videoCaptions: result.data })) 83 map(result => ({ video: res.video, videoCaptions: result.data }))
84 ) 84 )
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.html b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.html
index 860fb76fa..728884986 100644
--- a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.html
+++ b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.html
@@ -87,7 +87,7 @@
87 {{ error }} 87 {{ error }}
88</div> 88</div>
89 89
90<div *ngIf="videoUploaded && !error" class="alert alert-info" i18n> 90<div *ngIf="videoUploaded && !error" class="alert pt-alert-primary" i18n>
91 Congratulations! Your video is now available in your private library. 91 Congratulations! Your video is now available in your private library.
92</div> 92</div>
93 93
diff --git a/client/src/app/+videos/+video-edit/video-add.component.html b/client/src/app/+videos/+video-edit/video-add.component.html
index 29cf08e75..27ad14d63 100644
--- a/client/src/app/+videos/+video-edit/video-add.component.html
+++ b/client/src/app/+videos/+video-edit/video-add.component.html
@@ -40,7 +40,7 @@
40<div *ngIf="!user.isUploadDisabled()" class="margin-content"> 40<div *ngIf="!user.isUploadDisabled()" class="margin-content">
41 <my-user-quota *ngIf="!isInSecondStep() || secondStepType === 'go-live'" [user]="user" [userInformationLoaded]="userInformationLoaded"></my-user-quota> 41 <my-user-quota *ngIf="!isInSecondStep() || secondStepType === 'go-live'" [user]="user" [userInformationLoaded]="userInformationLoaded"></my-user-quota>
42 42
43 <div class="title-page title-page-single" *ngIf="isInSecondStep()"> 43 <div class="title-page" *ngIf="isInSecondStep()">
44 <ng-container *ngIf="secondStepType === 'import-url' || secondStepType === 'import-torrent'" i18n>Import {{ videoName }}</ng-container> 44 <ng-container *ngIf="secondStepType === 'import-url' || secondStepType === 'import-torrent'" i18n>Import {{ videoName }}</ng-container>
45 <ng-container *ngIf="secondStepType === 'upload'" i18n>Upload {{ videoName }}</ng-container> 45 <ng-container *ngIf="secondStepType === 'upload'" i18n>Upload {{ videoName }}</ng-container>
46 </div> 46 </div>
diff --git a/client/src/app/+videos/+video-edit/video-add.component.scss b/client/src/app/+videos/+video-edit/video-add.component.scss
index dda868789..461a38204 100644
--- a/client/src/app/+videos/+video-edit/video-add.component.scss
+++ b/client/src/app/+videos/+video-edit/video-add.component.scss
@@ -10,7 +10,6 @@ $nav-link-height: 40px;
10.upload-message { 10.upload-message {
11 width: 100%; 11 width: 100%;
12 text-align: center; 12 text-align: center;
13 font-size: 15px;
14 margin-bottom: 0; 13 margin-bottom: 0;
15 border-radius: 0; 14 border-radius: 0;
16 15
diff --git a/client/src/app/+videos/+video-edit/video-update.component.html b/client/src/app/+videos/+video-edit/video-update.component.html
index 4376f6fe4..ffd125695 100644
--- a/client/src/app/+videos/+video-edit/video-update.component.html
+++ b/client/src/app/+videos/+video-edit/video-update.component.html
@@ -1,6 +1,6 @@
1<div class="margin-content"> 1<div class="margin-content">
2 <div class="title-page title-page-single"> 2 <div class="title-page">
3 <span class="mr-1" i18n>Update</span> 3 <span class="me-1" i18n>Update</span>
4 <a [routerLink]="getVideoUrl()">{{ video?.name }}</a> 4 <a [routerLink]="getVideoUrl()">{{ video?.name }}</a>
5 </div> 5 </div>
6 6
@@ -12,6 +12,7 @@
12 [videoCaptions]="videoCaptions" [waitTranscodingEnabled]="isWaitTranscodingEnabled()" 12 [videoCaptions]="videoCaptions" [waitTranscodingEnabled]="isWaitTranscodingEnabled()"
13 type="update" (pluginFieldsAdded)="hydratePluginFieldsFromVideo()" 13 type="update" (pluginFieldsAdded)="hydratePluginFieldsFromVideo()"
14 [liveVideo]="liveVideo" [videoToUpdate]="videoDetails" 14 [liveVideo]="liveVideo" [videoToUpdate]="videoDetails"
15 [videoSource]="videoSource"
15 16
16 (formBuilt)="onFormBuilt()" 17 (formBuilt)="onFormBuilt()"
17 ></my-video-edit> 18 ></my-video-edit>
diff --git a/client/src/app/+videos/+video-edit/video-update.component.ts b/client/src/app/+videos/+video-edit/video-update.component.ts
index 9c4998f2e..43e8ba3e5 100644
--- a/client/src/app/+videos/+video-edit/video-update.component.ts
+++ b/client/src/app/+videos/+video-edit/video-update.component.ts
@@ -10,6 +10,7 @@ import { LiveVideoService } from '@app/shared/shared-video-live'
10import { LoadingBarService } from '@ngx-loading-bar/core' 10import { LoadingBarService } from '@ngx-loading-bar/core'
11import { LiveVideo, LiveVideoUpdate, VideoPrivacy } from '@shared/models' 11import { LiveVideo, LiveVideoUpdate, VideoPrivacy } from '@shared/models'
12import { hydrateFormFromVideo } from './shared/video-edit-utils' 12import { hydrateFormFromVideo } from './shared/video-edit-utils'
13import { VideoSource } from '@shared/models/videos/video-source'
13 14
14@Component({ 15@Component({
15 selector: 'my-videos-update', 16 selector: 'my-videos-update',
@@ -19,6 +20,7 @@ import { hydrateFormFromVideo } from './shared/video-edit-utils'
19export class VideoUpdateComponent extends FormReactive implements OnInit { 20export class VideoUpdateComponent extends FormReactive implements OnInit {
20 video: VideoEdit 21 video: VideoEdit
21 videoDetails: VideoDetails 22 videoDetails: VideoDetails
23 videoSource: VideoSource
22 userVideoChannels: SelectChannelItem[] = [] 24 userVideoChannels: SelectChannelItem[] = []
23 videoCaptions: VideoCaptionEdit[] = [] 25 videoCaptions: VideoCaptionEdit[] = []
24 liveVideo: LiveVideo 26 liveVideo: LiveVideo
@@ -46,13 +48,14 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
46 this.buildForm({}) 48 this.buildForm({})
47 49
48 const { videoData } = this.route.snapshot.data 50 const { videoData } = this.route.snapshot.data
49 const { video, videoChannels, videoCaptions, liveVideo } = videoData 51 const { video, videoChannels, videoCaptions, videoSource, liveVideo } = videoData
50 52
51 this.video = new VideoEdit(video) 53 this.video = new VideoEdit(video)
52 this.videoDetails = video 54 this.videoDetails = video
53 55
54 this.userVideoChannels = videoChannels 56 this.userVideoChannels = videoChannels
55 this.videoCaptions = videoCaptions 57 this.videoCaptions = videoCaptions
58 this.videoSource = videoSource
56 this.liveVideo = liveVideo 59 this.liveVideo = liveVideo
57 60
58 this.forbidScheduledPublication = this.video.privacy !== VideoPrivacy.PRIVATE 61 this.forbidScheduledPublication = this.video.privacy !== VideoPrivacy.PRIVATE
diff --git a/client/src/app/+videos/+video-edit/video-update.resolver.ts b/client/src/app/+videos/+video-edit/video-update.resolver.ts
index 82dae5c1c..524ceae10 100644
--- a/client/src/app/+videos/+video-edit/video-update.resolver.ts
+++ b/client/src/app/+videos/+video-edit/video-update.resolver.ts
@@ -23,7 +23,8 @@ export class VideoUpdateResolver implements Resolve<any> {
23 return this.videoService.getVideo({ videoId: uuid }) 23 return this.videoService.getVideo({ videoId: uuid })
24 .pipe( 24 .pipe(
25 switchMap(video => forkJoin(this.buildVideoObservables(video))), 25 switchMap(video => forkJoin(this.buildVideoObservables(video))),
26 map(([ video, videoChannels, videoCaptions, liveVideo ]) => ({ video, videoChannels, videoCaptions, liveVideo })) 26 map(([ video, videoSource, videoChannels, videoCaptions, liveVideo ]) =>
27 ({ video, videoChannels, videoCaptions, videoSource, liveVideo }))
27 ) 28 )
28 } 29 }
29 30
@@ -33,10 +34,12 @@ export class VideoUpdateResolver implements Resolve<any> {
33 .loadCompleteDescription(video.descriptionPath) 34 .loadCompleteDescription(video.descriptionPath)
34 .pipe(map(description => Object.assign(video, { description }))), 35 .pipe(map(description => Object.assign(video, { description }))),
35 36
37 this.videoService.getSource(video.id),
38
36 listUserChannelsForSelect(this.authService), 39 listUserChannelsForSelect(this.authService),
37 40
38 this.videoCaptionService 41 this.videoCaptionService
39 .listCaptions(video.id) 42 .listCaptions(video.uuid)
40 .pipe( 43 .pipe(
41 map(result => result.data) 44 map(result => result.data)
42 ), 45 ),
diff --git a/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html
index f23efca98..cf32e371a 100644
--- a/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html
+++ b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html
@@ -1,5 +1,5 @@
1<div class="video-actions-rates"> 1<div class="video-actions-rates">
2 <div class="video-actions full-width justify-content-end"> 2 <div class="video-actions justify-content-end">
3 <my-video-rate 3 <my-video-rate
4 [video]="video" [isUserLoggedIn]="isUserLoggedIn" 4 [video]="video" [isUserLoggedIn]="isUserLoggedIn"
5 (rateUpdated)="onRateUpdated($event)" (userRatingLoaded)="onRateUpdated($event)" 5 (rateUpdated)="onRateUpdated($event)" (userRatingLoaded)="onRateUpdated($event)"
diff --git a/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss
index fdf4e3edb..786d10f73 100644
--- a/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss
@@ -5,6 +5,9 @@
5 height: 40px; // Align with the title 5 height: 40px; // Align with the title
6 display: flex; 6 display: flex;
7 align-items: center; 7 align-items: center;
8 width: 100%;
9 margin: 0 auto;
10 max-width: initial;
8 11
9 .action-button:not(:first-child), 12 .action-button:not(:first-child),
10 .action-dropdown, 13 .action-dropdown,
diff --git a/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.ts b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.ts
index 48d48f33f..0fef246b3 100644
--- a/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.ts
+++ b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.ts
@@ -89,7 +89,7 @@ export class VideoRateComponent implements OnInit, OnChanges, OnDestroy {
89 // Unlogged users do not have ratings 89 // Unlogged users do not have ratings
90 if (this.isUserLoggedIn === false) return 90 if (this.isUserLoggedIn === false) return
91 91
92 this.videoService.getUserVideoRating(this.video.id) 92 this.videoService.getUserVideoRating(this.video.uuid)
93 .subscribe({ 93 .subscribe({
94 next: ratingObject => { 94 next: ratingObject => {
95 if (!ratingObject) return 95 if (!ratingObject) return
@@ -103,13 +103,13 @@ export class VideoRateComponent implements OnInit, OnChanges, OnDestroy {
103 } 103 }
104 104
105 private setRating (nextRating: UserVideoRateType) { 105 private setRating (nextRating: UserVideoRateType) {
106 const ratingMethods: { [id in UserVideoRateType]: (id: number) => Observable<any> } = { 106 const ratingMethods: { [id in UserVideoRateType]: (id: string) => Observable<any> } = {
107 like: this.videoService.setVideoLike, 107 like: this.videoService.setVideoLike,
108 dislike: this.videoService.setVideoDislike, 108 dislike: this.videoService.setVideoDislike,
109 none: this.videoService.unsetVideoLike 109 none: this.videoService.unsetVideoLike
110 } 110 }
111 111
112 ratingMethods[nextRating].call(this.videoService, this.video.id) 112 ratingMethods[nextRating].call(this.videoService, this.video.uuid)
113 .subscribe({ 113 .subscribe({
114 next: () => { 114 next: () => {
115 // Update the video like attribute 115 // Update the video like attribute
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.html b/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.html
index 3ee818c8b..6bc201f32 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.html
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.html
@@ -1,8 +1,8 @@
1<form novalidate [formGroup]="form" (ngSubmit)="formValidated()"> 1<form novalidate [formGroup]="form" (ngSubmit)="formValidated()">
2 <div class="avatar-and-textarea"> 2 <div class="avatar-and-textarea">
3 <my-actor-avatar [account]="user?.account" size="25"></my-actor-avatar> 3 <my-actor-avatar [actor]="user?.account" [actorType]="getAvatarActorType()" size="25"></my-actor-avatar>
4 4
5 <div class="form-group"> 5 <div class="textarea-wrapper">
6 <textarea i18n-placeholder placeholder="Add comment..." myAutoResize 6 <textarea i18n-placeholder placeholder="Add comment..." myAutoResize
7 [readonly]="(user === null) ? true : false" 7 [readonly]="(user === null) ? true : false"
8 (click)="openVisitorModal($event)" 8 (click)="openVisitorModal($event)"
@@ -88,8 +88,8 @@
88 </div> 88 </div>
89 <div class="modal-body"> 89 <div class="modal-body">
90 <div class="emoji-flex"> 90 <div class="emoji-flex">
91 <div class="emoji-flex-item" *ngFor="let emojiMarkup of emojiMarkupList"> 91 <div class="emoji-flex-item" *ngFor="let emojiMarkup of getEmojiMarkupList()">
92 {{ emojiMarkup[0] }} <code>:{{ emojiMarkup[1] }}:</code> 92 {{ emojiMarkup.emoji }} <code>:{{ emojiMarkup.name }}:</code>
93 </div> 93 </div>
94 </div> 94 </div>
95 </div> 95 </div>
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.scss b/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.scss
index ae889dd38..023d625e9 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.scss
@@ -17,9 +17,8 @@ form {
17 @include margin-right(10px); 17 @include margin-right(10px);
18 } 18 }
19 19
20 .form-group { 20 .textarea-wrapper {
21 flex-grow: 1; 21 flex-grow: 1;
22 margin: 0;
23 position: relative; 22 position: relative;
24 } 23 }
25 24
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.ts b/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.ts
index 85da83a4c..fd3614297 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.ts
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comment-add.component.ts
@@ -45,6 +45,8 @@ export class VideoCommentAddComponent extends FormReactive implements OnChanges,
45 addingComment = false 45 addingComment = false
46 addingCommentButtonValue: string 46 addingCommentButtonValue: string
47 47
48 private emojiMarkupList: { emoji: string, name: string }[]
49
48 constructor ( 50 constructor (
49 protected formValidatorService: FormValidatorService, 51 protected formValidatorService: FormValidatorService,
50 private notifier: Notifier, 52 private notifier: Notifier,
@@ -56,21 +58,6 @@ export class VideoCommentAddComponent extends FormReactive implements OnChanges,
56 super() 58 super()
57 } 59 }
58 60
59 get emojiMarkupList () {
60 const emojiMarkupObjectList = require('markdown-it-emoji/lib/data/light.json')
61
62 // Populate emoji-markup-list from object to array to avoid keys alphabetical order
63 const emojiMarkupArrayList = []
64 for (const emojiMarkupName in emojiMarkupObjectList) {
65 if (emojiMarkupName) {
66 const emoji = emojiMarkupObjectList[emojiMarkupName]
67 emojiMarkupArrayList.push([ emoji, emojiMarkupName ])
68 }
69 }
70
71 return emojiMarkupArrayList
72 }
73
74 ngOnInit () { 61 ngOnInit () {
75 this.buildForm({ 62 this.buildForm({
76 text: VIDEO_COMMENT_TEXT_VALIDATOR 63 text: VIDEO_COMMENT_TEXT_VALIDATOR
@@ -96,6 +83,20 @@ export class VideoCommentAddComponent extends FormReactive implements OnChanges,
96 } 83 }
97 } 84 }
98 85
86 getEmojiMarkupList () {
87 if (this.emojiMarkupList) return this.emojiMarkupList
88
89 const emojiMarkupObjectList = require('markdown-it-emoji/lib/data/light.json')
90
91 this.emojiMarkupList = []
92 for (const name of Object.keys(emojiMarkupObjectList)) {
93 const emoji = emojiMarkupObjectList[name]
94 this.emojiMarkupList.push({ emoji, name })
95 }
96
97 return this.emojiMarkupList
98 }
99
99 onValidKey () { 100 onValidKey () {
100 this.forceCheck() 101 this.forceCheck()
101 if (!this.form.valid) return 102 if (!this.form.valid) return
@@ -174,14 +175,20 @@ export class VideoCommentAddComponent extends FormReactive implements OnChanges,
174 return getLocaleDirection(this.localeId) === 'rtl' 175 return getLocaleDirection(this.localeId) === 'rtl'
175 } 176 }
176 177
178 getAvatarActorType () {
179 if (this.user) return 'account'
180
181 return 'unlogged'
182 }
183
177 private addCommentReply (commentCreate: VideoCommentCreate) { 184 private addCommentReply (commentCreate: VideoCommentCreate) {
178 return this.videoCommentService 185 return this.videoCommentService
179 .addCommentReply(this.video.id, this.parentComment.id, commentCreate) 186 .addCommentReply(this.video.uuid, this.parentComment.id, commentCreate)
180 } 187 }
181 188
182 private addCommentThread (commentCreate: VideoCommentCreate) { 189 private addCommentThread (commentCreate: VideoCommentCreate) {
183 return this.videoCommentService 190 return this.videoCommentService
184 .addCommentThread(this.video.id, commentCreate) 191 .addCommentThread(this.video.uuid, commentCreate)
185 } 192 }
186 193
187 private initTextValue () { 194 private initTextValue () {
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.html b/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.html
index 5014b9692..da35a9a2e 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.html
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.html
@@ -1,6 +1,10 @@
1<div *ngIf="isCommentDisplayed()" class="root-comment" [ngClass]="{ 'is-child': isChild() }"> 1<div *ngIf="isCommentDisplayed()" class="root-comment" [ngClass]="{ 'is-child': isChild() }">
2 <div class="left"> 2 <div class="left">
3 <my-actor-avatar *ngIf="!comment.isDeleted" [href]="comment.account.url" [account]="comment.account" [size]="isChild() ? '25' : '36'"></my-actor-avatar> 3 <my-actor-avatar
4 *ngIf="!comment.isDeleted" [href]="comment.account.url"
5 [actor]="comment.account" actorType="account" [size]="isChild() ? '25' : '36'"
6 ></my-actor-avatar>
7
4 <div class="vertical-border"></div> 8 <div class="vertical-border"></div>
5 </div> 9 </div>
6 10
@@ -16,7 +20,7 @@
16 {{ comment.account.displayName }} 20 {{ comment.account.displayName }}
17 </span> 21 </span>
18 22
19 <span class="comment-account-fid ml-1">{{ comment.by }}</span> 23 <span class="comment-account-fid ms-1">{{ comment.by }}</span>
20 </a> 24 </a>
21 </div> 25 </div>
22 26
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.scss b/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.scss
index 54f828014..8b5034083 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.scss
@@ -2,7 +2,6 @@
2@use '_mixins' as *; 2@use '_mixins' as *;
3 3
4.root-comment { 4.root-comment {
5 font-size: 15px;
6 display: flex; 5 display: flex;
7 6
8 .left { 7 .left {
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.html b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.html
index 0e00c9c0e..e27942e66 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.html
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.html
@@ -1,12 +1,12 @@
1<div> 1<div>
2 <div class="title-block"> 2 <div class="title-block">
3 <h2 class="title-page title-page-single"> 3 <h2 class="title-page">
4 {totalNotDeletedComments, plural, =0 {Comments} =1 {1 Comment} other {{{totalNotDeletedComments}} Comments}} 4 {totalNotDeletedComments, plural, =0 {Comments} =1 {1 Comment} other {{{totalNotDeletedComments}} Comments}}
5 </h2> 5 </h2>
6 6
7 <my-feed [syndicationItems]="syndicationItems"></my-feed> 7 <my-feed [syndicationItems]="syndicationItems"></my-feed>
8 8
9 <div ngbDropdown class="d-inline-block ml-4 dropdown-root"> 9 <div ngbDropdown class="d-inline-block ms-4 dropdown-root">
10 <button class="btn btn-sm btn-outline-secondary" id="dropdown-sort-comments" ngbDropdownToggle i18n> 10 <button class="btn btn-sm btn-outline-secondary" id="dropdown-sort-comments" ngbDropdownToggle i18n>
11 SORT BY 11 SORT BY
12 </button> 12 </button>
@@ -65,7 +65,7 @@
65 [redraftValue]="commentReplyRedraftValue" 65 [redraftValue]="commentReplyRedraftValue"
66 > 66 >
67 <div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment.id)" class="view-replies mb-2"> 67 <div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment.id)" class="view-replies mb-2">
68 <span class="glyphicon glyphicon-menu-down"></span> 68 <span class="chevron-down"></span>
69 69
70 <ng-container *ngIf="comment.totalRepliesFromVideoAuthor > 0; then hasAuthorComments; else noAuthorComments"></ng-container> 70 <ng-container *ngIf="comment.totalRepliesFromVideoAuthor > 0; then hasAuthorComments; else noAuthorComments"></ng-container>
71 71
@@ -80,7 +80,7 @@
80 80
81 <ng-template i18n #noAuthorComments>View {comment.totalReplies, plural, =1 {1 reply} other {{{ comment.totalReplies }} replies}}</ng-template> 81 <ng-template i18n #noAuthorComments>View {comment.totalReplies, plural, =1 {1 reply} other {{{ comment.totalReplies }} replies}}</ng-template>
82 82
83 <my-small-loader class="comment-thread-loading ml-1" [loading]="threadLoading[comment.id]"></my-small-loader> 83 <my-loader size="sm" class="ms-1" [loading]="threadLoading[comment.id]"></my-loader>
84 </div> 84 </div>
85 </my-video-comment> 85 </my-video-comment>
86 86
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.scss b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.scss
index 31aa73937..638147dfe 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.scss
@@ -7,18 +7,9 @@
7 7
8.view-replies { 8.view-replies {
9 font-weight: $font-semibold; 9 font-weight: $font-semibold;
10 font-size: 15px;
11 cursor: pointer; 10 cursor: pointer;
12} 11}
13 12
14.glyphicon,
15.comment-thread-loading {
16 @include margin-right(5px);
17
18 display: inline-block;
19 font-size: 13px;
20}
21
22.title-block { 13.title-block {
23 .title-page { 14 .title-page {
24 @include margin-right(0); 15 @include margin-right(0);
@@ -41,10 +32,9 @@
41} 32}
42 33
43#dropdown-sort-comments { 34#dropdown-sort-comments {
44 font-weight: 600; 35 font-weight: $font-semibold;
45 text-transform: uppercase; 36 text-transform: uppercase;
46 border: 0; 37 border: 0;
47 transform: translateY(-7%);
48} 38}
49 39
50@media screen and (max-width: 600px) { 40@media screen and (max-width: 600px) {
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts
index 17e0af3bc..8e556c58f 100644
--- a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts
+++ b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts
@@ -78,7 +78,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
78 this.threadLoading[commentId] = true 78 this.threadLoading[commentId] = true
79 79
80 const params = { 80 const params = {
81 videoId: this.video.id, 81 videoId: this.video.uuid,
82 threadId: commentId 82 threadId: commentId
83 } 83 }
84 84
@@ -110,7 +110,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
110 110
111 loadMoreThreads () { 111 loadMoreThreads () {
112 const params = { 112 const params = {
113 videoId: this.video.id, 113 videoId: this.video.uuid,
114 componentPagination: this.componentPagination, 114 componentPagination: this.componentPagination,
115 sort: this.sort 115 sort: this.sort
116 } 116 }
diff --git a/client/src/app/+videos/+video-watch/shared/information/privacy-concerns.component.html b/client/src/app/+videos/+video-watch/shared/information/privacy-concerns.component.html
index d579aaddb..b64d45564 100644
--- a/client/src/app/+videos/+video-watch/shared/information/privacy-concerns.component.html
+++ b/client/src/app/+videos/+video-watch/shared/information/privacy-concerns.component.html
@@ -1,6 +1,6 @@
1<div class="privacy-concerns" *ngIf="display"> 1<div class="privacy-concerns" *ngIf="display">
2 <div class="privacy-concerns-text"> 2 <div class="privacy-concerns-text">
3 <span class="mr-2"> 3 <span class="me-2">
4 <strong i18n>Friendly Reminder: </strong> 4 <strong i18n>Friendly Reminder: </strong>
5 <ng-container i18n> 5 <ng-container i18n>
6 the sharing system used for this video implies that some technical information about your system (such as a public IP address) can be sent to other peers. 6 the sharing system used for this video implies that some technical information about your system (such as a public IP address) can be sent to other peers.
diff --git a/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html b/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html
index be726c990..79b83811d 100644
--- a/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html
+++ b/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html
@@ -22,15 +22,15 @@
22 The video is being moved to an external server, it may not work properly. 22 The video is being moved to an external server, it may not work properly.
23</div> 23</div>
24 24
25<div i18n class="alert alert-info" *ngIf="hasVideoScheduledPublication()"> 25<div i18n class="alert pt-alert-primary" *ngIf="hasVideoScheduledPublication()">
26 This video will be published on {{ video.scheduledUpdate.updateAt | date: 'full' }}. 26 This video will be published on {{ video.scheduledUpdate.updateAt | date: 'full' }}.
27</div> 27</div>
28 28
29<div i18n class="alert alert-info" *ngIf="isWaitingForLive()"> 29<div i18n class="alert pt-alert-primary" *ngIf="isWaitingForLive()">
30 This live has not started yet. 30 This live has not started yet.
31</div> 31</div>
32 32
33<div i18n class="alert alert-info" *ngIf="isLiveEnded()"> 33<div i18n class="alert pt-alert-primary" *ngIf="isLiveEnded()">
34 This live has ended. 34 This live has ended.
35</div> 35</div>
36 36
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.html b/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.html
index 10ff46595..52ad1999d 100644
--- a/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.html
+++ b/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.html
@@ -11,9 +11,11 @@
11 >{{ video.originInstanceHost }}</a> 11 >{{ video.originInstanceHost }}</a>
12 12
13 <a 13 <a
14 i18n-title title="Open the video on the origin instance" class="glyphicon glyphicon-new-window" 14 i18n-title title="Open the video on the origin instance"
15 target="_blank" rel="noopener noreferrer" [href]="video.url" 15 target="_blank" rel="noopener noreferrer" [href]="video.url"
16 ></a> 16 >
17 <my-global-icon iconName="external-link"></my-global-icon>
18 </a>
17</div> 19</div>
18 20
19<div *ngIf="!!video.originallyPublishedAt" class="attribute attribute-originally-published-at"> 21<div *ngIf="!!video.originallyPublishedAt" class="attribute attribute-originally-published-at">
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.scss b/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.scss
index 26bead124..1470a9f6d 100644
--- a/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/metadata/video-attributes.component.scss
@@ -33,12 +33,6 @@ a.attribute-value {
33 } 33 }
34} 34}
35 35
36.glyphicon-new-window {
37 color: pvar(--inputPlaceholderColor);
38 margin-left: 5px;
39 font-size: 12px;
40}
41
42@media screen and (max-width: 1600px) { 36@media screen and (max-width: 1600px) {
43 .attributes .attribute { 37 .attributes .attribute {
44 margin-bottom: 5px; 38 margin-bottom: 5px;
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.html b/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.html
index a23152b67..a608a22f6 100644
--- a/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.html
+++ b/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.html
@@ -2,7 +2,7 @@
2 <my-actor-avatar 2 <my-actor-avatar
3 *ngIf="showChannel" 3 *ngIf="showChannel"
4 class="channel" 4 class="channel"
5 [channel]="video.channel" 5 [actor]="video.channel" actorType="channel"
6 [internalHref]="[ '/c', video.byVideoChannel ]" 6 [internalHref]="[ '/c', video.byVideoChannel ]"
7 [title]="channelLinkTitle" 7 [title]="channelLinkTitle"
8 size="35" 8 size="35"
@@ -12,7 +12,7 @@
12 *ngIf="showAccount" 12 *ngIf="showAccount"
13 class="account" 13 class="account"
14 [class.second-avatar]="showChannel" 14 [class.second-avatar]="showChannel"
15 [account]="video.account" 15 [actor]="video.account" actorType="account"
16 [internalHref]="[ '/a', video.byAccount ]" 16 [internalHref]="[ '/a', video.byAccount ]"
17 [title]="accountLinkTitle" 17 [title]="accountLinkTitle"
18 size="35"> 18 size="35">
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.scss b/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.scss
index 80711ff32..fd9dd1a6a 100644
--- a/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/metadata/video-avatar-channel.component.scss
@@ -1,14 +1,5 @@
1@use '_mixins' as *; 1@use '_mixins' as *;
2 2
3@mixin secondary {
4 height: 60%;
5 width: 60%;
6 position: absolute;
7 bottom: -5px;
8 right: -5px;
9 background-color: rgba(0, 0, 0, 0);
10}
11
12.wrapper { 3.wrapper {
13 @include margin-right(5px); 4 @include margin-right(5px);
14 5
@@ -16,6 +7,11 @@
16 margin-bottom: 5px; 7 margin-bottom: 5px;
17 8
18 .second-avatar { 9 .second-avatar {
19 @include secondary(); 10 height: 60%;
11 width: 60%;
12 position: absolute;
13 bottom: -5px;
14 right: -5px;
15 background-color: rgba(0, 0, 0, 0);
20 } 16 }
21} 17}
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.html b/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.html
index 2cfaad8f6..fa4dbb3ca 100644
--- a/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.html
+++ b/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.html
@@ -8,12 +8,12 @@
8 8
9 <div class="video-info-description-more" *ngIf="completeDescriptionShown === false && video.description?.length >= 250" (click)="showMoreDescription()"> 9 <div class="video-info-description-more" *ngIf="completeDescriptionShown === false && video.description?.length >= 250" (click)="showMoreDescription()">
10 <ng-container i18n>Show more</ng-container> 10 <ng-container i18n>Show more</ng-container>
11 <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-down"></span> 11 <span *ngIf="descriptionLoading === false" class="chevron-down"></span>
12 <my-small-loader class="description-loading" [loading]="descriptionLoading"></my-small-loader> 12 <my-loader size="sm" class="description-loading" [loading]="descriptionLoading"></my-loader>
13 </div> 13 </div>
14 14
15 <div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-info-description-more"> 15 <div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-info-description-more">
16 <ng-container i18n>Show less</ng-container> 16 <ng-container i18n>Show less</ng-container>
17 <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-up"></span> 17 <span *ngIf="descriptionLoading === false" class="chevron-up"></span>
18 </div> 18 </div>
19</div> 19</div>
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.scss b/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.scss
index fc8b4574c..b503a94cb 100644
--- a/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.scss
@@ -7,7 +7,6 @@
7 7
8 margin-top: 20px; 8 margin-top: 20px;
9 margin-bottom: 20px; 9 margin-bottom: 20px;
10 font-size: 15px;
11 10
12 .video-info-description-html { 11 .video-info-description-html {
13 @include peertube-word-wrap; 12 @include peertube-word-wrap;
@@ -17,13 +16,8 @@
17 } 16 }
18 } 17 }
19 18
20 .glyphicon,
21 .description-loading { 19 .description-loading {
22 @include margin-left(3px); 20 @include margin-left(5px);
23 }
24
25 .description-loading {
26 display: inline-block;
27 } 21 }
28 22
29 .video-info-description-more { 23 .video-info-description-more {
@@ -31,11 +25,6 @@
31 font-weight: $font-semibold; 25 font-weight: $font-semibold;
32 color: pvar(--greyForegroundColor); 26 color: pvar(--greyForegroundColor);
33 font-size: 14px; 27 font-size: 14px;
34
35 .glyphicon {
36 position: relative;
37 top: 2px;
38 }
39 } 28 }
40} 29}
41 30
diff --git a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html
index f5dd352a3..b04bd3548 100644
--- a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html
+++ b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html
@@ -6,9 +6,9 @@
6 <div class="playlist-display-name"> 6 <div class="playlist-display-name">
7 {{ playlist.displayName }} 7 {{ playlist.displayName }}
8 8
9 <span *ngIf="isUnlistedPlaylist()" class="badge badge-warning" i18n>Unlisted</span> 9 <span *ngIf="isUnlistedPlaylist()" class="pt-badge badge-warning" i18n>Unlisted</span>
10 <span *ngIf="isPrivatePlaylist()" class="badge badge-danger" i18n>Private</span> 10 <span *ngIf="isPrivatePlaylist()" class="pt-badge badge-danger" i18n>Private</span>
11 <span *ngIf="isPublicPlaylist()" class="badge badge-info" i18n>Public</span> 11 <span *ngIf="isPublicPlaylist()" class="pt-badge badge-info" i18n>Public</span>
12 </div> 12 </div>
13 13
14 <div class="playlist-by-index"> 14 <div class="playlist-by-index">
diff --git a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss
index 5c3453e4b..0f0ac1979 100644
--- a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss
@@ -15,43 +15,47 @@
15 .playlist-info { 15 .playlist-info {
16 padding: 5px 30px; 16 padding: 5px 30px;
17 background-color: pvar(--greyBackgroundColor); 17 background-color: pvar(--greyBackgroundColor);
18 }
19
20 .playlist-display-name {
21 font-size: 18px;
22 font-weight: $font-semibold;
23 margin-bottom: 5px;
18 24
19 .playlist-display-name { 25 .pt-badge {
20 font-size: 18px; 26 @include margin-left(5px);
21 font-weight: $font-semibold;
22 margin-bottom: 5px;
23 } 27 }
28 }
24 29
25 .playlist-by-index { 30 .playlist-by-index {
26 color: pvar(--greyForegroundColor); 31 color: pvar(--greyForegroundColor);
27 display: flex; 32 display: flex;
28 33
29 .playlist-by { 34 .playlist-by {
30 @include margin-right(5px); 35 @include margin-right(5px);
31 } 36 }
32 37
33 .playlist-index span:first-child::after { 38 .playlist-index span:first-child::after {
34 content: '/'; 39 content: '/';
35 margin: 0 3px; 40 margin: 0 3px;
36 }
37 } 41 }
42 }
38 43
39 .playlist-controls { 44 .playlist-controls {
40 display: flex; 45 display: flex;
41 margin: 10px 0; 46 margin: 10px 0;
42 47
43 my-global-icon:not(:last-child) { 48 my-global-icon:not(:last-child) {
44 @include margin-right(.5rem); 49 @include margin-right(.5rem);
45 } 50 }
46 51
47 my-global-icon { 52 my-global-icon {
48 &:not(.active) { 53 &:not(.active) {
49 opacity: .5; 54 opacity: .5;
50 } 55 }
51 56
52 ::ng-deep { 57 ::ng-deep {
53 cursor: pointer; 58 cursor: pointer;
54 }
55 } 59 }
56 } 60 }
57 } 61 }
diff --git a/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.html b/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.html
index e493ad8d7..5ac801622 100644
--- a/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.html
+++ b/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.html
@@ -1,9 +1,8 @@
1<div class="other-videos" [ngClass]="{ 'display-as-row': displayAsRow }"> 1<div class="other-videos" [ngClass]="{ 'display-as-row': displayAsRow }">
2 <ng-container *ngIf="hasVideos$ | async"> 2 <ng-container *ngIf="hasVideos$ | async">
3 <div class="title-page-container"> 3 <div class="title-page-container">
4 <h2 i18n class="title-page title-page-single"> 4 <h2 i18n class="title-page">Other videos</h2>
5 Other videos 5
6 </h2>
7 <div *ngIf="!playlist" class="title-page-autoplay" 6 <div *ngIf="!playlist" class="title-page-autoplay"
8 [ngbTooltip]="autoPlayNextVideoTooltip" placement="bottom-right auto" 7 [ngbTooltip]="autoPlayNextVideoTooltip" placement="bottom-right auto"
9 > 8 >
diff --git a/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.scss b/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.scss
index 784d0e961..5b1bf9cab 100644
--- a/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/recommendations/recommended-videos.component.scss
@@ -8,18 +8,14 @@
8 margin-bottom: 25px; 8 margin-bottom: 25px;
9 flex-wrap: wrap-reverse; 9 flex-wrap: wrap-reverse;
10 10
11 .title-page.active, 11 .title-page {
12 .title-page.title-page-single {
13 @include margin-right(.5rem !important); 12 @include margin-right(.5rem !important);
14 13
15 margin-bottom: unset; 14 margin-bottom: unset;
15 margin-top: 0;
16 } 16 }
17} 17}
18 18
19.title-page {
20 margin-top: 0;
21}
22
23.title-page-autoplay { 19.title-page-autoplay {
24 @include margin-left(auto); 20 @include margin-left(auto);
25 21
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.html b/client/src/app/+videos/+video-watch/video-watch.component.html
index 1ea0cf6b8..461891779 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.html
+++ b/client/src/app/+videos/+video-watch/video-watch.component.html
@@ -61,7 +61,7 @@
61 <div class="video-info-channel-left d-flex"> 61 <div class="video-info-channel-left d-flex">
62 <my-video-avatar-channel [video]="video" [showChannel]="!isChannelDisplayNameGeneric()"></my-video-avatar-channel> 62 <my-video-avatar-channel [video]="video" [showChannel]="!isChannelDisplayNameGeneric()"></my-video-avatar-channel>
63 63
64 <div class="video-info-channel-left-links ml-1"> 64 <div class="video-info-channel-left-links ms-1">
65 <ng-container *ngIf="!isChannelDisplayNameGeneric()"> 65 <ng-container *ngIf="!isChannelDisplayNameGeneric()">
66 <a [routerLink]="[ '/c', video.byVideoChannel ]" i18n-title title="Channel page"> 66 <a [routerLink]="[ '/c', video.byVideoChannel ]" i18n-title title="Channel page">
67 {{ video.channel.displayName }} 67 {{ video.channel.displayName }}
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.scss b/client/src/app/+videos/+video-watch/video-watch.component.scss
index 6818a4257..d438facd3 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/+videos/+video-watch/video-watch.component.scss
@@ -112,7 +112,6 @@ $video-height: 66vh;
112 margin-top: 50px; 112 margin-top: 50px;
113 text-align: center; 113 text-align: center;
114 font-weight: $font-semibold; 114 font-weight: $font-semibold;
115 font-size: 15px;
116} 115}
117 116
118.video-bottom { 117.video-bottom {
@@ -158,12 +157,11 @@ $video-height: 66vh;
158 157
159 margin-bottom: 10px; 158 margin-bottom: 10px;
160 align-self: start; 159 align-self: start;
161 font-size: 1em; 160 font-size: 14px;
162} 161}
163 162
164.video-info-channel { 163.video-info-channel {
165 font-weight: $font-semibold; 164 font-weight: $font-semibold;
166 font-size: 15px;
167 165
168 a { 166 a {
169 @include disable-default-a-behaviour; 167 @include disable-default-a-behaviour;
diff --git a/client/src/app/+videos/video-list/overview/video-overview.component.html b/client/src/app/+videos/video-list/overview/video-overview.component.html
index f250c2407..b38516af8 100644
--- a/client/src/app/+videos/video-list/overview/video-overview.component.html
+++ b/client/src/app/+videos/video-list/overview/video-overview.component.html
@@ -1,4 +1,4 @@
1<h1 class="sr-only" i18n>Discover</h1> 1<h1 class="visually-hidden" i18n>Discover</h1>
2<div class="margin-content"> 2<div class="margin-content">
3 3
4 <div class="no-results" i18n *ngIf="notResults">No results.</div> 4 <div class="no-results" i18n *ngIf="notResults">No results.</div>
@@ -10,7 +10,7 @@
10 10
11 <div class="section videos" *ngFor="let object of overview.categories"> 11 <div class="section videos" *ngFor="let object of overview.categories">
12 <h1 class="section-title"> 12 <h1 class="section-title">
13 <a routerLink="/search" [queryParams]="{ categoryOneOf: [ object.category.id ] }">{{ object.category.label }}</a> 13 <a class="link-orange" routerLink="/search" [queryParams]="{ categoryOneOf: [ object.category.id ] }">{{ object.category.label }}</a>
14 </h1> 14 </h1>
15 15
16 <div class="video-wrapper" *ngFor="let video of buildVideos(object.videos)"> 16 <div class="video-wrapper" *ngFor="let video of buildVideos(object.videos)">
@@ -21,7 +21,7 @@
21 21
22 <div class="section videos" *ngFor="let object of overview.tags"> 22 <div class="section videos" *ngFor="let object of overview.tags">
23 <h2 class="section-title"> 23 <h2 class="section-title">
24 <a routerLink="/search" [queryParams]="{ tagsOneOf: [ object.tag ] }">#{{ object.tag }}</a> 24 <a class="link-orange" routerLink="/search" [queryParams]="{ tagsOneOf: [ object.tag ] }">#{{ object.tag }}</a>
25 </h2> 25 </h2>
26 26
27 <div class="video-wrapper" *ngFor="let video of buildVideos(object.videos)"> 27 <div class="video-wrapper" *ngFor="let video of buildVideos(object.videos)">
@@ -32,8 +32,8 @@
32 32
33 <div class="section channel videos" *ngFor="let object of overview.channels"> 33 <div class="section channel videos" *ngFor="let object of overview.channels">
34 <div class="section-title"> 34 <div class="section-title">
35 <a [routerLink]="[ '/c', buildVideoChannelBy(object) ]"> 35 <a class="link-orange" [routerLink]="[ '/c', buildVideoChannelBy(object) ]">
36 <my-actor-avatar [channel]="buildVideoChannel(object)" size="28"></my-actor-avatar> 36 <my-actor-avatar [actor]="buildVideoChannel(object)" actorType="channel" size="28"></my-actor-avatar>
37 37
38 <h2 class="section-title">{{ object.channel.displayName }}</h2> 38 <h2 class="section-title">{{ object.channel.displayName }}</h2>
39 </a> 39 </a>
diff --git a/client/src/app/+videos/video-list/overview/video-overview.component.scss b/client/src/app/+videos/video-list/overview/video-overview.component.scss
index 8b2aa88f2..5a789b66d 100644
--- a/client/src/app/+videos/video-list/overview/video-overview.component.scss
+++ b/client/src/app/+videos/video-list/overview/video-overview.component.scss
@@ -13,7 +13,7 @@
13 13
14.section { 14.section {
15 &:first-child { 15 &:first-child {
16 padding-top: 30px; 16 padding-top: 15px;
17 17
18 .section-title { 18 .section-title {
19 border-top: 0 !important; 19 border-top: 0 !important;
@@ -22,66 +22,27 @@
22 22
23 .section-title { 23 .section-title {
24 font-size: 24px; 24 font-size: 24px;
25 font-weight: $font-semibold; 25 padding-top: 20px;
26 padding-top: 15px; 26 margin-bottom: 30px;
27 margin-bottom: 15px;
28 display: flex;
29 justify-content: space-between;
30 27
31 &:not(h2) { 28 &:not(h2) {
32 border-top: 1px solid $separator-border-color; 29 border-top: 1px solid $separator-border-color;
33 } 30 }
34 31
35 a { 32 a > h2 {
36 color: pvar(--mainForegroundColor); 33 margin-bottom: 0;
37 34 display: inline-block;
38 &:hover, 35 font-weight: $font-bold;
39 &:focus:not(.focus-visible),
40 &:active {
41 text-decoration: none;
42 outline: none;
43 }
44 } 36 }
45 }
46
47 &.channel {
48 .section-title {
49 a {
50 display: flex;
51 width: fit-content;
52 align-items: center;
53
54 my-actor-avatar {
55 @include margin-right(8px);
56
57 font-size: initial;
58 }
59 }
60 37
61 .followers { 38 my-actor-avatar {
62 @include margin-left(10px); 39 @include margin-right(8px);
63 40
64 color: pvar(--greyForegroundColor); 41 position: relative;
65 font-weight: normal; 42 top: -2px;
66 font-size: 14px;
67 position: relative;
68 top: 2px;
69 }
70 } 43 }
71 } 44 }
72 45
73 .show-more {
74 position: relative;
75 top: -5px;
76 display: inline-block;
77 font-size: 16px;
78 text-transform: uppercase;
79 color: pvar(--greyForegroundColor);
80 margin-bottom: 10px;
81 font-weight: $font-semibold;
82 text-decoration: none;
83 }
84
85 @media screen and (max-width: $mobile-view) { 46 @media screen and (max-width: $mobile-view) {
86 max-height: initial; 47 max-height: initial;
87 overflow: initial; 48 overflow: initial;
diff --git a/client/src/app/+videos/video-list/videos-list-common-page.component.ts b/client/src/app/+videos/video-list/videos-list-common-page.component.ts
index d2782036b..c8fa8ef30 100644
--- a/client/src/app/+videos/video-list/videos-list-common-page.component.ts
+++ b/client/src/app/+videos/video-list/videos-list-common-page.component.ts
@@ -204,13 +204,28 @@ export class VideosListCommonPageComponent implements OnInit, OnDestroy, Disable
204 if ([ 'hot', 'trending', 'likes', 'views' ].includes(sanitizedSort)) { 204 if ([ 'hot', 'trending', 'likes', 'views' ].includes(sanitizedSort)) {
205 this.title = $localize`Trending` 205 this.title = $localize`Trending`
206 206
207 if (sanitizedSort === 'hot') this.titleTooltip = $localize`Videos with the most interactions for recent videos` 207 if (sanitizedSort === 'hot') {
208 if (sanitizedSort === 'likes') this.titleTooltip = $localize`Videos that have the most likes` 208 this.titleTooltip = $localize`Videos with the most interactions for recent videos`
209 if (sanitizedSort === 'views') this.titleTooltip = undefined 209 return
210 }
211
212 if (sanitizedSort === 'likes') {
213 this.titleTooltip = $localize`Videos that have the most likes`
214 return
215 }
216
217 if (sanitizedSort === 'views') {
218 this.titleTooltip = undefined
219 return
220 }
210 221
211 if (sanitizedSort === 'trending') { 222 if (sanitizedSort === 'trending') {
212 if (this.trendingDays === 1) this.titleTooltip = $localize`Videos with the most views during the last 24 hours` 223 if (this.trendingDays === 1) {
213 else this.titleTooltip = $localize`Videos with the most views during the last ${this.trendingDays} days` 224 this.titleTooltip = $localize`Videos with the most views during the last 24 hours`
225 return
226 }
227
228 this.titleTooltip = $localize`Videos with the most views during the last ${this.trendingDays} days`
214 } 229 }
215 230
216 return 231 return