diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index c5624c4..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - } -} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..b3a60be --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,49 @@ +const js = require('@eslint/js'); +const globals = require('globals'); +const tsPlugin = require('@typescript-eslint/eslint-plugin'); + +const SOURCE_FILES = ['src/**/*.{js,ts}']; +const TS_FILES = ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.mts', 'src/**/*.cts']; + +const scopedTsConfigs = tsPlugin.configs['flat/recommended'].map((config) => ({ + ...config, + files: config.files ? config.files.map((pattern) => `src/${pattern}`) : TS_FILES, +})); + +module.exports = [ + { + ignores: ['node_modules/**', 'dist/**', 'coverage/**'], + linterOptions: { + reportUnusedDisableDirectives: false, + }, + }, + { + files: SOURCE_FILES, + languageOptions: { + ecmaVersion: 2021, + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.es2021, + }, + }, + }, + { + ...js.configs.recommended, + files: SOURCE_FILES, + }, + ...scopedTsConfigs, + { + files: SOURCE_FILES, + rules: { + 'no-useless-escape': 'off', + }, + }, + { + files: TS_FILES, + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, +]; diff --git a/package-lock.json b/package-lock.json index 5847322..43ffc68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,7 @@ "@angular/cli": "^21.1.5", "@angular/compiler-cli": "^21.1.5", "@angular/language-service": "^21.1.5", + "@eslint/js": "^10.0.1", "@types/core-js": "^2.5.2", "@types/file-saver": "^2.0.1", "@types/jasmine": "^6.0.0", @@ -52,6 +53,7 @@ "@typescript-eslint/parser": "^8.56.1", "ajv": "^8.18.0", "eslint": "^10.0.2", + "globals": "^17.3.0", "jasmine-core": "~6.1.0", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.4.2", @@ -3800,6 +3802,27 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, "node_modules/@eslint/object-schema": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.2.tgz", @@ -10285,6 +10308,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/globals": { + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.3.0.tgz", + "integrity": "sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", diff --git a/package.json b/package.json index 2c071ed..e0f5587 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@angular/cli": "^21.1.5", "@angular/compiler-cli": "^21.1.5", "@angular/language-service": "^21.1.5", + "@eslint/js": "^10.0.1", "@types/core-js": "^2.5.2", "@types/file-saver": "^2.0.1", "@types/jasmine": "^6.0.0", @@ -64,6 +65,7 @@ "@typescript-eslint/parser": "^8.56.1", "ajv": "^8.18.0", "eslint": "^10.0.2", + "globals": "^17.3.0", "jasmine-core": "~6.1.0", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.4.2", diff --git a/src/app/components/manage-role/manage-role.component.ts b/src/app/components/manage-role/manage-role.component.ts index f1a372c..e697ea1 100644 --- a/src/app/components/manage-role/manage-role.component.ts +++ b/src/app/components/manage-role/manage-role.component.ts @@ -50,9 +50,7 @@ export class ManageRoleComponent implements OnInit { changeRolePermissions(change, permission) { this.postsService.setRolePermission(this.role.key, permission, change.value).subscribe(res => { - if (res['success']) { - - } else { + if (!res['success']) { this.permissions[permission] = this.permissions[permission] === 'yes' ? 'no' : 'yes'; } }, err => { diff --git a/src/app/components/recent-videos/recent-videos.component.ts b/src/app/components/recent-videos/recent-videos.component.ts index 9437890..4880d72 100644 --- a/src/app/components/recent-videos/recent-videos.component.ts +++ b/src/app/components/recent-videos/recent-videos.component.ts @@ -256,13 +256,18 @@ export class RecentVideosComponent implements OnInit { navigateToFile(file: DatabaseFile, new_tab: boolean): void { localStorage.setItem('player_navigator', this.router.url); if (file.sub_id) { - !new_tab ? this.router.navigate(['/player', {uid: file.uid, - type: file.isAudio ? 'audio' : 'video'}]) - : window.open(`/#/player;uid=${file.uid};type=${file.isAudio ? 'audio' : 'video'}`); + if (!new_tab) { + this.router.navigate(['/player', {uid: file.uid, type: file.isAudio ? 'audio' : 'video'}]); + } else { + window.open(`/#/player;uid=${file.uid};type=${file.isAudio ? 'audio' : 'video'}`); + } } else { // normal files - !new_tab ? this.router.navigate(['/player', {type: file.isAudio ? 'audio' : 'video', uid: file.uid}]) - : window.open(`/#/player;type=${file.isAudio ? 'audio' : 'video'};uid=${file.uid}`); + if (!new_tab) { + this.router.navigate(['/player', {type: file.isAudio ? 'audio' : 'video', uid: file.uid}]); + } else { + window.open(`/#/player;type=${file.isAudio ? 'audio' : 'video'};uid=${file.uid}`); + } } } diff --git a/src/app/components/see-more/see-more.component.ts b/src/app/components/see-more/see-more.component.ts index eca48a5..aec0f11 100644 --- a/src/app/components/see-more/see-more.component.ts +++ b/src/app/components/see-more/see-more.component.ts @@ -17,8 +17,8 @@ export class LinkifyPipe implements PipeTransform { private stylize(text: string): string { let stylizedText: string = ''; if (text && text.length > 0) { - for (let line of text.split("\n")) { - for (let t of line.split(" ")) { + for (const line of text.split("\n")) { + for (const t of line.split(" ")) { if (t.startsWith("http") && t.length>7) { stylizedText += `${t} `; } diff --git a/src/app/dialogs/arg-modifier-dialog/arg-modifier-dialog.component.ts b/src/app/dialogs/arg-modifier-dialog/arg-modifier-dialog.component.ts index e752363..40567da 100644 --- a/src/app/dialogs/arg-modifier-dialog/arg-modifier-dialog.component.ts +++ b/src/app/dialogs/arg-modifier-dialog/arg-modifier-dialog.component.ts @@ -143,7 +143,7 @@ export class ArgModifierDialogComponent implements OnInit, AfterViewInit { }); // converts array of arrays to one array - const singular_arg_array = [].concat.apply([], arg_arrays); + const singular_arg_array = [].concat(...arg_arrays); const args_by_key = singular_arg_array.reduce((acc, curr) => { acc[curr.key] = curr; return acc; diff --git a/src/app/main/main.component.ts b/src/app/main/main.component.ts index b383c1f..af209ef 100644 --- a/src/app/main/main.component.ts +++ b/src/app/main/main.component.ts @@ -542,7 +542,7 @@ export class MainComponent implements OnInit { // tslint:disable-next-line: max-line-length const youtubeStrRegex = /(?:http(?:s)?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'<> #]+)/; const reYT = new RegExp(youtubeStrRegex); - const ytValid = true || reYT.test(str); + const ytValid = true; if (valid && ytValid && Date.now() - this.last_url_check > 1000) { if (str !== this.last_valid_url && this.allowQualitySelect) { // get info @@ -600,7 +600,7 @@ export class MainComponent implements OnInit { const isYouTubeHost = host === 'youtube.com' || host === 'm.youtube.com' || host === 'music.youtube.com' || host === 'youtu.be'; if (!isYouTubeHost) return raw; - let videoId = ''; + let videoId: string; if (host === 'youtu.be') { videoId = u.pathname.replace(/^\/+/, '').split('/')[0] || ''; diff --git a/src/app/player/player.component.ts b/src/app/player/player.component.ts index 76d4176..4a16226 100644 --- a/src/app/player/player.component.ts +++ b/src/app/player/player.component.ts @@ -192,14 +192,9 @@ export class PlayerComponent implements OnInit, AfterViewInit, OnDestroy { parseFileNames(): void { this.playlist = []; for (let i = 0; i < this.uids.length; i++) { - let file_obj = null; - if (this.playlist_id) { - file_obj = this.file_objs[i]; - } else if (this.sub_id) { - file_obj = this.subscription['videos'][i]; - } else { - file_obj = this.db_file; - } + const file_obj = this.playlist_id ? this.file_objs[i] + : this.sub_id ? this.subscription['videos'][i] + : this.db_file; const mime_type = file_obj.isAudio ? 'audio/mp3' : 'video/mp4' diff --git a/src/app/posts.services.ts b/src/app/posts.services.ts index fc939d2..358932c 100644 --- a/src/app/posts.services.ts +++ b/src/app/posts.services.ts @@ -4,6 +4,7 @@ import { THEMES_CONFIG } from '../themes'; import { Router, ActivatedRouteSnapshot } from '@angular/router'; import { BehaviorSubject, Observable } from 'rxjs'; +import { filter, take } from 'rxjs/operators'; import { MatSnackBar } from '@angular/material/snack-bar'; import { ChangeRolePermissionsRequest, @@ -240,17 +241,13 @@ export class PostsService { } return new Promise((resolve, reject) => { - let sub; - sub = this.service_initialized.subscribe(init => { - if (init) { - if (sub) { - sub.unsubscribe(); - } + this.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => { this._canActivate(route) .then(resolve) .catch(reject); - } - }); + }); }); } @@ -391,7 +388,7 @@ export class PostsService { return this.http.post(this.path + 'getAllFiles', body, this.httpOptions); } - updateFile(uid: string, change_obj: Object) { + updateFile(uid: string, change_obj: object) { const body: UpdateFileRequest = {uid: uid, change_obj: change_obj}; return this.http.post(this.path + 'updateFile', body, this.httpOptions); } diff --git a/src/typings.d.ts b/src/typings.d.ts index ef5c7bd..388fb92 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -1,5 +1,5 @@ /* SystemJS module definition */ -declare var module: NodeModule; +declare let module: NodeModule; interface NodeModule { id: string; }