diff --git a/.common/core/settings-core/script.js b/.common/core/settings-core/script.js index 303ce25..e00232d 100644 --- a/.common/core/settings-core/script.js +++ b/.common/core/settings-core/script.js @@ -101,6 +101,7 @@ function LoadJSON(settingsJson) { inputElement.id = setting.id; //Added setting ID inputElement.value = settingsMap.has(setting.id) ? settingsMap.get(setting.id) : setting.defaultValue; inputElement.autocomplete = 'new-password'; + inputElement.placeholder = setting.placeholder ? setting.placeholder : ''; break; case 'password': inputElement = document.createElement('input'); diff --git a/now-playing/script.js b/now-playing/script.js index 37c13e4..bf9f8e2 100644 --- a/now-playing/script.js +++ b/now-playing/script.js @@ -32,7 +32,8 @@ const fontSize = GetIntParam("fontSize", 20); const maxWidth = GetIntParam("maxWidth", 500); const textAlignment = urlParams.get('textAlignment') || 'left'; -const targetApplication = urlParams.get('targetApplication') || ''; +const includedApplications = urlParams.get('includedApplications') || ''; +const excludedApplications = urlParams.get('excludedApplications') || ''; const showAlbumArt = GetBooleanParam("showAlbumArt", true); const showProgressBar = GetBooleanParam("showProgressBar", true); const swapArtistTrack = GetBooleanParam("swapArtistTrack", false); @@ -43,6 +44,8 @@ const displayDuration = GetIntParam("displayDuration", 5); const showAnimation = urlParams.get('showAnimation') || 'slide-in-from-bottom'; const hideAnimation = urlParams.get('hideAnimation') || 'slide-out-bottom'; + + ///////////////// // GLOBAL VARS // ///////////////// @@ -315,20 +318,62 @@ function CheckSMTCBridgeVersion(installedVersion) { // Each theme must implement the following async function UpdatePlayerState(data) { - // Check if the user has provided a target application in the settings - const isFiltering = targetApplication && targetApplication.trim() !== ""; + // Parse and clean settings arrays + const includedList = includedApplications + ? includedApplications.split(',').map(app => app.trim().toLowerCase()).filter(Boolean) + : []; + + const excludedList = excludedApplications + ? excludedApplications.split(',').map(app => app.trim().toLowerCase()).filter(Boolean) + : []; - // Search for the session that matches the target application - const sessionToFind = isFiltering ? targetApplication : data.current_session_id; - let targetSession = data.sessions.find(s => { - // If filtering, check if the source_app_id matches the user's string - if (isFiltering) { - return s.source_app_id.toLowerCase() === targetApplication.toLowerCase(); - } - // Otherwise, match the system's current active session ID - return s.source_app_id === sessionToFind; + // Filter out any sessions belonging to excluded apps + const validSessions = data.sessions.filter(s => { + const appId = (s.source_app_id || "").toLowerCase(); + // Check if the source app ID matches any exclusion entry + const isExcluded = excludedList.some(excluded => appId.includes(excluded)); + return !isExcluded; }); + let targetSession = null; + + // Priority Check: If user specified included apps, hunt for them in exact order + if (includedList.length > 0) { + // Step 1: Look through the included list for an app that is CURRENTLY PLAYING + for (const targetApp of includedList) { + targetSession = validSessions.find(s => { + const matchesApp = (s.source_app_id || "").toLowerCase().includes(targetApp); + const isPlaying = s.playback_info && s.playback_info.PlaybackStatus === PlaybackStatus.PLAYING; + return matchesApp && isPlaying; + }); + if (targetSession) break; + } + + // Step 2: If none of the included apps are playing, fall back to ANY session in the included list (even if paused) + if (!targetSession) { + for (const targetApp of includedList) { + targetSession = validSessions.find(s => + (s.source_app_id || "").toLowerCase().includes(targetApp) + ); + if (targetSession) break; + } + } + } else { + // Fallback when no included list is provided: + // Priority 1: Find any session that is currently playing + targetSession = validSessions.find(s => s.playback_info && s.playback_info.PlaybackStatus === PlaybackStatus.PLAYING); + + // Priority 2: If nothing is playing, use system's current active session ID + if (!targetSession) { + targetSession = validSessions.find(s => s.source_app_id === data.current_session_id); + } + + // Priority 3: Ultimate fallback to the first valid session available + if (!targetSession && validSessions.length > 0) { + targetSession = validSessions[0]; + } + } + // If a target session was found, update the state of the widget if (targetSession) { // Extract the relevant properties from the session diff --git a/now-playing/settings/settings.json b/now-playing/settings/settings.json index 29f1910..eedca82 100644 --- a/now-playing/settings/settings.json +++ b/now-playing/settings/settings.json @@ -95,11 +95,20 @@ "group": "Appearance" }, { - "id": "targetApplication", - "label": "Target Application", - "description": "Specific app to track. Leave empty to automatically follow the active player.
View active sources", + "id": "includedApplications", + "label": "Included Apps", + "description": "List of apps to display, in order of priority.
Leave empty to track currently focused app.
View active sources", "type": "text", - "placeholder": "e.g., Spotify.exe", + "placeholder": "Spotify.exe, vlc.exe", + "defaultValue": "", + "group": "General" + }, + { + "id": "excludedApplications", + "label": "Excluded Apps", + "description": "Apps listed here will not be displayed.
View active sources", + "type": "text", + "placeholder": "Chrome, vlc.exe", "defaultValue": "", "group": "General" },