aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-02-10 14:25:38 +0100
committerChocobozzz <chocobozzz@cpy.re>2020-02-10 16:39:28 +0100
commitbe27ef3b4682c5639039474c39ee0d234d16f482 (patch)
treee3ee4a58ed9d99598150b87d6715e1c458ce7c92
parent361dcebc75dea74947b6c3aafd9d7d720c054b01 (diff)
downloadPeerTube-be27ef3b4682c5639039474c39ee0d234d16f482.tar.gz
PeerTube-be27ef3b4682c5639039474c39ee0d234d16f482.tar.zst
PeerTube-be27ef3b4682c5639039474c39ee0d234d16f482.zip
Strict templates enabled
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html4
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.html2
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.html2
-rw-r--r--client/src/app/+admin/plugins/plugin-search/plugin-search.component.html2
-rw-r--r--client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts6
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.html2
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html2
-rw-r--r--client/src/app/menu/avatar-notification.component.html2
-rw-r--r--client/src/app/menu/avatar-notification.component.ts1
-rw-r--r--client/src/app/search/search-filters.component.html4
-rw-r--r--client/src/app/search/search.component.ts3
-rw-r--r--client/src/app/shared/buttons/action-dropdown.component.ts6
-rw-r--r--client/src/app/shared/buttons/edit-button.component.ts2
-rw-r--r--client/src/app/shared/forms/markdown-textarea.component.ts2
-rw-r--r--client/src/app/shared/images/preview-upload.component.ts4
-rw-r--r--client/src/app/shared/rest/rest-table.ts5
-rw-r--r--client/src/app/shared/user-subscription/subscribe-button.component.html2
-rw-r--r--client/src/app/shared/video/abstract-video-list.ts3
-rw-r--r--client/src/app/shared/video/modals/video-blacklist.component.ts4
-rw-r--r--client/src/app/shared/video/modals/video-report.component.ts4
-rw-r--r--client/src/app/shared/video/video-thumbnail.component.ts2
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.html4
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment-add.component.ts4
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment-thread-tree.model.ts7
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.component.ts2
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.model.ts2
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.service.ts13
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comments.component.ts4
-rw-r--r--client/src/app/videos/+video-watch/modal/video-share.component.html2
-rw-r--r--client/tsconfig.json3
-rw-r--r--shared/models/plugins/register-server-setting.model.ts2
31 files changed, 60 insertions, 47 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
index d806ea355..b09614061 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
@@ -41,7 +41,7 @@
41 41
42 <div> 42 <div>
43 <p-multiSelect 43 <p-multiSelect
44 inputId="instanceCategories" [options]="categoryItems" formControlName="categories" showToggleAll="false" 44 inputId="instanceCategories" [options]="categoryItems" formControlName="categories" [showToggleAll]="false"
45 [defaultLabel]="getDefaultCategoryLabel()" [selectedItemsLabel]="getSelectedCategoryLabel()" 45 [defaultLabel]="getDefaultCategoryLabel()" [selectedItemsLabel]="getSelectedCategoryLabel()"
46 emptyFilterMessage="No results found" i18n-emptyFilterMessage 46 emptyFilterMessage="No results found" i18n-emptyFilterMessage
47 ></p-multiSelect> 47 ></p-multiSelect>
@@ -53,7 +53,7 @@
53 53
54 <div> 54 <div>
55 <p-multiSelect 55 <p-multiSelect
56 inputId="instanceLanguages" [options]="languageItems" formControlName="languages" showToggleAll="false" 56 inputId="instanceLanguages" [options]="languageItems" formControlName="languages" [showToggleAll]="false"
57 [defaultLabel]="getDefaultLanguageLabel()" [selectedItemsLabel]="getSelectedLanguageLabel()" 57 [defaultLabel]="getDefaultLanguageLabel()" [selectedItemsLabel]="getSelectedLanguageLabel()"
58 emptyFilterMessage="No results found" i18n-emptyFilterMessage 58 emptyFilterMessage="No results found" i18n-emptyFilterMessage
59 ></p-multiSelect> 59 ></p-multiSelect>
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html
index 6b5f3b450..c532b5f32 100644
--- a/client/src/app/+admin/follows/followers-list/followers-list.component.html
+++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html
@@ -6,7 +6,7 @@
6 <div class="caption"> 6 <div class="caption">
7 <input 7 <input
8 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..." 8 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
9 (keyup)="onSearch($event.target.value)" 9 (keyup)="onSearch($event)"
10 > 10 >
11 </div> 11 </div>
12 </ng-template> 12 </ng-template>
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html
index 5a252eda9..01aba0c11 100644
--- a/client/src/app/+admin/follows/following-list/following-list.component.html
+++ b/client/src/app/+admin/follows/following-list/following-list.component.html
@@ -7,7 +7,7 @@
7 <div> 7 <div>
8 <input 8 <input
9 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..." 9 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
10 (keyup)="onSearch($event.target.value)" 10 (keyup)="onSearch($event)"
11 > 11 >
12 </div> 12 </div>
13 </div> 13 </div>
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
index 6ec6301b1..5f18028c9 100644
--- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
+++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
@@ -3,7 +3,7 @@
3</div> 3</div>
4 4
5<div class="search-bar"> 5<div class="search-bar">
6 <input type="text" (input)="onSearchChange($event.target.value)" i18n-placeholder placeholder="Search..."/> 6 <input type="text" (input)="onSearchChange($event)" i18n-placeholder placeholder="Search..."/>
7</div> 7</div>
8 8
9<div class="alert alert-info" i18n *ngIf="pluginInstalled"> 9<div class="alert alert-info" i18n *ngIf="pluginInstalled">
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
index e08ded3f1..dc59e759b 100644
--- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
+++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
@@ -70,8 +70,10 @@ export class PluginSearchComponent implements OnInit {
70 this.reloadPlugins() 70 this.reloadPlugins()
71 } 71 }
72 72
73 onSearchChange (search: string) { 73 onSearchChange (event: Event) {
74 this.searchSubject.next(search) 74 const target = event.target as HTMLInputElement
75
76 this.searchSubject.next(target.value)
75 } 77 }
76 78
77 reloadPlugins () { 79 reloadPlugins () {
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html
index ca05bac19..249883efc 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.html
+++ b/client/src/app/+admin/users/user-list/user-list.component.html
@@ -25,7 +25,7 @@
25 <div> 25 <div>
26 <input 26 <input
27 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..." 27 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
28 (keyup)="onSearch($event.target.value)" 28 (keyup)="onSearch($event)"
29 > 29 >
30 </div> 30 </div>
31 </div> 31 </div>
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html
index 17d8cde06..51a672734 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html
+++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html
@@ -28,7 +28,7 @@
28 28
29 <div> 29 <div>
30 <p-multiSelect 30 <p-multiSelect
31 inputId="videoLanguages" [options]="languageItems" formControlName="videoLanguages" showToggleAll="true" 31 inputId="videoLanguages" [options]="languageItems" formControlName="videoLanguages" [showToggleAll]="true"
32 [defaultLabel]="getDefaultVideoLanguageLabel()" [selectedItemsLabel]="getSelectedVideoLanguageLabel()" 32 [defaultLabel]="getDefaultVideoLanguageLabel()" [selectedItemsLabel]="getSelectedVideoLanguageLabel()"
33 emptyFilterMessage="No results found" i18n-emptyFilterMessage 33 emptyFilterMessage="No results found" i18n-emptyFilterMessage
34 ></p-multiSelect> 34 ></p-multiSelect>
diff --git a/client/src/app/menu/avatar-notification.component.html b/client/src/app/menu/avatar-notification.component.html
index 7975afba5..df2a102a3 100644
--- a/client/src/app/menu/avatar-notification.component.html
+++ b/client/src/app/menu/avatar-notification.component.html
@@ -30,7 +30,7 @@
30 </div> 30 </div>
31 31
32 <my-user-notifications 32 <my-user-notifications
33 [ignoreLoadingBar]="true" [infiniteScroll]="false" itemsPerPage="10" 33 [ignoreLoadingBar]="true" [infiniteScroll]="false" [itemsPerPage]="10"
34 [markAllAsReadSubject]="markAllAsReadSubject" (notificationsLoaded)="onNotificationLoaded()" 34 [markAllAsReadSubject]="markAllAsReadSubject" (notificationsLoaded)="onNotificationLoaded()"
35 ></my-user-notifications> 35 ></my-user-notifications>
36 36
diff --git a/client/src/app/menu/avatar-notification.component.ts b/client/src/app/menu/avatar-notification.component.ts
index 989a11849..c447f031c 100644
--- a/client/src/app/menu/avatar-notification.component.ts
+++ b/client/src/app/menu/avatar-notification.component.ts
@@ -6,7 +6,6 @@ import { Notifier, UserNotificationSocket } from '@app/core'
6import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' 6import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
7import { NavigationEnd, Router } from '@angular/router' 7import { NavigationEnd, Router } from '@angular/router'
8import { filter } from 'rxjs/operators' 8import { filter } from 'rxjs/operators'
9import { UserNotificationsComponent } from '@app/shared'
10 9
11@Component({ 10@Component({
12 selector: 'my-avatar-notification', 11 selector: 'my-avatar-notification',
diff --git a/client/src/app/search/search-filters.component.html b/client/src/app/search/search-filters.component.html
index c275285d5..60680c7bd 100644
--- a/client/src/app/search/search-filters.component.html
+++ b/client/src/app/search/search-filters.component.html
@@ -146,7 +146,7 @@
146 [(ngModel)]="advancedSearch.tagsAllOf" name="tagsAllOf" id="tagsAllOf" 146 [(ngModel)]="advancedSearch.tagsAllOf" name="tagsAllOf" id="tagsAllOf"
147 [validators]="tagValidators" [errorMessages]="tagValidatorsMessages" 147 [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
148 i18n-placeholder placeholder="+ Tag" i18n-secondaryPlaceholder secondaryPlaceholder="Enter a tag" 148 i18n-placeholder placeholder="+ Tag" i18n-secondaryPlaceholder secondaryPlaceholder="Enter a tag"
149 maxItems="5" modelAsStrings="true" 149 [maxItems]="5" [modelAsStrings]="true"
150 ></tag-input> 150 ></tag-input>
151 </div> 151 </div>
152 152
@@ -159,7 +159,7 @@
159 [(ngModel)]="advancedSearch.tagsOneOf" name="tagsOneOf" id="tagsOneOf" 159 [(ngModel)]="advancedSearch.tagsOneOf" name="tagsOneOf" id="tagsOneOf"
160 [validators]="tagValidators" [errorMessages]="tagValidatorsMessages" 160 [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
161 i18n-placeholder placeholder="+ Tag" i18n-secondaryPlaceholder secondaryPlaceholder="Enter a tag" 161 i18n-placeholder placeholder="+ Tag" i18n-secondaryPlaceholder secondaryPlaceholder="Enter a tag"
162 maxItems="5" modelAsStrings="true" 162 [maxItems]="5" [modelAsStrings]="true"
163 ></tag-input> 163 ></tag-input>
164 </div> 164 </div>
165 </div> 165 </div>
diff --git a/client/src/app/search/search.component.ts b/client/src/app/search/search.component.ts
index dfd8d8823..075994dd3 100644
--- a/client/src/app/search/search.component.ts
+++ b/client/src/app/search/search.component.ts
@@ -141,7 +141,8 @@ export class SearchComponent implements OnInit, OnDestroy {
141 return this.advancedSearch.size() 141 return this.advancedSearch.size()
142 } 142 }
143 143
144 removeVideoFromArray (video: Video) { 144 // Add VideoChannel for typings, but the template already checks "video" argument is a video
145 removeVideoFromArray (video: Video | VideoChannel) {
145 this.results = this.results.filter(r => !this.isVideo(r) || r.id !== video.id) 146 this.results = this.results.filter(r => !this.isVideo(r) || r.id !== video.id)
146 } 147 }
147 148
diff --git a/client/src/app/shared/buttons/action-dropdown.component.ts b/client/src/app/shared/buttons/action-dropdown.component.ts
index a8b3ab16c..6649b092a 100644
--- a/client/src/app/shared/buttons/action-dropdown.component.ts
+++ b/client/src/app/shared/buttons/action-dropdown.component.ts
@@ -34,10 +34,10 @@ export class ActionDropdownComponent<T> {
34 @Input() label: string 34 @Input() label: string
35 @Input() theme: DropdownTheme = 'grey' 35 @Input() theme: DropdownTheme = 'grey'
36 36
37 getActions () { 37 getActions (): DropdownAction<T>[][] {
38 if (this.actions.length !== 0 && Array.isArray(this.actions[0])) return this.actions 38 if (this.actions.length !== 0 && Array.isArray(this.actions[0])) return this.actions as DropdownAction<T>[][]
39 39
40 return [ this.actions ] 40 return [ this.actions as DropdownAction<T>[] ]
41 } 41 }
42 42
43 areActionsDisplayed (actions: Array<DropdownAction<T> | DropdownAction<T>[]>, entry: T): boolean { 43 areActionsDisplayed (actions: Array<DropdownAction<T> | DropdownAction<T>[]>, entry: T): boolean {
diff --git a/client/src/app/shared/buttons/edit-button.component.ts b/client/src/app/shared/buttons/edit-button.component.ts
index 1fe4f7b30..9cfe1a3bb 100644
--- a/client/src/app/shared/buttons/edit-button.component.ts
+++ b/client/src/app/shared/buttons/edit-button.component.ts
@@ -8,5 +8,5 @@ import { Component, Input } from '@angular/core'
8 8
9export class EditButtonComponent { 9export class EditButtonComponent {
10 @Input() label: string 10 @Input() label: string
11 @Input() routerLink: string[] = [] 11 @Input() routerLink: string[] | string = []
12} 12}
diff --git a/client/src/app/shared/forms/markdown-textarea.component.ts b/client/src/app/shared/forms/markdown-textarea.component.ts
index 19cd37573..cbcfdfe78 100644
--- a/client/src/app/shared/forms/markdown-textarea.component.ts
+++ b/client/src/app/shared/forms/markdown-textarea.component.ts
@@ -21,7 +21,7 @@ import { MarkdownService } from '@app/shared/renderer'
21 21
22export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit { 22export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit {
23 @Input() content = '' 23 @Input() content = ''
24 @Input() classes: string[] = [] 24 @Input() classes: string[] | { [klass: string]: any[] | any } = []
25 @Input() textareaWidth = '100%' 25 @Input() textareaWidth = '100%'
26 @Input() textareaHeight = '150px' 26 @Input() textareaHeight = '150px'
27 @Input() previewColumn = false 27 @Input() previewColumn = false
diff --git a/client/src/app/shared/images/preview-upload.component.ts b/client/src/app/shared/images/preview-upload.component.ts
index f56f5b1f8..85a2173e9 100644
--- a/client/src/app/shared/images/preview-upload.component.ts
+++ b/client/src/app/shared/images/preview-upload.component.ts
@@ -26,7 +26,7 @@ export class PreviewUploadComponent implements OnInit, ControlValueAccessor {
26 allowedExtensionsMessage = '' 26 allowedExtensionsMessage = ''
27 27
28 private serverConfig: ServerConfig 28 private serverConfig: ServerConfig
29 private file: File 29 private file: Blob
30 30
31 constructor ( 31 constructor (
32 private sanitizer: DomSanitizer, 32 private sanitizer: DomSanitizer,
@@ -49,7 +49,7 @@ export class PreviewUploadComponent implements OnInit, ControlValueAccessor {
49 this.allowedExtensionsMessage = this.videoImageExtensions.join(', ') 49 this.allowedExtensionsMessage = this.videoImageExtensions.join(', ')
50 } 50 }
51 51
52 onFileChanged (file: File) { 52 onFileChanged (file: Blob) {
53 this.file = file 53 this.file = file
54 54
55 this.propagateChange(this.file) 55 this.propagateChange(this.file)
diff --git a/client/src/app/shared/rest/rest-table.ts b/client/src/app/shared/rest/rest-table.ts
index f44643c0f..a33e99e25 100644
--- a/client/src/app/shared/rest/rest-table.ts
+++ b/client/src/app/shared/rest/rest-table.ts
@@ -65,8 +65,9 @@ export abstract class RestTable {
65 }) 65 })
66 } 66 }
67 67
68 onSearch (search: string) { 68 onSearch (event: Event) {
69 this.searchStream.next(search) 69 const target = event.target as HTMLInputElement
70 this.searchStream.next(target.value)
70 } 71 }
71 72
72 protected abstract loadData (): void 73 protected abstract loadData (): void
diff --git a/client/src/app/shared/user-subscription/subscribe-button.component.html b/client/src/app/shared/user-subscription/subscribe-button.component.html
index f08c88f3c..85b3d1fdb 100644
--- a/client/src/app/shared/user-subscription/subscribe-button.component.html
+++ b/client/src/app/shared/user-subscription/subscribe-button.component.html
@@ -55,7 +55,7 @@
55 </button> 55 </button>
56 56
57 <button class="dropdown-item dropdown-item-neutral" i18n>Subscribe with a Mastodon account:</button> 57 <button class="dropdown-item dropdown-item-neutral" i18n>Subscribe with a Mastodon account:</button>
58 <my-remote-subscribe showHelp="true" [uri]="uri"></my-remote-subscribe> 58 <my-remote-subscribe [showHelp]="true" [uri]="uri"></my-remote-subscribe>
59 59
60 <div class="dropdown-divider"></div> 60 <div class="dropdown-divider"></div>
61 61
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts
index c2fe6f754..2f5f82aa3 100644
--- a/client/src/app/shared/video/abstract-video-list.ts
+++ b/client/src/app/shared/video/abstract-video-list.ts
@@ -14,6 +14,7 @@ import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
14import { I18n } from '@ngx-translate/i18n-polyfill' 14import { I18n } from '@ngx-translate/i18n-polyfill'
15import { isLastMonth, isLastWeek, isToday, isYesterday } from '@shared/core-utils/miscs/date' 15import { isLastMonth, isLastWeek, isToday, isYesterday } from '@shared/core-utils/miscs/date'
16import { ServerConfig } from '@shared/models' 16import { ServerConfig } from '@shared/models'
17import { GlobalIconName } from '@app/shared/images/global-icon.component'
17 18
18enum GroupDate { 19enum GroupDate {
19 UNKNOWN = 0, 20 UNKNOWN = 0,
@@ -61,7 +62,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
61 62
62 actions: { 63 actions: {
63 routerLink: string 64 routerLink: string
64 iconName: string 65 iconName: GlobalIconName
65 label: string 66 label: string
66 }[] = [] 67 }[] = []
67 68
diff --git a/client/src/app/shared/video/modals/video-blacklist.component.ts b/client/src/app/shared/video/modals/video-blacklist.component.ts
index f0c70a365..bdd9c7b99 100644
--- a/client/src/app/shared/video/modals/video-blacklist.component.ts
+++ b/client/src/app/shared/video/modals/video-blacklist.component.ts
@@ -1,12 +1,12 @@
1import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'
2import { Notifier, RedirectService } from '@app/core' 2import { Notifier, RedirectService } from '@app/core'
3import { VideoBlacklistService } from '../../../shared/video-blacklist' 3import { VideoBlacklistService } from '../../../shared/video-blacklist'
4import { VideoDetails } from '../../../shared/video/video-details.model'
5import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
7import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 6import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
8import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' 7import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
9import { FormReactive, VideoBlacklistValidatorsService } from '@app/shared/forms' 8import { FormReactive, VideoBlacklistValidatorsService } from '@app/shared/forms'
9import { Video } from '@app/shared/video/video.model'
10 10
11@Component({ 11@Component({
12 selector: 'my-video-blacklist', 12 selector: 'my-video-blacklist',
@@ -14,7 +14,7 @@ import { FormReactive, VideoBlacklistValidatorsService } from '@app/shared/forms
14 styleUrls: [ './video-blacklist.component.scss' ] 14 styleUrls: [ './video-blacklist.component.scss' ]
15}) 15})
16export class VideoBlacklistComponent extends FormReactive implements OnInit { 16export class VideoBlacklistComponent extends FormReactive implements OnInit {
17 @Input() video: VideoDetails = null 17 @Input() video: Video = null
18 18
19 @ViewChild('modal', { static: true }) modal: NgbModal 19 @ViewChild('modal', { static: true }) modal: NgbModal
20 20
diff --git a/client/src/app/shared/video/modals/video-report.component.ts b/client/src/app/shared/video/modals/video-report.component.ts
index 1d368ff17..ee991fade 100644
--- a/client/src/app/shared/video/modals/video-report.component.ts
+++ b/client/src/app/shared/video/modals/video-report.component.ts
@@ -1,13 +1,13 @@
1import { Component, Input, OnInit, ViewChild } from '@angular/core' 1import { Component, Input, OnInit, ViewChild } from '@angular/core'
2import { Notifier } from '@app/core' 2import { Notifier } from '@app/core'
3import { FormReactive } from '../../../shared/forms' 3import { FormReactive } from '../../../shared/forms'
4import { VideoDetails } from '../../../shared/video/video-details.model'
5import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
7import { VideoAbuseValidatorsService } from '@app/shared/forms/form-validators/video-abuse-validators.service' 6import { VideoAbuseValidatorsService } from '@app/shared/forms/form-validators/video-abuse-validators.service'
8import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 7import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
9import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' 8import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
10import { VideoAbuseService } from '@app/shared/video-abuse' 9import { VideoAbuseService } from '@app/shared/video-abuse'
10import { Video } from '@app/shared/video/video.model'
11 11
12@Component({ 12@Component({
13 selector: 'my-video-report', 13 selector: 'my-video-report',
@@ -15,7 +15,7 @@ import { VideoAbuseService } from '@app/shared/video-abuse'
15 styleUrls: [ './video-report.component.scss' ] 15 styleUrls: [ './video-report.component.scss' ]
16}) 16})
17export class VideoReportComponent extends FormReactive implements OnInit { 17export class VideoReportComponent extends FormReactive implements OnInit {
18 @Input() video: VideoDetails = null 18 @Input() video: Video = null
19 19
20 @ViewChild('modal', { static: true }) modal: NgbModal 20 @ViewChild('modal', { static: true }) modal: NgbModal
21 21
diff --git a/client/src/app/shared/video/video-thumbnail.component.ts b/client/src/app/shared/video/video-thumbnail.component.ts
index 2420ec715..111b4c8bb 100644
--- a/client/src/app/shared/video/video-thumbnail.component.ts
+++ b/client/src/app/shared/video/video-thumbnail.component.ts
@@ -12,7 +12,7 @@ export class VideoThumbnailComponent {
12 @Input() video: Video 12 @Input() video: Video
13 @Input() nsfw = false 13 @Input() nsfw = false
14 @Input() routerLink: any[] 14 @Input() routerLink: any[]
15 @Input() queryParams: any[] 15 @Input() queryParams: { [ p: string ]: any }
16 16
17 @Input() displayWatchLaterPlaylist: boolean 17 @Input() displayWatchLaterPlaylist: boolean
18 @Input() inWatchLaterPlaylist: boolean 18 @Input() inWatchLaterPlaylist: boolean
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 e40649d95..6d72e5765 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
@@ -29,7 +29,7 @@
29 <tag-input 29 <tag-input
30 [validators]="tagValidators" [errorMessages]="tagValidatorsMessages" 30 [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
31 i18n-placeholder placeholder="+ Tag" i18n-secondaryPlaceholder secondaryPlaceholder="Enter a new tag" 31 i18n-placeholder placeholder="+ Tag" i18n-secondaryPlaceholder secondaryPlaceholder="Enter a new tag"
32 formControlName="tags" maxItems="5" modelAsStrings="true" 32 formControlName="tags" [maxItems]="5" [modelAsStrings]="true"
33 ></tag-input> 33 ></tag-input>
34 </div> 34 </div>
35 35
@@ -44,7 +44,7 @@
44 </ng-template> 44 </ng-template>
45 </my-help> 45 </my-help>
46 46
47 <my-markdown-textarea truncate="250" formControlName="description" markdownVideo="true"></my-markdown-textarea> 47 <my-markdown-textarea [truncate]="250" formControlName="description" [markdownVideo]="true"></my-markdown-textarea>
48 48
49 <div *ngIf="formErrors.description" class="form-error"> 49 <div *ngIf="formErrors.description" class="form-error">
50 {{ formErrors.description }} 50 {{ formErrors.description }}
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
index 1be96ad9e..a8c432653 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
@@ -25,7 +25,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
25 @Input() parentComments: VideoComment[] 25 @Input() parentComments: VideoComment[]
26 @Input() focusOnInit = false 26 @Input() focusOnInit = false
27 27
28 @Output() commentCreated = new EventEmitter<VideoCommentCreate>() 28 @Output() commentCreated = new EventEmitter<VideoComment>()
29 @Output() cancel = new EventEmitter() 29 @Output() cancel = new EventEmitter()
30 30
31 @ViewChild('visitorModal', { static: true }) visitorModal: NgbModal 31 @ViewChild('visitorModal', { static: true }) visitorModal: NgbModal
@@ -96,7 +96,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
96 this.addingComment = true 96 this.addingComment = true
97 97
98 const commentCreate: VideoCommentCreate = this.form.value 98 const commentCreate: VideoCommentCreate = this.form.value
99 let obs: Observable<any> 99 let obs: Observable<VideoComment>
100 100
101 if (this.parentComment) { 101 if (this.parentComment) {
102 obs = this.addCommentReply(commentCreate) 102 obs = this.addCommentReply(commentCreate)
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-thread-tree.model.ts b/client/src/app/videos/+video-watch/comment/video-comment-thread-tree.model.ts
new file mode 100644
index 000000000..1566d7369
--- /dev/null
+++ b/client/src/app/videos/+video-watch/comment/video-comment-thread-tree.model.ts
@@ -0,0 +1,7 @@
1import { VideoCommentThreadTree as VideoCommentThreadTreeServerModel } from '../../../../../../shared/models/videos/video-comment.model'
2import { VideoComment } from '@app/videos/+video-watch/comment/video-comment.model'
3
4export class VideoCommentThreadTree implements VideoCommentThreadTreeServerModel {
5 comment: VideoComment
6 children: VideoCommentThreadTree[]
7}
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 61f9335d1..f7eca45fd 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,6 +1,5 @@
1import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core' 1import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'
2import { User, UserRight } from '../../../../../../shared/models/users' 2import { User, UserRight } from '../../../../../../shared/models/users'
3import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
4import { AuthService } from '@app/core/auth' 3import { AuthService } from '@app/core/auth'
5import { AccountService } from '@app/shared/account/account.service' 4import { AccountService } from '@app/shared/account/account.service'
6import { Video } from '@app/shared/video/video.model' 5import { Video } from '@app/shared/video/video.model'
@@ -10,6 +9,7 @@ import { Account } from '@app/shared/account/account.model'
10import { Notifier } from '@app/core' 9import { Notifier } from '@app/core'
11import { UserService } from '@app/shared' 10import { UserService } from '@app/shared'
12import { Actor } from '@app/shared/actor/actor.model' 11import { Actor } from '@app/shared/actor/actor.model'
12import { VideoCommentThreadTree } from '@app/videos/+video-watch/comment/video-comment-thread-tree.model'
13 13
14@Component({ 14@Component({
15 selector: 'my-video-comment', 15 selector: 'my-video-comment',
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.model.ts b/client/src/app/videos/+video-watch/comment/video-comment.model.ts
index aaeb0ea9c..171fc4acc 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment.model.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment.model.ts
@@ -1,5 +1,5 @@
1import { Account as AccountInterface } from '../../../../../../shared/models/actors' 1import { Account as AccountInterface } from '../../../../../../shared/models/actors'
2import { VideoComment as VideoCommentServerModel } from '../../../../../../shared/models/videos/video-comment.model' 2import { VideoComment as VideoCommentServerModel, VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model'
3import { Actor } from '@app/shared/actor/actor.model' 3import { Actor } from '@app/shared/actor/actor.model'
4import { getAbsoluteAPIUrl } from '@app/shared/misc/utils' 4import { getAbsoluteAPIUrl } from '@app/shared/misc/utils'
5 5
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 a81e5236a..0b0715390 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
@@ -7,13 +7,14 @@ import { FeedFormat, ResultList } from '../../../../../../shared/models'
7import { 7import {
8 VideoComment as VideoCommentServerModel, 8 VideoComment as VideoCommentServerModel,
9 VideoCommentCreate, 9 VideoCommentCreate,
10 VideoCommentThreadTree 10 VideoCommentThreadTree as VideoCommentThreadTreeServerModel
11} from '../../../../../../shared/models/videos/video-comment.model' 11} from '../../../../../../shared/models/videos/video-comment.model'
12import { environment } from '../../../../environments/environment' 12import { environment } from '../../../../environments/environment'
13import { RestExtractor, RestService } from '../../../shared/rest' 13import { RestExtractor, RestService } from '../../../shared/rest'
14import { ComponentPaginationLight } from '../../../shared/rest/component-pagination.model' 14import { ComponentPaginationLight } from '../../../shared/rest/component-pagination.model'
15import { CommentSortField } from '../../../shared/video/sort-field.type' 15import { CommentSortField } from '../../../shared/video/sort-field.type'
16import { VideoComment } from './video-comment.model' 16import { VideoComment } from './video-comment.model'
17import { VideoCommentThreadTree } from '@app/videos/+video-watch/comment/video-comment-thread-tree.model'
17 18
18@Injectable() 19@Injectable()
19export class VideoCommentService { 20export class VideoCommentService {
@@ -76,9 +77,9 @@ export class VideoCommentService {
76 const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comment-threads/${threadId}` 77 const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comment-threads/${threadId}`
77 78
78 return this.authHttp 79 return this.authHttp
79 .get(url) 80 .get<VideoCommentThreadTreeServerModel>(url)
80 .pipe( 81 .pipe(
81 map(tree => this.extractVideoCommentTree(tree as VideoCommentThreadTree)), 82 map(tree => this.extractVideoCommentTree(tree)),
82 catchError(err => this.restExtractor.handleError(err)) 83 catchError(err => this.restExtractor.handleError(err))
83 ) 84 )
84 } 85 }
@@ -138,12 +139,12 @@ export class VideoCommentService {
138 return { data: comments, total: totalComments } 139 return { data: comments, total: totalComments }
139 } 140 }
140 141
141 private extractVideoCommentTree (tree: VideoCommentThreadTree) { 142 private extractVideoCommentTree (tree: VideoCommentThreadTreeServerModel) {
142 if (!tree) return tree 143 if (!tree) return tree as VideoCommentThreadTree
143 144
144 tree.comment = new VideoComment(tree.comment) 145 tree.comment = new VideoComment(tree.comment)
145 tree.children.forEach(c => this.extractVideoCommentTree(c)) 146 tree.children.forEach(c => this.extractVideoCommentTree(c))
146 147
147 return tree 148 return tree as VideoCommentThreadTree
148 } 149 }
149} 150}
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.ts b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
index 47720b0ea..750c09c47 100644
--- a/client/src/app/videos/+video-watch/comment/video-comments.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
@@ -1,8 +1,7 @@
1import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild, Output, EventEmitter } from '@angular/core' 1import { Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'
2import { ActivatedRoute } from '@angular/router' 2import { ActivatedRoute } from '@angular/router'
3import { ConfirmService, Notifier } from '@app/core' 3import { ConfirmService, Notifier } from '@app/core'
4import { Subject, Subscription } from 'rxjs' 4import { Subject, Subscription } from 'rxjs'
5import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
6import { AuthService } from '../../../core/auth' 5import { AuthService } from '../../../core/auth'
7import { ComponentPagination, hasMoreItems } from '../../../shared/rest/component-pagination.model' 6import { ComponentPagination, hasMoreItems } from '../../../shared/rest/component-pagination.model'
8import { User } from '../../../shared/users' 7import { User } from '../../../shared/users'
@@ -13,6 +12,7 @@ import { VideoCommentService } from './video-comment.service'
13import { I18n } from '@ngx-translate/i18n-polyfill' 12import { I18n } from '@ngx-translate/i18n-polyfill'
14import { Syndication } from '@app/shared/video/syndication.model' 13import { Syndication } from '@app/shared/video/syndication.model'
15import { HooksService } from '@app/core/plugins/hooks.service' 14import { HooksService } from '@app/core/plugins/hooks.service'
15import { VideoCommentThreadTree } from '@app/videos/+video-watch/comment/video-comment-thread-tree.model'
16 16
17@Component({ 17@Component({
18 selector: 'my-video-comments', 18 selector: 'my-video-comments',
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.html b/client/src/app/videos/+video-watch/modal/video-share.component.html
index 549a9f30e..593dd8529 100644
--- a/client/src/app/videos/+video-watch/modal/video-share.component.html
+++ b/client/src/app/videos/+video-watch/modal/video-share.component.html
@@ -42,7 +42,7 @@
42 <ngb-tab i18n-title title="QR-Code" id="qrcode"> 42 <ngb-tab i18n-title title="QR-Code" id="qrcode">
43 <ng-template ngbTabContent> 43 <ng-template ngbTabContent>
44 <div class="tab-content"> 44 <div class="tab-content">
45 <qrcode [qrdata]="getVideoUrl()" size="256" level="Q"></qrcode> 45 <qrcode [qrdata]="getVideoUrl()" [size]="256" level="Q"></qrcode>
46 </div> 46 </div>
47 </ng-template> 47 </ng-template>
48 </ngb-tab> 48 </ngb-tab>
diff --git a/client/tsconfig.json b/client/tsconfig.json
index c4f2d6a6a..fbdeb6d5d 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -37,6 +37,7 @@
37 }, 37 },
38 "angularCompilerOptions": { 38 "angularCompilerOptions": {
39 "strictInjectionParameters": true, 39 "strictInjectionParameters": true,
40 "fullTemplateTypeCheck": true 40 "fullTemplateTypeCheck": true,
41 "strictTemplates": true
41 } 42 }
42} 43}
diff --git a/shared/models/plugins/register-server-setting.model.ts b/shared/models/plugins/register-server-setting.model.ts
index 65a181705..45d79228d 100644
--- a/shared/models/plugins/register-server-setting.model.ts
+++ b/shared/models/plugins/register-server-setting.model.ts
@@ -1,7 +1,7 @@
1export interface RegisterServerSettingOptions { 1export interface RegisterServerSettingOptions {
2 name: string 2 name: string
3 label: string 3 label: string
4 type: 'input' 4 type: 'input' | 'input-checkbox' | 'input-textarea'
5 5
6 // If the setting is not private, anyone can view its value (client code included) 6 // If the setting is not private, anyone can view its value (client code included)
7 // If the setting is private, only server-side hooks can access it 7 // If the setting is private, only server-side hooks can access it