-
-
Notifications
You must be signed in to change notification settings - Fork 654
refactor/ipc-events-handling #644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Enhance MPV player IPC handler to accept and forward extra parameters (url, path, title, userAgent, referer, origin). Attempt to reuse an existing MPV instance when reuse is enabled and an IPC socket is available; if reuse fails, fall back to spawning a new process. When creating a new MPV process, generate a unique platform-aware IPC socket path, build arguments conditionally from provided metadata (user-agent, referrer, origin via http-header-fields, force-media-title) and append the URL last. Improve logging for debugging and handle process spawn errors by clearing stale process/socket references. These changes enable smoother playback handoff, preserve headers and title for remote resources, and make MPV invocations more robust.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note
|
| Cohort / File(s) | Summary |
|---|---|
Claude & Configuration .claude/settings.local.json, CLAUDE.md, README.md, package.json, libs/m3u-state/tsconfig.lib.json |
Added Claude AI settings file with Bash/WebSearch/WebFetch permissions; introduced developer documentation covering IPTVnator architecture, commands, and testing; updated README from Tauri to Electron/Angular stack; added npm scripts for PWA builds and updated electron to v39; added global type declarations to tsconfig. |
Electron Backend IPC Enhancement apps/electron-backend/src/app/events/player.events.ts, apps/electron-backend/src/app/events/xtream.events.ts, apps/electron-backend/src/app/api/main.preload.ts, apps/electron-backend/src/app/app.ts |
Extended OPEN_MPV_PLAYER and OPEN_VLC_PLAYER IPC handlers with userAgent, referer, and origin parameters; added MPV process reuse logic with IPC socket management; replaced IPC channel constant with string literal in Xtream events; reformatted preload declarations; set minimum window size constraints (600×900). |
IPC to NgRx Migration apps/web/src/app/services/electron.service.ts, apps/web/src/app/services/pwa.service.ts, apps/web/src/app/app.component.ts, apps/web/src/app/home/home.component.ts, apps/web/src/app/home/video-player/video-player.component.ts |
Replaced direct IPC postMessage communication with NgRx store actions (updateManyPlaylists, updatePlaylist, handleAddingPlaylistByUrl); removed IPC command listeners and error posting; replaced window messaging with snackbar notifications; simplified home and app components by removing IPC infrastructure; removed OnDestroy lifecycle from components. |
Signal-Based Component Inputs apps/web/src/app/xtream-tauri/playlist-error-view/playlist-error-view.component.ts, libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts, libs/ui/components/src/lib/multi-epg/multi-epg-container.component.ts |
Migrated from @Input/@output decorators to Angular input()/output() signals; converted ViewChild to viewChild.required signal API; replaced constructor DI with inject() calls; removed OnInit lifecycle where applicable; updated component templates to invoke signal methods. |
Player Service Metadata Propagation apps/web/src/app/services/player.service.ts, apps/web/src/app/xtream/xtream-main-container.component.ts, apps/web/src/app/stalker/stalker.store.ts, apps/web/src/app/xtream-tauri/xtream.store.ts |
Added userAgent, referer, and origin optional parameters to openPlayer; propagated playlist metadata through player service calls to external player IPC events. |
State Management Updates libs/m3u-state/src/lib/actions.ts, libs/m3u-state/src/lib/effects.ts, libs/m3u-state/src/lib/reducers.ts, libs/shared/interfaces/src/lib/playlist.interface.ts, libs/shared/interfaces/src/lib/ipc-commands.ts |
Added handleAddingPlaylistByUrl NgRx action with isTemporary flag; updated addPlaylist$ effect to filter temporary playlists; added reducer case for new action; extended Playlist interface with referrer and origin fields; removed PLAYLIST_PARSE_RESPONSE and PLAYLIST_UPDATE_RESPONSE constants. |
UI & Navigation Refinements apps/web/src/app/xtream-tauri/navigation/navigation.component.html, apps/web/src/app/xtream-tauri/navigation/navigation.component.scss, apps/web/src/app/xtream-tauri/navigation/navigation.component.ts, apps/web/src/app/home/home.component.html, apps/web/src/app/home/home.component.scss, apps/web/src/app/stalker/stalker-shell/stalker-shell.component.scss, apps/web/src/app/xtream-tauri/xtream-shell/xtream-shell.component.scss |
Narrowed navigation sidebars from 200px/300px to 60px; updated navigation to use tooltips instead of labels and commented out portal info blocks; simplified home component template by removing grid wrapper; removed MatIconButton from navigation imports; adjusted portal status container height and removed borders. |
Styling & Layout Updates apps/web/src/app/xtream-tauri/portal-channels-list/portal-channels-list.component.scss, apps/web/src/app/xtream-tauri/sidebar.scss, apps/web/src/app/xtream-tauri/xtream-shell/xtream-shell.component.scss, apps/web/src/app/xtream-tauri/category-view/category-view.component.scss, apps/web/src/app/xtream/playlist-error-view/playlist-error-view.component.scss, apps/web/src/app/home/video-player/video-player.component.html |
Increased portal channels item width to 370px; increased main sidebar to 400px; removed left border from selected category items; updated button margins; added non-null assertion to async epg binding; normalized opacity notation to 0.X format. |
Config & Build Updates apps/web/project.json, libs/ui/components/eslint.config.mjs |
Added PWA build configuration with baseHref targeting; disabled click/focus ESLint template rules. |
Testing & Documentation libs/ui/components/src/lib/html-video-player/html-video-player.component.spec.ts, libs/ui/components/src/lib/info-overlay/info-overlay.component.spec.ts, libs/ui/components/src/lib/epg-list/epg-list.component.ts, libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.html, apps/web/src/assets/i18n/en.json, apps/web/src/app/xtream/playlist-error-view/playlist-error-view.component.ts, libs/services/src/lib/portal-status.service.ts |
Deleted info-overlay spec file; refactored epg-list to use store-based observables and removed DataService dependency; converted Material module imports to component-level; added null check in epg template; added AUTO_REFRESH_UPDATE_SUCCESS translation key; added deprecation comment to legacy Xtream playlist-error component; replaced IPC constant with string literal in portal-status service. |
Sequence Diagram(s)
sequenceDiagram
actor User
participant FrontendComponent
participant PlayerService
participant ElectronBackend
participant ExternalPlayer as External Player<br/>(MPV/VLC)
User->>FrontendComponent: Open stream
FrontendComponent->>PlayerService: openPlayer(url, title, playlist metadata)
PlayerService->>ElectronBackend: IPC invoke 'OPEN_MPV_PLAYER'<br/>(url, path, title, userAgent,<br/>referer, origin)
ElectronBackend->>ElectronBackend: Check if MPV reuse enabled
alt MPV reuse enabled
ElectronBackend->>ExternalPlayer: Send loadfile via IPC socket
else Create new instance
ElectronBackend->>ExternalPlayer: Spawn MPV with args:<br/>--user-agent, --referrer,<br/>--http-header Origin, title
end
ExternalPlayer->>User: Stream playback
sequenceDiagram
participant Service as Electron/<br/>PWA Service
participant Store as NgRx Store
participant Effect as addPlaylist$ Effect
participant SnackBar
participant User
rect rgb(200, 220, 240)
note over Service,User: Before: IPC postMessage
Service->>Service: window.postMessage(...)
end
rect rgb(220, 240, 200)
note over Service,User: After: NgRx + SnackBar
Service->>Store: dispatch(handleAddingPlaylistByUrl)
Store->>Effect: emit action
Effect->>Effect: Check isTemporary flag
alt isTemporary = true
Effect->>Store: Populate channels, skip persist
else isTemporary = false
Effect->>Effect: addPlaylist to store
end
Service->>SnackBar: Show success notification
SnackBar->>User: Display message
end
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~75 minutes
Areas requiring extra attention:
- IPC to NgRx migration (
electron.service.ts,pwa.service.ts): Verify all postMessage flows have proper NgRx action counterparts and snackbar coverage, especially error paths and async operation sequencing. - Player metadata propagation (
player.events.ts,player.service.ts,xtream.store.ts,stalker.store.ts,xtream-main-container.component.ts): Ensure userAgent, referer, and origin parameters flow correctly through all player invocation paths (MPV/VLC) and that optional chaining handles missing values. - Signal-based refactoring (
playlist-error-view.component.ts,recent-playlists.component.ts,multi-epg-container.component.ts): Verify signal API usage is consistent (input(), output(), viewChild), template bindings correctly invoke signal methods, and change detection behavior remains correct. - Temporary playlist handling (
effects.ts,reducers.ts,handleAddingPlaylistByUrlaction): Confirm the isTemporary branching logic properly skips persistence for temporary playlists while still populating channels. - Navigation UI overhaul (
navigation.component.html,navigation.component.scss): Verify tooltip positioning, accessibility of collapsed navigation, and that commented-out portal info blocks don't impact state management.
Possibly related PRs
- chore: update to angular v20 #613: Angular modernization across components (NgIf/NgFor imports removal, standalone component conversion, signal adoption) overlaps with this PR's component-level refactoring patterns.
- ci-add-github-actions-ui-fixes #638: Touches Electron backend IPC surface (
main.preload.tssaveFileDialog and related IPC patterns) with similar infrastructure changes as this PR's player events IPC enhancements.
Poem
🐰 Signals spring forth, replacing old Input ways,
NgRx actions light the frontend maze,
MPV takes metadata, userAgent in tow,
Navbars shrink and sidebars glow,
IPC fades to snackbar's gentle cheer—
Modern patterns bloom this season clear! 🌱
Pre-merge checks and finishing touches
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title 'refactor/ipc-events-handling' directly reflects the main change: refactoring IPC event handling logic, particularly for player subsystem. It is concise and relates to the primary objective of the PR. |
| Docstring Coverage | ✅ Passed | Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. |
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/web/src/app/services/player.service.ts (1)
24-73: IPC payload structure mismatch: frontend sends object but backend expects individual parametersThe backend handlers in
player.events.tsare registered to receive individual positional parameters:(event, url, path, title, userAgent?, referer?, origin?). However, the frontend inplayer.service.ts(lines 40–47, 53–60) sends an object payload{ url, mpvPlayerPath, title, ... }, causing parameter misalignment. Theurlargument receives the entire object instead of the stream URL,pathbecomes undefined instead of the player path, and so on.Additionally, the frontend passes
'user-agent'(hyphenated) while the backend handler expectsuserAgent(camelCase).Ensure the IPC calls match the backend signature by passing individual arguments in the correct order:
(OPEN_MPV_PLAYER, streamUrl, mpvPlayerPath, title, userAgent, referer, origin)rather than as an object.apps/web/src/app/services/electron.service.ts (1)
64-89: Fix user agent property name passed to Electron player launchers
The payload we emit fromPlaylistEffects.setActiveChannel$and other IPC senders uses the camel-caseduserAgentfield, but here we read'user-agent'. As a result the MPV/VLC bridges never receive the header we just wired through this PR, defeating the whole metadata propagation change. Please switch todata.userAgent(and mirror this in both MPV and VLC branches) so the user agent actually flows through.- data['user-agent'] ?? undefined, + data.userAgent ?? undefined,…and similarly for the VLC call just below.
🧹 Nitpick comments (7)
apps/web/src/app/xtream-tauri/navigation/navigation.component.scss (1)
40-44: LGTM: Formatting improvements enhance readability.The multiline gradient formatting and opacity standardization (
.7to0.7) improve code readability without affecting visual appearance.Also applies to: 62-82, 117-127, 204-204
apps/web/src/app/xtream-tauri/navigation/navigation.component.html (1)
13-22: Consider removing commented code.Multiple sections contain commented-out code (portal-info, portal-actions, nav-group-labels, item titles). If these sections are no longer needed, consider removing them entirely to reduce technical debt. If they're kept for future reference, add a comment explaining why.
Also applies to: 23-52, 56-56, 67-67, 84-84, 92-94, 105-107, 118-120, 131-133
apps/web/src/app/xtream/playlist-error-view/playlist-error-view.component.ts (1)
13-15: Consider consolidating duplicate components.The deprecation comment indicates there's another instance of this component in
xtream-tauri. Having duplicate components can lead to maintenance burden and inconsistencies.Consider consolidating the two implementations into a shared component or creating a clear migration plan to remove this deprecated version.
README.md (1)
125-134: Consider addressing markdown linting issues.The documentation updates accurately reflect the Electron/Angular stack. Static analysis has flagged a few minor markdown formatting issues:
- Line 125: Dollar signs before commands without showing output
- Line 128: Bare URL (consider using link syntax)
- Lines 132-133: Fenced code block missing language specifier
Apply these improvements:
- ``` $ npm run serve:backend - ``` + ```shell + $ npm run serve:backend + ``` -This will open the Electron app in a separate window, while the Angular dev server will run at http://localhost:4200. +This will open the Electron app in a separate window, while the Angular dev server will run at <http://localhost:4200>. -``` +```shell $ npm run serve:frontend</blockquote></details> <details> <summary>apps/electron-backend/src/app/events/player.events.ts (3)</summary><blockquote> `30-54`: **Consider adding connection timeout for robustness.** The socket connection has no timeout, which could cause the promise to hang indefinitely if MPV becomes unresponsive or the socket is stale. Consider adding a timeout: ```diff function sendMpvCommand(command: string, args: string[]): Promise<void> { return new Promise((resolve, reject) => { if (!mpvSocketPath) { reject(new Error('No MPV socket path available')); return; } const client = createConnection(mpvSocketPath); + const timeout = setTimeout(() => { + client.destroy(); + reject(new Error('MPV socket connection timeout')); + }, 5000); + // MPV expects commands in the format: { "command": ["cmd", "arg1", "arg2"] } const request = JSON.stringify({ command: [command, ...args] }) + '\n'; client.on('connect', () => { + clearTimeout(timeout); console.log('Connected to MPV socket, sending command:', request); client.write(request); client.end(); resolve(); }); client.on('error', (err) => { + clearTimeout(timeout); console.error('MPV socket error:', err); reject(err); }); }); }
106-110: Socket path uniqueness could be improved.Using
Date.now()for socket path uniqueness could theoretically result in collisions if multiple MPV instances are spawned within the same millisecond, though this is unlikely in practice.Consider using a more robust unique identifier:
+import { randomBytes } from 'crypto'; + // Generate unique socket path const socketPath = process.platform === 'win32' - ? `\\\\.\\pipe\\mpv-${Date.now()}` - : `/tmp/mpvsocket-${Date.now()}`; + ? `\\\\.\\pipe\\mpv-${randomBytes(8).toString('hex')}` + : `/tmp/mpvsocket-${randomBytes(8).toString('hex')}`;
67-77: Missing validation of MPV player path.The handler doesn't validate that the MPV executable exists before attempting to spawn the process. This could lead to unclear error messages when the player is not installed or the path is incorrect.
Add validation before spawning:
+ const mpvPath = getMpvPath(); + if (!existsSync(mpvPath)) { + throw new Error(`MPV player not found at path: ${mpvPath}`); + } + - const mpvPath = getMpvPath(); const reuseInstance = store.get(MPV_REUSE_INSTANCE, false);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (50)
.claude/settings.local.json(1 hunks)CLAUDE.md(1 hunks)README.md(2 hunks)apps/electron-backend/src/app/api/main.preload.ts(1 hunks)apps/electron-backend/src/app/app.ts(1 hunks)apps/electron-backend/src/app/events/player.events.ts(2 hunks)apps/electron-backend/src/app/events/xtream.events.ts(2 hunks)apps/web/project.json(2 hunks)apps/web/src/app/app.component.ts(3 hunks)apps/web/src/app/home/home.component.html(1 hunks)apps/web/src/app/home/home.component.scss(0 hunks)apps/web/src/app/home/home.component.ts(1 hunks)apps/web/src/app/home/video-player/video-player.component.html(1 hunks)apps/web/src/app/home/video-player/video-player.component.ts(2 hunks)apps/web/src/app/services/electron.service.ts(7 hunks)apps/web/src/app/services/player.service.ts(3 hunks)apps/web/src/app/services/pwa.service.ts(4 hunks)apps/web/src/app/stalker/stalker-shell/stalker-shell.component.html(1 hunks)apps/web/src/app/stalker/stalker-shell/stalker-shell.component.scss(1 hunks)apps/web/src/app/stalker/stalker.store.ts(1 hunks)apps/web/src/app/xtream-tauri/category-view/category-view.component.scss(0 hunks)apps/web/src/app/xtream-tauri/navigation/navigation.component.html(3 hunks)apps/web/src/app/xtream-tauri/navigation/navigation.component.scss(6 hunks)apps/web/src/app/xtream-tauri/navigation/navigation.component.ts(1 hunks)apps/web/src/app/xtream-tauri/playlist-error-view/playlist-error-view.component.html(1 hunks)apps/web/src/app/xtream-tauri/playlist-error-view/playlist-error-view.component.ts(2 hunks)apps/web/src/app/xtream-tauri/portal-channels-list/portal-channels-list.component.scss(9 hunks)apps/web/src/app/xtream-tauri/sidebar.scss(1 hunks)apps/web/src/app/xtream-tauri/xtream-shell/xtream-shell.component.scss(1 hunks)apps/web/src/app/xtream-tauri/xtream.store.ts(1 hunks)apps/web/src/app/xtream/playlist-error-view/playlist-error-view.component.scss(1 hunks)apps/web/src/app/xtream/playlist-error-view/playlist-error-view.component.ts(1 hunks)apps/web/src/app/xtream/xtream-main-container.component.ts(2 hunks)apps/web/src/assets/i18n/en.json(1 hunks)libs/m3u-state/src/lib/actions.ts(1 hunks)libs/m3u-state/src/lib/effects.ts(2 hunks)libs/m3u-state/src/lib/reducers.ts(1 hunks)libs/m3u-state/tsconfig.lib.json(1 hunks)libs/services/src/lib/portal-status.service.ts(1 hunks)libs/shared/interfaces/src/lib/ipc-commands.ts(0 hunks)libs/shared/interfaces/src/lib/playlist.interface.ts(1 hunks)libs/ui/components/eslint.config.mjs(1 hunks)libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.html(1 hunks)libs/ui/components/src/lib/epg-list/epg-list.component.ts(4 hunks)libs/ui/components/src/lib/html-video-player/html-video-player.component.spec.ts(2 hunks)libs/ui/components/src/lib/info-overlay/info-overlay.component.spec.ts(0 hunks)libs/ui/components/src/lib/multi-epg/multi-epg-container.component.ts(4 hunks)libs/ui/components/src/lib/recent-playlists/recent-playlists.component.html(2 hunks)libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts(4 hunks)package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/shared/interfaces/src/lib/ipc-commands.ts
- apps/web/src/app/xtream-tauri/category-view/category-view.component.scss
- apps/web/src/app/home/home.component.scss
- libs/ui/components/src/lib/info-overlay/info-overlay.component.spec.ts
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
README.md
125-125: Dollar signs used before commands without showing output
(MD014, commands-show-output)
128-128: Bare URL used
(MD034, no-bare-urls)
132-132: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
133-133: Dollar signs used before commands without showing output
(MD014, commands-show-output)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Build on ubuntu-latest
- GitHub Check: Build on macos-latest
- GitHub Check: Build on windows-latest
🔇 Additional comments (49)
apps/electron-backend/src/app/api/main.preload.ts (1)
11-14: LGTM! Formatting improvement for readability.The multi-line formatting of the
saveFileDialogsignature enhances readability and aligns with the style used by other multi-parameter functions in this file (e.g.,openInMpv,openInVlc).libs/services/src/lib/portal-status.service.ts (1)
31-41: LGTM! Clean refactoring to string literal.The replacement of the imported
XTREAM_REQUESTconstant with the string literal'XTREAM_REQUEST'aligns with the PR's IPC refactoring objectives. The channel name matches the backend handler inxtream.events.ts, ensuring consistent communication.apps/electron-backend/src/app/events/xtream.events.ts (2)
19-19: LGTM! Consistent IPC channel naming.The string literal
'XTREAM_REQUEST'matches the frontend usage inportal-status.service.ts, ensuring proper IPC communication. This refactoring reduces coupling to the shared constants file.
79-83: LGTM! Improved readability.The multiline formatting of the error type guard improves code readability without changing the logic. The defensive checks (
error && typeof error === 'object' && 'message' in error) are appropriate for safely handling unknown error types.libs/ui/components/src/lib/html-video-player/html-video-player.component.spec.ts (2)
4-4: LGTM: Alias import improves maintainability.The switch to an alias-based import path aligns with the PR's modernization strategy.
49-51: LGTM: Explicit empty implementation improves clarity.The expanded block body with the
/* empty */comment makes the intentional no-op implementation more obvious.libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts (2)
7-8: Excellent migration to Angular signal-based API!The migration from decorator-based
@Input()and@Output()to signal-basedinput()andoutput()is correctly implemented. This modernization provides better reactivity, type safety, and aligns with Angular's current best practices. The addition ofallPlaylistsLoadedsignal for reactive store selection is also well done.All three signals are properly marked as
readonly, and the template correctly invokes them as functions where needed.Also applies to: 62-67
143-146: Method rename improves clarity.The rename from
getGlobalFavorites()tonavigateToGlobalFavorites()better reflects the method's actual behavior, which is to navigate to the global favorites view and emit an event. The previous name suggested data retrieval, while the new name accurately describes the navigation action.libs/ui/components/src/lib/recent-playlists/recent-playlists.component.html (1)
28-28: Template correctly updated for signal-based API.The template changes properly align with the TypeScript migration to signal-based inputs and method rename. Line 45 correctly invokes
sidebarMode()as a function to access the signal's value, and line 28 uses the renamednavigateToGlobalFavorites()method.Also applies to: 45-45
libs/ui/components/src/lib/multi-epg/multi-epg-container.component.ts (4)
9-9: LGTM! Modern Angular patterns adopted.The imports correctly reflect the shift to inject-based DI and signal-based view queries.
Also applies to: 13-13
59-59: LGTM! Signal-based view query correctly implemented.The migration to
viewChild.requiredis appropriate, and the signal is correctly invoked at line 122.
83-83: LGTM! Improved type safety.The
numbertype is correct for browser/Electron environments and removes the unsafeanytype.
122-124: LGTM! Correct usage of viewChild signal.The signal is properly invoked with
this.epgContainer()and thenativeElementis accessed correctly.libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.html (1)
20-27: Null guard onitemlooks good.This defensive check prevents template errors when the EPG item hasn’t hydrated yet.
apps/web/src/app/xtream-tauri/xtream-shell/xtream-shell.component.scss (1)
16-16: LGTM: Sidebar width reduced for icon-only navigation.The width reduction from 200px to 60px aligns with the icon-only navigation pattern implemented in the corresponding HTML template changes.
apps/web/src/app/stalker/stalker-shell/stalker-shell.component.scss (1)
16-16: LGTM: Consistent sidebar width adjustment.The width reduction matches the change in
xtream-shell.component.scss, ensuring consistent icon-only navigation across both stalker and xtream shell components.apps/web/src/app/xtream-tauri/sidebar.scss (1)
2-2: LGTM: Sidebar width increased for content display.The width increase from 300px to 400px provides more space for content, which contrasts appropriately with the narrowed navigation sidebar (60px) in the shell components.
apps/web/src/app/xtream-tauri/navigation/navigation.component.scss (1)
47-47: LGTM: Min-height reduction aligns with UI changes.The reduction from 120px to 50px is appropriate given that the portal info and actions sections are now hidden (commented out in the HTML template).
package.json (3)
65-65: LGTM: PWA build configuration scripts.The new PWA-specific build and serve scripts are well-defined and align with the documented dual-environment architecture (Electron + PWA) mentioned in CLAUDE.md.
Also applies to: 68-68
180-180: Good: More flexible versioning for electron-builder.Adding the caret allows automatic updates to compatible versions (patches and minor releases) while preventing breaking major version changes.
179-179: No breaking changes identified. Electron 39.0.0 upgrade is compatible with this codebase.Verification of the identified breaking changes shows none apply:
- IPC communication: Uses modern
ipcMain.handle()andipcRenderer.invoke()patterns, fully compatible with Electron 39.- Preload script & contextBridge: Correctly configured with
contextIsolation: trueand propercontextBridge.exposeInMainWorld()syntax—compatible with v39.- MPV/VLC player integration: Uses standard IPC invoke pattern with no deprecated APIs.
- Breaking changes assessment:
- OSR paint handlers: not used
- window.open popups: used only for external URLs, not affected by resize-behavior change
- --host-rules: not used
- Stack upgrades (Node 22, Chromium 142, V8 14.2): no native modules, no impact
No code changes are required for this upgrade.
.claude/settings.local.json (1)
1-11: LGTM: Scoped permissions for development assistance.The local Claude configuration appropriately scopes permissions for development tasks. The WebFetch restriction to electronjs.org domain is sensible given the Electron version upgrade in this PR.
libs/m3u-state/tsconfig.lib.json (1)
10-10: LGTM: Including global type declarations.Explicitly including global type declarations ensures they're available during library compilation. This is particularly relevant given the interface extensions mentioned in the PR (new
referrerandoriginfields on Playlist).apps/web/src/app/xtream-tauri/portal-channels-list/portal-channels-list.component.scss (2)
10-10: LGTM: Increased list item width for better content display.The width increase from 280px to 370px provides more space for channel information, improving readability and reducing text truncation.
138-138: Good: Normalized opacity values for consistency.Standardizing opacity values from
.6to0.6improves code consistency across the stylesheet.Also applies to: 145-145
CLAUDE.md (1)
1-290: Excellent documentation for codebase understanding.This comprehensive guide clearly explains the dual-environment architecture (Electron + PWA), factory pattern for service injection, development workflows, and common patterns. This will significantly help with onboarding, maintenance, and AI-assisted development.
apps/web/src/app/xtream-tauri/playlist-error-view/playlist-error-view.component.ts (1)
1-1: LGTM: Modern signal-based input pattern.The migration from
@Input()decorators to Angular'sinput()signal API is excellent:
- Provides better type safety and reactivity
- Aligns with modern Angular (v17+) best practices
- Correctly preserves types and default values
- Making
currentPlaylistprivate is appropriate since it's only used internallyThe corresponding template (playlist-error-view.component.html) correctly uses function call syntax for these signal-based inputs.
Also applies to: 28-37
apps/web/src/app/xtream-tauri/playlist-error-view/playlist-error-view.component.html (2)
2-2: LGTM: Correct signal syntax with template updates.Template bindings correctly updated to use function call syntax (
viewType(),title(), etc.) to match the signal-based inputs in the component class. This change is required for the new input API.Also applies to: 4-4, 10-10, 14-15, 18-18
3-3: Good: Accessibility improvements with alt text.Added descriptive alt attributes to images ("Something went wrong", "empty category"), improving screen reader support and WCAG compliance.
Also applies to: 6-6
apps/web/src/app/home/video-player/video-player.component.html (1)
99-99: Verify the non-null assertion is safe.The non-null assertion operator
!tells TypeScript thatepgProgram$ | asyncwill never be null or undefined. If the observable can emit null/undefined values, this could lead to runtime errors in the child component.Please verify that
epgProgram$is guaranteed to emit a non-null value. If there's a possibility of null/undefined, consider using the safe navigation operator or an@ifguard instead:@if (epgProgram$ | async; as epgProgram) { <app-info-overlay [channel]="activeChannel" [epgProgram]="epgProgram" /> }apps/web/src/app/stalker/stalker-shell/stalker-shell.component.html (1)
7-7: LGTM!Reordering the bindings has no functional impact in Angular templates.
apps/web/src/app/xtream/playlist-error-view/playlist-error-view.component.scss (1)
25-25: LGTM!Adding uniform margins improves button spacing when multiple buttons are displayed horizontally.
apps/electron-backend/src/app/app.ts (1)
81-82: LGTM!Setting minimum window dimensions ensures the UI remains usable and prevents layout breakage at very small sizes.
libs/shared/interfaces/src/lib/playlist.interface.ts (1)
26-27: LGTM!Adding optional
referrerandoriginfields enables richer metadata propagation to external players while maintaining backward compatibility with existing code.apps/web/src/app/stalker/stalker.store.ts (1)
482-492: LGTM!The implementation correctly propagates playlist metadata (userAgent, referrer, origin) to the player service using safe optional chaining to handle undefined values gracefully.
apps/web/project.json (2)
48-66: LGTM!The PWA build configuration properly sets production-grade settings with an appropriate root-relative
baseHreffor PWA deployment.
82-84: LGTM!The PWA serve configuration correctly maps to the PWA build target.
apps/web/src/app/xtream/xtream-main-container.component.ts (2)
345-385: LGTM! Metadata propagation is well-structured.The playlist metadata extraction and forwarding to external players is implemented correctly with appropriate null safety using optional chaining.
396-425: No issues found—the code is correct as written.The destructured
referrerproperty from the Playlist interface is intentionally passed as therefererkey in IPC payloads. This is a consistent pattern throughout the codebase (also seen inm3u-state/effects.tsline 155). The Playlist interface usesreferrer(double 'r') for semantic clarity, while the IPC and backend handlers usereferer(single 'r', following the HTTP header standard). This is by design, not an error.Likely an incorrect or invalid review comment.
apps/web/src/app/home/home.component.html (1)
1-5: LGTM! Clean template simplification.The template refactor removes unnecessary wrapper elements while preserving the functionality.
libs/m3u-state/src/lib/actions.ts (1)
137-140: LGTM! Well-structured NgRx action.The new
handleAddingPlaylistByUrlaction follows NgRx conventions with a clear payload structure and descriptive naming.apps/web/src/assets/i18n/en.json (1)
69-70: LGTM! Translation key added correctly.The new
AUTO_REFRESH_UPDATE_SUCCESSkey is well-placed and provides a clear user-facing message.apps/web/src/app/xtream-tauri/xtream.store.ts (1)
842-858: LGTM! Metadata forwarding implemented correctly.The openPlayer method properly extracts and forwards playlist metadata to the player service. The use of optional chaining ensures null safety.
Note: This method exhibits the same
referrervsreferernaming pattern flagged in xtream-main-container.component.ts. Please verify consistency across the codebase as mentioned in that review.apps/electron-backend/src/app/events/player.events.ts (6)
26-28: LGTM: Module-level state for MPV reuse.The module-level variables properly track the MPV process and socket path for the reuse feature.
78-101: LGTM: MPV reuse logic with graceful fallback.The reuse logic properly validates preconditions and gracefully falls back to creating a new instance if the existing one is unavailable or the command fails.
112-136: LGTM: MPV arguments built correctly.The argument building logic properly handles optional parameters and correctly places the URL last, which is important for MPV.
138-142: Question: Shoulddetachedalways betrue?The
detachedflag is currently!reuseInstance, meaning the process is attached when reuse is enabled. This seems counterintuitive—when reusing, you want to keep the process reference but still allow it to run independently of the parent.Please verify if this is the intended behavior. Typically, external players should always be detached so they continue running even if the Electron app closes.
Consider changing to:
const proc = spawn(mpvPath, args, { shell: false, - detached: !reuseInstance, + detached: true, stdio: 'ignore', });
227-228: Good documentation of VLC origin limitation.The comment appropriately notes that VLC doesn't have a direct origin option. The origin is typically included in the referer for most IPTV use cases, so this limitation is acceptable.
262-379: LGTM: Comprehensive platform-aware path resolution.The helper functions provide robust path resolution across Windows, Linux, and macOS, checking multiple common installation locations and falling back gracefully to PATH lookup.
libs/ui/components/src/lib/html-video-player/html-video-player.component.spec.ts
Show resolved
Hide resolved
libs/ui/components/src/lib/multi-epg/multi-epg-container.component.ts
Outdated
Show resolved
Hide resolved
800ec6b to
665b429
Compare
Update navigation components to improve sidebar usability and layout. - Reformat stalker-shell navigation binding to align attributes consistently. - Add matTooltip and matTooltipPosition to portal icon and nav items to surface portal status and item labels on hover. Rework navigation markup to use mat-nav-list, add home shortcut and dividers, and hide several textual labels/actions by commenting them out to create a more compact icon-only sidebar while preserving code for future restore. - Collapse unused portal info/actions and library labels into comments to simplify DOM while keeping structure for reactivation. These changes make the left navigation more compact, provide quick hover context via tooltips, and prepare the UI for a condensed icon-driven layout.
Standardize generated installer/artifact file names across build targets by adding explicit artifactName patterns in package.json. Add a general artifactName at the top-level build config, ensure linux targets (snap/deb/rpm) carry the same pattern, and set a Windows-specific artifactName for win and nsis outputs that includes the platform and arch. This makes build outputs predictable for CI, releases, and automated upload tooling by embedding name, version, OS, arch, and extension in artifact filenames.
Update the GitHub release action to mark releases from pull request events as prerelease and to set a safe tag name when the is not triggered by a tag ref. - Set prerelease to true when github.event_name == 'pull_request' so draft releases created during PR workflows are marked as prereleases. - Use the tag name from github.ref_name when the workflow is triggered by a tag; otherwise generate a deterministic test tag "test-<sha>" to avoid using an invalid or empty tag name. This prevents accidental full releases from PR runs and ensures the action always has a valid tag_name value.
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.
Add title, user-agent, refer and origin fields to IPC payloads sent when opening MPV/VLC players and when launching streams from effects. Replace legacy userAgent property with standardized 'user-agent' key and consistently include referer and origin from channel.http. This ensures external players receive correct HTTP header metadata and stream titles for proper request handling and display.
da91d44 to
c4f7213
Compare
Update Angular in pnpm-lock to newer 20.3.x versions and align CDK/Material specifiers to the compatible 20.2.12/20.2.12 releases. This brings core, common, compiler, platform-browser, animations, forms and related packages to the 20.3.x series to fix version skew and ensure dependency compatibility. Add tsConfig for tests in libs/shared/interfaces project config so jest runner uses the correct TypeScript spec configuration, fixing test/compile issues for that library. Remove husky commit-msg hooks and local pre-commit checks to avoid running commitlint, tests and eslint on commit (CI remains unaffected).
Summary
What changed
Testing notes
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
UI/UX Improvements