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.
Add new English keys for remote control URL and QR code to support
remote-control features in the settings UI. Extend French locale with
many missing and corrected translations: add "Playlists" root entry,
Xtream/Stalker import labels, UI copy improvements (e.g. "Chaînes",
grammar fixes), new playlist export/copy messages, search/auto-refresh
labels, and removal success message. Fix several typos and phrasing in
French strings (IPTV, chaînes, ajouter(e), requièrent).
These changes enable new remote-control functionality and improve UX
for French users by completing and correcting the translations.
Add app-region: drag to container and header elements and app-region:
no-drag to interactive controls multiple components so the
Tauri window dragging behaves correctly while keeping buttons and form
controls clickable. Expand header search max width from 500px to 800px
to give more room on larger screens. Clean up and restyle video-player
toolbar toolbar primary colors and unify toolbar spacing.
Files changed include navigation, sidebar, header, main containers,
live-stream layout, navigation-bar, stalker container, and video-player
toolbar. These changes improve window drag UX on desktop and refine
toolbar/header appearance.
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.
Introduce explicit empty-state handling in RecentPlaylists:
- Replace previous direct rendering of an empty mat-list item with
app-empty-state for two cases: a global "welcome" state when no
playlists exist at all, and a "no-results" state when filters/search
return nothing. This clarifies UX and provides a CTA for adding
playlists in the welcome state.
- Change playlist data binding from playlists$ to playlistsData$ and
adapt loops and accessors to data.playlists / data.totalCount.
- Keep existing global favorites item and playlist-item rendering.
Wire up addPlaylist event and components:
- Add addPlaylistClicked output to RecentPlaylists component and
forward the event from the home component so the parent can open
the add-playlist flow.
- Import EmptyStateComponent and PlaylistType types used by the new
output.
Minor cleanup and imports:
- Reformat some imports and add tap to RxJS imports.
- Adjust template structure and placeholders for deferred loading.
Raise the maximumError for anyComponentStyle from 8kb to
kb in the web app build configuration. This relaxes the
build-size enforcement for component styles to accommodate
slightly larger CSS bundles and avoid spurious build failures.
Add new strings for the PLAYLIST view across English,
Spanish, French, German, and translations. The additions include a
welcome title description, a prompt to the first playlist, feature
labels for supported playlist types (MU/M3U, Xtream Codes Stalker),
and "no results title and description to clarify search/filter
.
These changes improve the onboarding experience new users and giveclearer feedback when searches return no. They also
ize feature labels across languages to communicate
supported playlist formats
- Shorten German settings TITLE from "Einstellungen / IPTVnator" to
"Einstellungen" to remove redundant app name and keep UI labels concise.
- Reformat and normalize Korean i18n JSON indentation and structure to
match expected layout (consistent nesting and whitespace).
- Reintroduce missing HOME -> nested sections (TABS, PLAYLISTS,
FILE_UPLOAD, URL_UPLOAD, TEXT_IMPORT, STALKER_PORTAL, XTREAM_PLAYLIST)
in ko.json to restore previously collapsed keys and ensure all keys
are present for runtime lookup.
- Fix several untranslated/placeholder labels and ensure key presence
for dialogs, validations and UI strings so translations load
consistently across components.
Update header component UI and streamline imports.
- Remove MatToolbarModule import and module list entry
because the toolbar styling is handled by local SCSS and the
Angular Material toolbar is no longer required.
- Rewrite header SCSS to introduce a .modern-header wrapper with
consistent sizing, padding, alignment and a subtle bottom border.
- Add layered ambient and depth effects: refined ::before ambient
gradient (headerAmbience), ::after bottom accent, and adjusted
keyframes for a gentler motion.
- Refine home-header styles to target .modern-header and tune colors
and gradients for a cohesive dark theme.
- Rework .brand-block visuals: lighter glass effect, adjusted
radii, blur, borders, hover transform, and shadowing for a modern
elevated look.
- Minor cleanup: remove legacy variables and comments; improve
box-sizing, layout, and pointer-event handling to ensure expected
interaction regions.
These changes modernize the header's visual design, improve layout
consistency across pages, and remove an unnecessary module import.
Enhance the header component to support a distinct "home" appearance
and emit search updates. Add a HostBinding that toggles a home-header
class from the isHome flag so styles can target the home state.
Expose a searchQuery output and wire an onSearchQueryUpdate method to
emit the search text, enabling parent components to react to user
searches.
Refactor imports to include HostBinding and output. Tidy toolbar metrics
and adjust element sizing for a compact brand block and pulsing logo.
Introduce comprehensive SCSS for the home header:
- gradient background, animated glow overlay, and edge accent
- brand block styling with blur, border, hover states and box-shadow
- logo sizing, pulse animation and responsive tweaks
- reduced toolbar height and overall visual polish
These changes separate home-specific styling from the default header
appearance and provide a programmatic hook for search interactions.
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.
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.
Refactor error handling for Xtream requests to avoid showing user
snackbars when the request is a portal status check (get_account_info).
Instead of treating these errors as full failures, log them with
console.log to indicate the portal may be unavailable and return early.
Key changes:
- Introduce isStatusCheck detection in electron and pwa services.
- Replace console.error + snackbar with console.log for status checks.
- Only display snackbars for non-status-check errors.
- Add a console.log when pwa response has no payload for status checks.
This prevents unnecessary user-facing error popups for routine
portal health/status checks while keeping errors surfaced for other
requests.
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.
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.
Change overflow handling in the xtream detail-view SCSS files to avoid
unwanted scrollbars and ensure proper layout stretching. In the web
version, remove a global overflow:auto and set overflow:visible on the
.details block and the grid container so inner content can expand as
needed. In the tauri variant, remove a min-height that forced an
artificial viewport-based height.
These tweaks fix layout clipping and scrollbar issues when detail
content
grows, and allow natural sizing across web and Tauri builds.
Add clearSelectedItem() to the stalker store to reset selected item
state (selectedVodId, selectedSerialId, selectedItvId, selectedItem).
This centralizes clearing logic and avoids manual nulling elsewhere.
Introduce goBackToList() in the container component to use the new
store method when navigating back from item details. Update the
template to conditionally show the back button when a selected item
exists, and ensure category title rendering and the disabled category
button behave correctly with the new conditional structure.
These changes simplify state management for returning from detail
views and make the template logic clearer and less error-prone.
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.
- Add missing semicolon in apps/web/src/styles.scss to fix invalid CSS
that could break style parsing for .scroll-viewport.
- Change preconnect in apps/web/src/index.html from fonts.gstatic.com to
fonts.googleapis.com and consolidate multiple Google Fonts links into
a single stylesheet URL to reduce redundant requests and ensure
Material Icons and selected font families load together.
Remove duplicated @import of Outfit in
libs/ui/components/src/lib/multi-epg/multi-epg-container.component.scss,
switch component font-family to Roboto (with fallback) and update
button font to match, ensuring consistent typography and avoiding
external import duplication across components. ese changes fix a
ntax error, optimize font loading, and standardize
typography across the UI.
Revamp the Multi-EPG component stylesheet to introduce a polished,
broadcast-control-room inspired dark theme and improved layout
styling.
- Add Google fonts (Outfit, JetBrains Mono) for a clean UI and mono
date display.
- Introduce color variables, gradients and accents for consistent
theming and easier maintenance.
- Rework base container (.parent) with subtle grid overlay and updated
typography.
- Implement a frosted glass navigation bar (#epg-navigation) with
blur, glow, and accessible button styles.
- Add today-date styling using a monospace font and glowing accent.
- Expand channels column width, update background, borders, shadows,
and hover transitions for clearer channel separation.
- Replace many hard-coded colors with variables and add transitions
for smoother interactions.
- Add utility classes for navigation buttons and improved disabled/
hover states.
These changes improve visual hierarchy, accessibility, and maintainabiity
of the EPG UI while setting up a consistent design system for further
enhancements.
Add a transient channel number overlay to the video player UI so users
see the numeric channel feedback when entering or changing channels.
- Insert conditional overlay markup in the video-player template that
renders when showChannelNumberOverlay is true and displays the
channelNumberInput value.
- Add styles for .channel-number-overlay and
.channel-number-display to center the overlay, style the numeric
display (large bold font, dark translucent background, rounded
corners, shadow) and include a brief scale-in animation.
- Keep overlay pointer-events disabled so it doesn't block player input.
This improves user experience by giving clear visual confirmation of
channel changes.
Add "Show program info (Press I)" translation and an info icon
button to the video player toolbar. Emit an infoOverlayClicked event
from the toolbar and expose isLeftDrawerOpened to control the menu
icon state. Update the menu icon to reflect drawer open/closed state.
Implement showOverlay() on the info overlay component to toggle
visibility and auto-hide after 10 seconds when shown. This enables
manual toggling of the program info overlay via the new toolbar
button or keyboard shortcut, improving discoverability and user
control of program information.
Refactor the info-overlay template to introduce a structured EPG
layout: replace the previous flat channel-logo + content structure with
an .epg-layout wrapper that groups .channel-logo and a richer .content
area. Split content into .content-header (separate program title and
channel name), conditional program description rendering, and a
program-timeline containing explicit start/end times and a progress
track. Remove fixed image width attribute and rely on responsive CSS.
Revamp component SCSS: import refined fonts, increase overlay max-height,
add horizontal padding, and add new styles for .epg-layout, .channel-logo,
.content, .content-header, .program-title and related elements. Add
animations, improved image handling (object-fit + drop shadow), and
layout spacing to support varying content lengths and improve visual
hierarchy.
These changes improve responsiveness, accessibility of EPG text
display, and visual polish of the overlay.
Update English translations for the remote-control UI and change the
documented default remote-control port.
- Change default remote control port description from 3000 to 8765 to
reflect actual configuration.
- Improve remote control UI copy:
- Add SUBTITLE "Control your IPTV player remotely".
- Capitalize UP_CHANNEL and DOWN_CHANNEL labels to "Channel Up" and
"Channel Down" for consistent UI presentation.
These changes clarify the feature and align text with current behavior.
- Replace local selected state with store signal (selectActive) in the
channel list container so templates bind to activeChannel()?.url
instead of comparing selected?.id. This unifies selection handling
with the global store and prevents stale local state.
- Update selectChannel to dispatch setActiveChannel instead of mutating
local selected property; keep EPG lookup behavior intact.
- Import selectActive alongside other selectors from m3u-state and
remove unused local InjectionToken in video player.
- Add remote control listener in VideoPlayer (Electron) to handle
channel up/down events and wire a new handleRemoteChannelChange
method skeleton. Use combineLatest/take to safely read required
observables for channel switching.
- Minor rxjs import and formatting adjustments.
These changes centralize active channel state in the store, simplify
template logic, and add support for remote channel changes on desktop.
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.
Update default remote control port from 3000 to 8765 in settings
store and component initialization to avoid conflicts with common
development ports and align with the desktop/tauri environment.
Unhide and scope the remote control UI to desktop builds only:
- Restore the remote control block in settings template and guard it
with @if (isDesktop) so the checkbox and description render for
desktop users (previously commented out as not ported).
- Keep the remote control settings section conditionally visible
when the remoteControl form value is true.
These changes ensure desktop users can configure and enable the
remote control feature with a non-conflicting default port.
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.
Add new German translation keys for sorting options used across the
UI (SORT_BY, SORT_BY_DATE, SORT_BY_RATING, SORT_BY_NAME, SORT_PLAYLISTS,
SORT_OPTIONS). Introduce EPG title and success message (EPG.TITLE,
EPG.FETCH_SUCCESS). Expand playlist-related messages: export success/error,
refresh Xtream dialog and messages (REFRESH_XTREAM, REFRESH_XTREAM_DIALOG),
remove dialog success, playlist update/error messages, auto-refresh flags,
and a safer CORS note for URL upload (URL_UPLOAD.CORS_NOTE). Add STREAM_FORMAT
label under settings.
Also improve existing German copy for GLOBAL_FAVORITES_DESCRIPTION and
minor reordering of IMPORTED_AS_TEXT to keep related keys together.
These changes localize newly added UI features (sorting, playlist import/
export, Xtream refresh, EPG feedback) and provide clearer user-facing
messages and safety guidance.
Filter out pre-release GitHub releases (beta,, rc, preview,
dev, canary, nightly) when resolving the latest app version and
validate release names using semver. Sort stable releases by
creation date and return the most recent stable release name.
Add isVersionOutdated(current, latest) to compare coerced semver
versions safely, handling invalid formats with a warning. Move
version comparison logic from the settings component to the
SettingsService and use the new helper to determine if the
installed app is outdated. This prevents false positives from
pre-release tags and improves version parsing robustness.
Update category header and list views to provide clearer context
and improve navigation state handling.
- Display category name with current page/total pages when viewing a
category (non-detail) so users see which page they're on.
- Add i18n "PAGE" key and fill "SELECT_CATEGORY" in translations for
en/de/ru to support the new page label and existing messaging.
- Tidy live-stream layout template formatting and fix filter pipe
spacing for consistency.
- Change no-channel-selected fallback to use the translated
"PORTALS.SELECT_CATEGORY" string.
- Preserve category selection state on CategoryContentView init:
only set selected category when the route category differs from
the current selection to keep paging/scroll position when returning
from a detail view.
These changes improve UX by making pagination explicit and avoiding
unnecessary state resets when navigating between list and detail.
Add a disabled category icon button next to the "Select category"
placeholder in the live stream layout when no channel is selected, and
align the placeholder text and icon with flex and spacing. This gives a
clearer visual cue for the missing category.
Also add missing translation keys ("SELECT_CATEGORY" and "PAGE") to
English, Russian and German locale files so the new UI text and paging
label are available across supported languages.
Remove unused .link-input styles from player-dialog component and tidy
vod-details template indentation and structure. Reformat container and
image/detail sections to use consistent indentation, add an alt attribute
to the movie poster img, replace several label elements with simpler divs
for clearer semantics, and ensure placeholder-cover fallback remains.
These changes improve readability, reduce unused CSS, and enhance HTML
accessibility.
Remove the PlayerDialogComponent (TS, HTML, SCSS) and the standalone
SafePipe from the xtream feature. These files were deleted because
the dialog and pipe are no longer used by the application, reducing
dead code and simplifying the web module surface.
This change prevents maintaining UI code (player
markup, styles, and clipboard/snackbar logic) and an unused DOM
sanitizer pipe, improving project maintainability and build size.
Add a complete Angular template for the Xtream Tauri account-info dialog.
The new HTML lays out user and server information in a responsive
two-column grid, including status, username, connection counts,
creation/expiry dates, trial indicator, allowed output formats and
server details (live/movies/series counts, URL, protocol, timezone,
server time and ports). Translation pipes are used for all labels and
conditional classes mark active/trial states. This provides a full UI
for displaying parsed accountInfo data and prepares the dialog for
binding with component logic and styles.
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.
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.
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.