Fixes#319 — Server appears as "undefined" on Samsung TV after network interruptions
when using mDNS (.local) hostnames.
Root cause:
The injected jellyfin_credentials in localStorage were missing the `Name` property.
When the TV couldn't reach the server (mDNS resolution failure), Jellyfin Web had
no cached server name to display, resulting in literal "undefined".
Changes:
- Add `Name` property to injected auto-login credentials using the real ServerName
from /System/Info/Public, with fallback to the server URL
- Store JellyfinServerName in AppSettings (fetched during server validation and
authentication, cleared on logout)
- Add the server's LocalAddress (IP-based) as a fallback entry in config.json so
the TV can still connect when mDNS resolution fails
- Add a visible warning banner in the UI when a .local hostname is detected,
advising users to use a direct IP address instead
- Add lblMdnsWarning localization key to all 28 language files (translated for
da, nl, en, fr, de, pt, tr — English fallback for remaining languages)
Description
Fixed UI freeze when update dialog appears during startup. Previously, network scanning and GitHub release loading continued running in the background while the update dialog was displayed, causing the window to freeze.
Changes:
- Added _initializationCts to cancel initialization tasks
- Pass cancellation token to LoadReleasesAsync() and LoadDevicesAsync()
- Cancel background tasks before showing update dialog
- Resume initialization after user dismisses dialog (Cancel/Skip/Manual)
- Added cancellation check in DeviceHelper.ScanForDevicesAsync() loop
Summary
- Add auto-update checker using GitHub Atom feed (bypasses API rate limits)
- Show update dialog on startup with two options: "Open Releases" (manual) or "Update Now" (automatic)
- Automatic updates: download, extract, replace files, restart app
- Support for Windows, Linux, and macOS
Changes
- New services: `UpdaterService`, `UpdateDialogService`
- New dialog: `UpdateDialog` with version info and release notes
- New settings: `CheckForUpdatesOnStartup`, `SkippedUpdateVersion`
- Localization: All 6 languages (EN, DE, NL, FR, DA, TR)
Technical Details
- Uses `/releases.atom` endpoint instead of REST API (no rate limit)
- Falls back to API only for download URLs when update is available
- Update script handles file replacement while app is closed
- Version comparison with semver support
Users with Jellyfin servers configured with a base path (e.g., http://ip:8096/jellyfin/)
were unable to authenticate. The "IP : Port / Full URL" mode didn't include a base path field, and
while "Full URL" mode worked, it wasn't intuitive for this use case.
The server validation (/System/Info/Public) succeeded, but authentication failed with:
'<' is an invalid start of a value - indicating the API returned HTML instead of JSON
because the base path was missing from the auth endpoint URL.
Fix: Added a third server input mode "IP : Port : Path" that allows users to enter
protocol, IP, port, and base path separately.
CSS Style Tab
- Theme preview images are now clickable - opens the theme's GitHub README page
- Clear button now also resets the theme preview
Settings
- Fixed dark mode toggle to be round (matching main window style)
Summary
- Add dark mode toggle icon (☀️/🌙) to main window and settings header for quick theme switching
- Create ThemeService for centralized theme management with save/load from settings
- Replace all hardcoded colors with DynamicResource for proper theme support
- Synchronize theme state between MainWindow and Settings via ThemeChanged event
- Update Buttons, TextBlocks, and ComboBoxes styles to be theme-aware
- Fix dark mode for all modal dialogs (BuildInfo, InstallationComplete, Installing, IpInput, TvLogs)
- Update DialogService to use theme-aware colors from FluentTheme resources
Summary
- Remove UpdateMode dropdown from Server tab - settings are now always applied via JS injection
- Remove User Tab completely - these settings are default in Jellyfin and API calls are unnecessary
- Simplify JellyfinPackagePatcher to always apply server settings when JellyfinIP is configured
- Remove UpdateUserConfigurationsAsync API method and InjectUserSettingsAsync HTML injection
- Clean up related constants, AppSettings properties, and localization strings (6 languages)
Removed
- ConfigUpdateModes constants and ConfigUpdateMode setting
- User settings: AutoPlayNextEpisode, RememberAudioSelections, RememberSubtitleSelections, PlayDefaultAudioTrack, UserAutoLogin
- 8 localization keys across all language files
Summary
- Add JellyThemes section to CSS Style tab with 6 pre-configured themes (Obsidian, Solaris, Nebula, Ember, Void, Phantom)
- Clicking a theme button inserts the CSS @import statement and auto-validates
- Add "GitHub JellyThemes" link button to open the theme repository
- Add localization strings for all 6 languages (en, de, nl, da, fr, tr)
New Files
- Models/JellyTheme.cs - Theme model with metadata (name, icon, color, CSS URL)
Modified Files
- ViewModels/JellyfinConfigViewModel.cs - JellyThemes collection and commands
- Views/JellyfinConfigView.axaml - Theme buttons UI with WrapPanel layout
- All localization JSON files - Added lblJellyThemes and lblJellyThemesHint
Summary
- Added admin detection during authentication - checks User.Policy.IsAdministrator from Jellyfin API
- Admin users can now select multiple Jellyfin users to configure during installation
- Non-admin users only configure their own account (single-user mode)
- Added "Refresh" button to reload user list without logout/login
- Added hint text explaining that selected users will be configured during installation
Changes
- JellyfinApiClient: Extended AuthenticateAsync() to return isAdmin, added LoadUsersAsync() method
- AppSettings: Added IsJellyfinAdmin and SelectedUserIds properties
- JellyfinConfigViewModel: Added admin state, user collections, refresh command
- JellyfinConfigView.axaml: Added multi-select ListBox for users (admin only), refresh button, hint text
- TizenInstallerService: Updated to use selected user IDs when admin, single user ID otherwise
- Localization: Added lblRefreshUsers and lblUserSelectionHint (6 languages)
Behavior
- Admin login: Shows user list with multi-select, "Refresh" button, configures all selected users
- Normal user login: No user selection UI, only own account is configured
- Auth status shows "Authenticated (Admin)" or "Authenticated"
Summary
- Removed obsolete Legacy API Key system - authentication now uses AccessToken from username/password login exclusively
- Removed user dropdown (LoadUsersAsync, AvailableJellyfinUsers, SelectedJellyfinUser) - no longer needed since you authenticate AS a specific user
- Removed "everyone" code path from TizenInstallerService
- Fixed server input mode not persisting after restart (Full URL mode would reset to IP:Port)
- Added Logout button to allow switching Jellyfin accounts
Changes
- JellyfinApiClient: Removed `LoadUsersAsync()`, updated auth to use AccessToken
- JellyfinConfigViewModel: Removed user collections, selection handlers, and LoadJellyfinUsersAsync
- JellyfinConfigView.axaml: Simplified Auto-Login section, removed user ComboBox
- AppSettings: Removed `JellyfinApiKey`, added `ServerInputMode` for persistence
- TizenInstallerService: Simplified to use single authenticated UserId
- Localization: Cleaned up obsolete labels (6 languages)
Description:
Consolidates the separate Settings window into the Jellyfin Config window, now renamed to "Settings".
Changes:
- Added new "Main" tab containing all application settings (Language, Certificate, Local IP, installation options)
- Merged SettingsViewModel into JellyfinConfigViewModel
- Updated navigation to open unified Settings window directly from MainWindow
- Removed obsolete SettingsView and SettingsViewModel files
- Added localization support for new tab in all 6 languages (EN, DE, DA, FR, NL, TR)
The Settings window now has 5 tabs: Main, Server, Playback, User, CSS Style
Fixed bug where closing the success modal after installation would shut down the entire app instead of just the modal window.
- Changed CloseWindow() from desktop.Shutdown() to RequestClose event
- Window now properly subscribes to RequestClose and calls Close()
Summary:
- Add new "CSS Style" tab in Jellyfin Config for custom CSS/theme injection
- Support for inline CSS and @import rules (e.g., ElegantFin, Ultrachromic themes)
- CSS validation button that tests @import URL reachability and syntax errors
- Custom CSS is injected as <style> tag into Jellyfin web app during installation
Changes:
- AppSettings.cs: Add CustomCss property
- JellyfinConfigViewModel.cs: Add CustomCss observable, validation logic, URL extraction
- JellyfinConfigView.axaml: New CSS Style tab with multiline TextBox and Validate button
- JellyfinHtmlPatcher.cs: Add InjectCustomCssAsync() method
- JellyfinWebPackagePatcher.cs: Call CSS injection during package patching
- Localization: Add CSS translations for all 6 languages (en, de, fr, nl, tr, da)
Features:
- Validates @import URLs are reachable before installation
- Basic CSS syntax validation (balanced braces/parentheses)
- Button disabled when CSS field is empty
- Status display with color feedback (green=valid, red=error)
Server Tab now has 3 sections:
1. Server Settings - Update Mode, Input Mode, Server URL/IP, Connection Status
2. Auto-Login Settings - User, Password, Authentication
3. Advanced Settings - TV Debug, Server Scripts, YouTube Fix
User Tab addition:
- Added "Legacy API Key System" section at bottom
- Moved API Key field and Jellyfin User(s) dropdown here
- These are legacy features from WPF era, kept for backward compatibility
### Bug Fixes:
- Fixed ServerMismatch breaking auto-login - The auto-login credentials were using a fake server ID derived from the URL (serverUrl.replace(/[^a-zAZ0-9]/g, '')). Now fetches the real server GUID from /System/Info/Public endpoint and stores it in AppSettings.JellyfinServerId for correct localStorage credential injection.
- Fixed URL handling for reverse proxy setups - URLs without explicit ports (e.g., https://xx.seedhost.eu/xxx/jellyfin/) now work correctly. Default ports (443 for HTTPS, 80 for HTTP) are no longer included in the stored URL.
- Auto-enable config patching on login - When authentication succeeds and Update Mode is "None", it automatically switches to "Server Settings" to enable
config patching. Removed the unused EnableAutoLoginConfigCommand button.
### UI Improvements:
- Reorganized UI with TabControl - Split settings into 3 tabs:
- Server: Server settings + Auto-login settings
- Playback: Browser/playback preferences
- User: User-specific settings
- Server Input Mode selector - Users can choose between:
- IP : Port mode - Enter protocol, IP, and port separately
- Full URL mode - Paste complete URL (auto-parses all fields)
- Removed Base Path field - No longer needed since Full URL mode handles paths automatically
- Improved button consistency - Test Server and Test Login buttons now have matching sizes and styling
- Label updates:
- "Status" → "Server Status"
- "Test" button → "Test Server"
- "Login" button → "Test Login"
### Localization:
Added/updated translations for all 6 languages (en, de, fr, nl, tr, da):
- lblTabServer, lblTabPlayback, lblTabUser
- lblServerInputMode, lblServerUrl, lblConnectionStatus
- lblAutoLoginUser, lblTestServer (updated)
### Modified files:
- JellyfinConfigView.axaml - Complete UI restructure with tabs
- JellyfinConfigViewModel.cs - New properties, auto-validation logic, server ID fetching
- JellyfinHtmlPatcher.cs - Fixed auto-login to use real server ID
- JellyfinPluginPatcher.cs - Exposed API client
- AppSettings.cs - Added JellyfinServerId, JellyfinServerLocalAddress
- All localization JSON files - New translation keys
Add support for Jellyfin servers behind reverse proxies (e.g., seedhost) and automatic login credential injection for Samsung TV installations.
Features:
- Add Base Path field for reverse proxy URLs (e.g., /xxx/jellyfin)
- Add JellyfinFullUrl property that combines host:port with base path
- Add username/password authentication with access token storage
- Add auto-login injection that pre-populates localStorage credentials
- Add "Test Connection" button to verify server reachability
- Add "Login" button to authenticate and store access token
Modified files:
- Helpers/AppSettings.cs: New properties for base path and credentials
- Helpers/JellyfinApiClient.cs: AuthenticateAsync() and TestServerConnectionAsync()
- Helpers/JellyfinHtmlPatcher.cs: InjectAutoLoginAsync() for credential injection
- Helpers/JellyfinWebPackagePatcher.cs: Integrate auto-login during packaging
- ViewModels/JellyfinConfigViewModel.cs: UI bindings and commands
- Views/JellyfinConfigView.axaml: New Auto-Login Settings section
- Assets/Localization/*.json: Added translations (en, de, fr, nl, da)
Fix for Add reverse proxy path support and auto-login credentials injection