aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.ts2
-rw-r--r--client/src/app/+accounts/account-about/account-about.component.ts4
-rw-r--r--client/src/app/+admin/moderation/moderation.component.scss1
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html4
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts8
-rw-r--r--client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html2
-rw-r--r--client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts6
-rw-r--r--client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts2
-rw-r--r--client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts8
-rw-r--r--client/src/app/shared/forms/markdown-textarea.component.ts2
-rw-r--r--client/src/app/shared/misc/help.component.ts2
-rw-r--r--client/src/app/shared/misc/utils.ts13
-rw-r--r--client/src/app/shared/renderer/html-renderer.service.ts35
-rw-r--r--client/src/app/shared/renderer/index.ts3
-rw-r--r--client/src/app/shared/renderer/linkifier.service.ts (renamed from client/src/app/videos/+video-watch/comment/linkifier.service.ts)0
-rw-r--r--client/src/app/shared/renderer/markdown.service.ts (renamed from client/src/app/videos/shared/markdown.service.ts)0
-rw-r--r--client/src/app/shared/shared.module.ts9
-rw-r--r--client/src/app/shared/video-abuse/video-abuse.service.ts4
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.component.ts27
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.service.ts6
-rw-r--r--client/src/app/videos/+video-watch/modal/video-support.component.ts3
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts2
-rw-r--r--client/src/app/videos/+video-watch/video-watch.module.ts4
-rw-r--r--client/src/app/videos/shared/index.ts1
24 files changed, 90 insertions, 58 deletions
diff --git a/client/src/app/+about/about-instance/about-instance.component.ts b/client/src/app/+about/about-instance/about-instance.component.ts
index d3ee8a1e4..a1b30fa8c 100644
--- a/client/src/app/+about/about-instance/about-instance.component.ts
+++ b/client/src/app/+about/about-instance/about-instance.component.ts
@@ -1,9 +1,9 @@
1import { Component, OnInit, ViewChild } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { Notifier, ServerService } from '@app/core' 2import { Notifier, ServerService } from '@app/core'
3import { MarkdownService } from '@app/videos/shared'
4import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
5import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component' 4import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
6import { InstanceService } from '@app/shared/instance/instance.service' 5import { InstanceService } from '@app/shared/instance/instance.service'
6import { MarkdownService } from '@app/shared/renderer'
7 7
8@Component({ 8@Component({
9 selector: 'my-about-instance', 9 selector: 'my-about-instance',
diff --git a/client/src/app/+accounts/account-about/account-about.component.ts b/client/src/app/+accounts/account-about/account-about.component.ts
index 6f3e6caa0..13890a0ee 100644
--- a/client/src/app/+accounts/account-about/account-about.component.ts
+++ b/client/src/app/+accounts/account-about/account-about.component.ts
@@ -1,9 +1,9 @@
1import { Component, OnInit, OnDestroy } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { Account } from '@app/shared/account/account.model' 2import { Account } from '@app/shared/account/account.model'
3import { AccountService } from '@app/shared/account/account.service' 3import { AccountService } from '@app/shared/account/account.service'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { Subscription } from 'rxjs' 5import { Subscription } from 'rxjs'
6import { MarkdownService } from '@app/videos/shared' 6import { MarkdownService } from '@app/shared/renderer'
7 7
8@Component({ 8@Component({
9 selector: 'my-account-about', 9 selector: 'my-account-about',
diff --git a/client/src/app/+admin/moderation/moderation.component.scss b/client/src/app/+admin/moderation/moderation.component.scss
index 02ccfc8ca..13b019c5b 100644
--- a/client/src/app/+admin/moderation/moderation.component.scss
+++ b/client/src/app/+admin/moderation/moderation.component.scss
@@ -10,6 +10,7 @@
10 font-weight: $font-semibold; 10 font-weight: $font-semibold;
11 min-width: 200px; 11 min-width: 200px;
12 display: inline-block; 12 display: inline-block;
13 vertical-align: top;
13} 14}
14 15
15.moderation-expanded-text { 16.moderation-expanded-text {
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
index e862d5162..05b549de6 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
@@ -51,11 +51,11 @@
51 <td class="moderation-expanded" colspan="6"> 51 <td class="moderation-expanded" colspan="6">
52 <div> 52 <div>
53 <span i18n class="moderation-expanded-label">Reason:</span> 53 <span i18n class="moderation-expanded-label">Reason:</span>
54 <span class="moderation-expanded-text">{{ videoAbuse.reason }}</span> 54 <span class="moderation-expanded-text" [innerHTML]="toHtml(videoAbuse.reason)"></span>
55 </div> 55 </div>
56 <div *ngIf="videoAbuse.moderationComment"> 56 <div *ngIf="videoAbuse.moderationComment">
57 <span i18n class="moderation-expanded-label">Moderation comment:</span> 57 <span i18n class="moderation-expanded-label">Moderation comment:</span>
58 <span class="moderation-expanded-text">{{ videoAbuse.moderationComment }}</span> 58 <span class="moderation-expanded-text" [innerHTML]="toHtml(videoAbuse.moderationComment)"></span>
59 </div> 59 </div>
60 </td> 60 </td>
61 </tr> 61 </tr>
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
index f64234b74..00c871659 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
@@ -9,6 +9,7 @@ import { DropdownAction } from '../../../shared/buttons/action-dropdown.componen
9import { ConfirmService } from '../../../core/index' 9import { ConfirmService } from '../../../core/index'
10import { ModerationCommentModalComponent } from './moderation-comment-modal.component' 10import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
11import { Video } from '../../../shared/video/video.model' 11import { Video } from '../../../shared/video/video.model'
12import { MarkdownService } from '@app/shared/renderer'
12 13
13@Component({ 14@Component({
14 selector: 'my-video-abuse-list', 15 selector: 'my-video-abuse-list',
@@ -30,7 +31,8 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
30 private notifier: Notifier, 31 private notifier: Notifier,
31 private videoAbuseService: VideoAbuseService, 32 private videoAbuseService: VideoAbuseService,
32 private confirmService: ConfirmService, 33 private confirmService: ConfirmService,
33 private i18n: I18n 34 private i18n: I18n,
35 private markdownRenderer: MarkdownService
34 ) { 36 ) {
35 super() 37 super()
36 38
@@ -108,6 +110,10 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
108 110
109 } 111 }
110 112
113 toHtml (text: string) {
114 return this.markdownRenderer.textMarkdownToHTML(text)
115 }
116
111 protected loadData () { 117 protected loadData () {
112 return this.videoAbuseService.getVideoAbuses(this.pagination, this.sort) 118 return this.videoAbuseService.getVideoAbuses(this.pagination, this.sort)
113 .subscribe( 119 .subscribe(
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
index 6398af218..247f441c1 100644
--- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
+++ b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
@@ -41,7 +41,7 @@
41 <tr> 41 <tr>
42 <td class="moderation-expanded" colspan="6"> 42 <td class="moderation-expanded" colspan="6">
43 <span i18n class="moderation-expanded-label">Blacklist reason:</span> 43 <span i18n class="moderation-expanded-label">Blacklist reason:</span>
44 <span class="moderation-expanded-text">{{ videoBlacklist.reason }}</span> 44 <span class="moderation-expanded-text" [innerHTML]="toHtml(videoBlacklist.reason)"></span>
45 </td> 45 </td>
46 </tr> 46 </tr>
47 </ng-template> 47 </ng-template>
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
index 6c6f17f0c..b27bbbfef 100644
--- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
+++ b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
@@ -7,6 +7,7 @@ import { VideoBlacklist } from '../../../../../../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component' 8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
9import { Video } from '../../../shared/video/video.model' 9import { Video } from '../../../shared/video/video.model'
10import { MarkdownService } from '@app/shared/renderer'
10 11
11@Component({ 12@Component({
12 selector: 'my-video-blacklist-list', 13 selector: 'my-video-blacklist-list',
@@ -26,6 +27,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
26 private notifier: Notifier, 27 private notifier: Notifier,
27 private confirmService: ConfirmService, 28 private confirmService: ConfirmService,
28 private videoBlacklistService: VideoBlacklistService, 29 private videoBlacklistService: VideoBlacklistService,
30 private markdownRenderer: MarkdownService,
29 private i18n: I18n 31 private i18n: I18n
30 ) { 32 ) {
31 super() 33 super()
@@ -52,6 +54,10 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
52 return this.i18n('no') 54 return this.i18n('no')
53 } 55 }
54 56
57 toHtml (text: string) {
58 return this.markdownRenderer.textMarkdownToHTML(text)
59 }
60
55 async removeVideoFromBlacklist (entry: VideoBlacklist) { 61 async removeVideoFromBlacklist (entry: VideoBlacklist) {
56 const confirmMessage = this.i18n( 62 const confirmMessage = this.i18n(
57 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.' 63 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.'
diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts
index ea7b0e118..895b19064 100644
--- a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts
+++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts
@@ -3,7 +3,7 @@ import { VideoChannelService } from '@app/shared/video-channel/video-channel.ser
3import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 3import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { Subscription } from 'rxjs' 5import { Subscription } from 'rxjs'
6import { MarkdownService } from '@app/videos/shared' 6import { MarkdownService } from '@app/shared/renderer'
7 7
8@Component({ 8@Component({
9 selector: 'my-video-channel-about', 9 selector: 'my-video-channel-about',
diff --git a/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
index 6e9806611..fcc966b84 100644
--- a/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
+++ b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
@@ -10,20 +10,20 @@ export class VideoAbuseValidatorsService {
10 10
11 constructor (private i18n: I18n) { 11 constructor (private i18n: I18n) {
12 this.VIDEO_ABUSE_REASON = { 12 this.VIDEO_ABUSE_REASON = {
13 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], 13 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ],
14 MESSAGES: { 14 MESSAGES: {
15 'required': this.i18n('Report reason is required.'), 15 'required': this.i18n('Report reason is required.'),
16 'minlength': this.i18n('Report reason must be at least 2 characters long.'), 16 'minlength': this.i18n('Report reason must be at least 2 characters long.'),
17 'maxlength': this.i18n('Report reason cannot be more than 300 characters long.') 17 'maxlength': this.i18n('Report reason cannot be more than 3000 characters long.')
18 } 18 }
19 } 19 }
20 20
21 this.VIDEO_ABUSE_MODERATION_COMMENT = { 21 this.VIDEO_ABUSE_MODERATION_COMMENT = {
22 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], 22 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ],
23 MESSAGES: { 23 MESSAGES: {
24 'required': this.i18n('Moderation comment is required.'), 24 'required': this.i18n('Moderation comment is required.'),
25 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'), 25 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'),
26 'maxlength': this.i18n('Moderation comment cannot be more than 300 characters long.') 26 'maxlength': this.i18n('Moderation comment cannot be more than 3000 characters long.')
27 } 27 }
28 } 28 }
29 } 29 }
diff --git a/client/src/app/shared/forms/markdown-textarea.component.ts b/client/src/app/shared/forms/markdown-textarea.component.ts
index b99169ed2..e87aca0d4 100644
--- a/client/src/app/shared/forms/markdown-textarea.component.ts
+++ b/client/src/app/shared/forms/markdown-textarea.component.ts
@@ -1,10 +1,10 @@
1import { debounceTime, distinctUntilChanged } from 'rxjs/operators' 1import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
2import { Component, forwardRef, Input, OnInit } from '@angular/core' 2import { Component, forwardRef, Input, OnInit } from '@angular/core'
3import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' 3import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
4import { MarkdownService } from '@app/videos/shared'
5import { Subject } from 'rxjs' 4import { Subject } from 'rxjs'
6import truncate from 'lodash-es/truncate' 5import truncate from 'lodash-es/truncate'
7import { ScreenService } from '@app/shared/misc/screen.service' 6import { ScreenService } from '@app/shared/misc/screen.service'
7import { MarkdownService } from '@app/shared/renderer'
8 8
9@Component({ 9@Component({
10 selector: 'my-markdown-textarea', 10 selector: 'my-markdown-textarea',
diff --git a/client/src/app/shared/misc/help.component.ts b/client/src/app/shared/misc/help.component.ts
index ba0452e77..f3426f70f 100644
--- a/client/src/app/shared/misc/help.component.ts
+++ b/client/src/app/shared/misc/help.component.ts
@@ -1,6 +1,6 @@
1import { Component, Input, OnChanges, OnInit } from '@angular/core' 1import { Component, Input, OnChanges, OnInit } from '@angular/core'
2import { MarkdownService } from '@app/videos/shared'
3import { I18n } from '@ngx-translate/i18n-polyfill' 2import { I18n } from '@ngx-translate/i18n-polyfill'
3import { MarkdownService } from '@app/shared/renderer'
4 4
5@Component({ 5@Component({
6 selector: 'my-help', 6 selector: 'my-help',
diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts
index 78e8e9682..7cc6055c2 100644
--- a/client/src/app/shared/misc/utils.ts
+++ b/client/src/app/shared/misc/utils.ts
@@ -102,12 +102,18 @@ function objectToFormData (obj: any, form?: FormData, namespace?: string) {
102 return fd 102 return fd
103} 103}
104 104
105function lineFeedToHtml (obj: any, keyToNormalize: string) { 105function objectLineFeedToHtml (obj: any, keyToNormalize: string) {
106 return immutableAssign(obj, { 106 return immutableAssign(obj, {
107 [keyToNormalize]: obj[keyToNormalize].replace(/\r?\n|\r/g, '<br />') 107 [keyToNormalize]: lineFeedToHtml(obj[keyToNormalize])
108 }) 108 })
109} 109}
110 110
111function lineFeedToHtml (text: string) {
112 if (!text) return text
113
114 return text.replace(/\r?\n|\r/g, '<br />')
115}
116
111function removeElementFromArray <T> (arr: T[], elem: T) { 117function removeElementFromArray <T> (arr: T[], elem: T) {
112 const index = arr.indexOf(elem) 118 const index = arr.indexOf(elem)
113 if (index !== -1) arr.splice(index, 1) 119 if (index !== -1) arr.splice(index, 1)
@@ -131,6 +137,7 @@ function scrollToTop () {
131export { 137export {
132 sortBy, 138 sortBy,
133 durationToString, 139 durationToString,
140 lineFeedToHtml,
134 objectToUrlEncoded, 141 objectToUrlEncoded,
135 getParameterByName, 142 getParameterByName,
136 populateAsyncUserVideoChannels, 143 populateAsyncUserVideoChannels,
@@ -138,7 +145,7 @@ export {
138 dateToHuman, 145 dateToHuman,
139 immutableAssign, 146 immutableAssign,
140 objectToFormData, 147 objectToFormData,
141 lineFeedToHtml, 148 objectLineFeedToHtml,
142 removeElementFromArray, 149 removeElementFromArray,
143 scrollToTop 150 scrollToTop
144} 151}
diff --git a/client/src/app/shared/renderer/html-renderer.service.ts b/client/src/app/shared/renderer/html-renderer.service.ts
new file mode 100644
index 000000000..d49df9b6d
--- /dev/null
+++ b/client/src/app/shared/renderer/html-renderer.service.ts
@@ -0,0 +1,35 @@
1import { Injectable } from '@angular/core'
2import { LinkifierService } from '@app/shared/renderer/linkifier.service'
3import * as sanitizeHtml from 'sanitize-html'
4
5@Injectable()
6export class HtmlRendererService {
7
8 constructor (private linkifier: LinkifierService) {
9
10 }
11
12 toSafeHtml (text: string) {
13 // Convert possible markdown to html
14 const html = this.linkifier.linkify(text)
15
16 return sanitizeHtml(html, {
17 allowedTags: [ 'a', 'p', 'span', 'br' ],
18 allowedSchemes: [ 'http', 'https' ],
19 allowedAttributes: {
20 'a': [ 'href', 'class', 'target' ]
21 },
22 transformTags: {
23 a: (tagName, attribs) => {
24 return {
25 tagName,
26 attribs: Object.assign(attribs, {
27 target: '_blank',
28 rel: 'noopener noreferrer'
29 })
30 }
31 }
32 }
33 })
34 }
35}
diff --git a/client/src/app/shared/renderer/index.ts b/client/src/app/shared/renderer/index.ts
new file mode 100644
index 000000000..39202b385
--- /dev/null
+++ b/client/src/app/shared/renderer/index.ts
@@ -0,0 +1,3 @@
1export * from './html-renderer.service'
2export * from './linkifier.service'
3export * from './markdown.service'
diff --git a/client/src/app/videos/+video-watch/comment/linkifier.service.ts b/client/src/app/shared/renderer/linkifier.service.ts
index 2529c9eaf..2529c9eaf 100644
--- a/client/src/app/videos/+video-watch/comment/linkifier.service.ts
+++ b/client/src/app/shared/renderer/linkifier.service.ts
diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/shared/renderer/markdown.service.ts
index 07017eca5..07017eca5 100644
--- a/client/src/app/videos/shared/markdown.service.ts
+++ b/client/src/app/shared/renderer/markdown.service.ts
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index d1320aeec..384f5d722 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -6,7 +6,6 @@ import { RouterModule } from '@angular/router'
6import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component' 6import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component'
7import { HelpComponent } from '@app/shared/misc/help.component' 7import { HelpComponent } from '@app/shared/misc/help.component'
8import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' 8import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive'
9import { MarkdownService } from '@app/videos/shared'
10 9
11import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes' 10import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes'
12import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' 11import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared'
@@ -34,10 +33,10 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
34import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 33import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
35import { 34import {
36 CustomConfigValidatorsService, 35 CustomConfigValidatorsService,
36 InstanceValidatorsService,
37 LoginValidatorsService, 37 LoginValidatorsService,
38 ReactiveFileComponent, 38 ReactiveFileComponent,
39 ResetPasswordValidatorsService, 39 ResetPasswordValidatorsService,
40 InstanceValidatorsService,
41 TextareaAutoResizeDirective, 40 TextareaAutoResizeDirective,
42 UserValidatorsService, 41 UserValidatorsService,
43 VideoAbuseValidatorsService, 42 VideoAbuseValidatorsService,
@@ -67,6 +66,7 @@ import { UserHistoryService } from '@app/shared/users/user-history.service'
67import { UserNotificationService } from '@app/shared/users/user-notification.service' 66import { UserNotificationService } from '@app/shared/users/user-notification.service'
68import { UserNotificationsComponent } from '@app/shared/users/user-notifications.component' 67import { UserNotificationsComponent } from '@app/shared/users/user-notifications.component'
69import { InstanceService } from '@app/shared/instance/instance.service' 68import { InstanceService } from '@app/shared/instance/instance.service'
69import { HtmlRendererService, LinkifierService, MarkdownService } from '@app/shared/renderer'
70 70
71@NgModule({ 71@NgModule({
72 imports: [ 72 imports: [
@@ -167,7 +167,6 @@ import { InstanceService } from '@app/shared/instance/instance.service'
167 UserService, 167 UserService,
168 VideoService, 168 VideoService,
169 AccountService, 169 AccountService,
170 MarkdownService,
171 VideoChannelService, 170 VideoChannelService,
172 VideoCaptionService, 171 VideoCaptionService,
173 VideoImportService, 172 VideoImportService,
@@ -192,6 +191,10 @@ import { InstanceService } from '@app/shared/instance/instance.service'
192 UserHistoryService, 191 UserHistoryService,
193 InstanceService, 192 InstanceService,
194 193
194 MarkdownService,
195 LinkifierService,
196 HtmlRendererService,
197
195 I18nPrimengCalendarService, 198 I18nPrimengCalendarService,
196 ScreenService, 199 ScreenService,
197 200
diff --git a/client/src/app/shared/video-abuse/video-abuse.service.ts b/client/src/app/shared/video-abuse/video-abuse.service.ts
index 61b7e1b98..b0b59ea0c 100644
--- a/client/src/app/shared/video-abuse/video-abuse.service.ts
+++ b/client/src/app/shared/video-abuse/video-abuse.service.ts
@@ -32,9 +32,7 @@ export class VideoAbuseService {
32 32
33 reportVideo (id: number, reason: string) { 33 reportVideo (id: number, reason: string) {
34 const url = VideoAbuseService.BASE_VIDEO_ABUSE_URL + id + '/abuse' 34 const url = VideoAbuseService.BASE_VIDEO_ABUSE_URL + id + '/abuse'
35 const body = { 35 const body = { reason }
36 reason
37 }
38 36
39 return this.authHttp.post(url, body) 37 return this.authHttp.post(url, body)
40 .pipe( 38 .pipe(
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.ts b/client/src/app/videos/+video-watch/comment/video-comment.component.ts
index 00f0460a1..aba7f9d1c 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment.component.ts
@@ -1,11 +1,10 @@
1import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core' 1import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'
2import { LinkifierService } from '@app/videos/+video-watch/comment/linkifier.service'
3import * as sanitizeHtml from 'sanitize-html'
4import { UserRight } from '../../../../../../shared/models/users' 2import { UserRight } from '../../../../../../shared/models/users'
5import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' 3import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
6import { AuthService } from '../../../core/auth' 4import { AuthService } from '../../../core/auth'
7import { Video } from '../../../shared/video/video.model' 5import { Video } from '../../../shared/video/video.model'
8import { VideoComment } from './video-comment.model' 6import { VideoComment } from './video-comment.model'
7import { HtmlRendererService } from '@app/shared/renderer'
9 8
10@Component({ 9@Component({
11 selector: 'my-video-comment', 10 selector: 'my-video-comment',
@@ -29,7 +28,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
29 newParentComments: VideoComment[] = [] 28 newParentComments: VideoComment[] = []
30 29
31 constructor ( 30 constructor (
32 private linkifierService: LinkifierService, 31 private htmlRenderer: HtmlRendererService,
33 private authService: AuthService 32 private authService: AuthService
34 ) {} 33 ) {}
35 34
@@ -87,27 +86,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
87 } 86 }
88 87
89 private init () { 88 private init () {
90 // Convert possible markdown to html 89 this.sanitizedCommentHTML = this.htmlRenderer.toSafeHtml(this.comment.text)
91 const html = this.linkifierService.linkify(this.comment.text)
92
93 this.sanitizedCommentHTML = sanitizeHtml(html, {
94 allowedTags: [ 'a', 'p', 'span', 'br' ],
95 allowedSchemes: [ 'http', 'https' ],
96 allowedAttributes: {
97 'a': [ 'href', 'class', 'target' ]
98 },
99 transformTags: {
100 a: (tagName, attribs) => {
101 return {
102 tagName,
103 attribs: Object.assign(attribs, {
104 target: '_blank',
105 rel: 'noopener noreferrer'
106 })
107 }
108 }
109 }
110 })
111 90
112 this.newParentComments = this.parentComments.concat([ this.comment ]) 91 this.newParentComments = this.parentComments.concat([ this.comment ])
113 } 92 }
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.service.ts b/client/src/app/videos/+video-watch/comment/video-comment.service.ts
index 921447d5b..b8e5878c5 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment.service.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment.service.ts
@@ -1,7 +1,7 @@
1import { catchError, map } from 'rxjs/operators' 1import { catchError, map } from 'rxjs/operators'
2import { HttpClient, HttpParams } from '@angular/common/http' 2import { HttpClient, HttpParams } from '@angular/common/http'
3import { Injectable } from '@angular/core' 3import { Injectable } from '@angular/core'
4import { lineFeedToHtml } from '@app/shared/misc/utils' 4import { objectLineFeedToHtml } from '@app/shared/misc/utils'
5import { Observable } from 'rxjs' 5import { Observable } from 'rxjs'
6import { ResultList, FeedFormat } from '../../../../../../shared/models' 6import { ResultList, FeedFormat } from '../../../../../../shared/models'
7import { 7import {
@@ -28,7 +28,7 @@ export class VideoCommentService {
28 28
29 addCommentThread (videoId: number | string, comment: VideoCommentCreate) { 29 addCommentThread (videoId: number | string, comment: VideoCommentCreate) {
30 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' 30 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads'
31 const normalizedComment = lineFeedToHtml(comment, 'text') 31 const normalizedComment = objectLineFeedToHtml(comment, 'text')
32 32
33 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment) 33 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
34 .pipe( 34 .pipe(
@@ -39,7 +39,7 @@ export class VideoCommentService {
39 39
40 addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) { 40 addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) {
41 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId 41 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId
42 const normalizedComment = lineFeedToHtml(comment, 'text') 42 const normalizedComment = objectLineFeedToHtml(comment, 'text')
43 43
44 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment) 44 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
45 .pipe( 45 .pipe(
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
index 154002120..deb8fbc67 100644
--- a/client/src/app/videos/+video-watch/modal/video-support.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-support.component.ts
@@ -1,8 +1,7 @@
1import { Component, Input, ViewChild } from '@angular/core' 1import { Component, Input, ViewChild } from '@angular/core'
2import { MarkdownService } from '@app/videos/shared'
3
4import { VideoDetails } from '../../../shared/video/video-details.model' 2import { VideoDetails } from '../../../shared/video/video-details.model'
5import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 3import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
4import { MarkdownService } from '@app/shared/renderer'
6 5
7@Component({ 6@Component({
8 selector: 'my-video-support', 7 selector: 'my-video-support',
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 67c5254b3..ee504bc58 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -19,7 +19,6 @@ import { AuthService, ConfirmService } from '../../core'
19import { RestExtractor, VideoBlacklistService } from '../../shared' 19import { RestExtractor, VideoBlacklistService } from '../../shared'
20import { VideoDetails } from '../../shared/video/video-details.model' 20import { VideoDetails } from '../../shared/video/video-details.model'
21import { VideoService } from '../../shared/video/video.service' 21import { VideoService } from '../../shared/video/video.service'
22import { MarkdownService } from '../shared'
23import { VideoDownloadComponent } from './modal/video-download.component' 22import { VideoDownloadComponent } from './modal/video-download.component'
24import { VideoReportComponent } from './modal/video-report.component' 23import { VideoReportComponent } from './modal/video-report.component'
25import { VideoShareComponent } from './modal/video-share.component' 24import { VideoShareComponent } from './modal/video-share.component'
@@ -30,6 +29,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
30import { environment } from '../../../environments/environment' 29import { environment } from '../../../environments/environment'
31import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils' 30import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
32import { VideoCaptionService } from '@app/shared/video-caption' 31import { VideoCaptionService } from '@app/shared/video-caption'
32import { MarkdownService } from '@app/shared/renderer'
33 33
34@Component({ 34@Component({
35 selector: 'my-video-watch', 35 selector: 'my-video-watch',
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 54a12c126..2f448db78 100644
--- a/client/src/app/videos/+video-watch/video-watch.module.ts
+++ b/client/src/app/videos/+video-watch/video-watch.module.ts
@@ -1,9 +1,7 @@
1import { NgModule } from '@angular/core' 1import { NgModule } from '@angular/core'
2import { LinkifierService } from '@app/videos/+video-watch/comment/linkifier.service'
3import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' 2import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
4import { ClipboardModule } from 'ngx-clipboard' 3import { ClipboardModule } from 'ngx-clipboard'
5import { SharedModule } from '../../shared' 4import { SharedModule } from '../../shared'
6import { MarkdownService } from '../shared'
7import { VideoCommentAddComponent } from './comment/video-comment-add.component' 5import { VideoCommentAddComponent } from './comment/video-comment-add.component'
8import { VideoCommentComponent } from './comment/video-comment.component' 6import { VideoCommentComponent } from './comment/video-comment.component'
9import { VideoCommentService } from './comment/video-comment.service' 7import { VideoCommentService } from './comment/video-comment.service'
@@ -46,8 +44,6 @@ import { RecommendationsModule } from '@app/videos/recommendations/recommendatio
46 ], 44 ],
47 45
48 providers: [ 46 providers: [
49 MarkdownService,
50 LinkifierService,
51 VideoCommentService 47 VideoCommentService
52 ] 48 ]
53}) 49})
diff --git a/client/src/app/videos/shared/index.ts b/client/src/app/videos/shared/index.ts
deleted file mode 100644
index 7a66944b9..000000000
--- a/client/src/app/videos/shared/index.ts
+++ /dev/null
@@ -1 +0,0 @@
1export * from './markdown.service'