diff --git a/apps/web/src/app/app.routes.ts b/apps/web/src/app/app.routes.ts index 0e3395f8f..0a0055583 100644 --- a/apps/web/src/app/app.routes.ts +++ b/apps/web/src/app/app.routes.ts @@ -72,6 +72,14 @@ export const routes: Routes = [ (c) => c.VideoPlayerComponent ), }, + { + path: 'downloads', + data: { layout: 'workspace' }, + loadComponent: () => + import('./xtream-electron/downloads/downloads.component').then( + (c) => c.DownloadsComponent + ), + }, ...withWorkspaceLayout(xtreamRoutes), ...withWorkspaceLayout(stalkerRoutes), { @@ -84,51 +92,11 @@ export const routes: Routes = [ }, ], }, - { - path: 'home', - loadComponent: () => - import('./home/home.component').then((c) => c.HomeComponent), - }, - { - path: 'playlists', - loadComponent: () => - import('./home/video-player/video-player.component').then( - (c) => c.VideoPlayerComponent - ), - }, - { - path: 'iptv', - loadComponent: () => - import('./home/video-player/video-player.component').then( - (c) => c.VideoPlayerComponent - ), - }, - { - path: 'playlists/:id', - pathMatch: 'full', - redirectTo: 'playlists/:id/all', - }, - { - path: 'playlists/:id/:view', - loadComponent: () => - import('./home/video-player/video-player.component').then( - (c) => c.VideoPlayerComponent - ), - }, { path: 'settings', redirectTo: '/workspace/settings', pathMatch: 'full', }, - ...xtreamRoutes, - { - path: 'portals/:id', - loadComponent: () => - import('./stalker/stalker-main-container.component').then( - (c) => c.StalkerMainContainerComponent - ), - }, - ...stalkerRoutes, { path: '**', redirectTo: '', diff --git a/apps/web/src/app/home/home.component.html b/apps/web/src/app/home/home.component.html deleted file mode 100644 index b64ff5a13..000000000 --- a/apps/web/src/app/home/home.component.html +++ /dev/null @@ -1,12 +0,0 @@ - - diff --git a/apps/web/src/app/home/home.component.scss b/apps/web/src/app/home/home.component.scss deleted file mode 100644 index c4b94498d..000000000 --- a/apps/web/src/app/home/home.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -.recent-playlists { - height: calc(100vh - 71px); - overflow: auto; -} diff --git a/apps/web/src/app/home/home.component.spec.ts b/apps/web/src/app/home/home.component.spec.ts deleted file mode 100644 index 5059a194b..000000000 --- a/apps/web/src/app/home/home.component.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; -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 } from '@ngx-translate/core'; -import { MockComponent, MockModule, MockProvider } from 'ng-mocks'; -import { Observable } from 'rxjs'; -import { DataService } from '../../../../../libs/services/src/lib/data.service'; -import { RecentPlaylistsComponent } from '../../../../../libs/ui/components/src/lib/recent-playlists/recent-playlists.component'; -import { ElectronServiceStub } from '../services/electron.service.stub'; -import { HomeComponent } from './home.component'; - -describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; - let electronService: DataService; - let mockStore: MockStore; - const actions$ = new Observable(); - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [ - HomeComponent, - CommonModule, - MockComponent(RecentPlaylistsComponent), - MockModule(MatProgressBarModule), - MockModule(MatSnackBarModule), - TranslateModule.forRoot(), - MockModule(RouterModule), - MockModule(MatDialogModule), - ], - providers: [ - MockProvider(ActivatedRoute, { - snapshot: { component: '' } as any, - }), - MockProvider(MatSnackBar), - { provide: DataService, useClass: ElectronServiceStub }, - provideMockStore(), - provideMockActions(actions$), - ], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(HomeComponent); - component = fixture.componentInstance; - electronService = TestBed.inject(DataService); - - mockStore = TestBed.inject(MockStore); - mockStore.setState({}); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('should set IPC event listeners', () => { - jest.spyOn(electronService, 'listenOn'); - component.setRendererListeners(); - expect(electronService.listenOn).toHaveBeenCalledTimes( - component.commandsList.length - ); - }); - - it('should remove all ipc listeners on destroy', () => { - jest.spyOn(electronService, 'removeAllListeners'); - component.ngOnDestroy(); - expect(electronService.removeAllListeners).toHaveBeenCalledTimes( - component.commandsList.length - ); - }); -}); diff --git a/apps/web/src/app/home/home.component.ts b/apps/web/src/app/home/home.component.ts deleted file mode 100644 index a81f882d2..000000000 --- a/apps/web/src/app/home/home.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Component, inject, signal } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; -import { PlaylistType, RecentPlaylistsComponent } from 'components'; -import { AddPlaylistDialogComponent } from '../shared/components/add-playlist/add-playlist-dialog.component'; -import { HeaderComponent } from '../shared/components/header/header.component'; -import { GlobalRecentlyViewedComponent } from '../xtream-electron/recently-viewed/global-recently-viewed.component'; -import { GlobalSearchResultsComponent } from '../xtream-electron/search-results/global-search-results.component'; - -@Component({ - selector: 'app-home', - templateUrl: './home.component.html', - styleUrls: ['./home.component.scss'], - imports: [HeaderComponent, RecentPlaylistsComponent, TranslatePipe], -}) -export class HomeComponent { - private readonly dialog = inject(MatDialog); - - searchQuery = signal(''); - - onSearchQueryChange(query: string): void { - this.searchQuery.set(query); - } - - onAddPlaylist(playlistType: PlaylistType): void { - this.dialog.open( - AddPlaylistDialogComponent, - { - width: '600px', - data: { type: playlistType }, - } - ); - } - - openGlobalSearch(): void { - this.dialog.open(GlobalSearchResultsComponent, { - width: '100%', - height: '100%', - maxWidth: '100%', - panelClass: 'global-search-overlay', - data: { isGlobalSearch: true }, - }); - } - - openGlobalRecent(): void { - this.dialog.open(GlobalRecentlyViewedComponent, { - width: '100%', - height: '100%', - maxWidth: '100%', - panelClass: 'global-search-overlay', - data: { isGlobal: true }, - hasBackdrop: true, - disableClose: false, - }); - } -} diff --git a/apps/web/src/app/settings/settings.component.ts b/apps/web/src/app/settings/settings.component.ts index 5b081029f..89b622a88 100644 --- a/apps/web/src/app/settings/settings.component.ts +++ b/apps/web/src/app/settings/settings.component.ts @@ -48,7 +48,6 @@ import { VideoPlayer, } from 'shared-interfaces'; import { SettingsStore } from '../services/settings-store.service'; -import { HeaderComponent } from '../shared/components/header/header.component'; import { SettingsContextService } from '../workspace/settings-context.service'; import { SettingsService } from './../services/settings.service'; @@ -65,7 +64,6 @@ interface SettingsSection { imports: [ CommonModule, FormsModule, - HeaderComponent, MatButtonModule, MatCheckboxModule, MatDividerModule, diff --git a/apps/web/src/app/shared/components/header/header.component.ts b/apps/web/src/app/shared/components/header/header.component.ts index f8b5a508b..70761ae30 100644 --- a/apps/web/src/app/shared/components/header/header.component.ts +++ b/apps/web/src/app/shared/components/header/header.component.ts @@ -1,6 +1,5 @@ import { Component, - HostBinding, OnInit, inject, input, @@ -20,7 +19,6 @@ import { TranslateModule } from '@ngx-translate/core'; import { DataService } from 'services'; //import { shell } from 'electron'; import { AddPlaylistMenuComponent, PlaylistType } from 'components'; -import { HomeComponent } from '../../../home/home.component'; import { AboutDialogComponent } from '../about-dialog/about-dialog.component'; import { AddPlaylistDialogComponent } from '../add-playlist/add-playlist-dialog.component'; import { FilterSortMenuComponent } from '../filter-sort-menu/filter-sort-menu.component'; @@ -44,10 +42,6 @@ import { FilterSortMenuComponent } from '../filter-sort-menu/filter-sort-menu.co ], }) export class HeaderComponent implements OnInit { - @HostBinding('class.home-header') get isHomeHeader() { - return this.isHome; - } - private activatedRoute = inject(ActivatedRoute); private dialog = inject(MatDialog); private dataService = inject(DataService); @@ -66,11 +60,10 @@ export class HeaderComponent implements OnInit { readonly globalSearchClicked = output(); readonly globalRecentClicked = output(); - isHome = true; + readonly isHome = false; ngOnInit() { - this.isHome = - this.activatedRoute.snapshot.component.name === HomeComponent.name; + // Initialization if needed } /** diff --git a/apps/web/src/app/workspace/workspace-settings-context-panel.component.scss b/apps/web/src/app/workspace/workspace-settings-context-panel.component.scss index f7fcb18e6..4e3ad65b1 100644 --- a/apps/web/src/app/workspace/workspace-settings-context-panel.component.scss +++ b/apps/web/src/app/workspace/workspace-settings-context-panel.component.scss @@ -1,4 +1,4 @@ -@import '../../nav-list.scss'; +@use '../../nav-list.scss'; :host { display: flex; diff --git a/apps/web/src/app/workspace/workspace-shell.component.html b/apps/web/src/app/workspace/workspace-shell.component.html index 0801c3e59..c505a39b3 100644 --- a/apps/web/src/app/workspace/workspace-shell.component.html +++ b/apps/web/src/app/workspace/workspace-shell.component.html @@ -106,7 +106,7 @@ person } - @if (downloadsContext()) { + @if (isElectron) { } @if (playlist.filename) { - + {{ 'HOME.PLAYLISTS.INFO_DIALOG.ORIGINAL_FILENAME' | translate }} - + {{ 'HOME.PLAYLISTS.INFO_DIALOG.IMPORT_DATE' | translate }} @@ -116,7 +118,7 @@ } @if (playlist.count) { - + {{ 'HOME.PLAYLISTS.INFO_DIALOG.CHANNELS' | translate }} @@ -124,7 +126,7 @@ } @if (isDesktop) { - + {{ 'HOME.PLAYLISTS.INFO_DIALOG.USER_AGENT' | translate }} @@ -135,7 +137,7 @@ } @if (playlist.filePath) { - + {{ 'HOME.PLAYLISTS.INFO_DIALOG.FILE_PATH' | translate }} @@ -151,7 +153,7 @@ } @if (isDesktop && (playlist.url || playlist.filePath)) { - + {{ 'HOME.PLAYLISTS.INFO_DIALOG.AUTO_UPDATE' | translate }}

diff --git a/libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts b/libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts index 29c939ccf..915b264b3 100644 --- a/libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts +++ b/libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts @@ -112,7 +112,9 @@ export class RecentPlaylistsComponent { ); }) .filter((item) => - item.title.toLowerCase().includes(searchQuery.toLowerCase()) + (item.title || '') + .toLowerCase() + .includes(searchQuery.toLowerCase()) ); // Apply sorting using the SortService @@ -160,11 +162,11 @@ export class RecentPlaylistsComponent { getPlaylist(playlistMeta: PlaylistMeta): void { if (playlistMeta.serverUrl) { - this.router.navigate(['xtreams', playlistMeta._id]); + this.router.navigate(['/workspace', 'xtreams', playlistMeta._id]); } else if (playlistMeta.macAddress) { - this.router.navigate(['stalker', playlistMeta._id]); + this.router.navigate(['/workspace', 'stalker', playlistMeta._id]); } else { - this.router.navigate(['playlists', playlistMeta._id]); + this.router.navigate(['/workspace', 'playlists', playlistMeta._id]); this.playlistClicked.emit(playlistMeta._id); } } @@ -280,7 +282,7 @@ export class RecentPlaylistsComponent { ); // Navigate to the playlist to trigger re-import - this.router.navigate(['xtreams', item._id]); + this.router.navigate(['/workspace', 'xtreams', item._id]); } catch (error) { console.error('Error refreshing Xtream playlist:', error); this.snackBar.open( diff --git a/test-signal.ts b/test-signal.ts new file mode 100644 index 000000000..e54ee353c --- /dev/null +++ b/test-signal.ts @@ -0,0 +1,3 @@ +import { signal } from '@angular/core'; +const sig = signal(undefined); +console.log(!!sig());