Commit Graph
66 Commits
Author SHA1 Message Date
4grayandClaude Opus 4.5 0643acac3a feat: add o_name support and Stalker playback position tracking
- Add o_name (original title) field to Stalker VOD interfaces
- Prefer o_name over name in adapters and grid list display
- Add playback position tracking for Stalker VOD content
- Support resume playback from last position in vod-details
- Add real-time position updates via IPC listener
- Add progress indicators for Stalker VOD items in grid view
- Add debug logging for VOD series seasons resource

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:55:45 +01:00
4gray f95ac9c34e refactor: refactor existing vod-details component and implement VOD details route component
- Added `VodDetailsRouteComponent` to handle VOD details with route parameters.
- Refactored existing `VodDetailsComponent` to use a unified structure for Xtream and Stalker portals.
- Enhanced VOD details display with normalized metadata and improved playback position handling.
- Integrated resizable sidebar functionality in main container and live stream layout components.
- Updated routing to use the new VOD details route component.
- Improved favorite toggling and download handling in VOD details.
- Adjusted styles for responsive sidebar and grid layouts.
2026-01-30 20:39:18 +01:00
4grayandClaude Opus 4.5 7c44541721 feat: add download manager for VOD and series episodes
Add comprehensive download functionality for Xtream and Stalker portals:

Backend (Electron):
- Add downloads table schema with foreign key to playlists
- Create downloads.events.ts with IPC handlers for download operations
- Support download start, cancel, retry, remove, and status queries
- Auto-create playlist entries for Stalker portals to satisfy FK constraints
- Add download folder selection and file reveal/play functionality

Frontend (Angular):
- Create DownloadsService with reactive signal-based state management
- Add DownloadsComponent with queue management UI
- Implement download buttons with three states: download, downloading, play local
- Support both Xtream and Stalker modes with proper playlist ID handling
- Add download progress indicators and status badges

UI Components:
- Update VodDetailsComponent with download/play-local buttons
- Update SeasonContainerComponent with episode download buttons
- Add navigation link to downloads page
- Style download buttons and progress indicators

Stalker Portal Support:
- Resolve stream URLs via fetchLinkToPlay API before downloading
- Handle both vod-series and regular-series episode types
- Use playlist._id for Stalker (vs portalId for Xtream)
- Pass playlist info for auto-creation in database

Translations:
- Add download-related strings for en, de, es, fr

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:22:30 +01:00
4grayandClaude Opus 4.5 85225c03d2 fix: improve VLC property parsing with defensive handling
- Add resolved flag to prevent double resolution race condition
- Use regex to parse numeric values instead of fragile line filtering
- Centralize cleanup in done() helper for consistent handling
- Increase timeout to 2000ms to match MPV

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 13:43:36 +01:00
4grayandClaude Opus 4.5 1df371b163 fix: replace deprecated substr() and fix MPV IPC timeout handling
- Use manual time calculation instead of fragile toISOString().substr()
- Explicitly resolve null on MPV IPC timeout to prevent hanging promises
- Clear timeout handle in all event paths to prevent races

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 13:34:32 +01:00
4grayandClaude Opus 4.5 9cd278256b fix: use specific listener cleanup instead of removeAllListeners
Return unsubscribe function from onPlaybackPositionUpdate to ensure
only the specific listener is removed on destroy, preventing issues
with multiple store instances.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 13:32:04 +01:00
4gray adb89145a3 feat: playback position persistence for all players and grid indicators 2026-01-18 11:40:27 +01:00
4gray e53555d324 fix(epg): robustly load better-sqlite3 from workerData, resourcesPath, or fallback 2026-01-13 23:31:27 +01:00
4gray b57f4a640a fix(electron): pass nativeModulesPath to workers and load native modules in worker to support packaged app 2026-01-13 22:55:32 +01:00
4gray 1bd31bf18c fix(electron): use app.isPackaged to detect dev mode
Replace custom environment-based dev detection with Electron's
built-in app.isPackaged check. Import the app module from Electron
and remove reliance on ELECTRON_IS_DEV and the environment file.

This simplifies logic, improves reliability of development vs
production detection, and reduces dependency on external env vars.
2026-01-13 22:43:11 +01:00
4gray 54f4abb48b fix(xtream): track and show import progress of playlist 2026-01-12 00:54:55 +01:00
4gray c173553d78 feat(xtream): add recently added views 2026-01-12 00:54:00 +01:00
4gray 33d8036ecc Merge pull request #724 from 4gray/refactor/store-refactoring
refactor/store-refactoring
2026-01-12 00:40:40 +01:00
4gray 960b295cd8 fix: handle Unicode search in DB queries 2026-01-12 00:39:11 +01:00
4gray 2630025b11 feat: restore hidden category state after playlist refresh 2026-01-11 21:20:50 +01:00
4gray e8a80fdb60 test(electron): add Playwright smoke E2E tests for app
Add a new Electron smoke test suite using Playwright to verify the
packaged application starts, renders the main window, and exposes
expected window properties. The tests launch the built Electron main
bundle, locate the primary (non-DevTools) window, wait for DOM load,
and assert the title contains "IPTVnator". They also check window
visibility and bounds, validate rendered body content, and capture
screenshots to dist/test-results/electron-backend-e2e for debugging.

Include helpers to resolve project paths, ensure the screenshot
directory exists, and robustly find the main application window. Set
NODE_ENV and ELECTRON_IS_DEV to ensure the app loads built artifacts.
2026-01-09 12:53:53 +01:00
4gray 2c3c979a96 fix(category): handle empty categoryIds in visibility update 2026-01-07 20:40:45 +01:00
4gray bc30acf4a7 fix: handle empty xtream categories gracefully
Skip database insert when categories array is empty to prevent
'values() must be called with at least one value' error.

Closes #684
2026-01-06 21:41:18 +01:00
4gray 2043b7d8a1 feat(xtream): add category management to hide/show categories
Add the ability to hide irrelevant or empty categories in Xtream playlists.
Users can now manage category visibility through a dialog accessible from
the sidebar header in both VOD/Series and Live TV views.

Features:
- New category management dialog with search filter and select/deselect all
- Visibility settings persisted to database per playlist
- Hidden categories are filtered from sidebar navigation
- New categories added during playlist refresh default to visible
- Database migration for existing installations

Files changed:
- Database: schema.ts, connection.ts (hidden column + migration)
- Backend: category.events.ts, main.preload.ts (IPC handlers)
- Frontend: new dialog component, store method, UI integration
- Translations: en.json
- Documentation: docs/architecture/category-management.md
2026-01-06 21:34:44 +01:00
4gray 5904025e82 refactor: remove unnecessary console logs from Stalker events and portal import components 2026-01-06 19:50:44 +01:00
4gray 532b33a3a8 refactor(epg): tidy imports and format long lines
Reorder imports and remove an unused duplicate to improve clarity and
consistency. Reformat multi-argument and long console/log calls,
return objects and function arguments across multiple lines to keep
within line width and improve readability. Update array/object
literals and error handling pushes to use consistent multi-line
formatting. These changes are purely stylistic and do not alter
behavior; they make the code easier to read and maintain.
2026-01-05 21:52:45 +01:00
4gray 61eef5e00d feat(stalker): feat: add auth for stalker portal, expend portal import UI
Refactor stalker-series-view template to guard fields with conditionals
so that only available metadata is displayed. Replace selectedItem() with
displayItem() to use the updated selection accessor. Add checks for
director, actors, year/release date, genre/genres_str, imdb and kinopoisk
ratings to avoid showing empty labels.

Enhance stalker-portal-import component by adding reactive form fields
for serial/device IDs and signatures, importing MatProgressSpinnerModule,
and wiring TranslateService and StalkerSessionService into the component.
Include a small loading-container style. These changes prepare the UI for
improved import UX and safer rendering of optional series metadata.
2026-01-04 19:07:37 +01:00
4gray 895a269200 feat(db): add EPG schema and IPC handlers for EPG storage
Add tables, indexes, FTS5 virtual table, and triggers to support EPG
(electronic program guide) data in the shared SQLite connection. The
changes introduce epg_channels and epg_programs tables, multiple
indexes for efficient lookups (by source, name, channel, start, and
time range), and an epg_programs_fts virtual table with triggers to
keep the full-text index synchronized with epg_programs.

Register EPG database event handlers in the Electron backend and
add an IPC handler for bulk-saving channels. The handler deletes
existing channels for a source and inserts new channels in chunks to
avoid large single inserts, returning the inserted count.

These changes enable storing, querying, and full-text searching EPG
data and prepare backend IPC endpoints for importing program guide
data.
2026-01-02 17:22:09 +01:00
4gray a6ad3fce14 feat(epg): add indexing and cleanup for faster lookups and memory
Introduce a lowercase display name index (Map) to allow O(1) resolution
from display name to channel id. Rebuild the index during merged-data
rebuild and use it in channel lookups to avoid expensive full scans.
Add a fallback partial-match pass only when the index lookup fails.

Add automatic and manual cleanup of expired programs:
- Add cleanupExpiredPrograms(hoursToKeep) to remove programs older
  than the specified number of hours from epgDataMerged.
- Invoke cleanup after worker fetches (auto-cleanup with 24 hours).
- Expose an IPC handler EPG_CLEANUP_EXPIRED to trigger cleanup on
  demand.

Other changes:
- Clear epgData.programs after merging to free memory.
- Log merged data rebuild and cleanup counts for observability.

These changes improve performance of channel resolution, reduce memory
usage by pruning stale program entries, and provide a manual hook for
on-demand maintenance.
2025-12-26 01:48:15 +01:00
4gray fe8e907e9f refactor(epg): implement streaming SAX-based EPG parser and batching
Replace full-file parsing with a streaming SAX parser to avoid loading
entire XMLTV payloads into memory. Add support for gzipped feeds by
using streaming gunzip (createGunzip) and piping into a SaxesParser,
allowing incremental processing of channels and programmes.

Introduce:
- StreamingEpgParser class that incrementally builds channel and program
  objects and emits batches.
- parseXmltvDate helper to normalize XMLTV datetimes to ISO strings.
- batching constants and response types for channel/program batches and
  progress reporting.
- use of Readable/Saxes for streaming parsing and reduced memory use.

This change improves performance and memory usage for large EPG files,
enables progress reporting and batch emission to the main thread, and
prepares for handling very large or gzipped EPG sources.
2025-12-26 01:32:51 +01:00
4gray 1265059c41 refactor(electron-backend): split DB event handlers into modules 2025-12-26 00:52:28 +01:00
4gray 815279f49f feat(db): add shared database library with sql config
Introduce a shared database schema library for Drizzle ORM and
configure its TypeScript build settings. Move the canonical schema
into libs/shared/database/src/lib/schema.ts and expose strong
typing and table definitions for playlists, categories, content,
recently_viewed and favorites. Add tsconfig.lib.json to set
outDir, declaration output and node types for the shared lib.

Keep apps/electron-backend compatibility by re-exporting the
schema and types from the new shared library (apps/electron-backend
now imports the shared definitions rather than duplicating them).

These changes centralize the database schema as a single source
of truth, prevent duplication, and enable read-only consumers
(e.g. agent-backend) to depend on compiled type declarations.
2025-12-26 00:35:07 +01:00
4gray e6ad644ee8 chore: improve player error handling
App imports and streams
capture MPV stdout/stderr now
friendly errors sent
2025-12-25 23:33:21 +01:00
4gray f10c8b5990 fix(playlist): use file basename as playlist title
Extract the file's basename and strip common playlist extensions
before passing it as the playlist title when loading from a selected
file. This replaces the previous hardcoded "from file" title with a
cleaner, context-aware name derived from the file path.

- import basename from node:path
- compute filename and remove .m3u, .m3u8, .pls, .txt extensions
- fall back to "from file" if resulting title is empty

This improves UX by giving imported playlists meaningful names.
2025-12-14 17:53:54 +01:00
4gray a5685ef27d feat(ui): re-enable input selection and add context menu
Re-enable user selection for input and textarea elements so users
can select and copy text in form fields. Add an Electron context
menu handler that shows a focused edit menu only for recognized
text input types or editable fields. The menu includes Cut, Copy,
Paste and Select All and respects the editFlags to enable actions.

This restores native editing UX in the renderer while avoiding
global context menus elsewhere in the app.
2025-12-14 17:11:12 +01:00
4gray 3e2afe11e3 feat(ui): add remote-control URLs + fix header typos and env
Add support for displaying local remote-control URLs and QR code in the
Settings UI, including styles for URL list, row layout, monospaced links,
and a QR container. Expose a new global API signature getLocalIpAddresses
for retrieving local IPs.

Fix several UI issues:
- Correct typo in header method name (opedAddPlaylistDialog -> openAddPlaylistDialog).
- Fix malformed GitHub URL and collapse img tag formatting.
- Reformat imports and viewChild usage for readability.

Change local development backend URL to localhost:3000 in the local
environment to point to the running local API during development.

These changes improve developer ergonomics (local backend), add a remote
control discovery UX for users on the same network, and tidy up header
bugs and formatting.
2025-12-06 21:46:35 +01:00
4gray 3b97fec939 feat(electron-backend): enable macOS title bar overlay for main window
Add macOS-specific title bar settings to the Electron main window
creation so the app uses a hidden title bar with an overlay on Darwin.
This ensures a more native, modern appearance on macOS while keeping
existing minimum size and saved bounds behavior unchanged.
2025-12-06 21:44:25 +01:00
4gray 7ee2cc4eea feat(db): add API to delete all playlists and related rows
Add a new IPC handler_DELETE_ALL_PLAYLIST that removes all
and related data from the SQLite database in a safe order that respects
foreign key relationships. The handler deletes favorites and recently
viewed entries first, then content, categories, and finally playlists.
Errors are logged and propagated.

Expose the new operation in the renderer preload API as
dbDeleteAllPlaylists() to allow UI code to invoke the purge. This
provides a single-call way to clear playlists and their dependent
records for testing or user-driven reset.
2025-12-06 14:46:37 +01:00
4gray ac39c2a9dd chore(deps): replace @libsql with better-sqlite3
Remove @libsql/client and its transitive entries from package-lock and
add better-sqlite3 plus its TypeScript types. This updates the lockfile
to reflect switching DB client dependencies: drop the @libsql packages
and related node_modules entries, and add "better-sqlite3" and
"@types/better-sqlite3". The change reduces unused libsql artifacts and
ensures type definitions are available for the new native sqlite client.
2025-12-06 09:26:27 +01:00
4gray a948ce0265 feat(electron): bundle worker assets and resolve worker path
Add webpack config and include it in the electron backend build so 
worker scripts are correctly bundled for packaged apps. Move worker 
files to be packaged as extraResources instead of asar unpack patterns 
so the packaged app can load worker JS from Resources/dist/... at 
runtime. Fix worker path resolution in epg.events: compute resourcesPath
from app.getAppPath() and point to dist/apps/electron-backend/workers 
when app.isPackaged. Remove verbose app path logging and update comments
to reflect the actual packaged layout.
Why: ensure webworker entry points are included in the renderer/backend
bundle and accessible when the Electron app is packaged, preventing
worker loading failures in production builds.
2025-11-24 20:46:15 +01:00
4gray 9f7995054d feat(epg): update worker path for packaged app and refine file inclusion in build 2025-11-24 17:19:35 +00:00
4gray 64afc2901e feat(epg): enhance worker path handling and add fallback for missing worker files 2025-11-24 16:21:00 +00:00
4gray 6b40287fae feat(epg): differentiate worker path for packaged and development environments 2025-11-24 16:08:05 +00:00
4gray 682b040aec fix(epg): update worker URL handling for packaged apps 2025-11-24 15:53:10 +00:00
4gray 1b4954e20b feat(epg): update worker path handling for production environment 2025-11-24 15:36:29 +00:00
4gray 5b697f458a feat(electron): load epg worker from asar.unpacked in prod
Update EPG worker path handling and unpack worker files for production
builds so the worker can be spawned when the app is packaged with ASAR.
- Change workerPath to let and, when the resolved path includes
  app.asar, replace it with app.asar.unpacked. This ensures the spawned
  worker points to the unpacked resource in production.
- Add electron-builder asarUnpack pattern for workers/** so worker files
  are packaged outside the ASAR archive.
These changes fix runtime errors where worker threads cannot be started
from inside app.asar and ensure the EPG parser can run in packaged apps.
2025-11-23 22:16:33 +01:00
4gray 12a513802a fix(electron): simplify production load and CI frontend build
Remove unused url.format import and switch from loadURL with a
formatted file: URL to loadFile for production. This simplifies code,
avoids manual file URL construction, and makes the production path
loading more robust.
Also update CI job to build the frontend via the NX command
(npx nx build web --skip-nx-cache) instead of npm run build:frontend,
aligning the workflow with the monorepo's canonical build command.
2025-11-23 19:14:01 +01:00
4gray 34ef9c57d1 fix: preserve favorites after auto-refresh 2025-11-22 11:40:16 +01:00
4gray a48f7d60be feat(electron-backend): add lightweight HTTP server for remote UI
Add a new HttpServer class that serves the built remote-control-web
static assets and provides a simple REST/API routing layer for remote
control endpoints.

Key changes:
- Implement server lifecycle: start, stop, updateSettings with port and
  enabled handling.
- Resolve distribution path depending on electron packaging (dev vs
  production).
- Serve static files with basic security (normalize path to prevent
  traversal) and SPA fallback to index.html for client-side routing.
- Provide registration API for remote control handlers mapped to
  /api/remote-control/* endpoints.
- Log server status and listening URL on start, and on stop.

These changes enable the Electron backend to host the remote control
web app and route API calls without external web servers, simplifying
development and packaging.
2025-11-22 11:26:22 +01:00
4gray 5d2875e554 feat(remote-control-web): add new web app for remote control
Add a new remote-control-web application using Angular standalone
bootstrap. Add main.ts to bootstrap Application with appConfig and log
bootstrap errors.

Introduce global styles (styles.scss) to reset page margins, ensure
full-height layout, set dark background, and prevent horizontal scroll.

Add Nx project configuration (project.json) for build, serve, test,
lint, extract-i18n and serve-static targets with production and
development configurations, asset and style wiring, and Jest test
integration.

Add tsconfig.spec.json to configure testing compilation (Jest, Node),
include test files and test setup.

Start app configuration provider file (app.config.ts) to prepare
application providers (partial file added).

These changes scaffold the new remote-control-web application and
enable building, serving and testing in the monorepo.
2025-11-22 11:26:22 +01:00
4gray 730200f704 feat(xtream): preserve user Xtream data during refresh
Save and restore favorited and recently viewed Xtream items when
deleting and re-importing playlist content.

- Return favoritedXtreamIds and recentlyViewedXtreamIds from
  deleteXtreamPlaylistContent so callers can capture user data before
 .
- Add restoreXtreamUserData to the database service to allow restoring
  favorites and recently viewed entries after a refresh.
- Query and collect xtreamIds and timestamps for favorites and recently
  viewed items in the backend before deleting content.
- Persist the captured user data to localStorage in the recent playlists
  component so it can be used to restore state after re-importing the
  playlist.
- Keep existing playlist metadata update flow intact.

This prevents loss of user-specific favorites and recent history when
refreshing Xtream playlists.
2025-11-13 19:26:37 +01:00
4gray d2b076f1fe feat: auto-update playlists on startup
Add automatic playlist refresh on application startup by listening
for successful playlist load and dispatching an IPC event for any
playlists with autoRefresh enabled.

- Inject Actions into AppComponent and add triggerAutoUpdatePlaylists
  that waits for PlaylistActions.loadPlaylistsSuccess, selects
  selectAllPlaylistsMeta from the store, filters playlists with
  autoRefresh, and sends AUTO_UPDATE_PLAYLISTS via DataService.
- Call triggerAutoUpdatePlaylists from ngOnInit and remove a now-
  unused commented commands list.
- Add helper functions in backend playlist events to fetch and parse
  playlists from URL or file, consolidating parsing logic and creating
  playlist objects.

This implements the previously noted TODO to trigger playlist auto-
refresh and centralizes playlist fetching/parsing for reuse and
clarity.
2025-11-11 08:25:02 +01:00
4gray e06c154e0f fix(mpv, electron): improve process startup & error reporting
Refine MPV/VLC launch error handling in the renderer to extract and show
error.message when available, preventing unhelpful "[object Object]"
messages in the UI.

In the Electron backend, ensure failed MPV instances fall through to
creation by commenting intent, and wrap spawn in a promise to reliably
detect startup failures. On spawn error, clear stored references and
reject with a descriptive message that includes the mpv path. Add an
exit handler, conditional storage of the process for reuse, and proc.unref
for detached runs. Use a short timeout to resolve the promise when spawn
succeeds and log startup state. Convert a silent log to console.error and
rethrow the error to surface failures to callers.

These changes make MPV startup more robust and produce clearer error
feedback for debugging and UI notifications.
2025-11-08 23:02:15 +01:00
4gray 588664c3aa refactor(player): remove unused player path args 2025-11-08 23:02:15 +01:00
4gray 656c86dc30 refactor: rework ipc events handling 2025-11-08 23:02:15 +01:00