chore: update to angular 19

This commit is contained in:
4gray committed 2025-03-03 19:32:38 +01:00
1 parent e2942f3e00
commit c147a9da7c
80 files changed
+27546 -31780

No files matched your search

+9 -14
View File
@@ -19,11 +19,12 @@
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser-esbuild",
"builder": "@angular/build:application",
"options": {
"outputPath": "dist",
"outputPath": {
"base": "dist"
},
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "src/tsconfig.app.json",
"polyfills": ["zone.js"],
"assets": [
@@ -36,9 +37,9 @@
"./node_modules/video.js/dist/video-js.css"
],
"scripts": [],
"serviceWorker": true,
"ngswConfigPath": "ngsw-config.json",
"webWorkerTsConfig": "tsconfig.worker.json"
"serviceWorker": "ngsw-config.json",
"webWorkerTsConfig": "tsconfig.worker.json",
"browser": "src/main.ts"
},
"configurations": {
"dev": {
@@ -48,8 +49,6 @@
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
@@ -64,8 +63,6 @@
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
@@ -80,8 +77,6 @@
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
@@ -92,7 +87,7 @@
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"builder": "@angular/build:dev-server",
"options": {
"buildTarget": "iptvnator:build"
},
@@ -109,7 +104,7 @@
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"builder": "@angular/build:extract-i18n",
"options": {
"buildTarget": "iptvnator:build"
}
+27267 -31414
View File
File diff suppressed because it is too large. Load diff
+150 -150
View File
@@ -1,151 +1,151 @@
{
"name": "iptvnator",
"version": "1.0.0-beta.5",
"description": "IPTV player application.",
"homepage": "https://github.com/4gray/iptvnator",
"author": {
"name": "4gray",
"email": "fourgray@proton.me"
},
"keywords": [
"angular",
"electron",
"typescript",
"m3u",
"m3u8",
"player",
"iptv",
"video",
"tv"
],
"main": "electron/main.js",
"private": true,
"scripts": {
"build:dev": "ng build -c dev",
"build:prod": "ng build -c production",
"build:web": "ng build -c web",
"serve": "ng serve -c dev",
"test": "ng test",
"test:watch": "ng test --watch",
"e2e": "npm run build:prod && npx playwright test --ui",
"e2e:ci": "npx playwright test --retries 3 --workers=1",
"version": "conventional-changelog -i CHANGELOG.md -p angular -s -r 0 && git add CHANGELOG.md",
"lint": "ng lint",
"build-pwa": "ng build -c production --base-href /iptvnator --deploy-url /iptvnator/",
"tauri": "tauri"
},
"dependencies": {
"@angular-builders/jest": "17.0.0",
"@angular/animations": "18.2.1",
"@angular/cdk": "18.2.1",
"@angular/material": "18.2.1",
"@ngrx/component-store": "18.0.2",
"@ngrx/effects": "18.0.2",
"@ngrx/entity": "18.0.2",
"@ngrx/router-store": "18.0.2",
"@ngrx/signals": "18.1.1",
"@ngrx/store": "18.0.2",
"@ngrx/store-devtools": "18.0.2",
"@ngx-pwa/local-storage": "18.0.0",
"@rx-angular/cdk": "18.0.0",
"@rx-angular/template": "18.0.0",
"@tauri-apps/api": "2.1.1",
"@tauri-apps/plugin-dialog": "2.2.0",
"@tauri-apps/plugin-fs": "2.2.0",
"@tauri-apps/plugin-http": "2.2.0",
"@tauri-apps/plugin-os": "2.2.0",
"@tauri-apps/plugin-process": "2.2.0",
"@tauri-apps/plugin-shell": "2.2.0",
"@tauri-apps/plugin-sql": "2.2.0",
"@tauri-apps/plugin-updater": "2.2.0",
"@tauri-apps/plugin-window-state": "2.2.0",
"@videojs/http-streaming": "2.15.0",
"@yangkghjh/videojs-aspect-ratio-panel": "0.0.1",
"artplayer": "5.2.1",
"axios": "1.6.2",
"date-fns": "2.29.3",
"dplayer": "1.27.1",
"epg-parser": "0.1.6",
"hls.js": "1.4.12",
"iptv-playlist-parser": "github:4gray/iptv-playlist-parser",
"lodash": "4.17.21",
"moment": "2.30.1",
"ngx-indexed-db": "19.0.0",
"ngx-skeleton-loader": "9.0.0",
"ngx-whats-new": "0.4.0",
"node-mpv": "github:4gray/Node-MPV",
"rxjs": "7.8.1",
"semver": "7.5.2",
"squirrelly": "9.1.0",
"uuid": "9.0.0",
"video.js": "7.20.3",
"videojs-contrib-quality-levels": "2.2.0",
"videojs-hls-quality-selector": "1.1.4",
"zone.js": "~0.14.10"
},
"devDependencies": {
"@angular-devkit/build-angular": "18.2.1",
"@angular-eslint/builder": "18.3.0",
"@angular-eslint/eslint-plugin": "18.3.0",
"@angular-eslint/eslint-plugin-template": "18.3.0",
"@angular-eslint/schematics": "18.3.0",
"@angular-eslint/template-parser": "18.3.0",
"@angular/cli": "18.2.1",
"@angular/common": "18.2.1",
"@angular/compiler": "18.2.1",
"@angular/compiler-cli": "18.2.1",
"@angular/core": "18.2.1",
"@angular/forms": "18.2.1",
"@angular/language-service": "18.2.1",
"@angular/platform-browser": "18.2.1",
"@angular/platform-browser-dynamic": "18.2.1",
"@angular/router": "18.2.1",
"@angular/service-worker": "18.2.1",
"@commitlint/cli": "18.4.3",
"@commitlint/config-conventional": "18.4.3",
"@eslint/eslintrc": "3.1.0",
"@eslint/js": "9.9.1",
"@ngrx/eslint-plugin": "^18.0.2",
"@ngx-translate/core": "15.0.0",
"@ngx-translate/http-loader": "8.0.0",
"@playwright/test": "1.46.1",
"@semantic-release/changelog": "6.0.3",
"@semantic-release/git": "10.0.1",
"@semantic-release/npm": "12.0.1",
"@tauri-apps/cli": "2.1.0",
"@types/dplayer": "1.25.5",
"@types/jest": "29.5.1",
"@types/mocha": "9.0.0",
"@types/node": "20.10.0",
"@types/video.js": "7.3.29",
"@types/videojs-hls-quality-selector": "1.1.0",
"@typescript-eslint/eslint-plugin": "^8.2.0",
"@typescript-eslint/eslint-plugin-tslint": "7.0.2",
"@typescript-eslint/parser": "^8.2.0",
"conventional-changelog-cli": "5.0.0",
"eslint": "^9.9.1",
"eslint-plugin-import": "2.29.1",
"globals": "15.9.0",
"husky": "5.0.9",
"jest": "29.5.0",
"jest-preset-angular": "13.1.0",
"ng-mocks": "14.13.0",
"node-polyfill-webpack-plugin": "1.1.4",
"npm-run-all": "4.1.5",
"playwright": "1.46.1",
"playwright-core": "1.46.1",
"prettier": "3.3.3",
"semantic-release": "19.0.3",
"ts-jest": "29.1.0",
"ts-node": "10.9.2",
"tslib": "2.3.0",
"typescript": "5.5.4",
"wait-on": "6.0.0"
},
"engines": {
"node": ">=18.0.0"
},
"browserslist": [
"chrome 91"
]
}
"name": "iptvnator",
"version": "1.0.0-beta.5",
"description": "IPTV player application.",
"homepage": "https://github.com/4gray/iptvnator",
"author": {
"name": "4gray",
"email": "fourgray@proton.me"
},
"keywords": [
"angular",
"electron",
"typescript",
"m3u",
"m3u8",
"player",
"iptv",
"video",
"tv"
],
"main": "electron/main.js",
"private": true,
"scripts": {
"build:dev": "ng build -c dev",
"build:prod": "ng build -c production",
"build:web": "ng build -c web",
"serve": "ng serve -c dev",
"test": "ng test",
"test:watch": "ng test --watch",
"e2e": "npm run build:prod && npx playwright test --ui",
"e2e:ci": "npx playwright test --retries 3 --workers=1",
"version": "conventional-changelog -i CHANGELOG.md -p angular -s -r 0 && git add CHANGELOG.md",
"lint": "ng lint",
"build-pwa": "ng build -c production --base-href /iptvnator --deploy-url /iptvnator/",
"tauri": "tauri"
},
"dependencies": {
"@angular-builders/jest": "17.0.0",
"@angular/animations": "19.2.0",
"@angular/cdk": "18.2.1",
"@angular/material": "18.2.1",
"@ngrx/component-store": "18.0.2",
"@ngrx/effects": "18.0.2",
"@ngrx/entity": "18.0.2",
"@ngrx/router-store": "18.0.2",
"@ngrx/signals": "18.1.1",
"@ngrx/store": "18.0.2",
"@ngrx/store-devtools": "18.0.2",
"@ngx-pwa/local-storage": "18.0.0",
"@rx-angular/cdk": "18.0.0",
"@rx-angular/template": "18.0.0",
"@tauri-apps/api": "2.1.1",
"@tauri-apps/plugin-dialog": "2.2.0",
"@tauri-apps/plugin-fs": "2.2.0",
"@tauri-apps/plugin-http": "2.2.0",
"@tauri-apps/plugin-os": "2.2.0",
"@tauri-apps/plugin-process": "2.2.0",
"@tauri-apps/plugin-shell": "2.2.0",
"@tauri-apps/plugin-sql": "2.2.0",
"@tauri-apps/plugin-updater": "2.2.0",
"@tauri-apps/plugin-window-state": "2.2.0",
"@videojs/http-streaming": "2.15.0",
"@yangkghjh/videojs-aspect-ratio-panel": "0.0.1",
"artplayer": "5.2.1",
"axios": "1.6.2",
"date-fns": "2.29.3",
"dplayer": "1.27.1",
"epg-parser": "0.1.6",
"hls.js": "1.4.12",
"iptv-playlist-parser": "github:4gray/iptv-playlist-parser",
"lodash": "4.17.21",
"moment": "2.30.1",
"ngx-indexed-db": "19.0.0",
"ngx-skeleton-loader": "10.0.0",
"ngx-whats-new": "0.4.0",
"node-mpv": "github:4gray/Node-MPV",
"rxjs": "7.8.1",
"semver": "7.5.2",
"squirrelly": "9.1.0",
"uuid": "9.0.0",
"video.js": "7.20.3",
"videojs-contrib-quality-levels": "2.2.0",
"videojs-hls-quality-selector": "1.1.4",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-eslint/builder": "18.3.0",
"@angular-eslint/eslint-plugin": "18.3.0",
"@angular-eslint/eslint-plugin-template": "18.3.0",
"@angular-eslint/schematics": "18.3.0",
"@angular-eslint/template-parser": "18.3.0",
"@angular/build": "^19.2.0",
"@angular/cli": "19.2.0",
"@angular/common": "19.2.0",
"@angular/compiler": "19.2.0",
"@angular/compiler-cli": "19.2.0",
"@angular/core": "19.2.0",
"@angular/forms": "19.2.0",
"@angular/language-service": "19.2.0",
"@angular/platform-browser": "19.2.0",
"@angular/platform-browser-dynamic": "19.2.0",
"@angular/router": "19.2.0",
"@angular/service-worker": "19.2.0",
"@commitlint/cli": "18.4.3",
"@commitlint/config-conventional": "18.4.3",
"@eslint/eslintrc": "3.1.0",
"@eslint/js": "9.9.1",
"@ngrx/eslint-plugin": "^18.0.2",
"@ngx-translate/core": "15.0.0",
"@ngx-translate/http-loader": "8.0.0",
"@playwright/test": "1.46.1",
"@semantic-release/changelog": "6.0.3",
"@semantic-release/git": "10.0.1",
"@semantic-release/npm": "12.0.1",
"@tauri-apps/cli": "2.1.0",
"@types/dplayer": "1.25.5",
"@types/jest": "29.5.1",
"@types/mocha": "9.0.0",
"@types/node": "20.10.0",
"@types/video.js": "7.3.29",
"@types/videojs-hls-quality-selector": "1.1.0",
"@typescript-eslint/eslint-plugin": "^8.2.0",
"@typescript-eslint/eslint-plugin-tslint": "7.0.2",
"@typescript-eslint/parser": "^8.2.0",
"conventional-changelog-cli": "5.0.0",
"eslint": "^9.9.1",
"eslint-plugin-import": "2.29.1",
"globals": "15.9.0",
"husky": "5.0.9",
"jest": "29.5.0",
"jest-preset-angular": "13.1.0",
"ng-mocks": "14.13.2",
"node-polyfill-webpack-plugin": "1.1.4",
"npm-run-all": "4.1.5",
"playwright": "1.46.1",
"playwright-core": "1.46.1",
"prettier": "3.3.3",
"semantic-release": "19.0.3",
"ts-jest": "29.1.0",
"ts-node": "10.9.2",
"tslib": "2.3.0",
"typescript": "5.5.4",
"wait-on": "6.0.0"
},
"engines": {
"node": ">=18.0.0"
},
"browserslist": [
"chrome 91"
]
}
+3 -3
View File
@@ -10,9 +10,9 @@ import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { provideMockStore } from '@ngrx/store/testing';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { MockModule, MockPipe, MockProviders } from 'ng-mocks';
import { MockComponent, MockModule, MockPipe, MockProviders } from 'ng-mocks';
import { NgxIndexedDBService } from 'ngx-indexed-db';
import { NgxWhatsNewModule } from 'ngx-whats-new';
import { NgxWhatsNewComponent } from 'ngx-whats-new';
import { of } from 'rxjs';
import { AppComponent } from './app.component';
import { DataService } from './services/data.service';
@@ -56,7 +56,7 @@ describe('AppComponent', () => {
],
imports: [
MockModule(MatSnackBarModule),
MockModule(NgxWhatsNewModule),
MockComponent(NgxWhatsNewComponent),
RouterTestingModule,
HttpClientTestingModule,
],
+1
View File
@@ -37,6 +37,7 @@ import { SearchResultsComponent } from './xtream-tauri/search-results/search-res
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
standalone: false
})
export class AppComponent {
/** Visibility flag of the "what is new" modal dialog */
@@ -9,11 +9,10 @@ import { parsePlaylist } from '../../state/actions';
import { DragDropFileUploadDirective } from './drag-drop-file-upload.directive';
@Component({
standalone: true,
imports: [DragDropFileUploadDirective, MatIconModule, TranslateModule],
selector: 'app-file-upload',
templateUrl: './file-upload.component.html',
styleUrls: ['./file-upload.component.scss'],
styleUrls: ['./file-upload.component.scss']
})
export class FileUploadComponent {
@Output() fileSelected = new EventEmitter<{
+3 -4
View File
@@ -7,7 +7,7 @@ import { ActivatedRoute, RouterModule } from '@angular/router';
import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { TranslateModule } from '@ngx-translate/core';
import { MockComponent, MockModule, MockProvider } from 'ng-mocks';
import { Observable } from 'rxjs';
import { DataService } from '../services/data.service';
@@ -24,13 +24,13 @@ describe('HomeComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [HomeComponent],
imports: [
HomeComponent,
CommonModule,
MockComponent(RecentPlaylistsComponent),
MockModule(MatProgressBarModule),
MockModule(MatSnackBarModule),
MockModule(TranslateModule),
TranslateModule.forRoot(),
MockModule(RouterModule),
MockModule(MatDialogModule),
],
@@ -38,7 +38,6 @@ describe('HomeComponent', () => {
MockProvider(ActivatedRoute, {
snapshot: { component: '' } as any,
}),
MockProvider(TranslateService),
MockProvider(MatSnackBar),
{ provide: DataService, useClass: ElectronServiceStub },
provideMockStore(),
+1 -2
View File
@@ -12,7 +12,6 @@ import { addPlaylist } from '../state/actions';
import { RecentPlaylistsComponent } from './recent-playlists/recent-playlists.component';
@Component({
standalone: true,
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
@@ -22,7 +21,7 @@ import { RecentPlaylistsComponent } from './recent-playlists/recent-playlists.co
NgIf,
RecentPlaylistsComponent,
TranslateModule,
],
]
})
export class HomeComponent {
/** Loading spinner state */
@@ -45,8 +45,7 @@ import { XtreamStore } from '../../../xtream-tauri/xtream.store';
CommonModule,
ReactiveFormsModule,
MatDialogModule,
],
standalone: true,
]
})
export class PlaylistInfoComponent {
isTauri = isTauri();
@@ -4,8 +4,8 @@ import { MatListModule } from '@angular/material/list';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { MockModule } from 'ng-mocks';
import { PlaylistItemComponent } from './playlist-item.component';
import { DataService } from '../../../services/data.service';
import { PlaylistItemComponent } from './playlist-item.component';
describe('PlaylistItemComponent', () => {
let component: PlaylistItemComponent;
@@ -13,12 +13,12 @@ describe('PlaylistItemComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [PlaylistItemComponent],
imports: [
PlaylistItemComponent,
MockModule(MatIconModule),
MockModule(MatListModule),
MockModule(MatTooltipModule),
MockModule(TranslateModule),
TranslateModule.forRoot(),
],
providers: [DataService],
}).compileComponents();
@@ -8,7 +8,6 @@ import {
inject,
} from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDivider } from '@angular/material/divider';
import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list';
import { MatTooltipModule } from '@angular/material/tooltip';
@@ -20,14 +19,12 @@ import {
import { PlaylistMeta } from '../../../shared/playlist-meta.type';
@Component({
standalone: true,
selector: 'app-playlist-item',
templateUrl: './playlist-item.component.html',
styleUrls: ['./playlist-item.component.scss'],
imports: [
DatePipe,
MatButtonModule,
MatDivider,
MatIconModule,
MatListModule,
MatTooltipModule,
@@ -11,7 +11,7 @@ import { provideMockActions } from '@ngrx/effects/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { MockComponent, MockModule, MockProvider } from 'ng-mocks';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { NgxSkeletonLoaderComponent } from 'ngx-skeleton-loader';
import { Observable } from 'rxjs';
import { PLAYLIST_UPDATE } from '../../../../shared/ipc-commands';
import { DataService } from '../../services/data.service';
@@ -33,19 +33,17 @@ describe('RecentPlaylistsComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
MockComponent(PlaylistItemComponent),
RecentPlaylistsComponent,
],
imports: [
RecentPlaylistsComponent,
MockComponent(PlaylistItemComponent),
MockModule(MatDialogModule),
MockModule(MatDividerModule),
MockModule(MatListModule),
MockModule(MatIconModule),
MockModule(MatInputModule),
MockModule(MatTooltipModule),
MockModule(NgxSkeletonLoaderModule),
MockModule(TranslateModule),
MockComponent(NgxSkeletonLoaderComponent),
TranslateModule.forRoot(),
],
providers: [
{ provide: DataService, useClass: ElectronServiceStub },
@@ -21,7 +21,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { NgxSkeletonLoaderComponent } from 'ngx-skeleton-loader';
import { BehaviorSubject, combineLatest, map } from 'rxjs';
import { GLOBAL_FAVORITES_PLAYLIST_ID } from '../../../../shared/constants';
import { IpcCommand } from '../../../../shared/ipc-command.class';
@@ -48,7 +48,6 @@ import { PlaylistInfoComponent } from './playlist-info/playlist-info.component';
import { PlaylistItemComponent } from './playlist-item/playlist-item.component';
@Component({
standalone: true,
selector: 'app-recent-playlists',
templateUrl: './recent-playlists.component.html',
styleUrls: ['./recent-playlists.component.scss'],
@@ -61,7 +60,7 @@ import { PlaylistItemComponent } from './playlist-item/playlist-item.component';
MatListModule,
NgFor,
NgIf,
NgxSkeletonLoaderModule,
NgxSkeletonLoaderComponent,
PlaylistItemComponent,
TranslateModule,
],
@@ -17,7 +17,6 @@ import { DataService } from '../../services/data.service';
import { addPlaylist } from '../../state/actions';
@Component({
standalone: true,
imports: [
FormsModule,
ReactiveFormsModule,
@@ -40,7 +39,7 @@ import { addPlaylist } from '../../state/actions';
width: 100%;
}
`,
],
]
})
export class StalkerPortalImportComponent {
@Output() addClicked = new EventEmitter<void>();
@@ -1,9 +1,9 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { TranslateModule, TranslatePipe } from '@ngx-translate/core';
import { TranslateModule } from '@ngx-translate/core';
import { MockModule, MockPipe } from 'ng-mocks';
import { MockModule } from 'ng-mocks';
import { TextImportComponent } from './text-import.component';
describe('TextImportComponent', () => {
@@ -12,12 +12,12 @@ describe('TextImportComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [TextImportComponent, MockPipe(TranslatePipe)],
imports: [
TextImportComponent,
MockModule(MatInputModule),
MockModule(FormsModule),
MockModule(ReactiveFormsModule),
MockModule(TranslateModule),
TranslateModule.forRoot(),
],
}).compileComponents();
}));
@@ -10,7 +10,6 @@ import { MatInputModule } from '@angular/material/input';
import { TranslateModule } from '@ngx-translate/core';
@Component({
standalone: true,
selector: 'app-text-import',
templateUrl: './text-import.component.html',
styleUrls: ['./text-import.component.scss'],
@@ -19,7 +18,7 @@ import { TranslateModule } from '@ngx-translate/core';
MatInputModule,
ReactiveFormsModule,
TranslateModule,
],
]
})
export class TextImportComponent {
@Output() textAdded = new EventEmitter<string>();
@@ -4,8 +4,8 @@ import { MatCardModule } from '@angular/material/card';
import { MatInputModule } from '@angular/material/input';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule, TranslatePipe } from '@ngx-translate/core';
import { MockModule, MockPipe } from 'ng-mocks';
import { TranslateModule } from '@ngx-translate/core';
import { MockModule } from 'ng-mocks';
import { DataService } from '../../services/data.service';
import { ElectronServiceStub } from '../../services/electron.service.stub';
import { UrlUploadComponent } from './url-upload.component';
@@ -16,13 +16,13 @@ describe('UrlUploadComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [UrlUploadComponent, MockPipe(TranslatePipe)],
imports: [
UrlUploadComponent,
MockModule(MatInputModule),
MockModule(MatCardModule),
MockModule(TranslateModule),
MockModule(FormsModule),
MockModule(ReactiveFormsModule),
TranslateModule.forRoot(),
NoopAnimationsModule,
],
providers: [
@@ -13,7 +13,6 @@ import { TranslateModule } from '@ngx-translate/core';
import { DataService } from '../../services/data.service';
@Component({
standalone: true,
selector: 'app-url-upload',
templateUrl: './url-upload.component.html',
imports: [
@@ -23,7 +22,7 @@ import { DataService } from '../../services/data.service';
NgIf,
ReactiveFormsModule,
TranslateModule,
],
]
})
export class UrlUploadComponent implements OnInit {
/** Emits url string to the parent component on form submit */
@@ -21,7 +21,6 @@ import {
import { addPlaylist } from '../../state/actions';
@Component({
standalone: true,
imports: [
FormsModule,
ReactiveFormsModule,
@@ -73,7 +72,7 @@ import { addPlaylist } from '../../state/actions';
justify-content: space-between;
}
`,
],
]
})
export class XtreamCodeImportComponent {
@Output() addClicked = new EventEmitter<void>();
@@ -14,7 +14,6 @@ import { Channel } from '../../../../../shared/channel.interface';
@Component({
selector: 'app-art-player',
standalone: true,
imports: [CommonModule],
template: `<div #artplayer class="artplayer-container"></div>`,
styles: [
@@ -29,7 +28,7 @@ import { Channel } from '../../../../../shared/channel.interface';
height: 100%;
}
`,
],
]
})
export class ArtPlayerComponent implements OnInit, OnDestroy, OnChanges {
@Input() channel: Channel;
@@ -1,4 +1,4 @@
import { NgClass, NgIf, NgOptimizedImage } from '@angular/common';
import { NgIf } from '@angular/common';
import {
Component,
ElementRef,
@@ -16,7 +16,6 @@ import { setAdjacentChannelAsActive } from '../../../state/actions';
@Component({
selector: 'app-audio-player',
standalone: true,
template: `
<div id="audio-player">
<div class="radio-logo">
@@ -81,9 +80,7 @@ import { setAdjacentChannelAsActive } from '../../../state/actions';
MatIconModule,
MatButtonModule,
NgIf,
NgClass,
FormsModule,
NgOptimizedImage,
],
})
export class AudioPlayerComponent implements OnChanges {
@@ -14,7 +14,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { TranslateModule } from '@ngx-translate/core';
import { MockModule, MockPipes, MockProviders } from 'ng-mocks';
import { NgxIndexedDBService } from 'ngx-indexed-db';
import { Observable } from 'rxjs';
@@ -57,7 +57,7 @@ describe('ChannelListContainerComponent', () => {
MockModule(MatSnackBarModule),
MockModule(MatTooltipModule),
MockModule(ScrollingModule),
MockModule(TranslateModule),
TranslateModule.forRoot(),
NoopAnimationsModule,
RouterTestingModule,
],
@@ -65,7 +65,7 @@ describe('ChannelListContainerComponent', () => {
{ provide: DataService, useClass: ElectronServiceStub },
{ provide: MatSnackBar, useClass: MatSnackBarStub },
MockPipes(FilterPipe),
MockProviders(NgxIndexedDBService, TranslateService),
MockProviders(NgxIndexedDBService),
provideMockActions(actions$),
provideMockStore(),
],
@@ -83,8 +83,8 @@ describe('ChannelListContainerComponent', () => {
...element,
http: {
...element.http,
origin: '' // Add the missing 'origin' property
}
origin: '', // Add the missing 'origin' property
},
})
);
@@ -36,7 +36,6 @@ import {
import { ChannelListItemComponent } from './channel-list-item/channel-list-item.component';
@Component({
standalone: true,
selector: 'app-channel-list-container',
templateUrl: './channel-list-container.component.html',
styleUrls: ['./channel-list-container.component.scss'],
@@ -56,7 +55,7 @@ import { ChannelListItemComponent } from './channel-list-item/channel-list-item.
ScrollingModule,
TitleCasePipe,
TranslateModule,
],
]
})
export class ChannelListContainerComponent {
/**
@@ -9,7 +9,6 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
@Component({
standalone: true,
selector: 'app-channel-list-item',
styleUrls: ['./channel-list-item.component.scss'],
template: `<mat-list-item
@@ -58,7 +57,7 @@ import { TranslateModule } from '@ngx-translate/core';
MatListModule,
MatTooltipModule,
TranslateModule,
],
]
})
export class ChannelListItemComponent {
@Input() isDraggable = false;
@@ -13,7 +13,6 @@ import { Channel } from '../../../../../shared/channel.interface';
@Component({
selector: 'app-d-player',
standalone: true,
imports: [CommonModule],
template: `<div #dplayer class="dplayer-container"></div>`,
styles: [
@@ -23,7 +22,7 @@ import { Channel } from '../../../../../shared/channel.interface';
height: calc(100vh - 64px);
}
`,
],
]
})
export class DPlayerComponent implements OnInit, OnDestroy, OnChanges {
@Input() channel: Channel;
@@ -15,7 +15,7 @@ describe('EpgItemDescriptionComponent', () => {
imports: [
EpgItemDescriptionComponent,
MockModule(MatDialogModule),
MockModule(TranslateModule),
TranslateModule.forRoot(),
],
providers: [
{
@@ -6,11 +6,10 @@ import { TranslateModule } from '@ngx-translate/core';
import { EpgProgram } from './../../../models/epg-program.model';
@Component({
standalone: true,
selector: 'app-epg-item-description',
templateUrl: './epg-item-description.component.html',
styleUrls: ['./epg-item-description.component.scss'],
imports: [MatButtonModule, MatDialogModule, NgIf, TranslateModule],
imports: [MatButtonModule, MatDialogModule, NgIf, TranslateModule]
})
export class EpgItemDescriptionComponent {
/** EPG program object */
@@ -5,7 +5,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import * as moment from 'moment';
import moment from 'moment';
import { MockModule, MockPipe } from 'ng-mocks';
import { MomentDatePipe } from './../../../../shared/pipes/moment-date.pipe';
import { EpgProgram } from './../../../models/epg-program.model';
@@ -69,7 +69,7 @@ describe('EpgListItemComponent', () => {
MockModule(MatListModule),
MockModule(MatIconModule),
MockModule(MatTooltipModule),
MockModule(TranslateModule),
TranslateModule.forRoot(),
],
}).compileComponents();
}));
@@ -8,11 +8,10 @@ import { EpgProgram } from '../../../models/epg-program.model';
import { EpgItemDescriptionComponent } from './../epg-item-description/epg-item-description.component';
@Component({
standalone: true,
imports: [MomentDatePipe, MatIconModule, MatTooltipModule, TranslateModule],
selector: 'app-epg-list-item',
templateUrl: './epg-list-item.component.html',
styleUrls: ['./epg-list-item.component.scss'],
styleUrls: ['./epg-list-item.component.scss']
})
export class EpgListItemComponent {
/** EPG Program to render */
@@ -7,7 +7,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { TranslatePipe } from '@ngx-translate/core';
import { TranslateModule } from '@ngx-translate/core';
import { MockComponent, MockModule, MockPipe, MockProvider } from 'ng-mocks';
import { BehaviorSubject, Observable } from 'rxjs';
import { Channel } from '../../../../../shared/channel.interface';
@@ -114,13 +114,11 @@ describe('EpgListComponent', () => {
};
TestBed.configureTestingModule({
declarations: [
imports: [
EpgListComponent,
MockPipe(MomentDatePipe),
MockPipe(TranslatePipe),
TranslateModule.forRoot(),
MockComponent(EpgListItemComponent),
],
imports: [
MockModule(MatIconModule),
MockModule(MatTooltipModule),
MockModule(MatListModule),
@@ -33,7 +33,6 @@ export interface EpgData {
const DATE_FORMAT = 'YYYY-MM-DD';
@Component({
standalone: true,
imports: [
AsyncPipe,
EpgListItemComponent,
@@ -48,7 +47,7 @@ const DATE_FORMAT = 'YYYY-MM-DD';
],
selector: 'app-epg-list',
templateUrl: './epg-list.component.html',
styleUrls: ['./epg-list.component.scss'],
styleUrls: ['./epg-list.component.scss']
})
export class EpgListComponent {
/** Channel info in EPG format */
@@ -1,7 +1,6 @@
import { SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslatePipe } from '@ngx-translate/core';
import { MockPipe } from 'ng-mocks';
import { TranslateModule } from '@ngx-translate/core';
import { DataService } from '../../../services/data.service';
import { HtmlVideoPlayerComponent } from './html-video-player.component';
@@ -28,7 +27,7 @@ describe('HtmlVideoPlayerComponent', () => {
};
TestBed.configureTestingModule({
declarations: [HtmlVideoPlayerComponent, MockPipe(TranslatePipe)],
imports: [HtmlVideoPlayerComponent, TranslateModule.forRoot()],
providers: [{ provide: DataService, useValue: dataServiceMock }],
}).compileComponents();
}));
@@ -6,11 +6,10 @@ import { MomentDatePipe } from '../../../shared/pipes/moment-date.pipe';
import { EpgProgram } from '../../models/epg-program.model';
@Component({
standalone: true,
imports: [MomentDatePipe, NgStyle],
selector: 'app-info-overlay',
templateUrl: './info-overlay.component.html',
styleUrls: ['./info-overlay.component.scss'],
styleUrls: ['./info-overlay.component.scss']
})
export class InfoOverlayComponent implements OnChanges {
/** Active channel */
@@ -39,7 +39,6 @@ interface EnrichedChannel extends EpgChannel {
}
@Component({
standalone: true,
imports: [
CommonModule,
MatButtonModule,
@@ -51,7 +50,7 @@ interface EnrichedChannel extends EpgChannel {
selector: 'app-multi-epg-container',
templateUrl: './multi-epg-container.component.html',
styleUrls: ['./multi-epg-container.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MultiEpgContainerComponent
implements OnInit, AfterViewInit, OnDestroy
@@ -15,7 +15,6 @@ import { selectPlaylistTitle } from '../../../../state/selectors';
import { SidebarView } from '../video-player.component';
import { ChannelListContainerComponent } from './../../channel-list-container/channel-list-container.component';
@Component({
standalone: true,
selector: 'app-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.scss'],
@@ -30,7 +29,7 @@ import { ChannelListContainerComponent } from './../../channel-list-container/ch
RecentPlaylistsComponent,
TranslateModule,
RouterLink,
],
]
})
export class SidebarComponent {
@Input() channels: Channel[] = [];
@@ -17,7 +17,6 @@ import {
} from '../../../../state/selectors';
@Component({
standalone: true,
imports: [
AsyncPipe,
MatButton,
@@ -30,7 +29,7 @@ import {
],
selector: 'app-toolbar',
templateUrl: './toolbar.component.html',
styleUrls: ['./toolbar.component.scss'],
styleUrls: ['./toolbar.component.scss']
})
export class ToolbarComponent {
@Input() activeChannel!: Channel;
@@ -8,8 +8,8 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { TranslatePipe } from '@ngx-translate/core';
import { MockComponent, MockModule, MockPipe, MockProviders } from 'ng-mocks';
import { TranslateModule } from '@ngx-translate/core';
import { MockComponent, MockModule, MockProviders } from 'ng-mocks';
import { DataService } from '../../../services/data.service';
import { ElectronServiceStub } from '../../../services/electron.service.stub';
import { VideoPlayer } from '../../../settings/settings.interface';
@@ -24,6 +24,7 @@ import { CommonModule } from '@angular/common';
import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { NgxIndexedDBService } from 'ngx-indexed-db';
import { NgxSkeletonLoaderComponent } from 'ngx-skeleton-loader';
import { Observable, of } from 'rxjs';
import { PlaylistsService } from '../../../services/playlists.service';
import { initialState } from '../../../state/state';
@@ -40,17 +41,6 @@ describe('VideoPlayerComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
MockComponent(EpgListComponent),
MockComponent(HtmlVideoPlayerComponent),
MockComponent(VjsPlayerComponent),
MockComponent(VideoPlayerComponent),
MockComponent(ChannelListContainerComponent),
MockComponent(InfoOverlayComponent),
VideoPlayerComponent,
MockPipe(TranslatePipe),
CommonModule,
],
providers: [
{ provide: MatSnackBar, useClass: MatSnackBarStub },
{ provide: DataService, useClass: ElectronServiceStub },
@@ -70,12 +60,22 @@ describe('VideoPlayerComponent', () => {
MockProviders(NgxIndexedDBService, PlaylistsService),
],
imports: [
MockComponent(EpgListComponent),
MockComponent(HtmlVideoPlayerComponent),
MockComponent(VjsPlayerComponent),
MockComponent(VideoPlayerComponent),
MockComponent(ChannelListContainerComponent),
MockComponent(InfoOverlayComponent),
VideoPlayerComponent,
CommonModule,
TranslateModule.forRoot(),
MockModule(MatSidenavModule),
MockModule(MatIconModule),
MockModule(MatToolbarModule),
MockModule(MatTooltipModule),
MockModule(RouterTestingModule),
MockModule(MatDividerModule),
MockComponent(NgxSkeletonLoaderComponent),
],
}).compileComponents();
}));
@@ -55,7 +55,6 @@ export const COMPONENT_OVERLAY_REF = new InjectionToken(
);
@Component({
standalone: true,
imports: [
AsyncPipe,
AudioPlayerComponent,
@@ -72,7 +71,7 @@ export const COMPONENT_OVERLAY_REF = new InjectionToken(
ArtPlayerComponent,
],
templateUrl: './video-player.component.html',
styleUrls: ['./video-player.component.scss'],
styleUrls: ['./video-player.component.scss']
})
export class VideoPlayerComponent implements OnInit, OnDestroy {
/** Active selected channel */
@@ -9,11 +9,10 @@ import { EpgItemDescriptionComponent } from '../../player/components/epg-list/ep
import { EpgItem } from '../../xtream/epg-item.interface';
@Component({
standalone: true,
selector: 'app-epg-view',
templateUrl: './epg-view.component.html',
imports: [DatePipe, MatIconButton, MatIcon, MatListModule, TranslateModule],
styleUrls: ['./epg-view.component.scss'],
styleUrls: ['./epg-view.component.scss']
})
export class EpgViewComponent {
@Input() epgItems: EpgItem[];
@@ -22,7 +22,6 @@ import { EpgViewComponent } from '../epg-view/epg-view.component';
import { WebPlayerViewComponent } from '../web-player-view/web-player-view.component';
@Component({
standalone: true,
selector: 'app-live-stream-layout',
templateUrl: './live-stream-layout.component.html',
styleUrls: ['./live-stream-layout.component.scss'],
@@ -39,7 +38,7 @@ import { WebPlayerViewComponent } from '../web-player-view/web-player-view.compo
WebPlayerViewComponent,
TranslateModule,
],
changeDetection: ChangeDetectionStrategy.OnPush,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LiveStreamLayoutComponent {
@Input({ required: true }) channels: XtreamItem[];
@@ -18,7 +18,6 @@ import { Settings, VideoPlayer } from '../../settings/settings.interface';
import { STORE_KEY } from '../../shared/enums/store-keys.enum';
@Component({
standalone: true,
selector: 'app-web-player-view',
templateUrl: './web-player-view.component.html',
styleUrls: ['./web-player-view.component.scss'],
@@ -29,7 +28,7 @@ import { STORE_KEY } from '../../shared/enums/store-keys.enum';
DPlayerComponent,
ArtPlayerComponent,
],
encapsulation: ViewEncapsulation.None,
encapsulation: ViewEncapsulation.None
})
export class WebPlayerViewComponent {
storage = inject(StorageMap);
+3 -1
View File
@@ -1,5 +1,6 @@
import { inject, TestBed } from '@angular/core/testing';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { TranslateModule } from '@ngx-translate/core';
import { MockComponent, MockModule } from 'ng-mocks';
import { EMPTY } from 'rxjs';
import { ConfirmDialogData } from '../shared/components/confirm-dialog/confirm-dialog-data.interface';
@@ -11,8 +12,9 @@ describe('Service: Dialog', () => {
TestBed.configureTestingModule({
providers: [DialogService, MatDialog],
imports: [
MockModule(MatDialogModule),
MockComponent(ConfirmDialogComponent),
MockModule(MatDialogModule),
TranslateModule.forRoot(),
],
});
});
+6 -13
View File
@@ -18,15 +18,10 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { provideMockStore } from '@ngrx/store/testing';
import {
TranslateModule,
TranslatePipe,
TranslateService,
} from '@ngx-translate/core';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import {
MockComponent,
MockModule,
MockPipe,
MockProvider,
MockProviders,
} from 'ng-mocks';
@@ -39,6 +34,7 @@ import { Theme } from './theme.enum';
import { signal } from '@angular/core';
import { NgxIndexedDBService } from 'ngx-indexed-db';
import { NgxWhatsNewModule } from 'ngx-whats-new';
import { of } from 'rxjs';
import { SETTINGS_UPDATE } from '../../../shared/ipc-commands';
import { DialogService } from '../services/dialog.service';
@@ -100,14 +96,8 @@ describe('SettingsComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
SettingsComponent,
MockComponent(HeaderComponent),
MockPipe(TranslatePipe),
],
providers: [
UntypedFormBuilder,
MockProvider(TranslateService),
{ provide: SettingsStore, useClass: MockSettingsStore },
MockProvider(EpgService),
MockProvider(DialogService),
@@ -122,6 +112,8 @@ describe('SettingsComponent', () => {
MockProviders(NgxIndexedDBService, PlaylistsService),
],
imports: [
SettingsComponent,
MockComponent(HeaderComponent),
HttpClientTestingModule,
FormsModule,
MockModule(MatSelectModule),
@@ -134,7 +126,8 @@ describe('SettingsComponent', () => {
MockModule(MatFormFieldModule),
MockModule(MatCheckboxModule),
MockModule(MatDividerModule),
MockModule(TranslateModule),
TranslateModule.forRoot(),
NgxWhatsNewModule,
],
}).compileComponents();
}));
+1 -2
View File
@@ -56,7 +56,6 @@ import { Theme } from './theme.enum';
@Component({
templateUrl: './settings.component.html',
styleUrls: ['./settings.component.scss'],
standalone: true,
imports: [
CommonModule,
FormsModule,
@@ -71,7 +70,7 @@ import { Theme } from './theme.enum';
ReactiveFormsModule,
TranslateModule,
MatDialogModule,
],
]
})
export class SettingsComponent implements OnInit {
@Input() isDialog = false;
@@ -4,7 +4,6 @@ import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
@Component({
standalone: true,
imports: [MatIconModule, TranslateModule],
template: `
<div mat-dialog-content>
@@ -58,7 +57,7 @@ import { TranslateModule } from '@ngx-translate/core';
font-size: 32px;
}
`,
],
]
})
export class AboutDialogComponent {
constructor(@Inject(MAT_DIALOG_DATA) public appVersion: string) {}
@@ -21,7 +21,6 @@ import { parsePlaylist } from '../../../state/actions';
export type PlaylistType = 'xtream' | 'url' | 'text' | 'file' | 'stalker';
@Component({
standalone: true,
imports: [
MatButtonModule,
MatDialogModule,
@@ -33,7 +32,7 @@ export type PlaylistType = 'xtream' | 'url' | 'text' | 'file' | 'stalker';
UrlUploadComponent,
],
selector: 'app-add-playlist',
templateUrl: './add-playlist-dialog.component.html',
templateUrl: './add-playlist-dialog.component.html'
})
export class AddPlaylistDialogComponent {
playlistType!: PlaylistType;
@@ -5,7 +5,6 @@ import { TranslateModule } from '@ngx-translate/core';
import { ConfirmDialogData } from './confirm-dialog-data.interface';
@Component({
imports: [MatButtonModule, MatDialogModule, TranslateModule],
standalone: true,
template: `
<h2 mat-dialog-title>
{{ dialogData.title }}
@@ -21,7 +20,7 @@ import { ConfirmDialogData } from './confirm-dialog-data.interface';
{{ dialogData?.confirmLabel || 'YES' | translate }}
</button>
</mat-dialog-actions>
`,
`
})
export class ConfirmDialogComponent {
/** Contains meta information to show in the dialog */
@@ -8,7 +8,6 @@ import { TranslateModule } from '@ngx-translate/core';
import { PortalStore } from '../../../xtream/portal.store';
@Component({
standalone: true,
template: `
<h2 mat-dialog-title>{{ 'INFORMATION' | translate }}</h2>
<mat-dialog-content class="mat-typography">
@@ -66,7 +65,7 @@ import { PortalStore } from '../../../xtream/portal.store';
MatIconModule,
RouterLink,
TranslateModule,
],
]
})
export class ExternalPlayerInfoDialogComponent {
portalStore = inject(PortalStore);
@@ -1,4 +1,4 @@
import { AsyncPipe, NgFor, NgIf } from '@angular/common';
import { AsyncPipe, NgIf } from '@angular/common';
import { Component, Input, OnInit, effect } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
@@ -27,7 +27,6 @@ import {
} from '../add-playlist/add-playlist-dialog.component';
@Component({
standalone: true,
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
@@ -41,7 +40,6 @@ import {
MatToolbarModule,
MatTooltipModule,
NgIf,
NgFor,
FormsModule,
NgxWhatsNewModule,
ReactiveFormsModule,
@@ -9,11 +9,10 @@ import {
} from '../../services/mpv-player.service';
@Component({
standalone: true,
imports: [CommonModule, MatIconModule, MatButtonModule],
selector: 'app-mpv-player-bar',
templateUrl: './mpv-player-bar.component.html',
styleUrls: ['./mpv-player-bar.component.scss'],
styleUrls: ['./mpv-player-bar.component.scss']
})
export class MpvPlayerBarComponent {
activeProcesses$: Observable<MpvProcess[]>;
@@ -8,10 +8,9 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { PlaylistsService } from '../../services/playlists.service';
@Component({
standalone: true,
selector: 'app-favorites-button',
templateUrl: './favorites-button.component.html',
imports: [MatButtonModule, MatIconModule, NgIf, TranslateModule],
imports: [MatButtonModule, MatIconModule, NgIf, TranslateModule]
})
export class FavoritesButtonComponent implements OnInit {
private playlistService = inject(PlaylistsService);
@@ -50,7 +50,6 @@ import { StalkerSeriesViewComponent } from './stalker-series-view/stalker-series
selector: 'app-stalker-main-container',
templateUrl: './stalker-main-container.component.html',
styleUrl: './stalker-main-container.component.scss',
standalone: true,
imports: [
AsyncPipe,
CategoryContentViewComponent,
@@ -62,7 +61,7 @@ import { StalkerSeriesViewComponent } from './stalker-series-view/stalker-series
StalkerSeriesViewComponent,
TranslateModule,
VodDetailsComponent,
],
]
})
export class StalkerMainContainerComponent implements OnInit {
breadcrumbs: Breadcrumb[] = [];
@@ -1,4 +1,4 @@
import { NgFor, NgIf, NgOptimizedImage } from '@angular/common';
import { NgIf, NgOptimizedImage } from '@angular/common';
import { Component, Signal, input, output } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDividerModule } from '@angular/material/divider';
@@ -28,13 +28,11 @@ function extractNumericValue(str: string) {
selector: 'app-stalker-series-view',
templateUrl: './stalker-series-view.component.html',
styleUrls: ['../../xtream/detail-view.scss'],
standalone: true,
imports: [
FavoritesButtonComponent,
MatButtonModule,
MatDividerModule,
NgIf,
NgFor,
NgOptimizedImage,
TranslateModule,
],
@@ -12,7 +12,6 @@ import { XtreamAccountInfo } from './account-info.interface';
@Component({
selector: 'app-account-info',
standalone: true,
imports: [
CommonModule,
MatButton,
@@ -138,7 +137,7 @@ import { XtreamAccountInfo } from './account-info.interface';
</button>
</mat-dialog-actions>
`,
styleUrl: './account-info.component.scss',
styleUrl: './account-info.component.scss'
})
export class AccountInfoComponent {
accountInfo: XtreamAccountInfo;
@@ -12,7 +12,6 @@ import { XtreamStore } from '../xtream.store';
selector: 'app-category-content-view',
templateUrl: './category-content-view.component.html',
styleUrls: ['./category-content-view.component.scss'],
standalone: true,
imports: [
MatCardModule,
MatIcon,
@@ -20,7 +19,7 @@ import { XtreamStore } from '../xtream.store';
MatTooltip,
NgOptimizedImage,
TranslateModule,
],
]
})
export class CategoryContentViewComponent {
private readonly activatedRoute = inject(ActivatedRoute);
@@ -16,7 +16,6 @@ import { XtreamStore } from '../xtream.store';
@Component({
selector: 'app-category-view',
standalone: true,
imports: [
MatCardModule,
MatListModule,
@@ -26,7 +25,7 @@ import { XtreamStore } from '../xtream.store';
],
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './category-view.component.html',
styleUrls: ['./category-view.component.scss'],
styleUrls: ['./category-view.component.scss']
})
export class CategoryViewComponent {
@Output() categoryClicked = new EventEmitter<XtreamCategory>();
@@ -16,7 +16,6 @@ import { XtreamStore } from '../xtream.store';
@Component({
selector: 'app-favorites',
standalone: true,
imports: [
AsyncPipe,
DatePipe,
@@ -29,7 +28,7 @@ import { XtreamStore } from '../xtream.store';
TranslateModule,
],
templateUrl: './favorites.component.html',
styleUrl: './favorites.component.scss',
styleUrl: './favorites.component.scss'
})
export class FavoritesComponent implements OnInit {
private favoritesService = inject(FavoritesService);
@@ -23,7 +23,6 @@ import { FavoritesService } from '../services/favorites.service';
import { XtreamStore } from '../xtream.store';
@Component({
standalone: true,
selector: 'app-live-stream-layout',
templateUrl: './live-stream-layout.component.html',
styleUrls: ['./live-stream-layout.component.scss', '../sidebar.scss'],
@@ -40,7 +39,7 @@ import { XtreamStore } from '../xtream.store';
TranslateModule,
WebPlayerViewComponent,
],
changeDetection: ChangeDetectionStrategy.OnPush,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LiveStreamLayoutComponent implements OnInit {
private favoritesService = inject(FavoritesService);
@@ -4,7 +4,6 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
@Component({
selector: 'app-loading-overlay',
standalone: true,
imports: [MatProgressBarModule, CommonModule],
template: `
<div class="overlay">
@@ -48,7 +47,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
}
}
`,
],
]
})
export class LoadingOverlayComponent {
current = input(0);
@@ -15,7 +15,6 @@ import { XtreamStore } from '../xtream.store';
@Component({
selector: 'app-navigation',
standalone: true,
imports: [
MatListModule,
MatIcon,
@@ -26,7 +25,7 @@ import { XtreamStore } from '../xtream.store';
MatTooltipModule,
],
templateUrl: './navigation.component.html',
styleUrl: './navigation.component.scss',
styleUrl: './navigation.component.scss'
})
export class NavigationComponent {
private readonly dialog = inject(MatDialog);
@@ -16,7 +16,6 @@ export interface PlayerDialogData {
@Component({
templateUrl: './player-dialog.component.html',
standalone: true,
imports: [
ClipboardModule,
MatButtonModule,
@@ -28,7 +27,7 @@ export interface PlayerDialogData {
WebPlayerViewComponent,
],
styleUrl: './player-dialog.component.scss',
encapsulation: ViewEncapsulation.None,
encapsulation: ViewEncapsulation.None
})
export class PlayerDialogComponent {
title: string;
@@ -12,11 +12,10 @@ import * as PlaylistActions from '../../state/actions';
import { selectCurrentPlaylist } from '../../state/selectors';
@Component({
standalone: true,
selector: 'app-playlist-error-view',
templateUrl: './playlist-error-view.component.html',
styleUrls: ['./playlist-error-view.component.scss'],
imports: [MatButtonModule, MatIconModule, RouterLink, TranslateModule],
imports: [MatButtonModule, MatIconModule, RouterLink, TranslateModule]
})
export class PlaylistErrorViewComponent {
private databaseService = inject(DatabaseService);
@@ -40,7 +40,6 @@ interface EpgProgram {
@Component({
selector: 'app-portal-channels-list',
standalone: true,
templateUrl: './portal-channels-list.component.html',
styleUrls: ['./portal-channels-list.component.scss'],
imports: [
@@ -56,7 +55,7 @@ interface EpgProgram {
MatInputModule,
TranslateModule,
MatTooltipModule,
],
]
})
export class PortalChannelsListComponent implements AfterViewInit {
@Output() playClicked = new EventEmitter<any>();
@@ -10,7 +10,6 @@ import { XtreamStore } from '../xtream.store';
@Component({
selector: 'app-recently-viewed',
standalone: true,
imports: [
CommonModule,
MatCardModule,
@@ -20,7 +19,7 @@ import { XtreamStore } from '../xtream.store';
MatIconButton,
],
templateUrl: './recently-viewed.component.html',
styleUrl: './recently-viewed.component.scss',
styleUrl: './recently-viewed.component.scss'
})
export class RecentlyViewedComponent {
private xtreamStore = inject(XtreamStore);
@@ -34,7 +34,6 @@ interface SearchResultsData {
@Component({
selector: 'app-search-results',
standalone: true,
imports: [
MatIconButton,
MatCardModule,
@@ -48,7 +47,7 @@ interface SearchResultsData {
],
providers: [],
templateUrl: './search-results.component.html',
styleUrls: ['./search-results.component.scss'],
styleUrls: ['./search-results.component.scss']
})
export class SearchResultsComponent implements AfterViewInit, OnDestroy {
@ViewChild('searchInput') searchInput!: ElementRef;
@@ -9,8 +9,7 @@ import { XtreamSerieEpisode } from '../../../../shared/xtream-serie-details.inte
selector: 'app-season-container',
templateUrl: './season-container.component.html',
styleUrls: ['./season-container.component.scss'],
standalone: true,
imports: [KeyValuePipe, MatCardModule, MatIcon, MatButton],
imports: [KeyValuePipe, MatCardModule, MatIcon, MatButton]
})
export class SeasonContainerComponent {
@Input({ required: true }) seasons: Record<string, XtreamSerieEpisode[]>;
@@ -15,8 +15,7 @@ import { XtreamStore } from '../xtream.store';
selector: 'app-serial-details',
templateUrl: './serial-details.component.html',
styleUrls: ['../detail-view.scss'],
standalone: true,
imports: [MatButton, MatIcon, SeasonContainerComponent, TranslateModule],
imports: [MatButton, MatIcon, SeasonContainerComponent, TranslateModule]
})
export class SerialDetailsComponent {
private readonly store = inject(Store);
@@ -15,14 +15,13 @@ import { SafePipe } from './safe.pipe';
@Component({
templateUrl: './vod-details.component.html',
styleUrls: ['../detail-view.scss'],
standalone: true,
imports: [
MatButton,
MatIcon,
SafePipe,
TranslateModule,
MatProgressSpinnerModule,
],
]
})
export class VodDetailsComponent implements OnInit, OnDestroy {
private settingsStore = inject(SettingsStore);
@@ -13,7 +13,6 @@ import { XtreamStore } from './xtream.store';
selector: 'app-xtream-main-container',
templateUrl: './xtream-main-container.component.html',
styleUrls: ['./xtream-main-container.component.scss', './sidebar.scss'],
standalone: true,
imports: [
CategoryViewComponent,
TranslateModule,
@@ -21,7 +20,7 @@ import { XtreamStore } from './xtream.store';
MpvPlayerBarComponent,
MatIcon,
MatIconButton,
],
]
})
export class XtreamMainContainerComponent {
readonly xtreamStore = inject(XtreamStore);
@@ -10,14 +10,13 @@ import { XtreamStore } from '../xtream.store';
@Component({
templateUrl: './xtream-shell.component.html',
styleUrls: ['./xtream-shell.component.scss'],
standalone: true,
imports: [
LoadingOverlayComponent,
NavigationComponent,
RouterOutlet,
TranslateModule,
],
providers: [XtreamStore],
providers: [XtreamStore]
})
export class XtreamShellComponent {
private readonly route = inject(ActivatedRoute);
@@ -14,7 +14,6 @@ import { PortalStore } from '../portal.store';
selector: 'app-category-content-view',
templateUrl: './category-content-view.component.html',
styleUrls: ['./category-content-view.component.scss'],
standalone: true,
imports: [
FilterPipe,
SortPipe,
@@ -24,7 +23,7 @@ import { PortalStore } from '../portal.store';
NgOptimizedImage,
PlaylistErrorViewComponent,
TranslateModule,
],
]
})
export class CategoryContentViewComponent {
@Input({ required: true }) items: XtreamItem[];
@@ -9,7 +9,6 @@ import { PortalStore } from '../portal.store';
@Component({
selector: 'app-category-view',
standalone: true,
template: `
@if (items?.length > 0) {
@for (
@@ -60,7 +59,7 @@ import { PortalStore } from '../portal.store';
MatIconModule,
PlaylistErrorViewComponent,
TranslateModule,
],
]
})
export class CategoryViewComponent {
@Input({ required: true }) items: XtreamCategory[];
@@ -1,4 +1,4 @@
import { AsyncPipe, NgFor, NgIf } from '@angular/common';
import { NgFor, NgIf } from '@angular/common';
import {
Component,
EventEmitter,
@@ -43,7 +43,6 @@ import { PortalStore } from '../portal.store';
selector: 'app-navigation-bar',
templateUrl: './navigation-bar.component.html',
styleUrls: ['./navigation-bar.component.scss'],
standalone: true,
imports: [
FormsModule,
MatButtonModule,
@@ -58,7 +57,6 @@ import { PortalStore } from '../portal.store';
MatMenuModule,
MatCheckboxModule,
MatTooltipModule,
AsyncPipe,
],
})
export class NavigationBarComponent implements OnChanges {
@@ -1,5 +1,4 @@
import { ClipboardModule } from '@angular/cdk/clipboard';
import { NgIf } from '@angular/common';
import { Component, Inject, ViewEncapsulation } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
@@ -17,7 +16,6 @@ export interface PlayerDialogData {
@Component({
templateUrl: './player-dialog.component.html',
standalone: true,
imports: [
ClipboardModule,
MatButtonModule,
@@ -25,7 +23,6 @@ export interface PlayerDialogData {
MatFormFieldModule,
MatIconModule,
MatInputModule,
NgIf,
TranslateModule,
WebPlayerViewComponent,
],
@@ -11,11 +11,10 @@ import * as PlaylistActions from '../../state/actions';
import { selectCurrentPlaylist } from '../../state/selectors';
@Component({
standalone: true,
selector: 'app-playlist-error-view',
templateUrl: './playlist-error-view.component.html',
styleUrls: ['./playlist-error-view.component.scss'],
imports: [MatButtonModule, MatIconModule, RouterLink, TranslateModule],
imports: [MatButtonModule, MatIconModule, RouterLink, TranslateModule]
})
export class PlaylistErrorViewComponent {
dialog = inject(MatDialog);
@@ -1,4 +1,4 @@
import { JsonPipe, KeyValuePipe, NgFor, NgIf } from '@angular/common';
import { KeyValuePipe, NgFor, NgIf } from '@angular/common';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { XtreamSerieEpisode } from '../../../../shared/xtream-serie-details.interface';
@@ -7,8 +7,7 @@ import { XtreamSerieEpisode } from '../../../../shared/xtream-serie-details.inte
selector: 'app-season-container',
templateUrl: './season-container.component.html',
styleUrls: ['./season-container.component.scss'],
standalone: true,
imports: [JsonPipe, KeyValuePipe, NgFor, MatCardModule, NgIf],
imports: [KeyValuePipe, NgFor, MatCardModule, NgIf],
})
export class SeasonContainerComponent {
@Input({ required: true }) seasons: Record<string, XtreamSerieEpisode[]>;
@@ -1,4 +1,4 @@
import { JsonPipe, NgIf } from '@angular/common';
import { NgIf } from '@angular/common';
import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
@@ -11,21 +11,17 @@ import {
} from '../../../../shared/xtream-serie-details.interface';
import { PlaylistsService } from '../../services/playlists.service';
import { selectCurrentPlaylist } from '../../state/selectors';
import { PlayerDialogComponent } from '../player-dialog/player-dialog.component';
import { SeasonContainerComponent } from '../season-container/season-container.component';
@Component({
selector: 'app-serial-details',
templateUrl: './serial-details.component.html',
styleUrls: ['../detail-view.scss'],
standalone: true,
imports: [
JsonPipe,
MatButtonModule,
MatIconModule,
NgIf,
SeasonContainerComponent,
PlayerDialogComponent,
TranslateModule,
],
})
@@ -20,7 +20,6 @@ import { SafePipe } from './safe.pipe';
selector: 'app-vod-details',
templateUrl: './vod-details.component.html',
styleUrls: ['../detail-view.scss'],
standalone: true,
imports: [
MatButtonModule,
MatIcon,
@@ -29,7 +28,7 @@ import { SafePipe } from './safe.pipe';
SafePipe,
TranslateModule,
MatProgressSpinnerModule,
],
]
})
export class VodDetailsComponent implements OnInit {
@Input({ required: true }) item: XtreamVodDetails;
@@ -93,7 +93,6 @@ type LayoutView =
selector: 'app-xtream-main-container',
templateUrl: './xtream-main-container.component.html',
styleUrls: ['./xtream-main-container.component.scss'],
standalone: true,
imports: [
MatButtonToggleModule,
CategoryViewComponent,
@@ -109,7 +108,7 @@ type LayoutView =
PlaylistErrorViewComponent,
TranslateModule,
LiveStreamLayoutComponent,
],
]
})
export class XtreamMainContainerComponent implements OnInit {
private readonly dataService = inject(DataService);
+1
View File
@@ -3,6 +3,7 @@
"compilerOptions": {
"module": "es2020",
"outDir": "./dist/out-tsc",
"esModuleInterop": true,
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",