@@ -1579,15 +1579,13 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
15791579 let ytAudioIframe = null;
15801580 let ytPlayer = null;
15811581 let ytPlayerReady = false;
1582- let fadeInterval = null;
15831582 let currentQuery = null;
15841583 let lastUrl = null;
15851584 let lastAppID = null;
15861585 let stoppingMusic = false;
15871586 let pausedForGame = false;
15881587 const sessionCache = new Map();
15891588
1590- // ------------------------ LocalStorage Wrapper ------------------------
15911589 localStorage.setItem = function (key, value) {
15921590 originalSetItem(key, value);
15931591 if (key === LOCAL_STORAGE_KEY) {
@@ -1614,7 +1612,6 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
16141612 } catch { return false; }
16151613 }
16161614
1617- // ------------------------ Cache Handling ------------------------
16181615 function loadCache() {
16191616 try { return JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY) || "{}"); }
16201617 catch { return {}; }
@@ -1647,7 +1644,6 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
16471644 sessionCache.set(query, entry);
16481645 }
16491646
1650- // ------------------------ YouTube API & Player ------------------------
16511647 if (!window.__MY_THEMEMUSIC_SCRIPT_LOADED__) {
16521648 Object.defineProperty(window, "__MY_THEMEMUSIC_SCRIPT_LOADED__", { value: true });
16531649 const tag = document.createElement('script');
@@ -1666,7 +1662,7 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
16661662 return waitForYouTubeAPI().then(() => {
16671663 if (ytPlayer && ytPlayerReady) {
16681664 if (ytPlayer.getVideoData?.().video_id === videoId) { ytPlayer.playVideo?.(); return; }
1669- return fadeOutAndStop().then(() => createYTPlayer(videoId));
1665+ return fadeOutAndStop({ clearCurrent: false } ).then(() => createYTPlayer(videoId));
16701666 }
16711667
16721668 ytAudioIframe?.remove();
@@ -1690,37 +1686,47 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
16901686 });
16911687 }
16921688
1693- function fadeOutAndStop() {
1689+ function fadeOutAndStop({ clearCurrent = true, fadeDuration = 300 } = {} ) {
16941690 return new Promise(resolve => {
16951691 if (!ytPlayer) return resolve();
16961692 pausedForGame = true;
1697- let volume = 100;
1698- clearInterval(fadeInterval);
16991693
1700- fadeInterval = setInterval(() => {
1694+ const startVolume = ytPlayer.getVolume?.() ?? 100;
1695+ const startTime = performance.now();
1696+
1697+ function step(now) {
17011698 if (!ytPlayer) return cleanup();
1702- volume = Math.max(0, volume - 10);
1703- ytPlayer.setVolume?.(volume);
1704- if (volume <= 0) cleanup();
1705- }, 50);
1699+
1700+ const elapsed = now - startTime;
1701+ const progress = Math.min(elapsed / fadeDuration, 1);
1702+ const newVolume = Math.round(startVolume * (1 - progress));
1703+
1704+ ytPlayer.setVolume?.(newVolume);
1705+
1706+ if (progress < 1) {
1707+ requestAnimationFrame(step);
1708+ } else {
1709+ cleanup();
1710+ }
1711+ }
17061712
17071713 function cleanup() {
1708- clearInterval(fadeInterval);
1709- fadeInterval = null;
17101714 try { ytPlayer.stopVideo?.(); ytPlayer.destroy?.(); } catch {}
17111715 ytAudioIframe?.remove();
17121716 ytAudioIframe = null;
17131717 ytPlayer = null;
17141718 ytPlayerReady = false;
17151719 currentQuery = null;
1716- clearCurrentlyPlaying();
1717- setTimeout(() => { pausedForGame = false; }, 2000);
1720+
1721+ if (clearCurrent) clearCurrentlyPlaying();
1722+ pausedForGame = false;
17181723 resolve();
17191724 }
1725+
1726+ requestAnimationFrame(step);
17201727 });
17211728 }
17221729
1723- // ------------------------ Currently Playing ------------------------
17241730 function updateCurrentlyPlaying(query, videoId) {
17251731 try {
17261732 const data = loadCache();
@@ -1738,11 +1744,13 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
17381744 } catch (e) { console.error(e); }
17391745 }
17401746
1741- // ------------------------ Play Theme Music ------------------------
17421747 function playYouTubeAudio(query) {
17431748 if (!getThemeMusicEnabled()) return;
17441749 if (query === currentQuery && ytPlayer && ytPlayerReady) return;
1750+
1751+ const prevQuery = currentQuery;
17451752 currentQuery = query;
1753+
17461754 updateCurrentlyPlaying(query, "loading");
17471755
17481756 const cachedId = getCachedVideo(query);
@@ -1751,7 +1759,7 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
17511759 return createYTPlayer(cachedId);
17521760 }
17531761
1754- return fadeOutAndStop().then(() => {
1762+ return fadeOutAndStop({ clearCurrent: false } ).then(() => {
17551763 return fetch("https://nonsteamlaunchers.onrender.com/api/x7a9/" + encodeURIComponent(query))
17561764 .then(res => res.json())
17571765 .then(data => {
@@ -1760,7 +1768,10 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
17601768 updateCurrentlyPlaying(query, data.videoId);
17611769 return createYTPlayer(data.videoId);
17621770 })
1763- .catch(() => { console.error("Theme music fetch failed"); updateCurrentlyPlaying(query, null); });
1771+ .catch(() => {
1772+ console.error("Theme music fetch failed");
1773+ updateCurrentlyPlaying(prevQuery, null);
1774+ });
17641775 });
17651776 }
17661777
@@ -1773,7 +1784,6 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
17731784 }
17741785 });
17751786
1776- // ------------------------ URL & App Handling ------------------------
17771787 function handleAppId(appId) {
17781788 if (!getThemeMusicEnabled() || pausedForGame) return;
17791789 const appInfo = window.appStore?.m_mapApps?.get(appId);
@@ -1803,7 +1813,6 @@ def check_if_shortcut_exists(display_name, exe_path, start_dir, launch_options):
18031813 }
18041814 requestAnimationFrame(watchUrl);
18051815
1806- // ------------------------ Steam Game Start ------------------------
18071816 if (window.SteamClient?.Apps?.RegisterForGameActionStart) {
18081817 SteamClient.Apps.RegisterForGameActionStart((appID) => {
18091818 if (stoppingMusic) return;
0 commit comments