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-edit.component.html13
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.scss4
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.ts5
-rw-r--r--client/src/app/videos/+video-edit/shared/video-image.component.scss2
-rw-r--r--client/src/app/videos/+video-edit/video-update.component.ts3
-rw-r--r--client/src/app/videos/+video-watch/modal/video-support.component.html22
-rw-r--r--client/src/app/videos/+video-watch/modal/video-support.component.scss3
-rw-r--r--client/src/app/videos/+video-watch/modal/video-support.component.ts36
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html8
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.scss23
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts8
-rw-r--r--client/src/app/videos/+video-watch/video-watch.module.ts2
-rw-r--r--client/src/app/videos/shared/markdown.service.ts38
13 files changed, 147 insertions, 20 deletions
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 899249778..bf2204013 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
@@ -111,7 +111,7 @@
111 </tab> 111 </tab>
112 112
113 <tab heading="Advanced settings"> 113 <tab heading="Advanced settings">
114 <div class="col-md-12"> 114 <div class="col-md-12 advanced-settings">
115 <div class="form-group"> 115 <div class="form-group">
116 <my-video-image 116 <my-video-image
117 inputLabel="Upload thumbnail" inputName="thumbnailfile" formControlName="thumbnailfile" 117 inputLabel="Upload thumbnail" inputName="thumbnailfile" formControlName="thumbnailfile"
@@ -125,6 +125,17 @@
125 previewWidth="360px" previewHeight="200px" 125 previewWidth="360px" previewHeight="200px"
126 ></my-video-image> 126 ></my-video-image>
127 </div> 127 </div>
128
129 <div class="form-group">
130 <label for="support">Support (markdown)</label>
131 <my-markdown-textarea
132 id="support" formControlName="support" textareaWidth="500px" [previewColumn]="true" markdownType="enhanced"
133 [classes]="{ 'input-error': formErrors['support'] }"
134 ></my-markdown-textarea>
135 <div *ngIf="formErrors.support" class="form-error">
136 {{ formErrors.support }}
137 </div>
138 </div>
128 </div> 139 </div>
129 </tab> 140 </tab>
130 141
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 f78336fa8..1317f7426 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
@@ -59,6 +59,10 @@
59 padding: 0 15px !important; 59 padding: 0 15px !important;
60 } 60 }
61 } 61 }
62
63 .advanced-settings .form-group {
64 margin-bottom: 20px;
65 }
62} 66}
63 67
64.submit-container { 68.submit-container {
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 85e5cc3f5..c26906551 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
@@ -1,7 +1,7 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { FormBuilder, FormControl, FormGroup } from '@angular/forms' 2import { FormBuilder, FormControl, FormGroup } from '@angular/forms'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { VIDEO_IMAGE } from '@app/shared' 4import { VIDEO_IMAGE, VIDEO_SUPPORT } from '@app/shared'
5import { NotificationsService } from 'angular2-notifications' 5import { NotificationsService } from 'angular2-notifications'
6import 'rxjs/add/observable/forkJoin' 6import 'rxjs/add/observable/forkJoin'
7import { ServerService } from '../../../core/server' 7import { ServerService } from '../../../core/server'
@@ -60,6 +60,7 @@ export class VideoEditComponent implements OnInit {
60 this.formErrors['description'] = '' 60 this.formErrors['description'] = ''
61 this.formErrors['thumbnailfile'] = '' 61 this.formErrors['thumbnailfile'] = ''
62 this.formErrors['previewfile'] = '' 62 this.formErrors['previewfile'] = ''
63 this.formErrors['support'] = ''
63 64
64 this.validationMessages['name'] = VIDEO_NAME.MESSAGES 65 this.validationMessages['name'] = VIDEO_NAME.MESSAGES
65 this.validationMessages['privacy'] = VIDEO_PRIVACY.MESSAGES 66 this.validationMessages['privacy'] = VIDEO_PRIVACY.MESSAGES
@@ -70,6 +71,7 @@ export class VideoEditComponent implements OnInit {
70 this.validationMessages['description'] = VIDEO_DESCRIPTION.MESSAGES 71 this.validationMessages['description'] = VIDEO_DESCRIPTION.MESSAGES
71 this.validationMessages['thumbnailfile'] = VIDEO_IMAGE.MESSAGES 72 this.validationMessages['thumbnailfile'] = VIDEO_IMAGE.MESSAGES
72 this.validationMessages['previewfile'] = VIDEO_IMAGE.MESSAGES 73 this.validationMessages['previewfile'] = VIDEO_IMAGE.MESSAGES
74 this.validationMessages['support'] = VIDEO_SUPPORT.MESSAGES
73 75
74 this.form.addControl('name', new FormControl('', VIDEO_NAME.VALIDATORS)) 76 this.form.addControl('name', new FormControl('', VIDEO_NAME.VALIDATORS))
75 this.form.addControl('privacy', new FormControl('', VIDEO_PRIVACY.VALIDATORS)) 77 this.form.addControl('privacy', new FormControl('', VIDEO_PRIVACY.VALIDATORS))
@@ -83,6 +85,7 @@ export class VideoEditComponent implements OnInit {
83 this.form.addControl('tags', new FormControl('')) 85 this.form.addControl('tags', new FormControl(''))
84 this.form.addControl('thumbnailfile', new FormControl('')) 86 this.form.addControl('thumbnailfile', new FormControl(''))
85 this.form.addControl('previewfile', new FormControl('')) 87 this.form.addControl('previewfile', new FormControl(''))
88 this.form.addControl('support', new FormControl(''))
86 } 89 }
87 90
88 ngOnInit () { 91 ngOnInit () {
diff --git a/client/src/app/videos/+video-edit/shared/video-image.component.scss b/client/src/app/videos/+video-edit/shared/video-image.component.scss
index c44d00b3c..98313536e 100644
--- a/client/src/app/videos/+video-edit/shared/video-image.component.scss
+++ b/client/src/app/videos/+video-edit/shared/video-image.component.scss
@@ -2,7 +2,7 @@
2@import '_mixins'; 2@import '_mixins';
3 3
4.root { 4.root {
5 height: 150px; 5 height: auto;
6 display: flex; 6 display: flex;
7 align-items: center; 7 align-items: center;
8 8
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 de34555ab..0ef3c0259 100644
--- a/client/src/app/videos/+video-edit/video-update.component.ts
+++ b/client/src/app/videos/+video-edit/video-update.component.ts
@@ -61,8 +61,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
61 .switchMap(video => { 61 .switchMap(video => {
62 return this.videoService 62 return this.videoService
63 .loadCompleteDescription(video.descriptionPath) 63 .loadCompleteDescription(video.descriptionPath)
64 .do(description => video.description = description) 64 .map(description => Object.assign(video, { description }))
65 .map(() => video)
66 }) 65 })
67 .subscribe( 66 .subscribe(
68 video => { 67 video => {
diff --git a/client/src/app/videos/+video-watch/modal/video-support.component.html b/client/src/app/videos/+video-watch/modal/video-support.component.html
new file mode 100644
index 000000000..16ad9502a
--- /dev/null
+++ b/client/src/app/videos/+video-watch/modal/video-support.component.html
@@ -0,0 +1,22 @@
1<div bsModal #modal="bs-modal" class="modal" tabindex="-1">
2 <div class="modal-dialog">
3 <div class="modal-content">
4
5 <div class="modal-header">
6 <span class="close" aria-hidden="true" (click)="hide()"></span>
7 <h4 class="modal-title">Support</h4>
8 </div>
9
10 <div class="modal-body">
11
12 <div [innerHTML]="videoHTMLSupport"></div>
13
14 <div class="form-group inputs">
15 <span class="action-button action-button-cancel" (click)="hide()">
16 Cancel
17 </span>
18 </div>
19 </div>
20 </div>
21 </div>
22</div>
diff --git a/client/src/app/videos/+video-watch/modal/video-support.component.scss b/client/src/app/videos/+video-watch/modal/video-support.component.scss
new file mode 100644
index 000000000..184e09027
--- /dev/null
+++ b/client/src/app/videos/+video-watch/modal/video-support.component.scss
@@ -0,0 +1,3 @@
1.action-button-cancel {
2 margin-right: 0 !important;
3}
diff --git a/client/src/app/videos/+video-watch/modal/video-support.component.ts b/client/src/app/videos/+video-watch/modal/video-support.component.ts
new file mode 100644
index 000000000..f805215b9
--- /dev/null
+++ b/client/src/app/videos/+video-watch/modal/video-support.component.ts
@@ -0,0 +1,36 @@
1import { Component, Input, ViewChild } from '@angular/core'
2import { MarkdownService } from '@app/videos/shared'
3
4import { ModalDirective } from 'ngx-bootstrap/modal'
5import { VideoDetails } from '../../../shared/video/video-details.model'
6
7@Component({
8 selector: 'my-video-support',
9 templateUrl: './video-support.component.html',
10 styleUrls: [ './video-support.component.scss' ]
11})
12export class VideoSupportComponent {
13 @Input() video: VideoDetails = null
14
15 @ViewChild('modal') modal: ModalDirective
16
17 videoHTMLSupport = ''
18
19 constructor (private markdownService: MarkdownService) {
20 // empty
21 }
22
23 show () {
24 this.modal.show()
25
26 if (this.video.support) {
27 this.videoHTMLSupport = this.markdownService.enhancedMarkdownToHTML(this.video.support)
28 } else {
29 this.videoHTMLSupport = ''
30 }
31 }
32
33 hide () {
34 this.modal.hide()
35 }
36}
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 8c173d6b3..b8ec048b2 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -44,9 +44,14 @@
44 <span class="icon icon-dislike" title="Dislike this video"></span> 44 <span class="icon icon-dislike" title="Dislike this video"></span>
45 </div> 45 </div>
46 46
47 <div (click)="showSupportModal()" class="action-button action-button-support">
48 <span class="icon icon-support"></span>
49 <span class="icon-text">Support</span>
50 </div>
51
47 <div (click)="showShareModal()" class="action-button action-button-share"> 52 <div (click)="showShareModal()" class="action-button action-button-share">
48 <span class="icon icon-share"></span> 53 <span class="icon icon-share"></span>
49 Share 54 <span class="icon-text">Share</span>
50 </div> 55 </div>
51 56
52 <div class="action-more" dropdown dropup="true" placement="right"> 57 <div class="action-more" dropdown dropup="true" placement="right">
@@ -175,6 +180,7 @@
175</div> 180</div>
176 181
177<ng-template [ngIf]="video !== null"> 182<ng-template [ngIf]="video !== null">
183 <my-video-support #videoSupportModal [video]="video"></my-video-support>
178 <my-video-share #videoShareModal [video]="video"></my-video-share> 184 <my-video-share #videoShareModal [video]="video"></my-video-share>
179 <my-video-download #videoDownloadModal [video]="video"></my-video-download> 185 <my-video-download #videoDownloadModal [video]="video"></my-video-download>
180 <my-video-report #videoReportModal [video]="video"></my-video-report> 186 <my-video-report #videoReportModal [video]="video"></my-video-report>
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 bc737ccd5..eb701e0ab 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/videos/+video-watch/video-watch.component.scss
@@ -99,6 +99,7 @@
99 font-weight: $font-semibold; 99 font-weight: $font-semibold;
100 display: inline-block; 100 display: inline-block;
101 padding: 0 10px 0 10px; 101 padding: 0 10px 0 10px;
102 white-space: nowrap;
102 103
103 .icon { 104 .icon {
104 @include icon(21px); 105 @include icon(21px);
@@ -114,6 +115,10 @@
114 background-image: url('../../../assets/images/video/dislike-grey.svg'); 115 background-image: url('../../../assets/images/video/dislike-grey.svg');
115 } 116 }
116 117
118 &.icon-support {
119 background-image: url('../../../assets/images/video/heart.svg');
120 }
121
117 &.icon-share { 122 &.icon-share {
118 background-image: url('../../../assets/images/video/share.svg'); 123 background-image: url('../../../assets/images/video/share.svg');
119 } 124 }
@@ -249,11 +254,7 @@
249} 254}
250 255
251 256
252@media screen and (max-width: 1300px) { 257@media screen and (max-width: 1600px) {
253 .other-videos {
254 display: none;
255 }
256
257 .video-bottom { 258 .video-bottom {
258 .video-info { 259 .video-info {
259 margin-right: 0; 260 margin-right: 0;
@@ -288,6 +289,12 @@
288 } 289 }
289} 290}
290 291
292@media screen and (max-width: 1200px) {
293 .other-videos {
294 display: none;
295 }
296}
297
291@media screen and (max-width: 600px) { 298@media screen and (max-width: 600px) {
292 .video-bottom { 299 .video-bottom {
293 margin: 20px 0 0 0; 300 margin: 20px 0 0 0;
@@ -304,3 +311,9 @@
304 } 311 }
305 } 312 }
306} 313}
314
315@media screen and (max-width: 450px) {
316 .video-bottom .action-button .icon-text {
317 display: none !important;
318 }
319}
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index 553eed341..6b118b1de 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -1,5 +1,6 @@
1import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
3import { MetaService } from '@ngx-meta/core' 4import { MetaService } from '@ngx-meta/core'
4import { NotificationsService } from 'angular2-notifications' 5import { NotificationsService } from 'angular2-notifications'
5import { Observable } from 'rxjs/Observable' 6import { Observable } from 'rxjs/Observable'
@@ -28,6 +29,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
28 @ViewChild('videoDownloadModal') videoDownloadModal: VideoDownloadComponent 29 @ViewChild('videoDownloadModal') videoDownloadModal: VideoDownloadComponent
29 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent 30 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent
30 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent 31 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent
32 @ViewChild('videoSupportModal') videoSupportModal: VideoSupportComponent
31 33
32 otherVideosDisplayed: Video[] = [] 34 otherVideosDisplayed: Video[] = []
33 35
@@ -189,6 +191,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
189 this.videoReportModal.show() 191 this.videoReportModal.show()
190 } 192 }
191 193
194 showSupportModal () {
195 this.videoSupportModal.show()
196 }
197
192 showShareModal () { 198 showShareModal () {
193 this.videoShareModal.show() 199 this.videoShareModal.show()
194 } 200 }
@@ -264,7 +270,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
264 return 270 return
265 } 271 }
266 272
267 this.videoHTMLDescription = this.markdownService.markdownToHTML(this.video.description) 273 this.videoHTMLDescription = this.markdownService.textMarkdownToHTML(this.video.description)
268 } 274 }
269 275
270 private setVideoLikesBarTooltipText () { 276 private setVideoLikesBarTooltipText () {
diff --git a/client/src/app/videos/+video-watch/video-watch.module.ts b/client/src/app/videos/+video-watch/video-watch.module.ts
index 085a9ec5a..6a22c36d9 100644
--- a/client/src/app/videos/+video-watch/video-watch.module.ts
+++ b/client/src/app/videos/+video-watch/video-watch.module.ts
@@ -1,4 +1,5 @@
1import { NgModule } from '@angular/core' 1import { NgModule } from '@angular/core'
2import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
2import { TooltipModule } from 'ngx-bootstrap/tooltip' 3import { TooltipModule } from 'ngx-bootstrap/tooltip'
3import { ClipboardModule } from 'ngx-clipboard' 4import { ClipboardModule } from 'ngx-clipboard'
4import { SharedModule } from '../../shared' 5import { SharedModule } from '../../shared'
@@ -29,6 +30,7 @@ import { VideoWatchComponent } from './video-watch.component'
29 VideoDownloadComponent, 30 VideoDownloadComponent,
30 VideoShareComponent, 31 VideoShareComponent,
31 VideoReportComponent, 32 VideoReportComponent,
33 VideoSupportComponent,
32 VideoCommentsComponent, 34 VideoCommentsComponent,
33 VideoCommentAddComponent, 35 VideoCommentAddComponent,
34 VideoCommentComponent 36 VideoCommentComponent
diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/videos/shared/markdown.service.ts
index a275446eb..bd100f092 100644
--- a/client/src/app/videos/shared/markdown.service.ts
+++ b/client/src/app/videos/shared/markdown.service.ts
@@ -4,33 +4,51 @@ import * as MarkdownIt from 'markdown-it'
4 4
5@Injectable() 5@Injectable()
6export class MarkdownService { 6export class MarkdownService {
7 private markdownIt: MarkdownIt.MarkdownIt 7 private textMarkdownIt: MarkdownIt.MarkdownIt
8 private linkifier: MarkdownIt.MarkdownIt 8 private linkifier: MarkdownIt.MarkdownIt
9 private enhancedMarkdownIt: MarkdownIt.MarkdownIt
9 10
10 constructor () { 11 constructor () {
11 this.markdownIt = new MarkdownIt('zero', { linkify: true, breaks: true }) 12 this.textMarkdownIt = new MarkdownIt('zero', { linkify: true, breaks: true })
12 .enable('linkify') 13 .enable('linkify')
13 .enable('autolink') 14 .enable('autolink')
14 .enable('emphasis') 15 .enable('emphasis')
15 .enable('link') 16 .enable('link')
16 .enable('newline') 17 .enable('newline')
17 .enable('list') 18 .enable('list')
18 this.setTargetToLinks(this.markdownIt) 19 this.setTargetToLinks(this.textMarkdownIt)
20
21 this.enhancedMarkdownIt = new MarkdownIt('zero', { linkify: true, breaks: true })
22 .enable('linkify')
23 .enable('autolink')
24 .enable('emphasis')
25 .enable('link')
26 .enable('newline')
27 .enable('list')
28 .enable('image')
29 this.setTargetToLinks(this.enhancedMarkdownIt)
19 30
20 this.linkifier = new MarkdownIt('zero', { linkify: true }) 31 this.linkifier = new MarkdownIt('zero', { linkify: true })
21 .enable('linkify') 32 .enable('linkify')
22 this.setTargetToLinks(this.linkifier) 33 this.setTargetToLinks(this.linkifier)
23 } 34 }
24 35
25 markdownToHTML (markdown: string) { 36 textMarkdownToHTML (markdown: string) {
26 const html = this.markdownIt.render(markdown) 37 const html = this.textMarkdownIt.render(markdown)
27 38
28 // Avoid linkify truncated links 39 return this.avoidTruncatedLinks(html)
29 return html.replace(/<a[^>]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...') 40 }
41
42 enhancedMarkdownToHTML (markdown: string) {
43 const html = this.enhancedMarkdownIt.render(markdown)
44
45 return this.avoidTruncatedLinks(html)
30 } 46 }
31 47
32 linkify (text: string) { 48 linkify (text: string) {
33 return this.linkifier.render(text) 49 const html = this.linkifier.render(text)
50
51 return this.avoidTruncatedLinks(html)
34 } 52 }
35 53
36 private setTargetToLinks (markdownIt: MarkdownIt.MarkdownIt) { 54 private setTargetToLinks (markdownIt: MarkdownIt.MarkdownIt) {
@@ -53,4 +71,8 @@ export class MarkdownService {
53 return defaultRender(tokens, idx, options, env, self) 71 return defaultRender(tokens, idx, options, env, self)
54 } 72 }
55 } 73 }
74
75 private avoidTruncatedLinks (html) {
76 return html.replace(/<a[^>]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...')
77 }
56} 78}