diff --git a/apps/electron-backend/src/app/api/main.preload.ts b/apps/electron-backend/src/app/api/main.preload.ts
index 37f2214d6..ab62c2f51 100644
--- a/apps/electron-backend/src/app/api/main.preload.ts
+++ b/apps/electron-backend/src/app/api/main.preload.ts
@@ -1,6 +1,8 @@
import { contextBridge, ipcRenderer } from 'electron';
contextBridge.exposeInMainWorld('electron', {
- getAppVersion: () => ipcRenderer.invoke('get-app-version'),
- platform: process.platform,
+ getAppVersion: () => ipcRenderer.invoke('get-app-version'),
+ platform: process.platform,
+ fetchPlaylistByUrl: (url: string) =>
+ ipcRenderer.invoke('fetch-playlist-by-url', url),
});
diff --git a/apps/electron-backend/src/app/events/playlist.events.ts b/apps/electron-backend/src/app/events/playlist.events.ts
new file mode 100644
index 000000000..d0dfba480
--- /dev/null
+++ b/apps/electron-backend/src/app/events/playlist.events.ts
@@ -0,0 +1,47 @@
+/**
+ * This module is responsible on handling all the inter process communications
+ * between the frontend to the electron backend.
+ */
+
+import axios from 'axios';
+import { ipcMain } from 'electron';
+import { parse } from 'iptv-playlist-parser';
+import { createPlaylistObject, getFilenameFromUrl } from 'm3u-utils';
+
+export default class PlaylistEvents {
+ static bootstrapPlaylistEvents(): Electron.IpcMain {
+ return ipcMain;
+ }
+}
+
+const https = require('https');
+
+// Retrieve app version
+ipcMain.handle('fetch-playlist-by-url', async (event, url) => {
+ try {
+ const agent = new https.Agent({
+ rejectUnauthorized: false,
+ });
+ const result = await axios.get(url, { httpsAgent: agent });
+ const parsedPlaylist = parse(result.data);
+
+ const extractedName =
+ url && url.length > 1 ? getFilenameFromUrl(url) : '';
+ const playlistName =
+ !extractedName || extractedName === 'Untitled playlist'
+ ? 'Imported from URL'
+ : extractedName;
+
+ const playlistObject = createPlaylistObject(
+ playlistName,
+ parsedPlaylist,
+ url,
+ 'URL'
+ );
+
+ return playlistObject;
+ } catch (error) {
+ console.error('Error fetching playlist:', error);
+ throw error;
+ }
+});
diff --git a/apps/electron-backend/src/main.ts b/apps/electron-backend/src/main.ts
index 6c871db48..40a41a7ce 100644
--- a/apps/electron-backend/src/main.ts
+++ b/apps/electron-backend/src/main.ts
@@ -1,29 +1,30 @@
-import SquirrelEvents from './app/events/squirrel.events';
-import ElectronEvents from './app/events/electron.events';
-import UpdateEvents from './app/events/update.events';
import { app, BrowserWindow } from 'electron';
import App from './app/app';
+import ElectronEvents from './app/events/electron.events';
+import PlaylistEvents from './app/events/playlist.events';
+import SquirrelEvents from './app/events/squirrel.events';
export default class Main {
- static initialize() {
- if (SquirrelEvents.handleEvents()) {
- // squirrel event handled (except first run event) and app will exit in 1000ms, so don't do anything else
- app.quit();
+ static initialize() {
+ if (SquirrelEvents.handleEvents()) {
+ // squirrel event handled (except first run event) and app will exit in 1000ms, so don't do anything else
+ app.quit();
+ }
}
- }
- static bootstrapApp() {
- App.main(app, BrowserWindow);
- }
-
- static bootstrapAppEvents() {
- ElectronEvents.bootstrapElectronEvents();
-
- // initialize auto updater service
- if (!App.isDevelopmentMode()) {
- // UpdateEvents.initAutoUpdateService();
+ static bootstrapApp() {
+ App.main(app, BrowserWindow);
+ }
+
+ static bootstrapAppEvents() {
+ ElectronEvents.bootstrapElectronEvents();
+ PlaylistEvents.bootstrapPlaylistEvents();
+
+ // initialize auto updater service
+ if (!App.isDevelopmentMode()) {
+ // UpdateEvents.initAutoUpdateService();
+ }
}
- }
}
// handle setup events as quickly as possible
diff --git a/apps/web/src/app/app.module.ts b/apps/web/src/app/app.module.ts
index 1303161c3..73ee8da7b 100644
--- a/apps/web/src/app/app.module.ts
+++ b/apps/web/src/app/app.module.ts
@@ -38,7 +38,7 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
* Conditionally imports the necessary service based on the current environment
*/
export function DataFactory() {
- if (isTauri()) {
+ if (window.electron) {
return new TauriService();
}
return new PwaService();
diff --git a/apps/web/src/app/home/home.component.ts b/apps/web/src/app/home/home.component.ts
index fa1596db0..0438db85a 100644
--- a/apps/web/src/app/home/home.component.ts
+++ b/apps/web/src/app/home/home.component.ts
@@ -1,11 +1,10 @@
-
-import { Component, NgZone } from '@angular/core';
+import { Component, inject, OnDestroy } from '@angular/core';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Store } from '@ngrx/store';
import { TranslatePipe } from '@ngx-translate/core';
+import { Playlist } from 'shared-interfaces';
import { ERROR, PLAYLIST_PARSE_RESPONSE } from '../../shared/ipc-commands';
-import { Playlist } from '../../shared/playlist.interface';
import { DataService } from '../services/data.service';
import { HeaderComponent } from '../shared/components/header/header.component';
import { addPlaylist } from '../state/actions';
@@ -16,13 +15,17 @@ import { RecentPlaylistsComponent } from './recent-playlists/recent-playlists.co
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
imports: [
- HeaderComponent,
- MatProgressBarModule,
- RecentPlaylistsComponent,
- TranslatePipe
-],
+ HeaderComponent,
+ MatProgressBarModule,
+ RecentPlaylistsComponent,
+ TranslatePipe,
+ ],
})
-export class HomeComponent {
+export class HomeComponent implements OnDestroy {
+ private dataService = inject(DataService);
+ private snackBar = inject(MatSnackBar);
+ private readonly store = inject(Store);
+
/** Loading spinner state */
isLoading = false;
@@ -48,12 +51,7 @@ export class HomeComponent {
listeners = [];
- constructor(
- private dataService: DataService,
- private ngZone: NgZone,
- private snackBar: MatSnackBar,
- private readonly store: Store
- ) {
+ constructor() {
this.setRendererListeners();
}
diff --git a/apps/web/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts b/apps/web/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts
index be220221e..327ac4e31 100644
--- a/apps/web/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts
+++ b/apps/web/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts
@@ -20,7 +20,7 @@ import { isTauri } from '@tauri-apps/api/core';
import { save } from '@tauri-apps/plugin-dialog';
import { writeTextFile } from '@tauri-apps/plugin-fs';
import { firstValueFrom } from 'rxjs';
-import { Playlist } from '../../../../shared/playlist.interface';
+import { Playlist } from 'shared-interfaces';
import { DatabaseService } from '../../../services/database.service';
import { PlaylistsService } from '../../../services/playlists.service';
import { PlaylistMeta } from '../../../shared/playlist-meta.type';
diff --git a/apps/web/src/app/home/recent-playlists/recent-playlists.component.ts b/apps/web/src/app/home/recent-playlists/recent-playlists.component.ts
index a1456de7b..5da99fc20 100644
--- a/apps/web/src/app/home/recent-playlists/recent-playlists.component.ts
+++ b/apps/web/src/app/home/recent-playlists/recent-playlists.component.ts
@@ -4,7 +4,6 @@ import {
Component,
ElementRef,
EventEmitter,
- HostListener,
Input,
OnDestroy,
OnInit,
@@ -23,8 +22,7 @@ import { Store } from '@ngrx/store';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { NgxSkeletonLoaderComponent } from 'ngx-skeleton-loader';
import { BehaviorSubject, combineLatest, map } from 'rxjs';
-import { GLOBAL_FAVORITES_PLAYLIST_ID } from '../../../shared/constants';
-import { Playlist } from '../../../shared/playlist.interface';
+import { GLOBAL_FAVORITES_PLAYLIST_ID, Playlist } from 'shared-interfaces';
import { DataService } from '../../services/data.service';
import { DatabaseService } from '../../services/database.service';
import { SortService } from '../../services/sort.service';
diff --git a/apps/web/src/app/home/stalker-portal-import/stalker-portal-import.component.ts b/apps/web/src/app/home/stalker-portal-import/stalker-portal-import.component.ts
index f2c7ad3fc..40b91299a 100644
--- a/apps/web/src/app/home/stalker-portal-import/stalker-portal-import.component.ts
+++ b/apps/web/src/app/home/stalker-portal-import/stalker-portal-import.component.ts
@@ -11,8 +11,8 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { Store } from '@ngrx/store';
import { TranslatePipe } from '@ngx-translate/core';
+import { Playlist } from 'shared-interfaces';
import { v4 as uuid } from 'uuid';
-import { Playlist } from '../../../shared/playlist.interface';
import { DataService } from '../../services/data.service';
import { addPlaylist } from '../../state/actions';
diff --git a/apps/web/src/app/home/url-upload/url-upload.component.html b/apps/web/src/app/home/url-upload/url-upload.component.html
index edc39bc04..0db7cbf21 100644
--- a/apps/web/src/app/home/url-upload/url-upload.component.html
+++ b/apps/web/src/app/home/url-upload/url-upload.component.html
@@ -7,10 +7,10 @@
formControlName="playlistUrl"
/>
- @if (!isTauri) {
-
- {{ 'HOME.URL_UPLOAD.CORS_NOTE' | translate }}
-
+ @if (!isDesktop) {
+
+ {{ 'HOME.URL_UPLOAD.CORS_NOTE' | translate }}
+
}