From 54909304287f3c04dcfb39660be8ead57dc95440 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 24 May 2023 16:48:54 +0200 Subject: Remove suppressImplicitAnyIndexErrors It's deprecated by TS --- .../edit-custom-config.component.ts | 4 ++-- .../+admin/overview/users/user-edit/user-edit.ts | 4 ++-- .../plugin-list-installed.component.ts | 2 +- ...y-account-notification-preferences.component.ts | 6 ++--- .../my-video-channel-syncs.component.ts | 2 +- .../+my-library/my-videos/my-videos.component.ts | 8 +++---- client/src/app/+search/search-filters.component.ts | 6 ++--- .../src/app/+stats/video/video-stats.component.ts | 2 +- .../+videos/+video-edit/shared/video-edit-utils.ts | 4 ++-- .../shared/comment/video-comments.component.ts | 4 ++-- .../video-list/overview/overview.service.ts | 7 ++++-- client/src/app/core/server/server.service.ts | 3 ++- .../app/core/users/user-local-storage.service.ts | 7 +++--- client/src/app/core/users/user.model.ts | 6 +++-- client/src/app/menu/language-chooser.component.ts | 7 +++--- .../shared-actor-image/actor-avatar.component.ts | 5 ++-- .../dynamic-element.service.ts | 5 ++-- .../video-miniature-markup.component.ts | 3 ++- .../videos-list-markup.component.ts | 3 ++- .../shared/shared-forms/form-validator.service.ts | 11 +++++---- .../shared/shared-icons/global-icon.component.ts | 2 +- .../app/shared/shared-instance/instance.service.ts | 3 ++- .../app/shared/shared-main/misc/help.component.ts | 2 +- .../shared/shared-main/video/video-edit.model.ts | 6 +++-- .../shared-share-modal/video-share.component.ts | 3 ++- .../video-download.component.ts | 27 +++++++++++----------- .../shared-video-miniature/video-filters.model.ts | 2 +- .../videos-selection.component.ts | 3 ++- 28 files changed, 84 insertions(+), 63 deletions(-) (limited to 'client/src/app') diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts index 30e4aa5d5..2c3b7560d 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts @@ -273,11 +273,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { const defaultValues = { transcoding: { - resolutions: {} + resolutions: {} as { [id: string]: string } }, live: { transcoding: { - resolutions: {} + resolutions: {} as { [id: string]: string } } } } diff --git a/client/src/app/+admin/overview/users/user-edit/user-edit.ts b/client/src/app/+admin/overview/users/user-edit/user-edit.ts index 5d6c6a91e..9547da2d1 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/overview/users/user-edit/user-edit.ts @@ -53,8 +53,8 @@ export abstract class UserEdit extends FormReactive implements OnInit { this.serverService.getServerLocale() .subscribe(translations => { if (authUser.role.id === UserRole.ADMINISTRATOR) { - this.roles = Object.keys(USER_ROLE_LABELS) - .map(key => ({ value: key.toString(), label: peertubeTranslate(USER_ROLE_LABELS[key], translations) })) + this.roles = Object.entries(USER_ROLE_LABELS) + .map(([ key, value ]) => ({ value: key.toString(), label: peertubeTranslate(value, translations) })) return } diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts index 2fdc14d85..3fa1c56dc 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts @@ -104,7 +104,7 @@ export class PluginListInstalledComponent implements OnInit { } isUninstalling (plugin: PeerTubePlugin) { - return !!this.uninstall[this.getPluginKey(plugin)] + return !!this.uninstalling[this.getPluginKey(plugin)] } isTheme (plugin: PeerTubePlugin) { diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts index 769ab647a..8faba676e 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts @@ -141,11 +141,11 @@ export class MyAccountNotificationPreferencesComponent implements OnInit { } private loadNotificationSettings () { - for (const key of Object.keys(this.user.notificationSettings)) { + for (const key of Object.keys(this.user.notificationSettings) as (keyof UserNotificationSetting)[]) { const value = this.user.notificationSettings[key] - this.emailNotifications[key] = value & UserNotificationSettingValue.EMAIL + this.emailNotifications[key] = !!(value & UserNotificationSettingValue.EMAIL) - this.webNotifications[key] = value & UserNotificationSettingValue.WEB + this.webNotifications[key] = !!(value & UserNotificationSettingValue.WEB) } } } diff --git a/client/src/app/+my-library/my-video-channel-syncs/my-video-channel-syncs.component.ts b/client/src/app/+my-library/my-video-channel-syncs/my-video-channel-syncs.component.ts index 74dbe222d..1f7287f44 100644 --- a/client/src/app/+my-library/my-video-channel-syncs/my-video-channel-syncs.component.ts +++ b/client/src/app/+my-library/my-video-channel-syncs/my-video-channel-syncs.component.ts @@ -124,7 +124,7 @@ export class MyVideoChannelSyncsComponent extends RestTable implements OnInit { return '/my-library/video-channel-syncs/create' } - getSyncStateClass (stateId: number) { + getSyncStateClass (stateId: VideoChannelSyncState) { return [ 'pt-badge', MyVideoChannelSyncsComponent.STATE_CLASS_BY_ID[stateId] ] } diff --git a/client/src/app/+my-library/my-videos/my-videos.component.ts b/client/src/app/+my-library/my-videos/my-videos.component.ts index 46dd304ba..b618b3f88 100644 --- a/client/src/app/+my-library/my-videos/my-videos.component.ts +++ b/client/src/app/+my-library/my-videos/my-videos.component.ts @@ -171,15 +171,15 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook { .subscribe(result => { this.videosContainedInPlaylists = Object.keys(result).reduce((acc, videoId) => ({ ...acc, - [videoId]: uniqBy(result[videoId], (p: VideoExistInPlaylist) => p.playlistId) + [videoId]: uniqBy(result[+videoId], (p: VideoExistInPlaylist) => p.playlistId) }), this.videosContainedInPlaylists) }) } async deleteSelectedVideos () { - const toDeleteVideosIds = Object.keys(this.selection) - .filter(k => this.selection[k] === true) - .map(k => parseInt(k, 10)) + const toDeleteVideosIds = Object.entries(this.selection) + .filter(([ _k, v ]) => v === true) + .map(([ k, _v ]) => parseInt(k, 10)) const res = await this.confirmService.confirm( prepareIcu($localize`Do you really want to delete {length, plural, =1 {this video} other {{length} videos}}?`)( diff --git a/client/src/app/+search/search-filters.component.ts b/client/src/app/+search/search-filters.component.ts index f9de04706..a6fc51383 100644 --- a/client/src/app/+search/search-filters.component.ts +++ b/client/src/app/+search/search-filters.component.ts @@ -118,11 +118,11 @@ export class SearchFiltersComponent implements OnInit { this.onDurationOrPublishedUpdated() } - resetField (fieldName: string, value?: any) { - this.advancedSearch[fieldName] = value + resetField (fieldName: keyof AdvancedSearch, value?: any) { + (this.advancedSearch as any)[fieldName] = value } - resetLocalField (fieldName: string, value?: any) { + resetLocalField (fieldName: keyof SearchFiltersComponent, value?: any) { this[fieldName] = value this.onDurationOrPublishedUpdated() } diff --git a/client/src/app/+stats/video/video-stats.component.ts b/client/src/app/+stats/video/video-stats.component.ts index 18312ec33..fa5e33ab6 100644 --- a/client/src/app/+stats/video/video-stats.component.ts +++ b/client/src/app/+stats/video/video-stats.component.ts @@ -47,7 +47,7 @@ export class VideoStatsComponent implements OnInit { chartHeight = '300px' chartWidth: string = null - availableCharts: { id: string, label: string, zoomEnabled: boolean }[] = [] + availableCharts: { id: ActiveGraphId, label: string, zoomEnabled: boolean }[] = [] activeGraphId: ActiveGraphId = 'viewers' video: VideoDetails diff --git a/client/src/app/+videos/+video-edit/shared/video-edit-utils.ts b/client/src/app/+videos/+video-edit/shared/video-edit-utils.ts index db1ef8d73..214bde680 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit-utils.ts +++ b/client/src/app/+videos/+video-edit/shared/video-edit-utils.ts @@ -8,11 +8,11 @@ function hydrateFormFromVideo (formGroup: FormGroup, video: VideoEdit, thumbnail const objects = [ { - url: 'thumbnailUrl', + url: 'thumbnailUrl' as 'thumbnailUrl', name: 'thumbnailfile' }, { - url: 'previewUrl', + url: 'previewUrl' as 'previewUrl', name: 'previewfile' } ] diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts index 28edcfdcb..96bdb28c9 100644 --- a/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts +++ b/client/src/app/+videos/+video-watch/shared/comment/video-comments.component.ts @@ -263,8 +263,8 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { this.syndicationItems = this.videoCommentService.getVideoCommentsFeeds(this.video) this.loadMoreThreads() - if (this.activatedRoute.params['threadId']) { - this.processHighlightedThread(+this.activatedRoute.params['threadId']) + if (this.activatedRoute.snapshot.params['threadId']) { + this.processHighlightedThread(+this.activatedRoute.snapshot.params['threadId']) } } } diff --git a/client/src/app/+videos/video-list/overview/overview.service.ts b/client/src/app/+videos/video-list/overview/overview.service.ts index 12d2aa1cb..4a7d9c7c5 100644 --- a/client/src/app/+videos/video-list/overview/overview.service.ts +++ b/client/src/app/+videos/video-list/overview/overview.service.ts @@ -5,6 +5,7 @@ import { Injectable } from '@angular/core' import { RestExtractor, ServerService } from '@app/core' import { immutableAssign } from '@app/helpers' import { VideoService } from '@app/shared/shared-main' +import { objectKeysTyped } from '@shared/core-utils' import { peertubeTranslate } from '@shared/core-utils/i18n' import { VideosOverview as VideosOverviewServer } from '@shared/models' import { environment } from '../../../../environments/environment' @@ -42,7 +43,7 @@ export class OverviewService { } // Build videos objects - for (const key of Object.keys(serverVideosOverview)) { + for (const key of objectKeysTyped(serverVideosOverview)) { for (const object of serverVideosOverview[key]) { observables.push( of(object.videos) @@ -50,7 +51,9 @@ export class OverviewService { switchMap(videos => this.videosService.extractVideos({ total: 0, data: videos })), map(result => result.data), tap(videos => { - videosOverviewResult[key].push(immutableAssign(object, { videos })) + // FIXME: typings & lint + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + videosOverviewResult[key].push(immutableAssign(object, { videos }) as any) }) ) ) diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index 9f191f0a6..fc269749b 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts @@ -193,7 +193,8 @@ export class ServerService { } private loadHTMLConfigLocally () { - const configString = window['PeerTubeServerConfig'] + // FIXME: typings + const configString = (window as any)['PeerTubeServerConfig'] if (!configString) { throw new Error('Could not find PeerTubeServerConfig in HTML') } diff --git a/client/src/app/core/users/user-local-storage.service.ts b/client/src/app/core/users/user-local-storage.service.ts index 1e629249a..a87f3b98a 100644 --- a/client/src/app/core/users/user-local-storage.service.ts +++ b/client/src/app/core/users/user-local-storage.service.ts @@ -4,7 +4,8 @@ import { Injectable } from '@angular/core' import { AuthService, AuthStatus } from '@app/core/auth' import { getBoolOrDefault } from '@root-helpers/local-storage-utils' import { logger } from '@root-helpers/logger' -import { UserLocalStorageKeys, OAuthUserTokens } from '@root-helpers/users' +import { OAuthUserTokens, UserLocalStorageKeys } from '@root-helpers/users' +import { objectKeysTyped } from '@shared/core-utils' import { UserRole, UserUpdateMe } from '@shared/models' import { NSFWPolicyType } from '@shared/models/videos' import { ServerService } from '../server' @@ -122,7 +123,7 @@ export class UserLocalStorageService { } setUserInfo (profile: UserUpdateMe) { - const localStorageKeys: { [ id in keyof UserUpdateMe ]: string } = { + const localStorageKeys = { nsfwPolicy: UserLocalStorageKeys.NSFW_POLICY, p2pEnabled: UserLocalStorageKeys.P2P_ENABLED, autoPlayVideo: UserLocalStorageKeys.AUTO_PLAY_VIDEO, @@ -132,7 +133,7 @@ export class UserLocalStorageService { videoLanguages: UserLocalStorageKeys.VIDEO_LANGUAGES } - const obj = Object.keys(localStorageKeys) + const obj: [ string, string | boolean | string[] ][] = objectKeysTyped(localStorageKeys) .filter(key => key in profile) .map(key => ([ localStorageKeys[key], profile[key] ])) diff --git a/client/src/app/core/users/user.model.ts b/client/src/app/core/users/user.model.ts index 2d783145f..d57608f1c 100644 --- a/client/src/app/core/users/user.model.ts +++ b/client/src/app/core/users/user.model.ts @@ -1,4 +1,5 @@ import { Account } from '@app/shared/shared-main/account/account.model' +import { objectKeysTyped } from '@shared/core-utils' import { hasUserRight } from '@shared/core-utils/users' import { ActorImage, @@ -130,8 +131,9 @@ export class User implements UserServerModel { } patch (obj: UserServerModel) { - for (const key of Object.keys(obj)) { - this[key] = obj[key] + for (const key of objectKeysTyped(obj)) { + // FIXME: typings + (this as any)[key] = obj[key] } if (obj.account !== undefined) { diff --git a/client/src/app/menu/language-chooser.component.ts b/client/src/app/menu/language-chooser.component.ts index b42e41855..f7ae69717 100644 --- a/client/src/app/menu/language-chooser.component.ts +++ b/client/src/app/menu/language-chooser.component.ts @@ -1,6 +1,7 @@ import { Component, ElementRef, Inject, LOCALE_ID, ViewChild } from '@angular/core' import { getDevLocale, isOnDevLocale, sortBy } from '@app/helpers' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' +import { objectKeysTyped } from '@shared/core-utils' import { getCompleteLocale, getShortLocale, I18N_LOCALES } from '@shared/core-utils/i18n' @Component({ @@ -17,8 +18,8 @@ export class LanguageChooserComponent { private modalService: NgbModal, @Inject(LOCALE_ID) private localeId: string ) { - const l = Object.keys(I18N_LOCALES) - .map(k => ({ id: k, label: I18N_LOCALES[k], iso: getShortLocale(k) })) + const l = objectKeysTyped(I18N_LOCALES) + .map(k => ({ id: k, label: I18N_LOCALES[k], iso: getShortLocale(k) })) this.languages = sortBy(l, 'label') } @@ -35,7 +36,7 @@ export class LanguageChooserComponent { const english = 'English' const locale = isOnDevLocale() ? getDevLocale() : getCompleteLocale(this.localeId) - if (locale) return I18N_LOCALES[locale] || english + if (locale) return I18N_LOCALES[locale as keyof typeof I18N_LOCALES] || english return english } } diff --git a/client/src/app/shared/shared-actor-image/actor-avatar.component.ts b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts index f1c1aa03f..ab2e02ad7 100644 --- a/client/src/app/shared/shared-actor-image/actor-avatar.component.ts +++ b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts @@ -1,6 +1,7 @@ import { Component, Input, OnChanges, OnInit } from '@angular/core' import { VideoChannel } from '../shared-main' import { Account } from '../shared-main/account/account.model' +import { objectKeysTyped } from '@shared/core-utils' type ActorInput = { name: string @@ -154,8 +155,8 @@ export class ActorAvatarComponent implements OnInit, OnChanges { 'wxyz': 'dark-blue' } - const theme = Object.keys(themes) - .find(chars => chars.includes(initialLowercase)) + const theme = objectKeysTyped(themes) + .find(chars => chars.includes(initialLowercase)) return themes[theme] || 'blue' } diff --git a/client/src/app/shared/shared-custom-markup/dynamic-element.service.ts b/client/src/app/shared/shared-custom-markup/dynamic-element.service.ts index 208dba721..a12907055 100644 --- a/client/src/app/shared/shared-custom-markup/dynamic-element.service.ts +++ b/client/src/app/shared/shared-custom-markup/dynamic-element.service.ts @@ -10,6 +10,7 @@ import { SimpleChanges, Type } from '@angular/core' +import { objectKeysTyped } from '@shared/core-utils' @Injectable() export class DynamicElementService { @@ -41,12 +42,12 @@ export class DynamicElementService { setModel (componentRef: ComponentRef, attributes: Partial) { const changes: SimpleChanges = {} - for (const key of Object.keys(attributes)) { + for (const key of objectKeysTyped(attributes)) { const previousValue = componentRef.instance[key] const newValue = attributes[key] componentRef.instance[key] = newValue - changes[key] = new SimpleChange(previousValue, newValue, previousValue === undefined) + changes[key as string] = new SimpleChange(previousValue, newValue, previousValue === undefined) } const component = componentRef.instance diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts index 21774b7aa..bd93929c9 100644 --- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts +++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts @@ -2,6 +2,7 @@ import { finalize } from 'rxjs/operators' import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core' import { AuthService, Notifier } from '@app/core' import { FindInBulkService } from '@app/shared/shared-search' +import { objectKeysTyped } from '@shared/core-utils' import { Video } from '../../shared-main' import { MiniatureDisplayOptions } from '../../shared-video-miniature' import { CustomMarkupComponent } from './shared' @@ -47,7 +48,7 @@ export class VideoMiniatureMarkupComponent implements CustomMarkupComponent, OnI ngOnInit () { if (this.onlyDisplayTitle) { - for (const key of Object.keys(this.displayOptions)) { + for (const key of objectKeysTyped(this.displayOptions)) { this.displayOptions[key] = false } } diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts index 7c2e7db6a..81363be87 100644 --- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts +++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts @@ -1,6 +1,7 @@ import { finalize } from 'rxjs/operators' import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core' import { AuthService, Notifier } from '@app/core' +import { objectKeysTyped } from '@shared/core-utils' import { VideoSortField } from '@shared/models' import { Video, VideoService } from '../../shared-main' import { MiniatureDisplayOptions } from '../../shared-video-miniature' @@ -66,7 +67,7 @@ export class VideosListMarkupComponent implements CustomMarkupComponent, OnInit ngOnInit () { if (this.onlyDisplayTitle) { - for (const key of Object.keys(this.displayOptions)) { + for (const key of objectKeysTyped(this.displayOptions)) { this.displayOptions[key] = false } } diff --git a/client/src/app/shared/shared-forms/form-validator.service.ts b/client/src/app/shared/shared-forms/form-validator.service.ts index 897008242..14ee044b5 100644 --- a/client/src/app/shared/shared-forms/form-validator.service.ts +++ b/client/src/app/shared/shared-forms/form-validator.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@angular/core' import { AsyncValidatorFn, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn } from '@angular/forms' +import { objectKeysTyped } from '@shared/core-utils' import { BuildFormArgument, BuildFormDefaultValues } from '../form-validators/form-validator.model' import { FormReactiveErrors, FormReactiveValidationMessages } from './form-reactive.service' @@ -47,13 +48,14 @@ export class FormValidatorService { obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {} ) { - for (const name of Object.keys(obj)) { + for (const name of objectKeysTyped(obj)) { formErrors[name] = '' const field = obj[name] if (this.isRecursiveField(field)) { this.updateFormGroup( - form[name], + // FIXME: typings + (form as any)[name], formErrors[name] as FormReactiveErrors, validationMessages[name] as FormReactiveValidationMessages, obj[name] as BuildFormArgument, @@ -67,7 +69,7 @@ export class FormValidatorService { const defaultValue = defaultValues[name] || '' form.addControl( - name, + name + '', new FormControl(defaultValue, field?.VALIDATORS as ValidatorFn[], field?.ASYNC_VALIDATORS as AsyncValidatorFn[]) ) } @@ -75,7 +77,8 @@ export class FormValidatorService { updateTreeValidity (group: FormGroup | FormArray): void { for (const key of Object.keys(group.controls)) { - const abstractControl = group.controls[key] as FormControl + // FIXME: typings + const abstractControl = (group.controls as any)[key] as FormControl if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) { this.updateTreeValidity(abstractControl) diff --git a/client/src/app/shared/shared-icons/global-icon.component.ts b/client/src/app/shared/shared-icons/global-icon.component.ts index 96179cbe6..eea460831 100644 --- a/client/src/app/shared/shared-icons/global-icon.component.ts +++ b/client/src/app/shared/shared-icons/global-icon.component.ts @@ -112,7 +112,7 @@ export class GlobalIconComponent implements OnInit { } } - private getSVGContent (options: { name: string }) { + private getSVGContent (options: { name: GlobalIconName }) { return icons[options.name] } } diff --git a/client/src/app/shared/shared-instance/instance.service.ts b/client/src/app/shared/shared-instance/instance.service.ts index 2defffbbe..3088f0899 100644 --- a/client/src/app/shared/shared-instance/instance.service.ts +++ b/client/src/app/shared/shared-instance/instance.service.ts @@ -3,6 +3,7 @@ import { catchError, map } from 'rxjs/operators' import { HttpClient } from '@angular/common/http' import { Injectable } from '@angular/core' import { MarkdownService, RestExtractor, ServerService } from '@app/core' +import { objectKeysTyped } from '@shared/core-utils' import { peertubeTranslate } from '@shared/core-utils/i18n' import { About } from '@shared/models' import { environment } from '../../../environments/environment' @@ -55,7 +56,7 @@ export class InstanceService { hardwareInformation: '' } - for (const key of Object.keys(html)) { + for (const key of objectKeysTyped(html)) { html[key] = await this.markdownService.enhancedMarkdownToHTML({ markdown: about.instance[key] }) } diff --git a/client/src/app/shared/shared-main/misc/help.component.ts b/client/src/app/shared/shared-main/misc/help.component.ts index 37e2abd97..80fe0e160 100644 --- a/client/src/app/shared/shared-main/misc/help.component.ts +++ b/client/src/app/shared/shared-main/misc/help.component.ts @@ -77,7 +77,7 @@ export class HelpComponent implements OnInit, OnChanges, AfterContentInit { } private createMarkdownList (rules: string[]) { - const rulesToText = { + const rulesToText: { [id: string]: string } = { emphasis: $localize`Emphasis`, link: $localize`Links`, newline: $localize`New lines`, diff --git a/client/src/app/shared/shared-main/video/video-edit.model.ts b/client/src/app/shared/shared-main/video/video-edit.model.ts index 91d57cb6b..47eee80d8 100644 --- a/client/src/app/shared/shared-main/video/video-edit.model.ts +++ b/client/src/app/shared/shared-main/video/video-edit.model.ts @@ -1,6 +1,7 @@ import { getAbsoluteAPIUrl } from '@app/helpers' import { VideoPrivacy, VideoScheduleUpdate, VideoUpdate } from '@shared/models' import { VideoDetails } from './video-details.model' +import { objectKeysTyped } from '@shared/core-utils' export class VideoEdit implements VideoUpdate { static readonly SPECIAL_SCHEDULED_PRIVACY = -1 @@ -65,8 +66,9 @@ export class VideoEdit implements VideoUpdate { } patch (values: { [ id: string ]: any }) { - Object.keys(values).forEach((key) => { - this[key] = values[key] + objectKeysTyped(values).forEach(key => { + // FIXME: typings + (this as any)[key] = values[key] }) // If schedule publication, the video is private and will be changed to public privacy diff --git a/client/src/app/shared/shared-share-modal/video-share.component.ts b/client/src/app/shared/shared-share-modal/video-share.component.ts index 1b69aa2d0..32f900f15 100644 --- a/client/src/app/shared/shared-share-modal/video-share.component.ts +++ b/client/src/app/shared/shared-share-modal/video-share.component.ts @@ -106,7 +106,8 @@ export class VideoShareComponent { includeVideoInPlaylist: false }, { set: (target, prop, value) => { - target[prop] = value + // FIXME: typings + (target as any)[prop] = value if (prop === 'embedP2P') { // Auto enabled warning title if P2P is enabled diff --git a/client/src/app/shared/shared-video-miniature/video-download.component.ts b/client/src/app/shared/shared-video-miniature/video-download.component.ts index 4135542dc..cac82d8d0 100644 --- a/client/src/app/shared/shared-video-miniature/video-download.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-download.component.ts @@ -1,4 +1,4 @@ -import { mapValues, pick } from 'lodash-es' +import { mapValues } from 'lodash-es' import { firstValueFrom } from 'rxjs' import { tap } from 'rxjs/operators' import { Component, ElementRef, Inject, LOCALE_ID, ViewChild } from '@angular/core' @@ -6,11 +6,12 @@ import { HooksService } from '@app/core' import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap' import { logger } from '@root-helpers/logger' import { videoRequiresAuth } from '@root-helpers/video' +import { objectKeysTyped, pick } from '@shared/core-utils' import { VideoCaption, VideoFile, VideoPrivacy } from '@shared/models' import { BytesPipe, NumberFormatterPipe, VideoDetails, VideoFileTokenService, VideoService } from '../shared-main' type DownloadType = 'video' | 'subtitles' -type FileMetadata = { [key: string]: { label: string, value: string } } +type FileMetadata = { [key: string]: { label: string, value: string | number } } @Component({ selector: 'my-video-download', @@ -218,10 +219,10 @@ export class VideoDownloadComponent { const keyToTranslateFunction = { encoder: (value: string) => ({ label: $localize`Encoder`, value }), format_long_name: (value: string) => ({ label: $localize`Format name`, value }), - size: (value: number) => ({ label: $localize`Size`, value: this.bytesPipe.transform(value, 2) }), - bit_rate: (value: number) => ({ + size: (value: number | string) => ({ label: $localize`Size`, value: this.bytesPipe.transform(+value, 2) }), + bit_rate: (value: number | string) => ({ label: $localize`Bitrate`, - value: `${this.numbersPipe.transform(value)}bps` + value: `${this.numbersPipe.transform(+value)}bps` }) } @@ -230,8 +231,8 @@ export class VideoDownloadComponent { delete sanitizedFormat.tags return mapValues( - pick(sanitizedFormat, Object.keys(keyToTranslateFunction)), - (val, key) => keyToTranslateFunction[key](val) + pick(sanitizedFormat, objectKeysTyped(keyToTranslateFunction)), + (val: string, key: keyof typeof keyToTranslateFunction) => keyToTranslateFunction[key](val) ) } @@ -242,29 +243,29 @@ export class VideoDownloadComponent { let keyToTranslateFunction = { codec_long_name: (value: string) => ({ label: $localize`Codec`, value }), profile: (value: string) => ({ label: $localize`Profile`, value }), - bit_rate: (value: number) => ({ + bit_rate: (value: number | string) => ({ label: $localize`Bitrate`, - value: `${this.numbersPipe.transform(value)}bps` + value: `${this.numbersPipe.transform(+value)}bps` }) } if (type === 'video') { keyToTranslateFunction = Object.assign(keyToTranslateFunction, { - width: (value: number) => ({ label: $localize`Resolution`, value: `${value}x${stream.height}` }), + width: (value: string | number) => ({ label: $localize`Resolution`, value: `${value}x${stream.height}` }), display_aspect_ratio: (value: string) => ({ label: $localize`Aspect ratio`, value }), avg_frame_rate: (value: string) => ({ label: $localize`Average frame rate`, value }), pix_fmt: (value: string) => ({ label: $localize`Pixel format`, value }) }) } else { keyToTranslateFunction = Object.assign(keyToTranslateFunction, { - sample_rate: (value: number) => ({ label: $localize`Sample rate`, value }), - channel_layout: (value: number) => ({ label: $localize`Channel Layout`, value }) + sample_rate: (value: string | number) => ({ label: $localize`Sample rate`, value }), + channel_layout: (value: string | number) => ({ label: $localize`Channel Layout`, value }) }) } return mapValues( pick(stream, Object.keys(keyToTranslateFunction)), - (val, key) => keyToTranslateFunction[key](val) + (val: string, key: keyof typeof keyToTranslateFunction) => keyToTranslateFunction[key](val) ) } diff --git a/client/src/app/shared/shared-video-miniature/video-filters.model.ts b/client/src/app/shared/shared-video-miniature/video-filters.model.ts index 6b4b72c75..4db73b25a 100644 --- a/client/src/app/shared/shared-video-miniature/video-filters.model.ts +++ b/client/src/app/shared/shared-video-miniature/video-filters.model.ts @@ -84,7 +84,7 @@ export class VideoFilters { if (specificKey && specificKey !== key) continue // FIXME: typings - this[key as any] = value + (this as any)[key] = value } this.buildActiveFilters() diff --git a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts index 460a0080e..86fe502e2 100644 --- a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts +++ b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts @@ -2,6 +2,7 @@ import { Observable, Subject } from 'rxjs' import { AfterContentInit, Component, ContentChildren, EventEmitter, Input, Output, QueryList, TemplateRef } from '@angular/core' import { ComponentPagination, Notifier, User } from '@app/core' import { logger } from '@root-helpers/logger' +import { objectKeysTyped } from '@shared/core-utils' import { ResultList, VideosExistInPlaylists, VideoSortField } from '@shared/models' import { PeerTubeTemplateDirective, Video } from '../shared-main' import { MiniatureDisplayOptions } from './video-miniature.component' @@ -93,7 +94,7 @@ export class VideosSelectionComponent implements AfterContentInit { } isInSelectionMode () { - return Object.keys(this._selection).some(k => this._selection[k] === true) + return objectKeysTyped(this._selection).some(k => this._selection[k] === true) } videoById (index: number, video: Video) { -- cgit v1.2.3