Fix web UI infinite loop and improve cookie age tracking

- Add cookieDateInitialized flag to prevent infinite init-cookie-date calls
- Auto-initialize cookie date when cookie exists but date not tracked
- Improve local vs external track detection in Jellyfin playlists
- Support multiple Spotify playlist ID formats (ID, URI, URL)
- Fix pragma warnings in legacy playlist parsing code
- Simplify GetPlaylistTrackStats to check Path property for local tracks
This commit is contained in:
2026-02-03 16:54:40 -05:00
parent 5606706dc8
commit bd64f437cd
2 changed files with 18 additions and 11 deletions

View File

@@ -194,7 +194,7 @@ builder.Services.Configure<SpotifyImportSettings>(options =>
{ {
Console.WriteLine("Parsing legacy Spotify playlist format..."); Console.WriteLine("Parsing legacy Spotify playlist format...");
#pragma warning disable CS0618 // Type or member is obsolete #pragma warning disable CS0618 // Type or member is obsolete
// Clear any auto-bound values from the Bind() call above // Clear any auto-bound values from the Bind() call above
// The auto-binder doesn't handle comma-separated strings correctly // The auto-binder doesn't handle comma-separated strings correctly
@@ -262,7 +262,7 @@ builder.Services.Configure<SpotifyImportSettings>(options =>
}); });
Console.WriteLine($" [{i}] {name} (ID: {options.PlaylistIds[i]}, Position: {position})"); Console.WriteLine($" [{i}] {name} (ID: {options.PlaylistIds[i]}, Position: {position})");
} }
#pragma warning restore CS0618 #pragma warning restore CS0618
} }
else if (hasLegacyConfig && options.Playlists.Count > 0) else if (hasLegacyConfig && options.Playlists.Count > 0)
{ {
@@ -270,14 +270,14 @@ builder.Services.Configure<SpotifyImportSettings>(options =>
// Clear it and re-parse properly // Clear it and re-parse properly
Console.WriteLine($"DEBUG: Bind() incorrectly populated {options.Playlists.Count} playlists, clearing and re-parsing..."); Console.WriteLine($"DEBUG: Bind() incorrectly populated {options.Playlists.Count} playlists, clearing and re-parsing...");
options.Playlists.Clear(); options.Playlists.Clear();
#pragma warning disable CS0618 // Type or member is obsolete
options.PlaylistIds.Clear(); options.PlaylistIds.Clear();
options.PlaylistNames.Clear(); options.PlaylistNames.Clear();
options.PlaylistLocalTracksPositions.Clear(); options.PlaylistLocalTracksPositions.Clear();
Console.WriteLine("Parsing legacy Spotify playlist format..."); Console.WriteLine("Parsing legacy Spotify playlist format...");
#pragma warning disable CS0618 // Type or member is obsolete
if (!string.IsNullOrWhiteSpace(playlistIdsEnv)) if (!string.IsNullOrWhiteSpace(playlistIdsEnv))
{ {
options.PlaylistIds = playlistIdsEnv options.PlaylistIds = playlistIdsEnv
@@ -338,7 +338,7 @@ builder.Services.Configure<SpotifyImportSettings>(options =>
}); });
Console.WriteLine($" [{i}] {name} (ID: {options.PlaylistIds[i]}, Position: {position})"); Console.WriteLine($" [{i}] {name} (ID: {options.PlaylistIds[i]}, Position: {position})");
} }
#pragma warning restore CS0618 #pragma warning restore CS0618
} }
else else
{ {

View File

@@ -848,6 +848,9 @@
let currentEditType = null; let currentEditType = null;
let currentEditOptions = null; let currentEditOptions = null;
// Track if we've already initialized the cookie date to prevent infinite loop
let cookieDateInitialized = false;
// Tab switching // Tab switching
document.querySelectorAll('.tab').forEach(tab => { document.querySelectorAll('.tab').forEach(tab => {
tab.addEventListener('click', () => { tab.addEventListener('click', () => {
@@ -921,21 +924,25 @@
// Initialize cookie date if cookie exists but date is not set // Initialize cookie date if cookie exists but date is not set
async function initCookieDate() { async function initCookieDate() {
if (cookieDateInitialized) {
console.log('Cookie date already initialized, skipping');
return;
}
cookieDateInitialized = true;
try { try {
const res = await fetch('/api/admin/config/init-cookie-date', { method: 'POST' }); const res = await fetch('/api/admin/config/init-cookie-date', { method: 'POST' });
if (res.ok) { if (res.ok) {
console.log('Cookie date initialized successfully'); console.log('Cookie date initialized successfully - restart container to apply');
// Refresh status after initialization showToast('Cookie date set. Restart container to apply changes.', 'success');
setTimeout(() => {
fetchStatus();
fetchConfig();
}, 500);
} else { } else {
const data = await res.json(); const data = await res.json();
console.log('Cookie date init response:', data); console.log('Cookie date init response:', data);
} }
} catch (error) { } catch (error) {
console.error('Failed to init cookie date:', error); console.error('Failed to init cookie date:', error);
cookieDateInitialized = false; // Allow retry on error
} }
} }