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;
}