v1.5.0: custom EPG sources, channel mapping, category picker, backup domains, Xtream live format, desktop tray + titlebar + notifications, settings panel polish#61
Merged
Conversation
refactor: improve splash comet setup logic and enhance canvas resizing
1 task
- Removed deprecated category management functions and replaced them with a new category picker implementation. - Updated event listeners to utilize the new category picker for handling category changes. - Simplified category filtering logic by integrating the picker’s filtering capabilities. - Cleaned up unused variables and functions related to category management. - Enhanced the UI for category selection with updated CSS styles for better visibility and interaction. closes #62
i18n key check
Missing keys fall back to English at runtime - this is informational, not a failure. |
User-facing - Per-playlist primary EPG URL override and additional waterfall sources on /login. New "Test sources" button validates without saving; new "Don't use the provider's default EPG" toggle skips auto-detect. - "Map channels" dialog on /epg lets users manually map a channel to any XMLTV entry when auto-match misses. Picker shows display-name + tvg-id + programme count, with a current-selection card and "Clear override". - Auto-name fallback: channels without a tvg-id (or with a tvg-id that doesn't match the XMLTV) now match by normalised display-name with HD/FHD/UHD/4K/SD suffix stripping and separator-insensitive compare, so "MDR Sachsen HD" auto-resolves to "MDR Sachsen", "Channel 21 HD" to "Channel21". - M3U Live TV side panel now reads from the loaded XMLTV instead of the hardcoded "No EPG available for M3U source" stub. Plumbing - Multi-source fetch is parallel via Promise.allSettled; per-URL conditional GET (If-Modified-Since/ETag) + per-URL IDB cache so a single 304 still benefits the merge. - Magic-byte gzip sniff (1F 8B) on every response, in addition to URL ext and Content-Type heuristics. - Force tauri-plugin-http for EPG fetches so the desktop / Android builds bypass browser CORS on arbitrary XMLTV hosts. - O(1) name lookup via a per-playlist nameIndex built once per EPG load. - Virtualised mapping list (~30 of 53k rows in DOM), debounced search, memoised tvg-id resolution. Other - ~50 new i18n keys translated to all 16 locales. - Locale message cache key bumped to v2 to invalidate stale pre-paint caches. - todo.md: extended programme-reminders entry with system-tray plan. Closes #63, closes #64
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
1 task
- Introduced UI elements for managing backup domains in the login page. - Implemented functionality to read and validate backup domain credentials. - Enhanced the Xtream API fetch mechanism to support automatic failover to backup domains. - Updated translations for backup domain features in Urdu and Chinese. - Refactored existing API calls to utilize the new xtreamApiFetch method for improved error handling and failover logic. ref #63
1 task
- Updated the playlist URL validation to accept any http(s) URL that serves an M3U playlist, making the extension optional. - Modified localization strings across multiple languages to reflect the new validation criteria for playlist URLs. - Enhanced the login page to display the updated helper text for playlist URL input. - Implemented changes in the catalog and player runtime scripts to support the new URL validation and improve container detection for streaming. closes #65
…atform clipboard write functionality
…rate into download process
…ry management strings feat(login): enhance focus management for spatial navigation fix(epg): improve rendering and interaction for category picker with accessibility enhancements fix(epg): optimize category selection and filtering logic fix(epg): update category selection state handling and aria attributes fix(epg): improve handling of document-level event listeners for category picker fix(epg): clear caches on active playlist change fix(epg): implement candidate fetch with timeout for Xtream API calls fix(movies): remove unused render token variable fix(series): remove unused render token variable
…and accessibility
- Updated language files for multiple languages to include translations for new settings. - Enhanced accessibility by adding ARIA labels for settings navigation. - Improved layout and styling for settings page to enhance user experience.
…proved scroll behavior
1 task
…r handling in loadTs function
…ay and update downloads page to use it feat(settings): refactor hash writing logic for better readability and maintainability feat(layout): change CatalogWarmingIndicator to load on idle for performance optimization feat(epg): enhance EPG response handling with improved stream processing and timeout support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v1.5.0 release. Headline work below; full changelog will land in the GitHub release notes once tagged.
Custom EPG sources + Jellyfin-style channel mapping
User-facing on
/loginand/epg:/login. A new "Test sources" button validates URLs without saving, and a "Don't use the provider's default EPG" toggle skips auto-detect entirely./epglets users manually map a channel to any XMLTV entry when auto-match misses. The picker shows display-name + tvg-id + programme count, with a current-selection card and "Clear override". List is virtualised (~30 of 53k rows in DOM), search is debounced, and tvg-id resolution is memoised.Plumbing:
Promise.allSettled; per-URL conditional GET (If-Modified-Since/ETag) + per-URL IDB cache so a single 304 still benefits the merged result.1F 8B) on every response, in addition to URL extension andContent-Typeheuristics.tauri-plugin-httpso desktop and Android bypass browser CORS on arbitrary XMLTV hosts.nameIndexbuilt once per EPG load.epg-worker.tsWeb Worker so multi-source merges don't jank the main thread.Closes #63, closes #64.
Shared category picker
CategoryPickerDialog.astrocomponent plussrc/scripts/lib/category-picker.ts(single ~650 LOC controller) replaces the four duplicated inline picker implementations that lived in/livetv,/movies,/series, and/epg.scoreNormMatch(prefix > whole-word > substring), stable on ties viaorigIndexso unrelated rows don't reorder when typing.data-row-kind="pseudo|all|hidden|regular"so styling and D-pad navigation can target row classes without string-matching the label.Closes #62.
Backup domains (Xtream)
/loginfor declaring backup domains per Xtream playlist alongside the primary host.src/scripts/lib/xtream-api.jswrapsplayer_api.phpcalls with automatic mirror failover. Candidates are fired sequentially until one returns 2xx; the winning index is pinned increds.jsso subsequent calls (including stream-URL builds vialoadCreds) target the same working host until the entry list changes.account-info.js,catalog.js, EPG auto-detect, etc.) to go throughxtreamApiFetchfor unified error handling.Refs #63.
Relaxed M3U URL validation + container detection
/loginaccepts anyhttp(s)://URL that serves an M3U playlist; the.m3u/.m3u8extension requirement is gone. Some providers (notably Dispatcharr) serve playlists from extensionless endpoints, so the hard regex blocked legitimate sources.streamKindHint+probeContainerinplayer-runtime.tsdecide HLS vs raw TS from URL extension + MIME, with an asyncRange: bytes=0-0Content-Type probe for ambiguous URLs (Dispatcharr's/proxy/ts/stream/<uuid>, Xtream's bare/live/<u>/<p>/<id>). Per-origin probe cache so a provider isn't re-probed on every channel switch.ensureLiveextracts thex-tvg-url/tvg-urlvalue from the M3U body intoxt_m3u_epg:<id>so the EPG-source resolver can pick it up.Closes #65.
Advanced playback: Xtream live stream format
<details>block on/loginfor Xtream playlists with a Live stream format selector: HLS (.m3u8) - default - or MPEG-TS (.ts).liveContaineron the Xtream entry; honoured whenstream.tsbuilds the live stream URL so users can force.tsfor providers that don't serve.m3u8(Dispatcharr) without changing anything else.ts.Refs #65.
Native container support in the embedded player
player-runtime.tsnow recognises a third stream kind,native, formp4,m4v,mkv,webm,mov,avi,m4a,mp3,aac,flac,ogg, and anyvideo/*/audio/*MIME. Both the Video.js backend (newloadNativepath) and the ArtPlayer backend skip hls.js / mpegts.js entirely and hand the URL straight to the underlying<video>element. The async container probe also returnsnativewhen it sees a generic media MIME, so extensionless URLs that serve straight MP4 still play.RTSP playback fix (external mpv)
buildMpvArgsnow appends--demuxer-lavf-o=rtsp_transport=udp+tcpwhenever the source isrtsp://, so mpv negotiates UDP first and falls back to TCP. Fixes "Open in MPV" being unable to play RTSP streams without manual user config. Unit-tested intests/player-runtime.test.ts.Window state + custom title bar (desktop)
tauri-plugin-window-stateis now registered on desktop; window position, size, and maximized state persist across launches.decorations: falseon desktop;set_shadow(true)keeps the drop shadow. Newsrc/components/TitleBar.astrorenders only whenhtml[data-tauri-desktop]is set, so Android, iOS, and web still use the host chrome.data-tauri-drag-regionstrip + minimize / maximize / close window-control buttons. Close routes through the sameCloseRequestedevent as the native X, so the close-to-tray behaviour from the new tray still applies.Sidebar,CatalogWarmingIndicator, and the toast container had their top offsets / safe-area padding updated so they sit below the custom title bar on desktop without clipping or overlapping it.System tray (desktop)
src-tauri/src/tray.rsinstalls a tray icon + menu: Show / Hide window, quick navigation (Live TV, Movies, Series, Search, Guide, Downloads, Settings), and Quit (withCmdOrCtrl+Qaccelerator).xt:tray:navigate <route>whichsrc/scripts/lib/tray-handler.tsresolves with a full document navigation (Astro is multi-page, so SPA-style routing isn't an option).Cmd+W/WM_CLOSE) hides the window rather than exiting. Quit is reached only via the tray menu / accelerator. This is the prerequisite for the upcoming programme-start reminders and any background-while-minimized features.Native clipboard + notifications
src/scripts/lib/clipboard.tswrites via@tauri-apps/plugin-clipboard-manageron Tauri (Windows / macOS / Linux viaarboard, Android viaClipboardManager, iOS viaUIPasteboard) and falls back tonavigator.clipboard.writeTexton web. Wired into the Stream-diagnostic "Copy report" button and Live TV's right-click "Copy stream URL". Bypasses the WebView gesture + permission restrictions that previously broke copy on mobile.src/scripts/lib/notify.tsroutes through@tauri-apps/plugin-notificationon Tauri so notifications land in the OS notification surface (Toast / Notification Center /NotificationManager/UNUserNotificationCenter) and uses the browserNotificationAPI on web. Permission is requested lazily on firstnotify(...)call and cached. Wired into download-complete on both the desktop and Android download paths, with i18n stringsdownloads.notify.complete.title/.body/.bodyGeneric.Settings page: "living instrument panel"
#settings-playlists,#settings-preferences,#settings-data,#settings-help,#settings-about,#settings-support,#settings-danger) with a sticky side-nav rail onlg+viewports that scrolls into a horizontal pill row on narrow screens.src/scripts/settings/settings_effects.tsadds three layered interactions on top of the existing controls:[aria-pressed="true"]buttons inside every[role="radiogroup"]via WAAPI + FLIP (font scale, theme, EPG default, channel column width, retention, perf mode...)..icon-mark-host/ settings-group children) emits a brief accent ring so the change is felt.data-perf-mode="on"collapse all of the above to instant snaps - placement still works, just without the morph.aria-label="Settings sections"(i18n'd), every settings link is keyboard-focusable, danger-zone link carriesdata-danger="true"for styling without colour-only signal.WelcomeCard component
src/components/WelcomeCard.astro- a reusable "no playlists yet" hero card used on/and/livetv, replacing the ad-hoc empty-state markup that lived inline in each page. Same hit targets, same i18n keys, single source of truth.Layout polish
max-widthand adjusted poster dimensions on/movies/detail,/series/detail,/login, and/searchso 1080p TVs no longer pin content to the left and detail-page posters scale predictably across breakpoints.Splash polish
userToPxscales offMath.min(contentW, contentH)so the orbit stays inside the visible square regardless of aspect.Misc
package.jsonandsrc-tauri/tauri.conf.json.toast.jsmigrated to TypeScript (toast.ts); call sites untouched.todo.md: extended programme-reminders entry with system-tray plan.tests/epg-data.test.tscovering mapping / name-normalisation edge cases.1.5.0 release polish
Late fixes caught while testing the release branch on Android:
xmltv.phpbody streams throughtauri-plugin-httpvery slowly on Android. The 20s default fetch timeout aborted the body read mid-stream and EPG never populated. Bumped the EPG-specific timeout to 90s, and switched gzip decompression to use an explicitReadableStreamso it doesn't rely onBlob.prototype.stream()(missing on some Android WebView builds)./settingsnudged the route hero off-screen on every load becausesetActive()wrote#settings-playliststo the URL on initial render. Initial entry no longer touches the URL; the hash is only written on explicit nav-link click. Also fixed the active highlight sticking on Android by switchingpickActive()fromoffsetToptogetBoundingClientRect().{"uri":"content://..."}). Promoted the existing prettifier insettings.astrointo a sharedandroid-fs.jsexport and reused it on the downloads page.tauri android devpanicked at boot becauseandroid_loggerandtauri_plugin_logboth tried to claim the globallogslot. Skipped the log plugin on Android (android_loggeralready routes to logcat).SpatialNavigation.init/add/makeFocusabletorequestIdleCallbackwith a first-arrow-keydown fallback, so touch-only Android navigations don't pay the 200-500ms per-page tabindex-walk cost. SwitchedCatalogWarmingIndicatorfromclient:loadtoclient:idlefor the same reason.